diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e645270 --- /dev/null +++ b/.gitignore @@ -0,0 +1,353 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ diff --git a/Buffs/Dusk.cs b/Buffs/Dusk.cs new file mode 100644 index 0000000..efc8457 --- /dev/null +++ b/Buffs/Dusk.cs @@ -0,0 +1,19 @@ +using Terraria; +using Terraria.ModLoader; + +namespace Starflower.Buffs +{ + class Dusk : ModBuff + { + public override void SetDefaults() + { + DisplayName.SetDefault("Weapon Imbue: Dusk"); + Description.SetDefault("Melee attacks put your foes to sleep"); + } + + public override void Update(Player player, ref int buffIndex) + { + player.GetModPlayer().hasDusk = true; + } + } +} diff --git a/Buffs/Dusk.png b/Buffs/Dusk.png new file mode 100644 index 0000000..e39b461 Binary files /dev/null and b/Buffs/Dusk.png differ diff --git a/Buffs/Nightfall.cs b/Buffs/Nightfall.cs new file mode 100644 index 0000000..8a4979c --- /dev/null +++ b/Buffs/Nightfall.cs @@ -0,0 +1,20 @@ +using Terraria.ModLoader; +using Terraria; + +namespace Starflower.Buffs +{ + class Nightfall : ModBuff + { + public override void SetDefaults() + { + DisplayName.SetDefault("Nightfall"); + Description.SetDefault("It's your bedtime."); + } + + public override void Update(NPC npc, ref int buffIndex) + { + // Move at 1/2 speed. + npc.velocity /= 2; + } + } +} \ No newline at end of file diff --git a/Buffs/Nightfall.png b/Buffs/Nightfall.png new file mode 100644 index 0000000..e39b461 Binary files /dev/null and b/Buffs/Nightfall.png differ diff --git a/Buffs/ShootingStar.cs b/Buffs/ShootingStar.cs new file mode 100644 index 0000000..10f55ad --- /dev/null +++ b/Buffs/ShootingStar.cs @@ -0,0 +1,20 @@ +using Terraria; +using Terraria.ModLoader; + +namespace Starflower.Buffs +{ + public class ShootingStar : ModBuff + { + + public override void SetDefaults() + { + DisplayName.SetDefault("Shooting Star"); + Description.SetDefault("20% increased bullet damage"); + } + + public override void Update(Player player, ref int buffIndex) + { + player.bulletDamage *= 1.2f; + } + } +} diff --git a/Buffs/ShootingStar.png b/Buffs/ShootingStar.png new file mode 100644 index 0000000..038360c Binary files /dev/null and b/Buffs/ShootingStar.png differ diff --git a/Buffs/Starlight.cs b/Buffs/Starlight.cs new file mode 100644 index 0000000..60f88c0 --- /dev/null +++ b/Buffs/Starlight.cs @@ -0,0 +1,21 @@ +using Terraria; +using Terraria.ModLoader; + +namespace Starflower.Buffs +{ + public class Starlight : ModBuff + { + + public override void SetDefaults() + { + DisplayName.SetDefault("Starlight"); + Description.SetDefault("Twinkle twinkle little star."); + } + + public override void Update(Player player, ref int buffIndex) + { + // Xpos, Ypos, Red, Green, Blue. Brightness corresponds to size of RGB numbers. + Lighting.AddLight((int)(player.position.X + (float)(player.width / 2)) / 16, (int)(player.position.Y + (float)(player.height / 2)) / 16, 5f, 5f, 2.5f); + } + } +} diff --git a/Buffs/Starlight.png b/Buffs/Starlight.png new file mode 100644 index 0000000..d2a0ae7 Binary files /dev/null and b/Buffs/Starlight.png differ diff --git a/Items/FlaskOfDusk.cs b/Items/FlaskOfDusk.cs new file mode 100644 index 0000000..de6588b --- /dev/null +++ b/Items/FlaskOfDusk.cs @@ -0,0 +1,48 @@ +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using static Terraria.ModLoader.ModContent; + +namespace Starflower.Items +{ + public class FlaskOfDusk : ModItem + { + public override void SetStaticDefaults() + { + Tooltip.SetDefault("Melee attacks put your foes to sleep\n10 minute duration"); + } + + public override void SetDefaults() + { + item.width = 16; + item.height = 26; + item.useStyle = ItemUseStyleID.EatingUsing; + item.useAnimation = 17; + item.useTime = 17; + item.useTurn = true; + item.UseSound = SoundID.Item3; + item.maxStack = 30; + item.consumable = true; + item.rare = 1; + item.value = 80; + } + + public override bool UseItem(Player player) + { + player.AddBuff(BuffType(), 36000); + return true; + } + + public override void AddRecipes() + { + ModRecipe recipe = new ModRecipe(mod); + recipe.AddIngredient(ItemID.BottledWater); + recipe.AddIngredient(ItemID.Daybloom); + recipe.AddIngredient(ItemID.Moonglow); + recipe.AddIngredient(mod, "Starflower"); + recipe.AddTile(TileID.ImbuingStation); + recipe.SetResult(this); + recipe.AddRecipe(); + } + } +} \ No newline at end of file diff --git a/Items/FlaskOfDusk.png b/Items/FlaskOfDusk.png new file mode 100644 index 0000000..1e6f0e2 Binary files /dev/null and b/Items/FlaskOfDusk.png differ diff --git a/Items/ShootingStarPotion.cs b/Items/ShootingStarPotion.cs new file mode 100644 index 0000000..715413c --- /dev/null +++ b/Items/ShootingStarPotion.cs @@ -0,0 +1,48 @@ +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Starflower.Items +{ + public class ShootingStarPotion : ModItem + { + public override void SetStaticDefaults() + { + Tooltip.SetDefault("20% increased bullet damage\n5 minute duration"); + } + + public override void SetDefaults() + { + item.width = 16; + item.height = 30; + item.useStyle = ItemUseStyleID.EatingUsing; + item.useAnimation = 17; + item.useTime = 17; + item.useTurn = true; + item.UseSound = SoundID.Item3; + item.maxStack = 30; + item.consumable = true; + item.rare = 1; + item.value = 80; + } + + public override bool UseItem(Player player) + { + player.AddBuff(mod.BuffType("ShootingStar"), 18000); + return true; + } + + public override void AddRecipes() + { + ModRecipe recipe = new ModRecipe(mod); + recipe.AddIngredient(ItemID.BottledWater); + recipe.AddIngredient(ItemID.Shiverthorn); + recipe.AddIngredient(mod, "Starflower"); + recipe.AddIngredient(ItemID.FallenStar); + recipe.AddTile(TileID.Bottles); + recipe.SetResult(this); + recipe.AddRecipe(); + } + + } +} diff --git a/Items/ShootingStarPotion.png b/Items/ShootingStarPotion.png new file mode 100644 index 0000000..d077fa6 Binary files /dev/null and b/Items/ShootingStarPotion.png differ diff --git a/Items/Starflower.cs b/Items/Starflower.cs new file mode 100644 index 0000000..a4945e8 --- /dev/null +++ b/Items/Starflower.cs @@ -0,0 +1,15 @@ +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Starflower.Items { + public class Starflower : ModItem { + + public override void SetDefaults() { + item.maxStack = 99; + item.width = 14; + item.height = 18; + item.value = 80; + } + } +} diff --git a/Items/Starflower.png b/Items/Starflower.png new file mode 100644 index 0000000..f927922 Binary files /dev/null and b/Items/Starflower.png differ diff --git a/Items/StarflowerPlanterBox.cs b/Items/StarflowerPlanterBox.cs new file mode 100644 index 0000000..1af12cc --- /dev/null +++ b/Items/StarflowerPlanterBox.cs @@ -0,0 +1,45 @@ +using Terraria.ID; +using Terraria.ModLoader; +using static Terraria.ModLoader.ModContent; + +namespace Starflower.Items +{ + public class StarflowerPlanterBox : ModItem + { + public static bool isCraftable; + + public override void SetStaticDefaults() + { + Tooltip.SetDefault("Only starflowers can grow in this arcane soil\nIt's not a bug, it's lore"); + } + + public override void SetDefaults() + { + item.maxStack = 999; + item.width = 24; + item.height = 20; + item.value = 100; + item.autoReuse = true; + item.useTurn = true; + item.useStyle = 1; + item.useAnimation = 15; + item.useTime = 10; + item.consumable = true; + item.createTile = mod.TileType("StarflowerPlanterBox"); + } + + public override void AddRecipes() + { + if (GetInstance().isPlanterBoxCraftingEnabled) + { + ModRecipe recipe = new ModRecipe(mod); + recipe.AddIngredient(ItemID.DirtBlock, 2); + recipe.AddRecipeGroup("Wood", 2); + recipe.AddIngredient(mod, "StarflowerSeeds"); + recipe.AddTile(TileID.WorkBenches); + recipe.SetResult(this); + recipe.AddRecipe(); + } + } + } +} diff --git a/Items/StarflowerPlanterBox.png b/Items/StarflowerPlanterBox.png new file mode 100644 index 0000000..d98e03c Binary files /dev/null and b/Items/StarflowerPlanterBox.png differ diff --git a/Items/StarflowerSeeds.cs b/Items/StarflowerSeeds.cs new file mode 100644 index 0000000..55e88ba --- /dev/null +++ b/Items/StarflowerSeeds.cs @@ -0,0 +1,23 @@ +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using static Terraria.ModLoader.ModContent; + +namespace Starflower.Items { + public class StarflowerSeeds : ModItem { + + public override void SetDefaults() { + item.autoReuse = true; + item.useTurn = true; + item.useStyle = 1; + item.useAnimation = 15; + item.useTime = 10; + item.maxStack = 99; + item.consumable = true; + item.width = 12; + item.height = 14; + item.value = 80; + item.createTile = TileType(); + } + } +} diff --git a/Items/StarflowerSeeds.png b/Items/StarflowerSeeds.png new file mode 100644 index 0000000..bd7d273 Binary files /dev/null and b/Items/StarflowerSeeds.png differ diff --git a/Items/StarlightPotion.cs b/Items/StarlightPotion.cs new file mode 100644 index 0000000..4162ae7 --- /dev/null +++ b/Items/StarlightPotion.cs @@ -0,0 +1,58 @@ +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; + +namespace Starflower.Items +{ + public class StarlightPotion : ModItem + { + public override void SetStaticDefaults() + { + Tooltip.SetDefault("Emits a powerful aura of light\n3 minute duration"); + } + + public override void SetDefaults() + { + item.width = 16; + item.height = 30; + item.useStyle = ItemUseStyleID.EatingUsing; + item.useAnimation = 17; + item.useTime = 17; + item.useTurn = true; + item.UseSound = SoundID.Item3; + item.maxStack = 30; + item.consumable = true; + item.rare = 1; + item.value = 80; + } + + public override bool UseItem(Player player) + { + player.AddBuff(mod.BuffType("Starlight"), 10800); + return true; + } + + public override void AddRecipes() + { + // Topaz version + ModRecipe recipe = new ModRecipe(mod); + recipe.AddIngredient(ItemID.BottledWater); + recipe.AddIngredient(ItemID.Blinkroot); + recipe.AddIngredient(mod, "Starflower"); + recipe.AddIngredient(ItemID.Topaz); + recipe.AddTile(TileID.Bottles); + recipe.SetResult(this); + recipe.AddRecipe(); + // Amythest version + recipe = new ModRecipe(mod); + recipe.AddIngredient(ItemID.BottledWater); + recipe.AddIngredient(ItemID.Blinkroot); + recipe.AddIngredient(mod, "Starflower"); + recipe.AddIngredient(ItemID.Amethyst); + recipe.AddTile(TileID.Bottles); + recipe.SetResult(this); + recipe.AddRecipe(); + } + + } +} diff --git a/Items/StarlightPotion.png b/Items/StarlightPotion.png new file mode 100644 index 0000000..b492de6 Binary files /dev/null and b/Items/StarlightPotion.png differ diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json new file mode 100644 index 0000000..14574ad --- /dev/null +++ b/Properties/launchSettings.json @@ -0,0 +1,14 @@ +{ + "profiles": { + "Terraria": { + "commandName": "Executable", + "executablePath": "$(tMLPath)", + "workingDirectory": "$(TerrariaSteamPath)" + }, + "TerrariaServer": { + "commandName": "Executable", + "executablePath": "$(tMLServerPath)", + "workingDirectory": "$(TerrariaSteamPath)" + } + } +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..5458515 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Starflower + diff --git a/Starflower.cs b/Starflower.cs new file mode 100644 index 0000000..fb8121c --- /dev/null +++ b/Starflower.cs @@ -0,0 +1,7 @@ +using Terraria.ModLoader; + +namespace Starflower { + public class Starflower : Mod { + public Starflower() { } + } +} diff --git a/Starflower.csproj b/Starflower.csproj new file mode 100644 index 0000000..3f53d78 --- /dev/null +++ b/Starflower.csproj @@ -0,0 +1,13 @@ + + + + + Starflower + net45 + x86 + latest + + + + + \ No newline at end of file diff --git a/StarflowerConfig.cs b/StarflowerConfig.cs new file mode 100644 index 0000000..1b7727a --- /dev/null +++ b/StarflowerConfig.cs @@ -0,0 +1,16 @@ +using System.ComponentModel; +using Terraria.ModLoader.Config; + +namespace Starflower +{ + class StarflowerServerConfig : ModConfig + { + public override ConfigScope Mode => ConfigScope.ServerSide; + + [Label("Craftable starflower planter boxes")] + [Tooltip("Provides an alternative way of getting starflower planter boxes,\nin case there's no room for the item in the dryad's shop because you have so many mods installed.\nRequires a reload to take effect.")] + [DefaultValue(false)] + [ReloadRequired] + public bool isPlanterBoxCraftingEnabled; + } +} diff --git a/StarflowerGlobalNPC.cs b/StarflowerGlobalNPC.cs new file mode 100644 index 0000000..3aec5f0 --- /dev/null +++ b/StarflowerGlobalNPC.cs @@ -0,0 +1,19 @@ +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using static Terraria.ModLoader.ModContent; + +namespace Starflower +{ + class StarflowerGlobalNPC : GlobalNPC + { + public override void SetupShop(int type, Chest shop, ref int nextSlot) + { + if (type == NPCID.Dryad && NPC.downedSlimeKing) + { + shop.item[nextSlot].SetDefaults(ItemType()); + nextSlot++; + } + } + } +} \ No newline at end of file diff --git a/StarflowerGlobalTile.cs b/StarflowerGlobalTile.cs new file mode 100644 index 0000000..e6b45eb --- /dev/null +++ b/StarflowerGlobalTile.cs @@ -0,0 +1,22 @@ +using Terraria.ModLoader; +using Terraria; +using Terraria.ID; +using static Terraria.ModLoader.ModContent; + +namespace Starflower +{ + class StarflowerGlobalTile : GlobalTile + { + public override bool CanPlace(int i, int j, int type) + { + if (type == TileID.ImmatureHerbs) + { + if (Main.tile[i, j].type == TileType()) + { + return false; + } + } + return base.CanPlace(i, j, type); + } + } +} \ No newline at end of file diff --git a/StarflowerPlayer.cs b/StarflowerPlayer.cs new file mode 100644 index 0000000..395bb17 --- /dev/null +++ b/StarflowerPlayer.cs @@ -0,0 +1,45 @@ +using Terraria.ModLoader; +using Terraria; +using Terraria.ID; +using static Terraria.ModLoader.ModContent; + +namespace Starflower +{ + class StarflowerPlayer : ModPlayer + { + public bool hasDusk; + + public override void ResetEffects() + { + hasDusk = false; + } + + // Moved into it's own method so I don't have to repeat code. + private void ApplyNightfall(NPC target) + { + // Nightfall will not apply to bosses. + if (!target.boss) + { + target.AddBuff(BuffType(), 60 * Main.rand.Next(5, 10), false); + } + } + + // Melee weapons. + public override void OnHitNPC(Item item, NPC target, int damage, float knockback, bool crit) + { + if (hasDusk) + { + ApplyNightfall(target); + } + } + + // Ranged weapons with melee damage type. + public override void OnHitNPCWithProj(Projectile proj, NPC target, int damage, float knockback, bool crit) + { + if ((proj.melee) && hasDusk && !proj.noEnchantments) + { + ApplyNightfall(target); + } + } + } +} \ No newline at end of file diff --git a/StarflowerWorld.cs b/StarflowerWorld.cs new file mode 100644 index 0000000..ad8afee --- /dev/null +++ b/StarflowerWorld.cs @@ -0,0 +1,91 @@ +using Microsoft.Xna.Framework; +using System.Collections.Generic; +using Terraria; +using Terraria.ID; +using Terraria.GameContent.Generation; +using Terraria.ModLoader; +using Terraria.World.Generation; +using static Terraria.ModLoader.ModContent; + +namespace Starflower +{ + public class StarflowerWorld : ModWorld + { + public override void ModifyWorldGenTasks(List tasks, ref float totalWeight) + { + // Generate at some arbitrary point after sky islands but before trees, because otherwise trees break for some reason. + // Right after silt just happens to be the arbitrary point I chose, because I couldn't guess the sky island ID. + // Tree breaking is fixed by checking if a starflower can be placed before trying to place it. + int genIndex = tasks.FindIndex(genpass => genpass.Name.Equals("Silt")); + tasks.Insert(genIndex + 1, new PassLegacy("Planting Starflower", GenerateStarflower)); + } + + private void GenerateStarflower(GenerationProgress progress) + { + progress.Message = "Planting Starflower"; + + for (int k = 0; k < (int)((double)(Main.maxTilesX * Main.maxTilesY) * 1E-06); k++) + { + GenerateOneStarflower(skyOnly: true); + } + } + + // Called every frame. + public override void PostUpdate() + { + // Complex math copied from source code. It's weirdly specific, but whatever, it works. + // Value from 151 to 422.8 representing world size + int starflowerGenerateChance = (int)MathHelper.Lerp(151, (float)151 * 2.8f, MathHelper.Clamp((float)Main.maxTilesX / 4200f - 1f, 0f, 1f)); + // Value from 151.2 to 604.8 also representing world size. + float numTilesToUpdate = (float)(Main.maxTilesX * Main.maxTilesY) * 3E-05f * (float)Main.worldRate; // worldRate defaults to 1. + for (int i = 0; (float)i < numTilesToUpdate; i++) + { + // Very low chance + if (Main.rand.Next(500) == 0 && Main.rand.Next(starflowerGenerateChance) == 0) + { + GenerateOneStarflower(skyOnly: false); + } + } + } + + private void GenerateOneStarflower(bool skyOnly) + { + int yLimit; + if (skyOnly) + { + yLimit = (int)WorldGen.worldSurfaceLow; + } + else + { + yLimit = Main.maxTilesY - 20; + } + int attempts = 0; + int starflowerID = TileType(); + Tile tile; + Tile tileBelow; + bool placeSuccessful = false; + while (!placeSuccessful) + { + attempts++; + // Pick a location. + int x = WorldGen.genRand.Next(20, Main.maxTilesX - 20); + int y = WorldGen.genRand.Next(20, yLimit); + tile = Main.tile[x, y]; + tileBelow = Main.tile[x, y + 1]; + // Attempt to place tile. + // Starflower cannot be placed on active tiles, or if the tile below is inactive, a half brick, sloped, or a planter box. + if (!tile.active() && tileBelow.nactive() && !tileBelow.halfBrick() && tileBelow.slope() == 0 && tileBelow.type != TileID.PlanterBox && tileBelow.type != TileType()) + { + WorldGen.PlaceTile(x, y, starflowerID, true); + // Check if place was successful. + placeSuccessful = tile.active() && tile.type == starflowerID; + } + // Don't allow infinite loops. + if (attempts >= 30000) + { + return; + } + } + } + } +} diff --git a/Tiles/Starflower.cs b/Tiles/Starflower.cs new file mode 100644 index 0000000..9a0749f --- /dev/null +++ b/Tiles/Starflower.cs @@ -0,0 +1,83 @@ +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.ID; +using Terraria.ModLoader; +using Terraria.ObjectData; +using static Terraria.ModLoader.ModContent; + +namespace Starflower.Tiles +{ + public class Starflower : ModTile + { + public override void SetDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileCut[Type] = true; + Main.tileNoFail[Type] = true; + soundType = 6; + TileObjectData.newTile.CopyFrom(TileObjectData.StyleAlch); + TileObjectData.newTile.AnchorValidTiles = new int[] { + TileID.Cloud, + TileID.RainCloud + }; + TileObjectData.newTile.AnchorAlternateTiles = new int[] { + TileID.ClayPot, + TileID.PlanterBox, + TileType() + }; + TileObjectData.addTile(Type); + } + + public override bool CanPlace(int i, int j) + { + // Starflower cannot be placed on herbs or itself. + if (Main.tileAlch[Main.tile[i, j].type] || Main.tile[i, j].type == Type) + { + return false; + } + return true; + } + + public override void SetSpriteEffects(int i, int j, ref SpriteEffects spriteEffects) + { + if (i % 2 == 1) + { + spriteEffects = SpriteEffects.FlipHorizontally; + } + } + + public override bool Drop(int i, int j) + { + int growthStage = Main.tile[i, j].frameX / 15; + if (growthStage > 0) + { + // I thought this was a workaround but it turns out the source code does it this way too. Ech. + if (Main.player[Player.FindClosest(new Microsoft.Xna.Framework.Vector2(i * 16, j * 16), 0, 0)].HeldItem.netID == ItemID.StaffofRegrowth) + { + Item.NewItem(i * 16, j * 16, 0, 0, mod.ItemType("StarflowerSeeds"), Main.rand.Next(1, 6)); + Item.NewItem(i * 16, j * 16, 0, 0, mod.ItemType("Starflower"), Main.rand.Next(1, 3)); + } + else if (growthStage == 2) + { + Item.NewItem(i * 16, j * 16, 0, 0, mod.ItemType("StarflowerSeeds"), Main.rand.Next(1, 4)); + Item.NewItem(i * 16, j * 16, 0, 0, mod.ItemType("Starflower")); + } + } + // Tells game not to use default drop. Method won't work without a return statement. + return false; + } + + // Not sure why 15 is the number considering my textures are 14 pixels wide, and 18 is the number for 16 pixel wide textures. + public override void RandomUpdate(int i, int j) + { + if (Main.tile[i, j].frameX == 0) + { + Main.tile[i, j].frameX += 15; + } + else if (Main.tile[i, j].frameX == 15) + { + Main.tile[i, j].frameX += 15; + } + } + } +} diff --git a/Tiles/Starflower.png b/Tiles/Starflower.png new file mode 100644 index 0000000..7de0ec1 Binary files /dev/null and b/Tiles/Starflower.png differ diff --git a/Tiles/StarflowerPlanterBox.cs b/Tiles/StarflowerPlanterBox.cs new file mode 100644 index 0000000..1a9ef0a --- /dev/null +++ b/Tiles/StarflowerPlanterBox.cs @@ -0,0 +1,52 @@ +using Terraria; +using Terraria.ModLoader; +// TODO: Herbs should not be possible to cut with weapon swings when on this. +// TODO: Make weeds grow on this. +// TODO: Make smart cursor treat this like a planter box. +// TODO: Allow vanilla herbs to be placed on this. + +namespace Starflower.Tiles +{ + public class StarflowerPlanterBox : ModTile + { + public override void SetDefaults() + { + Main.tileSolid[Type] = true; + Main.tileSolidTop[Type] = true; + Main.tileFrameImportant[Type] = true; + Main.tileTable[Type] = true; + Main.tileSpelunker[Type] = true; + drop = mod.ItemType("StarflowerPlanterBox"); + } + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + Tile tile = Main.tile[i, j]; + Tile left = Main.tile[i - 1, j]; + Tile right = Main.tile[i + 1, j]; + if (tile == null || left == null || right == null) + { + return false; + } + bool isLeftSame = left.type == tile.type; + bool isRightSame = right.type == tile.type; + if (isLeftSame && isRightSame) + { + tile.frameX = 18; + } + else if (isLeftSame && !isRightSame) + { + tile.frameX = 36; + } + else if (!isLeftSame && isRightSame) + { + tile.frameX = 0; + } + else + { + tile.frameX = 54; + } + return true; + } + } +} diff --git a/Tiles/StarflowerPlanterBox.png b/Tiles/StarflowerPlanterBox.png new file mode 100644 index 0000000..78c9a92 Binary files /dev/null and b/Tiles/StarflowerPlanterBox.png differ diff --git a/build.txt b/build.txt new file mode 100644 index 0000000..ed01b68 --- /dev/null +++ b/build.txt @@ -0,0 +1,5 @@ +author = AlurienFlame +version = 1.0 +displayName = Starflower +buildIgnore = *.csproj, obj\*, bin\*, .vs\* + diff --git a/description.txt b/description.txt new file mode 100644 index 0000000..640d33d --- /dev/null +++ b/description.txt @@ -0,0 +1,7 @@ +Adds an herb that spawns on sky islands, +a planter box to go with it, +and three potions crafted from it. + +- Starlight Potion: Emits a powerful aura of light +- Shooting Star Potion: 20% increased bullet damage +- Flask of Dusk: Melee attacks slow enemies \ No newline at end of file