diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index f39547848..8634e9230 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -5,9 +5,9 @@ name: .NET Build and Test on: push: - branches: [ "master" ] + branches: [ "master", "Yggdrasil/newContent0"] pull_request: - branches: [ "master" ] + branches: [ "master", "Yggdrasil/newContent0"] jobs: build-and-test: diff --git a/Libraries/ModLiquidLib.dll b/Libraries/ModLiquidLib.dll new file mode 100644 index 000000000..5cc5b7ac9 Binary files /dev/null and b/Libraries/ModLiquidLib.dll differ diff --git a/Libraries/ModLiquidLib.xml b/Libraries/ModLiquidLib.xml new file mode 100644 index 000000000..a17b6d58a --- /dev/null +++ b/Libraries/ModLiquidLib.xml @@ -0,0 +1,1238 @@ + + + + ModLiquidLib + + + + Whether or not this tile counts as a this liquid's source for crafting purposes. + + + The Item created when a bucket is used on a liquid selected + + + Whats Items a liquid can be absorbed by. Used for defining sponges. + + + Whether or not the NPC can spawn in the liquid specified. NOTE: only works for modded liquids and npcs + + + Whether or not the liquid uses the water loot pool when fished it. NOTE: this set does not effect/change Water, lava or honey and is mainly used for modded liquids. + + + + This class allows you to modify the behavior of any liquid in the game, both vanilla and modded. +
To use it, simply create a new class deriving from this one. Implementations will be registered automatically. +
+
+ + + Allows you to draw things behind the liquid at the given coordinates. Return false to stop the game from drawing the liquid normally. Returns true by default. + This method is only called in "Color" and "White" lighting modes. Use for the other Lighting modes pre drawing + + The x position in tile coordinates. + The y position in tile coordinates. + + The LiquidDrawCache of the rendering + The amount the liquid rendered is offset by + Whether or not the liquid is in the background + + + + Allows you to draw things in front of the liquid at the given coordinates. This can also be used to do things such as rendering glowmasks. + This hook is not called if returns false. + This method is only called in "Color" and "White" lighting modes. Use for the other Lighting modes post drawing + + The x position in tile coordinates. + The y position in tile coordinates. + + The LiquidDrawCache of the rendering + The amount the liquid rendered is offset by + Whether or not the liquid is in the background + + + + Allows you to make stuff happen whenever the liquid at the given coordinates is drawn. For example, creating bubble dusts or changing the color the liquid is drawn in. + This hook is seperate from Liquid Rendering, Only use this for things such as spawning particles. + Return false to stop Lava from spawning some of its bubbles. Returns true by default. + + The x position in tile coordinates. + The y position in tile coordinates. + + Various information about the liquid that is being drawn, such as opacity, visual liquid, etc. + + + + Allows you to draw things behind the liquid at the given coordinates. Return false to stop the game from drawing the liquid normally. Returns true by default. + This method is only called in "Retro" and "Trippy" lighting modes. Use for the other Lighting modes pre drawing + + The x position in tile coordinates. + The y position in tile coordinates. + + + + + + Allows you to draw things in front of the liquid at the given coordinates. This can also be used to do things such as rendering glowmasks. + This hook is not called if returns false. + This method is only called in "Retro" and "Trippy" lighting modes. Use for the other Lighting modes post drawing + + The x position in tile coordinates. + The y position in tile coordinates. + + + + + + Allows you to make stuff happen whenever the liquid at the given coordinates is drawn. For example, creating bubble dusts or changing the color the liquid is drawn in. + This hook is not called if returns false. + + The x position in tile coordinates. + The y position in tile coordinates. + + + Various information about the liquid that is being drawn, such as color, opacity, waterfall length, etc. + Gets the amount of liquid in a tile for retro rendering + Gets the number of quality the game has for retro rendering + + + + Allows you to draw things behind the liquid at the given coordinates. Return false to stop the game from drawing the liquid normally. Returns true by default. + Only called for liquid slopes. If you want to predraw the liquid itself, see or + + The x position in tile coordinates. + The y position in tile coordinates. + + Whether or not the slope is rendered behind tiles + The rendering position of the slope. Use this rather than x/y as the rendering can be offset sometimes + The size of the liquid + The color of the liquid. Usually the light color of the liquid + + + + Allows you to draw things in front of the liquid at the given coordinates. This can also be used to do things such as rendering glowmasks. + This hook is not called if returns false. + Only called for liquid slopes. If you want to postdraw the liquid itself, see or + + The x position in tile coordinates. + The y position in tile coordinates. + + Whether or not the slope is rendered behind tiles + The rendering position of the slope. Use this rather than x/y as the rendering can be offset sometimes + The size of the liquid + The color of the liquid. Usually the light color of the liquid + + + + Allows you to determine how much light this liquid emits.
+ It can also let you light up the block in front of this liquid.
+ See for vanilla tile light values to use as a reference.
+
+ The x position in tile coordinates. + The y position in tile coordinates. + + The red component of light, usually a value between 0 and 1 + The green component of light, usually a value between 0 and 1 + The blue component of light, usually a value between 0 and 1 +
+ + + Allows for disabling lava bubbles in "Retro" and "Trippy" lighting modes. Only calls when lava's PreRetroDraw isnt false. Returns false by default. + + The x position in tile coordinates. + The y position in tile coordinates. + + + + + The ID of the waterfall/liquidfall style the game should use when the liquid is near a half block. + Returns null by default. + + The x position in tile coordinates. + The y position in tile coordinates. + + + + + Allows the changing of liquid movement in-game as well as allowing you to do other stuff with liquids during updates such as custom evaporation. Returns true by default. + + The x position in tile coordinates. + The y position in tile coordinates. + + + + + + + Allows you to make liquids evaporate in the underworld. Also allows for disabling of water evaporation. Returns null by default. + + The x position in tile coordinates. + The y position in tile coordinates. + + + + + + Allows you to change how liquids move when loading or creating a world. Returns true by default. + + The x position in tile coordinates. + The y position in tile coordinates. + + + + + + Used to change what tile the liquid generates upon coming in contact with another liquid. Use the otherLiquid param to check what liquid this liquid is interacting with.
+ This method is called even if a tile isn't generated. It is recommended that modders use a non-frame important tile as the result, otherwise the tile may fail to generate.
+ It is recomended that developers use PreLiquidMerge for handling custom collisions and effects as that method is only called when a tile is requested to generate.
+ This hook is still called, even if PreLiquidMerge is returned false.
+ NOTE: it is encouraged to set a default tile that this liquid results in, otherwise it will default to stone.
+ Returns 1 by default. +
+ The x position in tile coordinates. + The y position in tile coordinates. + + The liquid ID of the liquid colliding with this one. + +
+ + + Used to modify the sound thats played when two liquids merge with each other.
+ Called every time liquids collide and only on clients.
+ Is not called if PreLiquidMerge returns false. +
+ The x position in tile coordinates. + The y position in tile coordinates. + + The liquid ID of the liquid colliding with this one. + The sound to be played, set this to a sound if you don't want the default merge sound to play. +
+ + + Used to do do extra effects and special merges when two liquids collide with each other. Use the otherLiquid param to check which liquid is colliding with this liquid.
+ NOTE: this method is called ONLY on servers when in multiplayer. Make sure you send a packet if you want to do extra visual effects. To learn more about handling custom packets, please see .
+ Return false to prevent the normal liquid merging logic.
+ Retruns true by default. +
+ The x position of the target liquid in tile coordinates
+ NOTE: This may not always mean the x position of THIS liquid, as it may mean the x position of the other liquid. + The y position of the target liquid in tile coordinates
+ NOTE: This may not always mean the y position of THIS liquid, as it may mean the y position of the other liquid. + The x position of where the tile is sechedualed to generate at in tile coordninates.
+ NOTE: most of the time this x position is the same as liquid's x position, this means that the tile is being generated over the liquid.
+ Useful for when trying to do something else other than generating a tile. + The y position of where the tile is sechedualed to generate at in tile coordninates.
+ NOTE: most of the time this y position is the same as liquid's y position, this means that the tile is being generated over the liquid.
+ Useful for when trying to do something else other than generating a tile. + + The Liquid ID of the liquid colliding with this liquid + +
+ + + Allows the editing of how fast liquids fall, return null for the regular liquid falling to apply.
+ For Modded Liquids, use ModLiquid.FallDelay property to edit how fast your liquid falls. This method can be used to edit other mod liquids falling as well.
+ Returns null by default
+ NOTE: liquids can only have a maximum fall delay of 10 (which is the same as the fall of Honey), this is due to the delay being reset to 10 when in quickfall mode. +
+ + +
+ + + Allows you to determine which liquids the given liquid type can be considered as when looking for avaliable liquids. + + + + + + + Allows the user to specify whether the liquid prevents the placement or blockswap of a tile over this liquid. Usually used by lava to stop players from placing ontop of it.
+ Return true for the liquid to prevent tile placement, return false if the liquid can have tiles placed over it. Return null for the default logic to run.
+ Returns null by default. +
+ The player instance thats attempting to place a tile over the liquid. + The x position in tile coordinates. + The y position in tile coordinates. + + +
+ + + Allows you to decide what happens when the player enters and exits this liquid. Vanilla liquids use this to spawn dusts and make a splashing noise when a player enters and leaves.
+ Players now also have a moddedWet array to show which modded liquids are being entered in at a time. Please see array on how to use it.
+ Return true to allow the liquids to call their normal splash code. Returns true by default. +
+ The player instance thats entering or exiting the liquid. + + Whether the currently the liquid is being entered or exited. +
+ + + Allows you to decide what happens when a NPC enters and exits this liquid. Vanilla liquids use this to spawn dusts and make a splashing noise when a NPC enters and leaves.
+ NPCs now also have a moddedWet array to show which modded liquids are being entered in at a time. Please see array on how to use it.
+ Return true to allow the liquids to call their normal splash code. Returns true by default. +
+ The NPC instance thats entering or exiting the liquid. + + Whether the currently the liquid is being entered or exited. +
+ + + Allows you to decide what happens when a projectile enters and exits this liquid. Vanilla liquids use this to spawn dusts and make a splashing noise when a projectile enters and leaves.
+ Projectiles now also have a moddedWet array to show which modded liquids are being entered in at a time. Please see array on how to use it.
+ Return true to allow the liquids to call their normal splash code. Returns true by default. +
+ The projectile instance thats entering or exiting the liquid. + + Whether the currently the liquid is being entered or exited. +
+ + + Allows you to decide what happens when a fishing bobber catches a fish. Water uses this to create extra water bubbles and to make a splash sound.
+ Return false to disable the water splashing fishing bobbers create. +
+ The projectile instance thats fishing in the liquid. + + +
+ + + Allows you to decide what happens when an item enters and exits this liquid. Vanilla liquids use this to spawn dusts and make a splashing noise when an item enters and leaves.
+ Items now also have a moddedWet array to show which modded liquids are being entered in at a time. Please see array on how to use it.
+ Return true to allow the liquids to call their normal splash code. Returns true by default. +
+ The item instance thats entering or exiting the liquid. + + Whether the currently the liquid is being entered or exited. +
+ + + Allows the user to specify how a liquid interacts with the player (especially player movement).
+ Please see , , or to see how vanilla handles it's liquid collision.
+ Return true for the liquid to use the normal liquid collision code.
+ Returns true by default. +
+ The player instance thats being effected by the liquid. + + Whether or not the player is falling through the liquid. + Whether or not the player ignores platforms when falling. + +
+ + + Allows the user to specify how a liquid interacts with the player (especially player gravity).
+ Please see , to see how vanilla handles it's liquid gravity. +
+ The player instance thats being effected by the liquid. + + The current player.gravity being changed. + The current player.maxFallSpeed being changed. + The current Player.jumpHeight being changed. + The current Player.jumpSpeed being changed. +
+ + + Allows the user to specify how a liquid interacts with an item (especially item gravity and movement).
+ Please see , to see how vanilla handles it's liquid collision.

+ This method is also used to modify items detected to be in liquids. Use this to do things such as deleting items touching this liquid. +
+ The item instance thats being effected by the liquid. + + The velocity of the item when in the liquid. + The gravity of the item. + The maximum fall speed of the item. +
+ + + Allows the user to specify how a liquid interacts with a npc (especially npc movement).
+ Please see , to see how vanilla handles it's liquid collision.
+ Return true for the liquid to call the method that applies the liquid velocity multiplier.
+ Returns true by default. +
+ The npc instance thats being effected by the liquid. + + The velocity of the NPC before being modified by the liquid. + +
+ + + Allows the user to specify how a liquid interacts with an npc (especially npc gravity).
+ Please see , to see how vanilla handles it's liquid collision. +
+ The npc instance thats being effected by the liquid. + + The gravity of the npc. + The maximum fall speed of the npc. +
+ + + Allows the user to specify how a liquid interacts with a projectile (especially projectile movement).
+ Please see , to see how vanilla handles it's liquid collision.
+ Return true for the liquid to use the normal liquid collision code.
+ Returns true by default. +
+ The projectile instance thats being effected by the liquid. + + The velocity of the item when in the liquid. + The position of where the projectile is calculated when colliding with this liquid. + The modified width of this projectile. + The modified height of this projectile. + Whether or not the projectile can fall through. + +
+ + + Hook for deciding whether a liquid should allow or disallow, when overtop of the Collision.CheckDrowning position, to be considered drowning or not.
+ Not to be confused with CanPlayersDrown, which is a hook called every frame to check if the player is drowning or not. Useful for making items such as a Breething Reed.
+ Return null to execute the normal Collision.CheckDrowning behaviour. Returns null by default. +
+ + +
+ + + Hook for deciding whether a liquid should emit breath dusts when a player or npc is slowly drowning.
+ ChecksForDrowning must be set to true for this to run. + Return null to execute the normal breath behaviour. Returns null by default. +
+ + +
+ + + Allows you to give conditions for when the game attempts to check to see if the player is drowning.
+ Set isDrowning to either true or false depending on whether the player should or should not be drowning.
+ This is used by items such as the Breething Reed to make the player be submerged deeper underwater.
+ Please see for how vanilla uses the isDrowning boolean flag.
+ ChecksForDrowning must be set to true for this to run. Not to be confused with ChecksForDrowning hook. +
+ The player instance thats being effected by the liquid. + + The boolean flag for whether or not the player is drowning. +
+ + + The multiper responsable for the poolsize of liquid being fished in.
+ Honey uses this to multiply its pool size by 1.5x, this means that honey only needs a minimum of 50 tiles rather than 75 tiles of liquid. +
+ + The multiplier used, for most liquids this will be 1, but for honey it's 1.5. +
+ + + Allows bobbers to ignore the application of the shimmer effect when being wet by shimmer.
+ This allows modders to easily enable fishing in shimmer. Do keep in mind, the fishing loot normally is water. +
+ +
+ + + The opacity liquid slopes render at. Lava uses this to render at 1f opacity, and honey does the following calculation for it's opacity:
+ Math.Max(0.5f * 1.7f, 1f)
+ The game does additional calulations after this hook to get the final opacity. Use this method to edit liquid slope's default opacity to render at.
+ slopeOpacity defaults at 0.5f. +
+ + The opacity already given to a liquid. Edit this to change the default liquid slope opacity. +
+ + + Allows you to change the Light Mask Mode for any liquid. The Light Mask Mode is the mask for lighting to determine how light interacts with a liquid.
+ Vanilla has options for Water (slight blue fade) and Honey (dark black) while lava uses the None option.
+
+ The x position in tile coordinates. + The y position in tile coordinates. + + Edit this param to change the Light Mask Mode of the liquid. +
+ + + The multiplier used when the Waves qaulity setting is set to Medium.
+ Honey and Lava set this multiplier to be 0.3x.
+ This setting is to make waves go the same distance no matter the liquid. For some reason vanilla manually applies a multiplier rather than doing seperate math for the wave speed. +
+ + The multiplier used, for most liquids this will be 1f, but for honey and lava it's 0.3. +
+ + + Allows manipulation of tiles when grass burns. This allows modders to make grasses burn with a liquid or do other interactions if a liquid is nearby a tile.
+ Only effects tiles in a 9x9 area around a liquid and only executes every few seconds.
+ Can be used to allow modders to make sure their grasses burn when near lava. +
+ The x position in tile coordinates. + The y position in tile coordinates. + + The x position of the liquid in tile coordinates. + The y position of the liquid in tile coordinates. +
+ + + Allows modders to do extra interactions when a liquid is pumped.
+ Works similarly to a Pre hook, executing before any liquids are moved for each pump.
+ Return true for pumps to execute their normal liquid moving logic.
+ Returns true by default. +
+ + The x position of the in pump in tile coordinates. + The y position of the in pump in tile coordinates. + The x position of the out pump in tile coordinates. + The y position of the out pump in tile coordinates. + +
+ + + A hook to modify a liquid's stopwatch MPH multiplier whether that be modder or vanilla liquids.
+ Water has its multiplier set to 0.5, honey 0.25 and shimmer 0.375 as an example of existing values. +
+ + The multiplier for the stopwatch MPH. +
+ + + Executed whenever the collision check for players is executed and found true. + This is used for adding de/buffs, damaging the player or incrimenting/deincrementing timers or ModPlayer fields. + Vanilla liquids use this to add buffs or debuffs such as On Fire!, Honey, or Shimmering. + + The player instance being effected by this liquid. + + + + + Executed whenever the collision check for NPCs is executed and found true. + This is used for adding debuffs, damaging the npc or incrimenting/deincrementing timers or GlobalNPC fields. + Vanilla liquids use this to damage the NPC and apply On Fire! when touching lava. + + The NPC instance being effected by this liquid. + + + + + Executed whenever the collision check for projectiles is executed and found true. + This is used for changing projectile types, killing projectiles, and doing other misc effects. + Vanilla liquids use this to transforming flaming arrows into arrows and killing flamethrower flames. + + The Projectile instance being effected by this liquid. + + + + + Allows you to animate a liquid.
+ Returning false will cause the liquid/s to nolonger play an animation.
+ Use frameState to keep track of how long the current frame has been active, and use frame to change the current frame.
+ GameTime has also been provided to check the current seconds that has overlapped ingame.
+ Returns true by default. +
+ + The current amount of time that has passed since the game has been opened. + The current frame the liquid is on. + The current frame counter the liquid is on. + +
+ + + Allows you to modify the ripple strength and offset when an NPC enters, exists and moves through a liquid.
+ This is executed right before QueueRipple is called in Terraria.GameContent.Shaders.WaterShaderData.DrawWaves. +
+ The NPC instance moving through the liquid. + + The strength and size of a ripple. + The offset of a ripple. +
+ + + Allows you to modify the ripple strength and offset when a player enters, exists and moves through a liquid.
+ This is executed right before QueueRipple is called in Terraria.GameContent.Shaders.WaterShaderData.DrawWaves. +
+ The player moving through the liquid. + + The strength and size of a ripple. + The offset of a ripple. +
+ + + Contains extra hooks for ModTile that are useful for liquid implementatiom. + + + + + Creates a waterfall at the tile position.
+ Useful when creating a tile similar to rain or snow cloud blocks. +
+ The x position in tile coordinates. + The y position in tile coordinates. + +
+ + + Allows the rendering of this tile in liquids.
+ Lily pads use this hook to draw themselves to liquids so water ripples/waves effect those tiles. +
+ The x position in tile coordinates. + The y position in tile coordinates. + +
+ + + Gets the ModLiquid instance with the given type. If no ModLiquid with the given type exists, returns null. + + + + + + + + Get the id (type) of a ModLiquid by class. Assumes one instance per class. + + + + + This class represents a type of liquid that can be added by a mod. Only one instance of this class will ever exist for each type of liquid that is added. Any hooks that are called will be called by the instance corresponding to the liquid type. This is to prevent the game from using a massive amount of memory storing liquid instances.
+
+
+ + The Liquid ID of this Modded Liquid + + + The block texture of this liquid. Used for some slope framing and when liquids are rendered in retro lighting modes. + + + The slope texture of this liquid. Used for rendering the liquids next to tile slopes. + + + The default sound that plays when an entity enters and exits this liquid. Overriding any OnSplash hooks/methods will prevent this from being used. + + + The default dust ID thats used when an entity enters and exists this liquid. Overriding any OnSplash hooks/methods will prevent this from being used. + + + Liquids can only have a maximum fall delay of 10 (which is the same as the fall of Honey), this is due to the delay being reset to 10 when in quickfall mode. + + + The vanilla ID of what should replace the instance when a user unloads and subsequently deletes data from your mod in their save file. Defaults to 0. + + + An array of the IDs of liquids that this tile can be considered as when looking for available liquids. + + + The check in Collision that checks if a coord will be drowning in water. + + + Whether or not, when drowning, a player or npc will emit dusts from their mouth. + + + The multiplier used to change how many tiles are needed to fish in a pool of liquid. Honey uses a 1.5x multiplier for its pool size. + + + The multiplier used only when Waves quality setting is set to Medium. Honey and Lava use this to set the modifier to 0.3x. + + + The opacity that this liquid slope renders at. Lava and Honey use this to look thicker. Defaults to 0.5f. + + + The multiplier thats used to specify how slow (or fast) the player moves while in this liquid. + + + The multiplier used for stopwatches to know how to offset the MPH reading. + + + The default value that ModLiquidNPC.moddedLiquidMovementSpeed sets to before ModNPC.SetDefaults + + + The multiplier thats used to specify how slow (or fast) projectiles move while in this liquid. + + + Uses lava based collision check for when applying this liquid's wet boolean.
+ This means collision is more sensitive, and the wet is active even when touching the smallest amount of this liquid.
+
+ + Whether or not this liquid removes the On Fire! debuffs when entering. + + + The multiplier repsonsible for multiplying how much opacity each step in this liquid's fall should be drawn at. +
Only effects slopes when underground (similar to other liquids).
+
+ + + Adds an entry to the minimap for this liquid with the given color and display name. This should be called in SetDefaults. + + + + + +

Overload specific: This overload has an additional parameter. This function will be used to dynamically adjust the hover text. The parameters for the function are the default display name, x-coordinate, and y-coordinate. +
+
+ + + Legacy helper method for creating a localization sub-key MapEntry + + + + + + Allows you to modify the properties after initial loading has completed. +
This is where you would set the properties of this liquid. Many properties are stored as arrays throughout Terraria's code. +
For example: + + WATERFALL_LENGTH = 10 + DefaultOpacity = 0.6f; + VisualViscosity = 0; + +
+
+ + + Allows you to choose which minimap entry the liquid at the given coordinates will use. 0 is the first entry added by AddMapEntry, 1 is the second entry, etc. Returns 0 by default. + + The x position in tile coordinates. + The y position in tile coordinates. + + + + Allows you to draw things behind the liquid at the given coordinates. Return false to stop the game from drawing the liquid normally. Returns true by default. + This method is only called in "Color" and "White" lighting modes. Use for the other Lighting modes pre drawing + + The x position in tile coordinates. + The y position in tile coordinates. + The LiquidDrawCache of the rendering + The amount the liquid rendered is offset by + Whether or not the liquid is in the background + + + + Allows you to draw things in front of the liquid at the given coordinates. This can also be used to do things such as rendering glowmasks. + This hook is not called if returns false. + This method is only called in "Color" and "White" lighting modes. Use for the other Lighting modes post drawing + + The x position in tile coordinates. + The y position in tile coordinates. + The LiquidDrawCache of the rendering + The amount the liquid rendered is offset by + Whether or not the liquid is in the background + + + + Allows you to make stuff happen whenever the liquid at the given coordinates is drawn. For example, creating bubble dusts or changing the color the liquid is drawn in. + This hook is seperate from Liquid Rendering, Only use this for things such as spawning particles. + + The x position in tile coordinates. + The y position in tile coordinates. + Various information about the liquid that is being drawn, such as opacity, visual liquid, etc. + + + + Allows you to draw things behind the liquid at the given coordinates. Return false to stop the game from drawing the liquid normally. Returns true by default. + This method is only called in "Retro" and "Trippy" lighting modes. Use for the other Lighting modes pre drawing + + The x position in tile coordinates. + The y position in tile coordinates. + + + + + Allows you to draw things in front of the liquid at the given coordinates. This can also be used to do things such as rendering glowmasks. + This hook is not called if returns false. + This method is only called in "Retro" and "Trippy" lighting modes. Use for the other Lighting modes post drawing + + The x position in tile coordinates. + The y position in tile coordinates. + + + + + Allows you to make stuff happen whenever the liquid at the given coordinates is drawn. For example, creating bubble dusts or changing the color the liquid is drawn in. + This hook is not called if returns false. + + The x position in tile coordinates. + The y position in tile coordinates. + + Various information about the liquid that is being drawn, such as color, opacity, waterfall length, etc. + Gets the amount of liquid in a tile for retro rendering + Gets the number of quality the game has for retro rendering + + + + Allows you to draw things behind the liquid at the given coordinates. Return false to stop the game from drawing the liquid normally. Returns true by default. + Only called for liquid slopes. If you want to predraw the liquid itself, see or + + The x position in tile coordinates. + The y position in tile coordinates. + Whether or not the slope is rendered behind tiles + The rendering position of the slope. Use this rather than x/y as the rendering can be offset sometimes + The size of the liquid + The color of the liquid. Usually the light color of the liquid + + + + Allows you to draw things in front of the liquid at the given coordinates. This can also be used to do things such as rendering glowmasks. + This hook is not called if returns false. + Only called for liquid slopes. If you want to postdraw the liquid itself, see or + + The x position in tile coordinates. + The y position in tile coordinates. + Whether or not the slope is rendered behind tiles + The rendering position of the slope. Use this rather than x/y as the rendering can be offset sometimes + The size of the liquid + The color of the liquid. Usually the light color of the liquid + + + + Allows you to determine how much light this liquid emits.
+ It can also let you light up the block in front of this liquid.
+ See for vanilla tile light values to use as a reference.
+
+ The x position in tile coordinates. + The y position in tile coordinates. + The red component of light, usually a value between 0 and 1 + The green component of light, usually a value between 0 and 1 + The blue component of light, usually a value between 0 and 1 +
+ + + Modifies the LightMaskMode used for this liquid.
+ Due to limitations in the lighting engine, tile coordinates and editing of vanilla lightmasks are unavaliable.
+ NOTE: set LiquidLightMaskMode to None for this hook/method to be called. Otherwise this liquid will use the other mask mode instead. +
+ The current LightMap index. Water uses this to randomise its colors slightly. + The red component of light, usually a value between 0 and 1 + The green component of light, usually a value between 0 and 1 + The blue component of light, usually a value between 0 and 1 +
+ + + Allows you to change the Light Mask Mode for this liquid. The Light Mask Mode is the mask for lighting to determine how light interacts with this liquid.
+ Vanilla has options for Water (slight blue fade) and Honey (dark black) while lava uses the None option.
+ Defaults to LightMaskMode.None. +
+ The x position in tile coordinates. + The y position in tile coordinates. +
+ + + The ID of the waterfall/liquidfall style the game should use when this liquid is near a half block + + The x position in tile coordinates. + The y position in tile coordinates. + + + + Allows the changing of liquid movement in-game as well as allowing you to do other stuff with liquids during updates such as custom evaporation. Returns true by default. + + The x position in tile coordinates. + The y position in tile coordinates. + + + + + + Allows you to make your liquid evaporate like water when in the underworld. Returns false by default. + + The x position in tile coordinates. + The y position in tile coordinates. + + + + + Allows you to change how your liquid moves when loading or creating a world. Returns true by default. + + The x position in tile coordinates. + The y position in tile coordinates. + + + + + Used to change what tile the liquid generates upon coming in contact with another liquid. Use the otherLiquid param to check what liquid this liquid is interacting with.
+ This method is called even if a tile isn't generated. It is recommended that modders use a non-frame important tile as the result, otherwise the tile may fail to generate.
+ It is recomended that developers use PreLiquidMerge for handling custom collisions and effects as that method is only called when a tile is requested to generate.
+ This hook is still called, even if PreLiquidMerge is returned false.
+ NOTE: it is encouraged to set a default tile that this liquid results in, otherwise it will default to stone.
+ Returns 1 by default. +
+ The x position in tile coordinates. + The y position in tile coordinates. + The liquid ID of the liquid colliding with this one. + +
+ + + Used to modify the sound thats played when two liquids merge with each other.
+ Called every time liquids collide and only on clients.
+ Is not called if PreLiquidMerge returns false. +
+ The x position in tile coordinates. + The y position in tile coordinates. + The liquid ID of the liquid colliding with this one. + The sound to be played, set this to a sound if you don't want the default merge sound to play. +
+ + + Used to do do extra effects and special merges when two liquids collide with each other. Use the otherLiquid param to check which liquid is colliding with this liquid.
+ NOTE: this method is called ONLY on servers when in multiplayer. Make sure you send a packet if you want to do extra visual effects. To learn more about handling custom packets, please see .
+ Return false to prevent the normal liquid merging logic.
+ Retruns true by default. +
+ The x position of the target liquid in tile coordinates
+ NOTE: This may not always mean the x position of THIS liquid, as it may mean the x position of the other liquid. + The y position of the target liquid in tile coordinates
+ NOTE: This may not always mean the y position of THIS liquid, as it may mean the y position of the other liquid. + The x position of where the tile is sechedualed to generate at in tile coordninates.
+ NOTE: most of the time this x position is the same as liquid's x position, this means that the tile is being generated over the liquid.
+ Useful for when trying to do something else other than generating a tile. + The y position of where the tile is sechedualed to generate at in tile coordninates.
+ NOTE: most of the time this y position is the same as liquid's y position, this means that the tile is being generated over the liquid.
+ Useful for when trying to do something else other than generating a tile. + The Liquid ID of the liquid colliding with this liquid + +
+ + + Allows the user to specify whether the liquid prevents the placement or blockswap of a tile over this liquid. Usually used by lava to stop players from placing ontop of it.
+ Return true for the liquid to prevent tile placement, return false if the liquid can have tiles placed over it.
+ Returns false by default. +
+ The player instance thats attempting to place a tile over the liquid. + The x position in tile coordinates. + The y position in tile coordinates. + +
+ + + Allows you to decide what happens when the player enters and exits this liquid. Vanilla liquids use this to spawn dusts and make a splashing noise when a player enters and leaves.
+ Players now also have a moddedWet array to show which modded liquids are being entered in at a time. Please see array on how to use it.
+ Return false for the liquid to not execute the default modded liquid splash code.
+ Returns true by default. +
+ The player instance thats entering or exiting the liquid. + Whether the currently the liquid is being entered or exited. + +
+ + + Allows you to decide what happens when a NPC enters and exits this liquid. Vanilla liquids use this to spawn dusts and make a splashing noise when a NPC enters and leaves.
+ NPCs now also have a moddedWet array to show which modded liquids are being entered in at a time. Please see array on how to use it.
+ Return false for the liquid to not execute the default modded liquid splash code.
+ Returns true by default. +
+ The NPC instance thats entering or exiting the liquid. + Whether the currently the liquid is being entered or exited. + +
+ + + Allows you to decide what happens when a projectile enters and exits this liquid. Vanilla liquids use this to spawn dusts and make a splashing noise when a projectile enters and leaves.
+ Projectiles now also have a moddedWet array to show which modded liquids are being entered in at a time. Please see array on how to use it.
+ Return false for the liquid to not execute the default modded liquid splash code.
+ Returns true by default. +
+ The projectile instance thats entering or exiting the liquid. + Whether the currently the liquid is being entered or exited. + +
+ + + Allows you to decide what happens when an item enters and exits this liquid. Vanilla liquids use this to spawn dusts and make a splashing noise when an item enters and leaves.
+ Items now also have a moddedWet array to show which modded liquids are being entered in at a time. Please see array on how to use it.
+ Return false for the liquid to not execute the default modded liquid splash code.
+ Returns true by default. +
+ The item instance thats entering or exiting the liquid. + Whether the currently the liquid is being entered or exited. + +
+ + + Allows you to decide what happens when a fishing bobber catches a fish. Water uses this to create extra water bubbles and to make a splash sound. /// + The projectile instance thats fishing in the liquid. + + + + + Allows the user to specify how the liquid interacts with the player (especially player movement).
+ Please see , , or to see how vanilla handles it's liquid collision.
+ Return true for the liquid to use the normal liquid collision code.
+ Returns true by default. +
+ The player instance thats being effected by the liquid. + Whether or not the player is falling through the liquid. + Whether or not the player ignores platforms when falling. + +
+ + + Allows the user to specify how the liquid interacts with the player (especially player gravity).
+ Please see , to see how vanilla handles it's liquid gravity. +
+ The player instance thats being effected by the liquid. + The current player.gravity being changed. + The current player.maxFallSpeed being changed. + The current Player.jumpHeight being changed. + The current Player.jumpSpeed being changed. +
+ + + Allows the user to specify how the liquid interacts with an item (especially item gravity and movement).
+ Please see , to see how vanilla handles it's liquid collision.

+ This method is also used to modify items detected to be in liquids. Use this to do things such as deleting items touching this liquid. +
+ The item instance thats being effected by the liquid. + The velocity of the item when in the liquid. + The gravity of the item. + The maximum fall speed of the item. +
+ + + Allows the user to specify how the liquid interacts with an npc (especially npc movement).
+ Please see , to see how vanilla handles it's liquid collision.
+ Return true for the liquid to call the method that applies the liquid velocity multiplier.
+ Returns true by default. +
+ The npc instance thats being effected by the liquid. + The velocity of the NPC before being modified by the liquid. + +
+ + + Allows the user to specify how the liquid interacts with an npc (especially npc gravity).
+ Please see , to see how vanilla handles it's liquid gravity. +
+ The npc instance thats being effected by the liquid. + The gravity of the npc. + The maximum fall speed of the npc. +
+ + + Allows the user to specify how the liquid interacts with a projectile (especially projectile movement).
+ Please see , to see how vanilla handles it's liquid collision.
+ Return true for the liquid to use the normal liquid collision code.
+ Returns true by default. +
+ The projectile instance thats being effected by the liquid. + The velocity of the item when in the liquid. + The position of where the projectile is calculated when colliding with this liquid. + The modified width of this projectile. + The modified height of this projectile. + Whether or not the projectile can fall through. + +
+ + + Allows you to give conditions for when the game attempts to check to see if the player is drowning.
+ Set isDrowning to either true or false depending on whether the player should or should not be drowning.
+ This is used by items such as the Breething Reed to make the player be submerged deeper underwater.
+ Please see for how vanilla uses the isDrowning boolean flag.
+ ChecksForDrowning must be set to true for this to run. Not to be confused with ChecksForDrowning. +
+ The player instance thats being effected by the liquid. + The boolean flag for whether or not the player is drowning. +
+ + + Allows manipulation of tiles when grass burns. This allows modders to make grasses burn with their liquid or do other interactions if a liquid is nearby a tile.
+ Only effects tiles in a 9x9 area around a liquid and only executes every few seconds. +
+ The x position in tile coordinates. + The y position in tile coordinates. + The x position of the liquid in tile coordinates. + The y position of the liquid in tile coordinates. +
+ + + Allows modders to do extra interactions when their liquid is pumped.
+ Works similarly to a Pre hook, executing before any liquids are moved for each pump.
+ Return true for pumps to execute their normal liquid moving logic.
+ Returns true by default. +
+ The x position of the in pump in tile coordinates. + The y position of the in pump in tile coordinates. + The x position of the out pump in tile coordinates. + The y position of the out pump in tile coordinates. + +
+ + + Executed whenever the collision check for players is executed and found true. + This is used for adding de/buffs, damaging the player or incrimenting/deincrementing timers or ModPlayer fields. + Vanilla liquids use this to add buffs or debuffs such as On Fire!, Honey, or Shimmering. + + The player instance being effected by this liquid. + + + + Executed whenever the collision check for NPCs is executed and found true. + This is used for adding debuffs, damaging the npc or incrimenting/deincrementing timers or GlobalNPC fields. + Vanilla liquids use this to damage the NPC and apply On Fire! when touching lava. + + The NPC instance being effected by this liquid. + + + + Executed whenever the collision check for projectiles is executed and found true. + This is used for changing projectile types, killing projectiles, and doing other misc effects. + Vanilla liquids use this to transforming flaming arrows into arrows and killing flamethrower flames. + + The Projectile instance being effected by this liquid. + + + + Allows you to animate your liquid.
+ Overriding this method will prevent normal vanilla liquid animations from playing, allowing you to animate without interference.
+ Use frameState to keep track of how long the current frame has been active, and use frame to change the current frame.
+ GameTime has also been provided to check the current seconds that has overlapped ingame. +
+ The current amount of time that has passed since the game has been opened. + The current frame the liquid is on. + The current frame counter the liquid is on. +
+ + + Allows you to modify the ripple strength and offset when an NPC enters, exists and moves through this liquid.
+ This is executed right before QueueRipple is called in Terraria.GameContent.Shaders.WaterShaderData.DrawWaves. +
+ The NPC instance moving through the liquid. + The strength and size of a ripple. + The offset of a ripple. +
+ + + Allows you to modify the ripple strength and offset when a player enters, exists and moves through this liquid.
+ This is executed right before QueueRipple is called in Terraria.GameContent.Shaders.WaterShaderData.DrawWaves. +
+ The player moving through the liquid. + The strength and size of a ripple. + The offset of a ripple. +
+ + + The current frame of the waterfall + + + + + The background frame of the waterfall (used for custom rain waterfalls) + + + + + The frame counter of the waterfall + + + + + Allows you to draw things behind the waterfall at the given coordinates. Return false to stop the game from drawing the waterfall normally. Returns true by default. + + The current waterfall data. + The x position in tile coordinates. + The Y position in tile coordinates. + + + + + + Allows you to draw things in front of the waterfall at the given coordinates. This can also be used to do things such as rendering glowmasks. + + The current waterfall data, this is used inside of the waterfalls WaterfallData array. + The x position in tile coordinates. + The Y position in tile coordinates. + + + + + + Allows you to animate your waterfall.
+ Overriding this method will make your waterfall nolonger animate normally.

+ Use frame to specify which frame the waterfall is using currently.

+ Use frameBackground to specify which background frame the waterfall is using. (This normally goes unused, but is very useful for modders looking into drawing their own waterfalls manually).
+ Rain clouds use this to specify the framing of the rain behind the main rain waterfall.

+ Use frameCounter to specify the duration between frames.

+ Please see ModLiquidExampleMod.Content.Waterfalls.BloodClotLiquidFall.AnimateWaterfall or ModLiquidExampleMod.Content.Waterfalls.HoneyRain.AnimateWaterfall. +
+ Waterfalls use this to know what frame to use when drawing. + Unused normally, can be used by modders for extra framing. + Used to specify a certain amount of time between waterfall frames. +
+ + + Edits the opacity of the waterfall. For example: Waterfalls have an opacity of 60% (0.6f) which allows you to see some stuff behind them, while Lavafalls have an opacity of 100% (1f) which prevents you from seeing anything behind.
+ Returns null be default. +
+ The x position in tile coordinates. + The Y position in tile coordinates. + The current waterfall water style alpha + The maximum length of the waterfall + + Tile at the waterfall position + +
+ + + Allows you to prevent the waterfall/liquidfall from making any water sounds when on screen. This is useful for waterfalls/liquidfalls that arent made of water. Returns true by default. + + + + + + Modded liquids start at the index of 0 as vanilla liquids are recorded in their own seperate fields.
+ Use (id - LiquidID.Count) to get the correct modded liquid ID wet type +
+
+ + + Modded liquids start at the index of 0 as vanilla liquids are recorded in their own seperate fields.
+ Use (id - LiquidID.Count) to get the correct modded liquid ID movement speed +
+
+ + + The X position of the Tile + + + + + + + The Y position of the Tile + + + + + + + Gets the Position of the tile, the same values that would be inputted in Main.tile to get this Tile + + + The outputted X value, if you want the X by itself use Tile.X + The outputted Y value, if you want the Y by itself use Tile.Y + + + + Adds a required crafting liquid with the given liquid type to this recipe. Ex: recipe.AddLiquid(LiquidID.Lava) + + + The liquid identifier. + No liquid has ID " + liquidID + + + + Adds a required crafting liquid to this recipe with the given liquid name from the given mod. If the mod parameter is null, then it will automatically use a liquid from the mod creating this recipe. + + + The mod. + Name of the liquid. + The liquid " + liquidName + " does not exist in mod " + mod.Name + ". If you are trying to use a vanilla tile, try using Recipe.AddLiquid(liquidID). + + + + Adds a required crafting liquid to this recipe of the given type of liquid. + + + The liquid. + + + + Adds a required crafting liquid to this recipe of the given type of liquid. + + +
+
diff --git a/Sources/Everglow.Core/Utilities/MathUtils.Geometry.cs b/Sources/Everglow.Core/Utilities/MathUtils.Geometry.cs index 07b565dc3..d706a6de9 100644 --- a/Sources/Everglow.Core/Utilities/MathUtils.Geometry.cs +++ b/Sources/Everglow.Core/Utilities/MathUtils.Geometry.cs @@ -1,3 +1,5 @@ +using Terraria; + namespace Everglow.Commons.Utilities; public static partial class MathUtils @@ -32,6 +34,38 @@ public static float ToRotationSafe(this Vector2 vector, float defaultValue = def } } + /// + /// 判定2D 圆形与 AABB 是å¦ç›¸äº¤ï¼ˆè¾¹ç•Œç®—相交) + /// + /// + /// + /// + /// + /// + public static bool IntersectsCircleAABB(Vector2 circleCenter, float radius, Vector2 aabbMin, Vector2 aabbMax) + { + float closestX = Math.Clamp(circleCenter.X, aabbMin.X, aabbMax.X); + float closestY = Math.Clamp(circleCenter.Y, aabbMin.Y, aabbMax.Y); + + float dx = circleCenter.X - closestX; + float dy = circleCenter.Y - closestY; + + return (dx * dx + dy * dy) <= (radius * radius); + } + + /// + /// 判定2D 圆形与 AABB 是å¦ç›¸äº¤ï¼ˆè¾¹ç•Œç®—相交) + /// + /// + /// + /// + /// + /// + public static bool IntersectsCircleAABB(Vector2 circleCenter, float radius, Rectangle hitBox) + { + return IntersectsCircleAABB(circleCenter, radius, hitBox.TopLeft(), hitBox.BottomRight()); + } + /// /// 2D 多边形与 AABB 是å¦ç›¸äº¤ /// @@ -177,6 +211,23 @@ public static bool IsPointInPolygon(List polygon, Vector2 point) return isInside; } + // Distance from point pos to line defined by points a and b + public static float PointToLineDistance(Vector2 a, Vector2 b, Vector2 pos) + { + float dx = b.X - a.X; + float dy = b.Y - a.Y; + + float numerator = MathF.Abs(dy * pos.X - dx * pos.Y + b.X * a.Y - b.Y * a.X); + float denominator = MathF.Sqrt(dx * dx + dy * dy); + + if (denominator < float.Epsilon) + { + return (pos - a).Length(); // a and b are same point + } + + return numerator / denominator; + } + /// /// 判断点是å¦åœ¨çº¿æ®µä¸Š /// @@ -303,6 +354,48 @@ public static bool DoLineSegmentsIntersectByAlgebra(Vector2 p1, Vector2 p2, Vect return r >= 0 && r <= 1 && s >= 0 && s <= 1; } + /// + /// 获å–2D多边形包围盒(AABB) + /// + /// + /// + public static Rectangle GetPolygonAABBBound_Rectangle(List polygon) + { + if (polygon == null || polygon.Count < 3) + { + return Rectangle.emptyRectangle; + } + + Vector4 v4 = GetPolygonAABBBound_Vector4(polygon); + return new Rectangle((int)v4.X, (int)v4.Y, (int)(v4.Z - v4.X), (int)(v4.W - v4.Y)); + } + + /// + /// 获å–2D多边形包围盒(AABB) + /// + /// + /// (minX, minY, maxX, maxY) çš„ Vector4 结构 + public static Vector4 GetPolygonAABBBound_Vector4(List polygon) + { + if (polygon == null || polygon.Count < 3) + { + return Vector4.zero; + } + + float minX = float.MaxValue; + float minY = float.MaxValue; + float maxX = float.MinValue; + float maxY = float.MinValue; + foreach (Vector2 p in polygon) + { + minX = MathF.Min(minX, p.X); + minY = MathF.Min(minY, p.Y); + maxX = MathF.Max(maxX, p.X); + maxY = MathF.Max(maxY, p.Y); + } + return new Vector4(minX, minY, maxX, maxY); + } + /// /// 校验多边形边是å¦ç›¸äº¤ï¼ˆç›¸é‚»è¾¹é™¤å¤–,é¿å…自相交多边形)(未完æˆ) /// diff --git a/Sources/Everglow.Core/VFX/VFXBatch.cs b/Sources/Everglow.Core/VFX/VFXBatch.cs index bcabd9eb2..a7e3e4db0 100644 --- a/Sources/Everglow.Core/VFX/VFXBatch.cs +++ b/Sources/Everglow.Core/VFX/VFXBatch.cs @@ -12,7 +12,7 @@ public class VFXBatch : IDisposable private const int MAX_INDICES = MAX_VERTICES * 3; //numbers Copy from SpriteBatch - private const int MAX_VERTICES = 8192; + private const int MAX_VERTICES = 1048576; private List buffers = new(); diff --git a/Sources/Everglow.Function/DeveloperContent/Items/TileDataReader.cs b/Sources/Everglow.Function/DeveloperContent/Items/TileDataReader.cs index 4a2371977..9fbc66bf9 100644 --- a/Sources/Everglow.Function/DeveloperContent/Items/TileDataReader.cs +++ b/Sources/Everglow.Function/DeveloperContent/Items/TileDataReader.cs @@ -3,6 +3,8 @@ using Everglow.Commons.Vertex; using Everglow.Commons.VFX; using Everglow.Commons.VFX.Pipelines; +using Terraria; +using Terraria.ObjectData; namespace Everglow.Commons.DeveloperContent.Items; @@ -54,6 +56,7 @@ public class TileDataReaderSystem : Visual public Point FixPoint; public static List OwnerPlayerWhoAmI = new List(); public List ContinueTiles = new List(); + public List SurfaceTiles = new List(); public List CheckLiquidTiles = new List(); public Point OldTilePos = new Point(0, 0); public bool EverLasting = false; @@ -110,7 +113,7 @@ public override void Draw() OwnerPlayerWhoAmI.Remove(player.whoAmI); return; } - Tile tile = Main.tile[i, j]; + Tile tile = TileUtils.SafeGetTile(i, j); int colorType = ItemRarityID.White; Color drawColor = Color.White; if (!tile.HasTile) @@ -119,20 +122,31 @@ public override void Draw() drawColor = Color.Gray; } DrawBlockBound(i, j, drawColor); - if (ContinueTiles.Count < MaxContinueCount) + if (tile.HasTile) { - var drawContinueColor = new Color(0.12f, 0.24f, 0.4f, 0); - foreach (Point point in ContinueTiles) + if (ContinueTiles.Count < MaxContinueCount) + { + var drawContinueColor = new Color(0.12f, 0.24f, 0.4f, 0); + foreach (var check_tile in ContinueTiles) + { + DrawBlockBound(check_tile.X, check_tile.Y, drawContinueColor); + } + } + if (SurfaceTiles.Count < MaxContinueCount) { - DrawBlockBound(point.X, point.Y, drawContinueColor); + var drawSurfaceTilesColor = new Color(0.8f, 0.03f, 0.06f, 0); + foreach (var check_tile in SurfaceTiles) + { + DrawBlockBound(check_tile.X, check_tile.Y, drawSurfaceTilesColor); + } } } if (CheckLiquidTiles.Count < MaxContinueCount) { var drawContinueColor = new Color(0.0f, 0.0f, 0.6f, 0); - foreach (Point point in CheckLiquidTiles) + foreach (var check_tile in CheckLiquidTiles) { - DrawBlockBound(point.X, point.Y, drawContinueColor); + DrawBlockBound(check_tile.X, check_tile.Y, drawContinueColor); } } string datas = GetDatas(i, j); @@ -146,6 +160,7 @@ public string GetDatas(int i, int j) string datas = "\nCoordinate: [" + i + ", " + j + "]"; datas += "\nHasTile: " + tile.HasTile; datas += "\nType :" + tile.TileType; + //datas += "\nPaint :" + tile.BlockColorAndCoating().Invisible; if (tile.HasTile) { datas += " " + TileID.Search.GetName(tile.TileType); @@ -154,10 +169,31 @@ public string GetDatas(int i, int j) { datas += "\nContinue Tiles : " + ContinueTiles.Count; } + if (SurfaceTiles.Count < MaxContinueCount) + { + datas += "\nSurface Tiles : " + SurfaceTiles.Count; + } + int multiStyle = TileObjectData.GetTileStyle(tile); + if (multiStyle >= 0) + { + datas += "\nMultiTile Style: " + multiStyle; + } } if (!tile.HasTile) { - datas += "\nCan Fill Liquid Blocks: " + CheckLiquidTiles.Count; + if (CheckLiquidTiles.Count <= 900) + { + datas += "\nCan Fill Liquid Blocks: " + CheckLiquidTiles.Count; + } + } + //float waterLine; + //Collision.GetWaterLine(i, j, out waterLine); + //datas += "\n" + waterLine; + + if (tile.WallType > WallID.None) + { + datas += "\nWallType :" + tile.WallType; + datas += " " + WallID.Search.GetName(tile.WallType); } // datas += "\nSlope: " + tile.Slope; @@ -171,105 +207,16 @@ public string GetDatas(int i, int j) /// public void UpdateContinueTiles(int i, int j) { - ContinueTiles = new List(); - CheckLiquidTiles = new List(); - BFSContinueTile(i, j); - BFSFillLiquid(i, j); - } - - private static readonly (int, int)[] directions = - { - (0, 1), - (1, 0), - (0, -1), - (-1, 0), - }; - - private static readonly (int, int)[] directionsLiquid = - { - (1, 0), - (0, 1), - (-1, 0), - }; - - public void BFSContinueTile(int i, int j) - { - BFSContinueTile(new Point(i, j)); - } - - public void BFSContinueTile(Point checkPoint) - { - var queueChecked = new Queue(); - - // 将起始点加入队列 - queueChecked.Enqueue(checkPoint); - var visited = new List(); - - while (queueChecked.Count > 0) + Tile tile = TileUtils.SafeGetTile(i, j); + if (tile.HasTile) { - var tilePos = queueChecked.Dequeue(); - - foreach (var (dx, dy) in directions) - { - int checkX = tilePos.X + dx; - int checkY = tilePos.Y + dy; - var point = new Point(checkX, checkY); - Tile tile = TileUtils.SafeGetTile(checkX, checkY); - - // 检查边界和障ç¢ç‰© - if (checkX >= 20 && checkX < Main.maxTilesX - 20 && checkY >= 20 && checkY < Main.maxTilesY - 20 && - tile.HasTile && !visited.Contains(point)) - { - queueChecked.Enqueue(point); - visited.Add(point); - } - } - if (queueChecked.Count > MaxContinueCount || visited.Count > MaxContinueCount) - { - break; - } + SurfaceTiles = TileUtils.BFSSurface(new Point(i, j), 625); + ContinueTiles = TileUtils.BFSContinueTile(new Point(i, j), false, 625); } - ContinueTiles = visited; - } - - public void BFSFillLiquid(int i, int j) - { - BFSFillLiquid(new Point(i, j)); - } - - public void BFSFillLiquid(Point checkPoint) - { - var queueChecked = new Queue(); - - // 将起始点加入队列 - queueChecked.Enqueue(checkPoint); - var visited = new List(); - - while (queueChecked.Count > 0) + else { - var tilePos = queueChecked.Dequeue(); - - foreach (var (dx, dy) in directionsLiquid) - { - int checkX = tilePos.X + dx; - int checkY = tilePos.Y + dy; - var point = new Point(checkX, checkY); - Tile tile = TileUtils.SafeGetTile(checkX, checkY); - - // 检查边界和障ç¢ç‰© - if (checkX >= 20 && checkX < Main.maxTilesX - 20 && checkY >= 20 && checkY < Main.maxTilesY - 20 && - !Collision.IsWorldPointSolid(point.ToWorldCoordinates()) && !visited.Contains(point)) - { - queueChecked.Enqueue(point); - visited.Add(point); - } - } - if (queueChecked.Count > MaxContinueCount || visited.Count > MaxContinueCount) - { - break; - } + CheckLiquidTiles = TileUtils.BFSGetCanFillLiquidTiles(i, j); } - CheckLiquidTiles = visited; } public void DrawBlockBound(int i, int j, Color color) diff --git a/Sources/Everglow.Function/DeveloperContent/Items/TileFliper.cs b/Sources/Everglow.Function/DeveloperContent/Items/TileFliper.cs new file mode 100644 index 000000000..441a46b5c --- /dev/null +++ b/Sources/Everglow.Function/DeveloperContent/Items/TileFliper.cs @@ -0,0 +1,44 @@ +namespace Everglow.Commons.DeveloperContent.Items; + +public class TileFliper : ModItem +{ + public override string LocalizationCategory => Utilities.LocalizationUtils.Categories.Tools; + + public bool EnableFlipSystem = false; + + public override void SetDefaults() + { + Item.DamageType = DamageClass.Magic; + Item.damage = 0; + Item.width = 34; + Item.height = 34; + Item.useTime = 2; + Item.useAnimation = 2; + Item.useStyle = ItemUseStyleID.Swing; + Item.noMelee = true; + Item.value = 0; + Item.rare = ItemRarityID.White; + Item.UseSound = SoundID.Item44; + Item.noUseGraphic = true; + } + + public override void HoldItem(Player player) + { + // if(Main.mouseLeft && Main.mouseLeftRelease && !EnableFlipSystem) + // { + // EnableFlipSystem = true; + // } + if (!EnableFlipSystem) + { + EnableFlipSystem = true; + TileFliperSystemVFX tileFliperSystemVFX = new TileFliperSystemVFX() + { + Owner = player, + Active = true, + Visible = true, + }; + Ins.VFXManager.Add(tileFliperSystemVFX); + } + base.HoldItem(player); + } +} diff --git a/Sources/Everglow.Function/DeveloperContent/Items/TileFliper.png b/Sources/Everglow.Function/DeveloperContent/Items/TileFliper.png new file mode 100644 index 000000000..8a24d353f Binary files /dev/null and b/Sources/Everglow.Function/DeveloperContent/Items/TileFliper.png differ diff --git a/Sources/Everglow.Function/DeveloperContent/Items/TileFliperSystemVFX.cs b/Sources/Everglow.Function/DeveloperContent/Items/TileFliperSystemVFX.cs new file mode 100644 index 000000000..c2f15909f --- /dev/null +++ b/Sources/Everglow.Function/DeveloperContent/Items/TileFliperSystemVFX.cs @@ -0,0 +1,177 @@ +using Everglow.Commons.Enums; +using Everglow.Commons.VFX; +using Everglow.Commons.VFX.Pipelines; + +namespace Everglow.Commons.DeveloperContent.Items; + +[Pipeline(typeof(WCSPipeline))] +public class TileFliperSystemVFX : Visual +{ + public Point FixPoint; + + public Point ControlPoint; + + public Player Owner; + + public Item TileFliperItem = null; + + public Rectangle FlipArea() + { + int minX = Math.Min(FixPoint.X, ControlPoint.X); + int maxX = Math.Max(FixPoint.X, ControlPoint.X); + int minY = Math.Min(FixPoint.Y, ControlPoint.Y); + int maxY = Math.Max(FixPoint.Y, ControlPoint.Y); + return new Rectangle(minX, minY, maxX - minX + 1, maxY - minY + 1); + } + + public override CodeLayer DrawLayer => CodeLayer.PostDrawTiles; + + public override void Update() + { + if (Owner.HeldItem.type == ModContent.ItemType()) + { + if (TileFliperItem is null) + { + TileFliperItem = Owner.HeldItem; + } + TileFliper tf = TileFliperItem.ModItem as TileFliper; + if (tf != null) + { + tf.EnableFlipSystem = true; + } + } + else + { + Kill(); + return; + } + + if (Main.mouseLeft && Main.mouseLeftRelease) + { + FixPoint = Main.MouseWorld.ToTileCoordinates(); + } + if (Main.mouseLeft) + { + ControlPoint = Main.MouseWorld.ToTileCoordinates(); + } + if (Main.mouseRight && Main.mouseRightRelease) + { + FlipTheTileMap(); + } + } + + public void FlipTheTileMap() + { + Rectangle flip = FlipArea(); + for (int i = 0; i < flip.Width / 2; i++) + { + for (int j = 0; j < flip.Height; j++) + { + var tile0 = Main.tile[i + flip.X, j + flip.Y]; + var tile1 = Main.tile[flip.X + flip.Width - i - 1, j + flip.Y]; + (tile0.TileType, tile1.TileType) = (tile1.TileType, tile0.TileType); + (tile0.HasTile, tile1.HasTile) = (tile1.HasTile, tile0.HasTile); + (tile0.WallType, tile1.WallType) = (tile1.WallType, tile0.WallType); + (tile0.Slope, tile1.Slope) = (tile1.Slope, tile0.Slope); + ReverseSlope(i + flip.X, j + flip.Y); + ReverseSlope(flip.X + flip.Width - i - 1, j + flip.Y); + (tile0.LiquidType, tile1.LiquidType) = (tile1.LiquidType, tile0.LiquidType); + (tile0.LiquidAmount, tile1.LiquidAmount) = (tile1.LiquidAmount, tile0.LiquidAmount); + (tile0.TileColor, tile1.TileColor) = (tile1.TileColor, tile0.TileColor); + (tile0.WallColor, tile1.WallColor) = (tile1.WallColor, tile0.WallColor); + (tile0.IsHalfBlock, tile1.IsHalfBlock) = (tile1.IsHalfBlock, tile0.IsHalfBlock); + (tile0.TileFrameX, tile1.TileFrameX) = (tile1.TileFrameX, tile0.TileFrameX); + (tile0.TileFrameY, tile1.TileFrameY) = (tile1.TileFrameY, tile0.TileFrameY); + (tile0.HasActuator, tile1.HasActuator) = (tile1.HasActuator, tile0.HasActuator); + (tile0.IsActuated, tile1.IsActuated) = (tile1.IsActuated, tile0.IsActuated); + } + } + for (int i = 0; i < flip.Width; i++) + { + for (int j = 0; j < flip.Height; j++) + { + WorldGen.SquareTileFrame(i + flip.X, j + flip.Y); + WorldGen.SquareWallFrame(i + flip.X, j + flip.Y); + } + } + } + + public void ReverseSlope(int i, int j) + { + Tile tile = Main.tile[i, j]; + if (tile.Slope == SlopeType.SlopeDownLeft) + { + tile.Slope = SlopeType.SlopeDownRight; + return; + } + if (tile.Slope == SlopeType.SlopeUpLeft) + { + tile.Slope = SlopeType.SlopeUpRight; + return; + } + if (tile.Slope == SlopeType.SlopeDownRight) + { + tile.Slope = SlopeType.SlopeDownLeft; + return; + } + if (tile.Slope == SlopeType.SlopeUpRight) + { + tile.Slope = SlopeType.SlopeUpLeft; + return; + } + } + + public override void Kill() + { + if (TileFliperItem != null) + { + TileFliper tf = TileFliperItem.ModItem as TileFliper; + if (tf != null) + { + tf.EnableFlipSystem = false; + } + } + base.Kill(); + } + + public override void Draw() + { + Rectangle drawTileArea = FlipArea(); + var startPoint = new Point(drawTileArea.X, drawTileArea.Y); + Texture2D tex = ModAsset.TileBlock4x4.Value; + Color drawColor = new Color(0.4f, 0.2f, 1f, 0.3f); + for (int i = 0; i < drawTileArea.Width; i++) + { + for (int j = 0; j < drawTileArea.Height; j++) + { + Vector2 drawPos = (startPoint + new Point(i, j)).ToWorldCoordinates(); + Rectangle drawFrame = new Rectangle(16, 16, 16, 16); + if (i == 0) + { + drawFrame.X = 0; + } + if (j == 0) + { + drawFrame.Y = 0; + } + if (i == drawTileArea.Width - 1) + { + drawFrame.X = 32; + } + if (j == drawTileArea.Height - 1) + { + drawFrame.Y = 32; + } + if (i == drawTileArea.Width - 1 && i == 0) + { + drawFrame.X = 48; + } + if (j == drawTileArea.Height - 1 && j == 0) + { + drawFrame.Y = 48; + } + Ins.Batch.Draw(tex, drawPos, drawFrame, drawColor, 0, new Vector2(8), 1f, SpriteEffects.None); + } + } + } +} diff --git a/Sources/Everglow.Function/DeveloperContent/Items/TileToolBox.cs b/Sources/Everglow.Function/DeveloperContent/Items/TileToolBox.cs new file mode 100644 index 000000000..673f8546e --- /dev/null +++ b/Sources/Everglow.Function/DeveloperContent/Items/TileToolBox.cs @@ -0,0 +1,36 @@ +using Everglow.Commons.DeveloperContent.VFXs; + +namespace Everglow.Commons.DeveloperContent.Items; + +/// +/// Create line-connected points in world, help developers to visualize polygon. +/// +public class TileToolBox : ModItem +{ + public TileToolBoxInterface Visual { get; private set; } = null; + + public override void SetDefaults() + { + Item.width = 16; + Item.height = 16; + Item.value = 0; + Item.rare = ItemRarityID.White; + } + + public override void HoldItem(Player player) + { + if (Main.mouseLeft && Main.mouseLeftRelease) + { + if (Visual is not null && Visual.Active) + { + return; + } + var helper = new TileToolBoxInterface() + { + Owner = player, + }; + Ins.VFXManager.Add(helper); + Visual = helper; + } + } +} diff --git a/Sources/Everglow.Function/DeveloperContent/Items/TileToolBox.png b/Sources/Everglow.Function/DeveloperContent/Items/TileToolBox.png new file mode 100644 index 000000000..f4ee6ba4c Binary files /dev/null and b/Sources/Everglow.Function/DeveloperContent/Items/TileToolBox.png differ diff --git a/Sources/Everglow.Function/DeveloperContent/Items/WorldAnchor.cs b/Sources/Everglow.Function/DeveloperContent/Items/WorldAnchor.cs new file mode 100644 index 000000000..c535fb51a --- /dev/null +++ b/Sources/Everglow.Function/DeveloperContent/Items/WorldAnchor.cs @@ -0,0 +1,44 @@ +using Everglow.Commons.Utilities; +using Terraria; + +namespace Everglow.Commons.DeveloperContent.Items; + +/// +/// Visulalize the data of mouse-covered-tile. +/// +public class WorldAnchor : ModItem +{ + public bool EnableResidentEffect = false; + + public override void SetDefaults() + { + Item.width = 16; + Item.height = 16; + Item.value = 0; + Item.rare = ItemRarityID.White; + } + + public override void HoldItem(Player player) + { + int i = Main.MouseWorld.ToTileCoordinates().X; + int j = Main.MouseWorld.ToTileCoordinates().Y; + if (Main.mapFullscreen) + { + Vector2 mouseFromCenter = Main.MouseScreen - new Vector2(Main.screenWidth, Main.screenHeight) / 2f; + Vector2 mouseMap = Main.mapFullscreenPos + mouseFromCenter / Main.mapFullscreenScale * Main.GameViewMatrix.Zoom; + i = (int)mouseMap.X; + j = (int)mouseMap.Y; + } + + string text = string.Empty; + var tile = TileUtils.SafeGetTile(i, j); + if (tile.HasTile) + { + text += "TileType :" + tile.TileType; + text += " " + TileID.Search.GetName(tile.TileType); + } + text += "\n[" + i + ", " + j + "]\n"; + text += "[" + i / (float)Main.maxTilesX + ", " + j / (float)Main.maxTilesY + "]"; + Main.instance.MouseText(text); + } +} diff --git a/Sources/Everglow.Function/DeveloperContent/Items/WorldAnchor.png b/Sources/Everglow.Function/DeveloperContent/Items/WorldAnchor.png new file mode 100644 index 000000000..f633ecd23 Binary files /dev/null and b/Sources/Everglow.Function/DeveloperContent/Items/WorldAnchor.png differ diff --git a/Sources/Everglow.Function/DeveloperContent/VFXs/TileToolBoxInterface.cs b/Sources/Everglow.Function/DeveloperContent/VFXs/TileToolBoxInterface.cs new file mode 100644 index 000000000..12a87b3e3 --- /dev/null +++ b/Sources/Everglow.Function/DeveloperContent/VFXs/TileToolBoxInterface.cs @@ -0,0 +1,922 @@ +using Everglow.Commons.DeveloperContent.Items; +using Everglow.Commons.Enums; +using Everglow.Commons.TileHelper; +using Everglow.Commons.Utilities; +using Everglow.Commons.Vertex; +using Everglow.Commons.VFX; +using Everglow.Commons.VFX.Pipelines; +using Terraria.GameContent; +using static Everglow.Commons.Utilities.MathUtils; +using static Everglow.Commons.Utilities.TileUtils; +using static Everglow.Commons.VFX.CommonDusts.LightDust; + +namespace Everglow.Commons.DeveloperContent.VFXs; + +[Pipeline(typeof(WCSPipeline))] +public class TileToolBoxInterface : Visual +{ + public const int TotalTool = 12; + + public Player Owner = null; + public Vector2 Position; + public int CurrentTileType; + public int CurrentWallType = 0; + public int SelectedTool = -1; + public int MouseOverTool = -1; + public int Timer; + public int PlayerHeldItemTile = -1; + public int PlayerHeldItemWall = -1; + + /// + /// 0: Tile, 1: Wall + /// + public int State = 0; + public bool Open = true; + public bool ShouldDrawMouseTlie = false; + public bool ShouldDrawBrushCoveredTlies = false; + public bool ShouldDrawSelectedTlies = false; + public bool RectangleSelecting = false; + public bool Brushing = false; + public bool ClickAnyButtonInThisFrame = false; + public bool CircleSelecting = false; + public Point RectangleSelectStart; + public Point RectangleSelectEnd; + public Point CircleSelectCenter; + public float CircleSelectRadius; + public float BrushSize = 16; + public string MouseText; + + public enum ToolID + { + TilePicker, + TileColorBoard, + PaintBucket, + MagicWand, + Undo, + Redo, + RectangleSelect, + PolygonSelect, + CircleSelect, + Unselect, + PaintBrush, + SwitchTileAndWall, + None, + History, + Smoothe, + } + + public class ToolButton + { + public float Scale; + public Vector2 Position; + public int Type; + } + + public List Tools = []; + public List SelectedTiles = []; + public List CurrentSelectedTiles = []; + public List BrushCoveredTiles = []; + public List BrushPaintedTiles = []; + public List PolygonSelectPoints = []; + public static Stack<(MapIO Mp, string Pt)> UndoMapIOs = []; + public static Stack<(MapIO Mp, string Pt)> RedoMapIOs = []; + + public override CodeLayer DrawLayer => CodeLayer.PostDrawDusts; + + public override void Update() + { + if (Tools.Count <= 0) + { + Initialization(); + } + UpdateActive(); + if (ClickAnyButtonInThisFrame && Main.mouseLeftRelease) + { + ClickAnyButtonInThisFrame = false; + } + + if (Main.mouseRight && Main.mouseRightRelease) + { + UpdateRightClick(); + } + if (Main.mouseLeft && Main.mouseLeftRelease) + { + UpdateLeftClick(); + } + UpdateTools(); + } + + /// + /// Initialize the tool buttons. This method is called once when the visual is first updated, and it populates the Tools list with the necessary buttons for the interface. + /// + public void Initialization() + { + for (int k = 0; k < TotalTool; k++) + { + Tools.Add(new ToolButton() + { + Position = Vector2.zeroVector, + Scale = 1f, + Type = k, + }); + } + } + + public void UpdateActive() + { + if (Owner.HeldItem is not null) + { + if (State == 0) + { + if (Owner.HeldItem.createTile != PlayerHeldItemTile && Owner.HeldItem.createTile >= 0) + { + CurrentTileType = Owner.HeldItem.createTile; + } + } + PlayerHeldItemTile = Owner.HeldItem.createTile; + if (State == 1) + { + if (Owner.HeldItem.createWall != PlayerHeldItemWall && Owner.HeldItem.createWall >= 1) + { + CurrentWallType = Owner.HeldItem.createWall; + } + } + PlayerHeldItemWall = Owner.HeldItem.createWall; + } + else + { + PlayerHeldItemTile = -1; + } + if (Open) + { + if (Timer < 60) + { + Timer += 6; + } + } + else + { + if (Timer > 0) + { + Timer -= 6; + } + else + { + Active = false; + return; + } + } + } + + public void UpdateTools() + { + for (int t = Tools.Count - 1; t >= 0; t--) + { + var ui = Tools[t]; + float value = Timer / 60f; + value = MathF.Pow(value, 0.5f); + ui.Position = new Vector2(0, value * TotalTool * 6).RotatedBy(ui.Type / (float)Tools.Count * MathHelper.TwoPi - 1 + value); + Tools[t] = ui; + } + ShouldDrawMouseTlie = false; + ShouldDrawBrushCoveredTlies = false; + ShouldDrawSelectedTlies = false; + switch (SelectedTool) + { + case (int)ToolID.TilePicker: + ShouldDrawMouseTlie = true; + break; + case (int)ToolID.RectangleSelect: + ShouldDrawSelectedTlies = true; + ShouldDrawMouseTlie = true; + if (!ClickAnyButtonInThisFrame) + { + if (Main.mouseLeft) + { + if (!RectangleSelecting) + { + RectangleSelecting = true; + RectangleSelectStart = Main.MouseWorld.ToTileCoordinates(); + } + RectangleSelectEnd = Main.MouseWorld.ToTileCoordinates(); + CurrentSelectedTiles = GetAABBAreaOfTile(RectangleSelectStart, RectangleSelectEnd); + } + else + { + RectangleSelecting = false; + SelectedTiles.AddRangeDistinct(CurrentSelectedTiles); + CurrentSelectedTiles = []; + } + } + break; + case (int)ToolID.PolygonSelect: + ShouldDrawSelectedTlies = true; + ShouldDrawMouseTlie = true; + break; + case (int)ToolID.CircleSelect: + ShouldDrawSelectedTlies = true; + ShouldDrawMouseTlie = true; + if (!ClickAnyButtonInThisFrame) + { + if (Main.mouseLeft) + { + if (!CircleSelecting) + { + CircleSelecting = true; + var point = Main.MouseWorld.ToTileCoordinates(); + CircleSelectCenter = point; + } + CircleSelectRadius = (CircleSelectCenter.ToWorldCoordinates() - Main.MouseWorld).Length() / 16f; + CurrentSelectedTiles = GetCircleAreaOfTilePos(CircleSelectCenter, CircleSelectRadius); + } + else + { + CircleSelecting = false; + SelectedTiles.AddRangeDistinct(CurrentSelectedTiles); + CurrentSelectedTiles = []; + } + } + break; + case (int)ToolID.MagicWand: + ShouldDrawSelectedTlies = true; + break; + case (int)ToolID.PaintBucket: + ShouldDrawSelectedTlies = true; + break; + case (int)ToolID.PaintBrush: + ShouldDrawBrushCoveredTlies = true; + if (!ClickAnyButtonInThisFrame) + { + Point brushStart = (Main.MouseWorld - new Vector2(BrushSize)).ToTileCoordinates(); + Point brushEnd = (Main.MouseWorld + new Vector2(BrushSize)).ToTileCoordinates(); + BrushCoveredTiles = GetAABBAreaOfTile(brushStart, brushEnd); + if (Main.mouseLeft) + { + Brushing = true; + + // HashSet set = new HashSet(BrushPaintedTiles); + // foreach (var pos in BrushCoveredTiles) + // { + // set.Add(pos); + // } + // BrushPaintedTiles = set.ToList(); + BrushPaintedTiles.AddRangeDistinct(BrushCoveredTiles); + } + if (!Main.mouseLeft && Brushing) + { + if (BrushPaintedTiles.Count > 0) + { + SaveStepToUndoable(BrushPaintedTiles); + } + foreach (var pos in BrushPaintedTiles) + { + var tile = SafeGetTile(pos); + if (State == 0) + { + ChangeTile(tile, CurrentTileType, 0); + } + if (State == 1) + { + ChangeWall(tile, CurrentWallType, 0); + } + WorldGen.TileFrame(pos.X, pos.Y, true, true); + WorldGen.SquareWallFrame(pos.X, pos.Y); + } + BrushPaintedTiles = []; + } + } + break; + } + } + + public void UpdateLeftClick() + { + var mouseTile = SafeGetTile(Main.MouseWorld.ToTileCoordinates()); + if (MouseOverTool >= 0) + { + if (SelectedTool == (int)ToolID.PolygonSelect) + { + SelectedTiles.AddRangeDistinct(CurrentSelectedTiles); + CurrentSelectedTiles = []; + } + if (MouseOverTool == SelectedTool) + { + SelectedTool = -1; + ClickAnyButtonInThisFrame = true; + } + else + { + switch (MouseOverTool) + { + case -1: + SelectedTool = -1; + break; + case (int)ToolID.Undo: + SelectedTool = -1; + if (UndoMapIOs.Count > 0) + { + var mapIOandStream_undo = UndoMapIOs.Pop(); + SaveStepToRedoable(mapIOandStream_undo.Mp); + ReadMapIO(mapIOandStream_undo); + File.Delete(mapIOandStream_undo.Pt); + } + break; + case (int)ToolID.Redo: + SelectedTool = -1; + if (RedoMapIOs.Count > 0) + { + var mapIOandStream_redo = RedoMapIOs.Pop(); + SaveStepToUndoable(mapIOandStream_redo.Mp); + ReadMapIO(mapIOandStream_redo); + File.Delete(mapIOandStream_redo.Pt); + } + break; + case (int)ToolID.Unselect: + SelectedTiles = []; + CurrentSelectedTiles = []; + PolygonSelectPoints = []; + break; + case (int)ToolID.SwitchTileAndWall: + State += 1; + State %= 2; + break; + default: + SelectedTool = MouseOverTool; + break; + } + if (MouseOverTool != -1) + { + ClickAnyButtonInThisFrame = true; + } + PolygonSelectPoints = []; + } + } + else + { + RectangleSelecting = false; + CircleSelecting = false; + switch (SelectedTool) + { + case -1: + if (Owner.HeldItem.type == ModContent.ItemType()) + { + Position = Main.MouseWorld; + Timer = 0; + } + break; + case (int)ToolID.PaintBucket: + SaveStepToUndoable(SelectedTiles); + foreach (var pos in SelectedTiles) + { + if (State == 0) + { + ChangeTile(SafeGetTile(pos), CurrentTileType, (int)TileChangeState.Forceful); + } + else if (State == 1) + { + ChangeWall(SafeGetTile(pos), CurrentWallType, (int)TileChangeState.Forceful); + } + WorldGen.TileFrame(pos.X, pos.Y, true, true); + WorldGen.SquareWallFrame(pos.X, pos.Y); + } + break; + case (int)ToolID.TilePicker: + if (State == 0) + { + if (mouseTile.HasTile) + { + CurrentTileType = mouseTile.TileType; + } + else + { + CurrentTileType = -1; + } + } + else if (State == 1) + { + CurrentWallType = mouseTile.WallType; + } + break; + case (int)ToolID.RectangleSelect: + break; + case (int)ToolID.PolygonSelect: + if (!ClickAnyButtonInThisFrame) + { + var point = Main.MouseWorld.ToTileCoordinates(); + if (!PolygonSelectPoints.Contains(point)) + { + PolygonSelectPoints.Add(point); + } + else + { + PolygonSelectPoints.Remove(point); + } + if (PolygonSelectPoints.Count >= 3) + { + CurrentSelectedTiles = GetPolygonAreaOfTilePos(PolygonSelectPoints); + } + else + { + CurrentSelectedTiles.Clear(); + } + } + break; + case (int)ToolID.MagicWand: + if (!ClickAnyButtonInThisFrame) + { + var point = Main.MouseWorld.ToTileCoordinates(); + if (State == 0) + { + if (mouseTile.HasTile) + { + SelectedTiles.AddRangeDistinct(BFSContinueTile(point, false, 2048, [mouseTile.TileType])); + } + else + { + SelectedTiles.AddRangeDistinct(BFSContinueEmpty(point, false, 2048)); + } + } + if (State == 1) + { + SelectedTiles.AddRangeDistinct(BFSContinueWall(point, 2048, [mouseTile.WallType])); + } + } + break; + case (int)ToolID.CircleSelect: + break; + } + } + } + + public void UpdateRightClick() + { + switch (SelectedTool) + { + case -1: + Open = false; + break; + default: + if (SelectedTool == (int)ToolID.PolygonSelect) + { + SelectedTiles.AddRangeDistinct(CurrentSelectedTiles); + CurrentSelectedTiles = []; + } + SelectedTool = -1; + break; + } + } + + public override void Draw() + { + MouseText = " "; + if (Main.mapFullscreen) + { + return; + } + MouseOverTool = -1; + foreach (var ui in Tools) + { + DrawToolUI(ui); + } + if (MouseOverTool != -1) + { + MouseText += Enum.GetName(typeof(ToolID), MouseOverTool); + } + if (SelectedTool == (int)ToolID.TilePicker && MouseOverTool == -1) + { + int type = -1; + var checkTile = SafeGetTile(Main.MouseWorld.ToTileCoordinates()); + if (State == 0) + { + if (checkTile.HasTile) + { + type = checkTile.TileType; + } + } + else if (State == 1) + { + type = checkTile.WallType; + } + if (MouseText.Length > 2) + { + MouseText += "\n"; + } + MouseText += "[c/00FFFF:"; + if (State == 0) + { + AddTileData(type); + } + else if (State == 1) + { + AddWallData(type); + } + MouseText += "]"; + } + if (MouseOverTool == (int)ToolID.TileColorBoard) + { + MouseText += "\n"; + if (State == 0) + { + AddTileData(CurrentTileType); + } + else if (State == 1) + { + AddWallData(CurrentWallType); + } + } + if (SelectedTool != -1) + { + Texture2D tex = ModAsset.TileToolBoxUI.Value; + Rectangle frame = ToolFrame(SelectedTool); + Ins.Batch.Draw(tex, Main.MouseWorld + new Vector2(16), frame, Color.White, 0, frame.Size() / 2f, 0.75f, SpriteEffects.None); + if (SelectedTool == (int)ToolID.PolygonSelect) + { + DrawSelectPolygon(); + } + if (SelectedTool == (int)ToolID.CircleSelect && CircleSelecting) + { + Texture2D point = ModAsset.LightPoint2.Value; + Ins.Batch.Draw(point, CircleSelectCenter.ToWorldCoordinates(), null, new Color(0.4f, 0.4f, 1f, 0f), 0, point.Size() * 0.5f, 1f, SpriteEffects.None); + } + if (MouseOverTool == -1) + { + if (MouseText.Length > 2) + { + MouseText += "\n"; + } + MouseText += "[c/666666:Right Click to Cancel the Tool.]"; + } + } + if (ShouldDrawMouseTlie) + { + DrawTile(Main.MouseWorld.ToTileCoordinates(), new Color(1f, 0.75f, 0.15f, 0.4f)); + } + if (ShouldDrawBrushCoveredTlies) + { + var drawColor = new Color(1f, 0.0f, 0.2f, 0.7f); + if (State == 1) + { + drawColor = new Color(0f, 0.6f, 0.1f, 0.7f); + } + DrawListOfTiles(BrushPaintedTiles, drawColor); + DrawListOfTiles(BrushCoveredTiles, new Color(0.7f, 0.4f, 0.4f, 0.4f)); + } + if (ShouldDrawSelectedTlies) + { + DrawListOfTiles(CurrentSelectedTiles, new Color(0.7f, 0.4f, 0.4f, 0.4f)); + DrawListOfTiles(SelectedTiles, new Color(0.7f, 0.4f, 0.4f, 0.4f) * 0.5f); + } + Main.instance.MouseText(MouseText, ItemRarityID.White); + if (State == 0 && CurrentTileType >= 0) + { + Main.instance.LoadTiles(CurrentTileType); + Texture2D tileTex = TextureAssets.Tile[CurrentTileType].Value; + var frame = new Rectangle(162, 54, 16, 16); + Ins.Batch.Draw(tileTex, Position, frame, Color.White, 0, frame.Size() * 0.5f, 1f, SpriteEffects.None); + } + if (State == 1 && CurrentWallType >= 1) + { + Main.instance.LoadWall(CurrentWallType); + Texture2D wallTex = TextureAssets.Wall[CurrentWallType].Value; + var frame = new Rectangle(324, 108, 32, 32); + Ins.Batch.Draw(wallTex, Position, frame, Color.White, 0, frame.Size() * 0.5f, 1f, SpriteEffects.None); + } + } + + public void DrawSelectPolygon() + { + Texture2D point = ModAsset.LightPoint2.Value; + for (int i = 0; i < PolygonSelectPoints.Count; i++) + { + float drawScale = 0.75f; + var drawColor = new Color(0.4f, 0.4f, 1f, 0f) * 0.5f; + if (Main.MouseWorld.ToTileCoordinates() == PolygonSelectPoints[i]) + { + drawColor = new Color(1f, 0.7f, 0f, 0f); + drawScale = 1f; + } + Ins.Batch.Draw(point, PolygonSelectPoints[i].ToWorldCoordinates(), null, drawColor, 0, point.Size() * 0.5f, drawScale, SpriteEffects.None); + if (PolygonSelectPoints.Count >= 2) + { + Vector2 next; + if (i < PolygonSelectPoints.Count - 1) + { + next = PolygonSelectPoints[i + 1].ToWorldCoordinates(); + } + else + { + next = PolygonSelectPoints[0].ToWorldCoordinates(); + } + DrawLine(PolygonSelectPoints[i].ToWorldCoordinates(), next); + } + } + } + + public void DrawLine(Vector2 pos0, Vector2 pos1) + { + var drawColor = new Color(0, 0.2f, 0.4f, 0); + Texture2D tex = ModAsset.White.Value; + List bars = new List(); + Vector2 dir = (pos0 - pos1).RotatedBy(MathHelper.PiOver2).NormalizeSafe(); + bars.Add(pos0 + dir, drawColor, new Vector3(0, 0, 0)); + bars.Add(pos0 - dir, drawColor, new Vector3(0, 0, 0)); + bars.Add(pos1 + dir, drawColor, new Vector3(0, 0, 0)); + bars.Add(pos1 - dir, drawColor, new Vector3(0, 0, 0)); + Ins.Batch.Draw(tex, bars, PrimitiveType.TriangleStrip); + } + + public void DrawTile(Point pos, Color color) + { + Texture2D tile = ModAsset.TileBlock.Value; + Ins.Batch.Draw(tile, pos.ToWorldCoordinates(), null, color, 0, tile.Size() / 2f, 1f, SpriteEffects.None); + } + + public void DrawListOfTiles(List tiles, Color drawColor) + { + Texture2D tex = ModAsset.TileBlock4x4.Value; + foreach (var pos in tiles) + { + if (!VFXManager.InScreen(pos.ToWorldCoordinates(), 32)) + { + continue; + } + Rectangle drawFrame = new Rectangle(16, 16, 16, 16); + if (!tiles.Contains(pos + new Point(-1, 0))) + { + drawFrame.X = 0; + } + if (!tiles.Contains(pos + new Point(0, -1))) + { + drawFrame.Y = 0; + } + if (!tiles.Contains(pos + new Point(1, 0))) + { + drawFrame.X = 32; + } + if (!tiles.Contains(pos + new Point(0, 1))) + { + drawFrame.Y = 32; + } + if (!tiles.Contains(pos + new Point(-1, 0)) && !tiles.Contains(pos + new Point(1, 0))) + { + drawFrame.X = 48; + } + if (!tiles.Contains(pos + new Point(0, -1)) && !tiles.Contains(pos + new Point(0, 1))) + { + drawFrame.Y = 48; + } + Ins.Batch.Draw(tex, pos.ToWorldCoordinates(), drawFrame, drawColor, 0, drawFrame.Size() / 2f, 1f, SpriteEffects.None); + } + } + + public void DrawToolUI(ToolButton tool) + { + Texture2D tex = ModAsset.TileToolBoxUI.Value; + Texture2D panel = ModAsset.Wires_0.Value; + Rectangle frame = ToolFrame(tool.Type); + Vector2 pos = Position + tool.Position; + tool.Scale = 1f; + if ((Main.MouseWorld - pos).Length() < 20) + { + MouseOverTool = tool.Type; + panel = ModAsset.Wires_1.Value; + tool.Scale = 1.2f; + } + + Ins.Batch.Draw(panel, pos, null, Color.White, 0, panel.Size() / 2f, tool.Scale, SpriteEffects.None); + Ins.Batch.Draw(tex, pos, frame, Color.White, 0, frame.Size() / 2f, tool.Scale, SpriteEffects.None); + } + + public void AddTileData(int type) + { + string datas = "Clear Tile(-1)"; + if (type >= 0) + { + datas = TileID.Search.GetName(type) + "(" + type + ")"; + } + MouseText += datas; + } + + public void AddWallData(int type) + { + string datas = "Clear Wall(-1)"; + if (type >= 0) + { + datas = WallID.Search.GetName(type) + "(" + type + ")"; + } + MouseText += datas; + } + + public Rectangle ToolFrame(int id) + { + Rectangle frame = new Rectangle(0, 0, 32, 32); + switch (id) + { + case (int)ToolID.TilePicker: + frame = new Rectangle(2, 6, 26, 26); + break; + case (int)ToolID.TileColorBoard: + frame = new Rectangle(40, 22, 28, 20); + if (State == 0) + { + if (CurrentTileType >= 0) + { + frame = new Rectangle(40, 0, 28, 20); + } + } + else if (State == 1) + { + if (CurrentWallType >= 1) + { + frame = new Rectangle(40, 0, 28, 20); + } + } + break; + case (int)ToolID.PaintBucket: + frame = new Rectangle(76, 10, 22, 20); + break; + case (int)ToolID.History: + frame = new Rectangle(106, 4, 30, 30); + break; + case (int)ToolID.Undo: + frame = new Rectangle(142, 12, 18, 18); + if (UndoMapIOs.Count <= 0) + { + frame.X += 48; + } + break; + case (int)ToolID.Redo: + frame = new Rectangle(166, 12, 18, 18); + if (RedoMapIOs.Count <= 0) + { + frame.X += 48; + } + break; + case (int)ToolID.RectangleSelect: + frame = new Rectangle(8, 42, 18, 18); + break; + case (int)ToolID.PolygonSelect: + frame = new Rectangle(36, 42, 18, 18); + break; + case (int)ToolID.CircleSelect: + frame = new Rectangle(62, 42, 18, 18); + break; + case (int)ToolID.Unselect: + frame = new Rectangle(88, 42, 18, 18); + break; + case (int)ToolID.PaintBrush: + frame = new Rectangle(120, 44, 22, 20); + break; + case (int)ToolID.None: + frame = new Rectangle(12, 68, 16, 22); + break; + case (int)ToolID.MagicWand: + frame = new Rectangle(36, 68, 20, 20); + break; + case (int)ToolID.Smoothe: + frame = new Rectangle(64, 72, 18, 14); + break; + case (int)ToolID.SwitchTileAndWall: + frame = new Rectangle(88, 72, 20, 20); + break; + } + if (State == 1) + { + frame.Y += 100; + } + return frame; + } + + public Rectangle GetBoundOfTiles(List tiles) + { + int x = int.MaxValue; + int y = int.MaxValue; + int x_max = 0; + int y_max = 0; + foreach (var pos in tiles) + { + if (pos.X < x) + { + x = pos.X; + } + if (pos.Y < y) + { + y = pos.Y; + } + if (pos.X > x_max) + { + x_max = pos.X; + } + if (pos.Y > y_max) + { + y_max = pos.Y; + } + } + int width = x_max - x + 1; + int height = y_max - y + 1; + return new Rectangle(x, y, width, height); + } + + public void ReadMapIO((MapIO Mp, string Pt) item) + { + var mapIO = item.Mp; + var path = item.Pt; + mapIO.Read(path); + var it = mapIO.GetEnumerator(); + while (it.MoveNext()) + { + WorldGen.SquareTileFrame(it.CurrentCoord.X, it.CurrentCoord.Y); + WorldGen.SquareWallFrame(it.CurrentCoord.X, it.CurrentCoord.Y); + } + } + + public void SaveStepToUndoable(List tiles) + { + if (tiles.Count <= 0) + { + return; + } + Rectangle area = GetBoundOfTiles(tiles); + var mapIO = new MapIO(area); + string path = Path.Combine(Main.SavePath, "Mods", "ModDatas", "Everglow"); + path = Path.Combine(path, "TileToolBox"); + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } + + string writePath = path + "\\Undo" + UndoMapIOs.Count.ToString() + ".mapio"; + mapIO.Write(writePath); + UndoMapIOs.Push((mapIO, writePath)); + } + + public void SaveStepToRedoable(MapIO mapIO) + { + string path = Path.Combine(Main.SavePath, "Mods", "ModDatas", "Everglow"); + path = Path.Combine(path, "TileToolBox"); + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } + + string writePath = path + "\\Redo" + RedoMapIOs.Count.ToString() + ".mapio"; + mapIO.Write(writePath); + RedoMapIOs.Push((mapIO, writePath)); + } + + public void SaveStepToUndoable(MapIO mapIO) + { + string path = Path.Combine(Main.SavePath, "Mods", "ModDatas", "Everglow"); + path = Path.Combine(path, "TileToolBox"); + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } + + string writePath = path + "\\Undo" + UndoMapIOs.Count.ToString() + ".mapio"; + mapIO.Write(writePath); + UndoMapIOs.Push((mapIO, writePath)); + } + + public static void ClearHistory() + { + string path = Path.Combine(Main.SavePath, "Mods", "ModDatas", "Everglow"); + path = Path.Combine(path, "TileToolBox"); + if (!Directory.Exists(path)) + { + return; + } + DeleteFilesByPattern(path, "*.mapio"); + UndoMapIOs = []; + RedoMapIOs = []; + } + + public static void DeleteFilesByPattern(string directoryPath, string searchPattern = "*.*") + { + if (!Directory.Exists(directoryPath)) + { + Console.WriteLine($" Path does not exist.: {directoryPath}"); + return; + } + + int deletedCount = 0; + try + { + string[] files = Directory.GetFiles(directoryPath, searchPattern); + + foreach (string file in files) + { + File.Delete(file); + deletedCount++; + } + + Console.WriteLine($" {deletedCount} Have been deleted."); + return; + } + catch (Exception ex) + { + Console.WriteLine($" Fail: {ex.Message}"); + return; + } + } +} diff --git a/Sources/Everglow.Function/DeveloperContent/VFXs/TileToolBoxSystem.cs b/Sources/Everglow.Function/DeveloperContent/VFXs/TileToolBoxSystem.cs new file mode 100644 index 000000000..79e724138 --- /dev/null +++ b/Sources/Everglow.Function/DeveloperContent/VFXs/TileToolBoxSystem.cs @@ -0,0 +1,26 @@ +using Everglow.Commons.DeveloperContent.Items; +using Everglow.Commons.Enums; +using Everglow.Commons.TileHelper; +using Everglow.Commons.Utilities; +using Everglow.Commons.Vertex; +using Everglow.Commons.VFX; +using Everglow.Commons.VFX.Pipelines; +using static Everglow.Commons.Utilities.MathUtils; +using static Everglow.Commons.Utilities.TileUtils; + +namespace Everglow.Commons.DeveloperContent.VFXs; + +public class TileToolBoxSystem : ModSystem +{ + public override void OnWorldLoad() + { + TileToolBoxInterface.ClearHistory(); + base.OnWorldLoad(); + } + + public override void OnWorldUnload() + { + TileToolBoxInterface.ClearHistory(); + base.OnWorldUnload(); + } +} diff --git a/Sources/Everglow.Function/DeveloperContent/VFXs/TileToolBoxSystemListExtension.cs b/Sources/Everglow.Function/DeveloperContent/VFXs/TileToolBoxSystemListExtension.cs new file mode 100644 index 000000000..89198959e --- /dev/null +++ b/Sources/Everglow.Function/DeveloperContent/VFXs/TileToolBoxSystemListExtension.cs @@ -0,0 +1,16 @@ +namespace Everglow.Commons.DeveloperContent.VFXs; + +public static class TileToolBoxSystemListExtension +{ + public static void AddRangeDistinct(this List list, IEnumerable source) + { + HashSet temp = new HashSet(list); + foreach (var item in source) + { + temp.Add(item); + } + + list.Clear(); + list.AddRange(temp); + } +} diff --git a/Sources/Everglow.Function/DeveloperContent/VFXs/TileToolBoxUI.png b/Sources/Everglow.Function/DeveloperContent/VFXs/TileToolBoxUI.png new file mode 100644 index 000000000..1a69d9fe8 Binary files /dev/null and b/Sources/Everglow.Function/DeveloperContent/VFXs/TileToolBoxUI.png differ diff --git a/Sources/Everglow.Function/Mechanics/ElementalDebuff/ElementalDebuffInstance.cs b/Sources/Everglow.Function/Mechanics/ElementalDebuff/ElementalDebuffInstance.cs index 7bc76eb7e..830d67ca4 100644 --- a/Sources/Everglow.Function/Mechanics/ElementalDebuff/ElementalDebuffInstance.cs +++ b/Sources/Everglow.Function/Mechanics/ElementalDebuff/ElementalDebuffInstance.cs @@ -190,7 +190,6 @@ public void ApplyDot(NPC npc) { return; } - npc.lifeRegen -= Handler.DotDamage; npc.SetLifeRegenExpectedLossPerSecond(Handler.DotDamage); } diff --git a/Sources/Everglow.Function/Textures/CrossStar.png b/Sources/Everglow.Function/Textures/CrossStar.png new file mode 100644 index 000000000..3ab25c90c Binary files /dev/null and b/Sources/Everglow.Function/Textures/CrossStar.png differ diff --git a/Sources/Everglow.Function/Textures/CrossStar_black.png b/Sources/Everglow.Function/Textures/CrossStar_black.png new file mode 100644 index 000000000..176cab564 Binary files /dev/null and b/Sources/Everglow.Function/Textures/CrossStar_black.png differ diff --git a/Sources/Everglow.Function/Textures/Noise_WaterFallWave.png b/Sources/Everglow.Function/Textures/Noise_WaterFallWave.png new file mode 100644 index 000000000..ad5f84825 Binary files /dev/null and b/Sources/Everglow.Function/Textures/Noise_WaterFallWave.png differ diff --git a/Sources/Everglow.Function/Textures/Noise_flame_2_pure.png b/Sources/Everglow.Function/Textures/Noise_flame_2_pure.png new file mode 100644 index 000000000..d6ce3fd32 Binary files /dev/null and b/Sources/Everglow.Function/Textures/Noise_flame_2_pure.png differ diff --git a/Sources/Everglow.Function/Textures/Noise_flame_2_pure_black.png b/Sources/Everglow.Function/Textures/Noise_flame_2_pure_black.png new file mode 100644 index 000000000..5ffc4f9b8 Binary files /dev/null and b/Sources/Everglow.Function/Textures/Noise_flame_2_pure_black.png differ diff --git a/Sources/Everglow.Function/Textures/SquareBloom.png b/Sources/Everglow.Function/Textures/SquareBloom.png new file mode 100644 index 000000000..e404699e5 Binary files /dev/null and b/Sources/Everglow.Function/Textures/SquareBloom.png differ diff --git a/Sources/Everglow.Function/Textures/SquareBloom_black.png b/Sources/Everglow.Function/Textures/SquareBloom_black.png new file mode 100644 index 000000000..df8283c36 Binary files /dev/null and b/Sources/Everglow.Function/Textures/SquareBloom_black.png differ diff --git a/Sources/Everglow.Function/Textures/SquarePiece.png b/Sources/Everglow.Function/Textures/SquarePiece.png new file mode 100644 index 000000000..668470cfb Binary files /dev/null and b/Sources/Everglow.Function/Textures/SquarePiece.png differ diff --git a/Sources/Everglow.Function/Textures/TileBlock4x4.png b/Sources/Everglow.Function/Textures/TileBlock4x4.png new file mode 100644 index 000000000..5ff38424e Binary files /dev/null and b/Sources/Everglow.Function/Textures/TileBlock4x4.png differ diff --git a/Sources/Everglow.Function/Textures/Vanilla_Chat_Back.png b/Sources/Everglow.Function/Textures/Vanilla_Chat_Back.png new file mode 100644 index 000000000..d9c391e83 Binary files /dev/null and b/Sources/Everglow.Function/Textures/Vanilla_Chat_Back.png differ diff --git a/Sources/Everglow.Function/Textures/Vanilla_Chat_Back_Highlight.png b/Sources/Everglow.Function/Textures/Vanilla_Chat_Back_Highlight.png new file mode 100644 index 000000000..e66f8f653 Binary files /dev/null and b/Sources/Everglow.Function/Textures/Vanilla_Chat_Back_Highlight.png differ diff --git a/Sources/Everglow.Function/Textures/Vanilla_Chat_Back_gray.png b/Sources/Everglow.Function/Textures/Vanilla_Chat_Back_gray.png new file mode 100644 index 000000000..ca2b68341 Binary files /dev/null and b/Sources/Everglow.Function/Textures/Vanilla_Chat_Back_gray.png differ diff --git a/Sources/Everglow.Function/TileHelper/AirTile.cs b/Sources/Everglow.Function/TileHelper/AirTile.cs index d28bb57e6..2976cc94f 100644 --- a/Sources/Everglow.Function/TileHelper/AirTile.cs +++ b/Sources/Everglow.Function/TileHelper/AirTile.cs @@ -1,3 +1,4 @@ + namespace Everglow.Commons.TileHelper; public class AirTile : ModTile @@ -6,21 +7,7 @@ public override void SetStaticDefaults() { Main.tileSolid[Type] = true; Main.tileMergeDirt[Type] = true; - Main.tileBlockLight[Type] = true; - AddMapEntry(Color.White); - } -} - -public class AirTileItem : ModItem -{ - public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; - - public override void SetDefaults() - { - Item.useTime = 5; - Item.useAnimation = 5; - Item.createTile = ModContent.TileType(); - Item.useStyle = ItemUseStyleID.Swing; - Item.autoReuse = true; + Main.tileBlockLight[Type] = false; + AddMapEntry(Color.Transparent); } } diff --git a/Sources/Everglow.Function/TileHelper/AirTile.png b/Sources/Everglow.Function/TileHelper/AirTile.png index 8765fb6cf..1397e4f70 100644 Binary files a/Sources/Everglow.Function/TileHelper/AirTile.png and b/Sources/Everglow.Function/TileHelper/AirTile.png differ diff --git a/Sources/Everglow.Function/TileHelper/AirTileItem.cs b/Sources/Everglow.Function/TileHelper/AirTileItem.cs new file mode 100644 index 000000000..360c0f5c4 --- /dev/null +++ b/Sources/Everglow.Function/TileHelper/AirTileItem.cs @@ -0,0 +1,15 @@ +namespace Everglow.Commons.TileHelper; + +public class AirTileItem : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.useTime = 5; + Item.useAnimation = 5; + Item.createTile = ModContent.TileType(); + Item.useStyle = ItemUseStyleID.Swing; + Item.autoReuse = true; + } +} diff --git a/Sources/Everglow.Function/TileHelper/AirWall.cs b/Sources/Everglow.Function/TileHelper/AirWall.cs index 43e91efa4..bd978b0a6 100644 --- a/Sources/Everglow.Function/TileHelper/AirWall.cs +++ b/Sources/Everglow.Function/TileHelper/AirWall.cs @@ -1,3 +1,4 @@ + namespace Everglow.Commons.TileHelper; public class AirWall : ModWall @@ -6,6 +7,12 @@ public override void SetStaticDefaults() { AddMapEntry(Color.White); } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + return false; + base.PreDraw(i, j, spriteBatch); + } } public class AirWallItem : ModItem @@ -16,7 +23,7 @@ public override void SetDefaults() { Item.useTime = 5; Item.useAnimation = 5; - Item.createTile = ModContent.WallType(); + Item.createWall = ModContent.WallType(); Item.useStyle = ItemUseStyleID.Swing; Item.autoReuse = true; } diff --git a/Sources/Everglow.Function/TileHelper/AirWall.png b/Sources/Everglow.Function/TileHelper/AirWall.png index 8765fb6cf..05a13cf9b 100644 Binary files a/Sources/Everglow.Function/TileHelper/AirWall.png and b/Sources/Everglow.Function/TileHelper/AirWall.png differ diff --git a/Sources/Everglow.Function/TileHelper/CableKnot.png b/Sources/Everglow.Function/TileHelper/CableKnot.png index 81a362f8c..586e489fd 100644 Binary files a/Sources/Everglow.Function/TileHelper/CableKnot.png and b/Sources/Everglow.Function/TileHelper/CableKnot.png differ diff --git a/Sources/Everglow.Function/TileHelper/CableTile.cs b/Sources/Everglow.Function/TileHelper/CableTile.cs index b7ee95721..2cdbe3b52 100644 --- a/Sources/Everglow.Function/TileHelper/CableTile.cs +++ b/Sources/Everglow.Function/TileHelper/CableTile.cs @@ -48,6 +48,11 @@ public abstract class CableTile : ModTile, ITileFluentlyDrawn /// public float Elasticity = 60; + /// + /// How far should start drawing the rope in an area out of screen . + /// + public float DrawOffScreenRange = 1200f; + public override void SetStaticDefaults() { Main.tileFrameImportant[Type] = true; @@ -467,22 +472,22 @@ public static bool TryGetCableEntityAs(int i, int j, out T entity) /// /// é¼ æ ‡åˆ’è¿‡ç‚¹ä½ /// - public Dictionary MouseOverPoint = new Dictionary(); + public Dictionary MouseOverWinchPlayers = new Dictionary(); public override void MouseOver(int i, int j) { - if (!MouseOverPoint.ContainsKey(Main.LocalPlayer)) + if (!MouseOverWinchPlayers.ContainsKey(Main.LocalPlayer)) { - MouseOverPoint.Add(Main.LocalPlayer, new Point(i, j)); + MouseOverWinchPlayers.Add(Main.LocalPlayer, new Point(i, j)); if (Main.LocalPlayer.HeldItem.ModItem is CableTileItem) { CableTilePlaceHelpingSystem vfx = new CableTilePlaceHelpingSystem { FixPoint = new Point(i, j), Active = true, Visible = true, Style = 0 }; Ins.VFXManager.Add(vfx); } } - else if (MouseOverPoint[Main.LocalPlayer] != new Point(i, j)) + else if (MouseOverWinchPlayers[Main.LocalPlayer] != new Point(i, j)) { - MouseOverPoint.Remove(Main.LocalPlayer); + MouseOverWinchPlayers.Remove(Main.LocalPlayer); } } @@ -602,9 +607,9 @@ public override void Update() if (cableTile.HasHoldRope.ContainsKey(Main.LocalPlayer)) { Active = false; - if (cableTile.MouseOverPoint.ContainsKey(Main.LocalPlayer)) + if (cableTile.MouseOverWinchPlayers.ContainsKey(Main.LocalPlayer)) { - cableTile.MouseOverPoint.Remove(Main.LocalPlayer); + cableTile.MouseOverWinchPlayers.Remove(Main.LocalPlayer); } return; } @@ -613,9 +618,9 @@ public override void Update() if (x != FixPoint.X || y != FixPoint.Y) { Active = false; - if (cableTile.MouseOverPoint.ContainsKey(Main.LocalPlayer)) + if (cableTile.MouseOverWinchPlayers.ContainsKey(Main.LocalPlayer)) { - cableTile.MouseOverPoint.Remove(Main.LocalPlayer); + cableTile.MouseOverWinchPlayers.Remove(Main.LocalPlayer); } return; } diff --git a/Sources/Everglow.Function/TileHelper/CableTile_HangingTile_GlobaDrawing.cs b/Sources/Everglow.Function/TileHelper/CableTile_HangingTile_GlobaDrawing.cs new file mode 100644 index 000000000..b0926fc0c --- /dev/null +++ b/Sources/Everglow.Function/TileHelper/CableTile_HangingTile_GlobaDrawing.cs @@ -0,0 +1,133 @@ +using System.Reflection; +using Everglow.Commons.Utilities; +using Everglow.Commons.VFX; +using MonoMod.Cil; +using Terraria.GameContent.Drawing; + +namespace Everglow.Commons.TileHelper; + +public class CableTile_HangingTile_GlobaDrawing : GlobalTile +{ + public override void Load() + { + Ins.HookManager.AddHook(typeof(TileDrawing).GetMethod(nameof(TileDrawing.Draw), BindingFlags.Public | BindingFlags.Instance), ILHook_TileDrawing_DrawCableTile_HangingTile); + } + + private void ILHook_TileDrawing_DrawCableTile_HangingTile(ILContext il) + { + ILCursor cursor = new ILCursor(il); + if (cursor.TryGotoNext( + MoveType.After, + x => x.MatchStfld(typeof(TileDrawing).GetField("_martianGlow", BindingFlags.NonPublic | BindingFlags.Instance)), + x => x.MatchLdarg(0), // åŒ¹é… ldarg.0 + x => x.MatchLdfld(typeof(TileDrawing).GetField("_currentTileDrawInfo", BindingFlags.NonPublic | BindingFlags.Instance)))) // åŒ¹é… ldfld + { + cursor.Index += 2; + cursor.EmitDelegate(ILHook_SearchCableTile_HangingTilesAndCallPreDraw); + } + } + + private void ILHook_SearchCableTile_HangingTilesAndCallPreDraw() + { + Vector2 unscaledPosition = Main.Camera.UnscaledPosition; + Vector2 vector = new Vector2(Main.offScreenRange); + if (Main.drawToScreen) + { + vector = Vector2.Zero; + } + GetScreenDrawArea(unscaledPosition, vector + (Main.Camera.UnscaledPosition - Main.Camera.ScaledPosition), out int firstTileX, out int lastTileX, out int firstTileY, out int lastTileY); + foreach (var hangingTile in TileLoader.tiles.OfType()) + { + foreach (var tilePos in hangingTile.RopesOfAllThisTileInTheWorld.Keys) + { + var worldPos = tilePos.ToWorldCoordinates(); + if (VFXManager.InScreen(worldPos, hangingTile.DrawOffScreenRange) && (tilePos.X < firstTileX - 2 || tilePos.X >= lastTileX + 2 || tilePos.Y < firstTileY || tilePos.Y >= lastTileY + 4)) + { + int type = Main.tile[tilePos].type; + TileLoader.PreDraw(tilePos.X, tilePos.Y, type, Main.spriteBatch); + } + } + } + foreach (var cableTile in TileLoader.tiles.OfType()) + { + foreach (var tilePos in cableTile.RopesOfAllThisTileInTheWorld.Keys) + { + var worldPos = tilePos.ToWorldCoordinates(); + if (VFXManager.InScreen(worldPos, cableTile.DrawOffScreenRange) && (tilePos.X < firstTileX - 2 || tilePos.X >= lastTileX + 2 || tilePos.Y < firstTileY || tilePos.Y >= lastTileY + 4)) + { + int type = Main.tile[tilePos].type; + TileLoader.PreDraw(tilePos.X, tilePos.Y, type, Main.spriteBatch); + } + } + } + + foreach (var offestScreenTile in TileLoader.tiles.OfType()) + { + for (int x = ITileOffsetOverScreenDrawn.SpecialTilePositon.Count - 1; x >= 0; x--) + { + var tilePos = ITileOffsetOverScreenDrawn.SpecialTilePositon[x]; + var worldPos = tilePos.ToWorldCoordinates(); + if (VFXManager.InScreen(worldPos, offestScreenTile.TileOffsetScreenRange()) && (tilePos.X < firstTileX - 2 || tilePos.X >= lastTileX + 2 || tilePos.Y < firstTileY || tilePos.Y >= lastTileY + 4)) + { + var tile = Main.tile[tilePos]; + if (tile.HasTile && TileLoader.GetTile(tile.type) is ITileOffsetOverScreenDrawn) + { + int type = tile.type; + TileLoader.PreDraw(tilePos.X, tilePos.Y, type, Main.spriteBatch); + } + else + { + ITileOffsetOverScreenDrawn.SpecialTilePositon.Remove(tilePos); + } + } + } + } + } + + private void GetScreenDrawArea(Vector2 screenPosition, Vector2 offSet, out int firstTileX, out int lastTileX, out int firstTileY, out int lastTileY) + { + firstTileX = (int)((screenPosition.X - offSet.X) / 16f - 1f); + lastTileX = (int)((screenPosition.X + Main.screenWidth + offSet.X) / 16f) + 2; + firstTileY = (int)((screenPosition.Y - offSet.Y) / 16f - 1f); + lastTileY = (int)((screenPosition.Y + Main.screenHeight + offSet.Y) / 16f) + 5; + if (firstTileX < 4) + { + firstTileX = 4; + } + + if (lastTileX > Main.maxTilesX - 4) + { + lastTileX = Main.maxTilesX - 4; + } + + if (firstTileY < 4) + { + firstTileY = 4; + } + + if (lastTileY > Main.maxTilesY - 4) + { + lastTileY = Main.maxTilesY - 4; + } + } + + public override bool PreDraw(int i, int j, int type, SpriteBatch spriteBatch) + { + Point checkPos = (Main.screenPosition + new Vector2(Main.screenWidth, Main.screenHeight) * 0.5f).ToTileCoordinates(); + if (checkPos.X == i && checkPos.Y == j) + { + foreach (var hangingTile in TileLoader.tiles.OfType()) + { + foreach (var tilePos in hangingTile.RopesOfAllThisTileInTheWorld.Keys) + { + var worldPos = tilePos.ToWorldCoordinates(); + if (VFXManager.InScreen(worldPos, hangingTile.DrawOffScreenRange)) + { + TileFluentDrawManager.AddFluentPoint(hangingTile, tilePos.X, tilePos.Y); + } + } + } + } + return base.PreDraw(i, j, type, spriteBatch); + } +} diff --git a/Sources/Everglow.Function/TileHelper/HangingExit.png b/Sources/Everglow.Function/TileHelper/HangingExit.png new file mode 100644 index 000000000..3dc65a4b6 Binary files /dev/null and b/Sources/Everglow.Function/TileHelper/HangingExit.png differ diff --git a/Sources/Everglow.Function/TileHelper/HangingTile.cs b/Sources/Everglow.Function/TileHelper/HangingTile.cs index 03db6bb01..125019d4c 100644 --- a/Sources/Everglow.Function/TileHelper/HangingTile.cs +++ b/Sources/Everglow.Function/TileHelper/HangingTile.cs @@ -1,8 +1,6 @@ -using Everglow.Commons.Enums; using Everglow.Commons.Physics.MassSpringSystem; +using Everglow.Commons.Utilities; using Everglow.Commons.Vertex; -using Everglow.Commons.VFX; -using Everglow.Commons.VFX.Pipelines; using Terraria.Audio; using Terraria.DataStructures; using Terraria.GameContent.Drawing; @@ -16,20 +14,19 @@ namespace Everglow.Commons.TileHelper; /// public abstract class HangingTile : ModTile, ITileFluentlyDrawn { - public override string Texture => "Everglow/Commons/TileHelper/HangingWinch"; - /// /// Max cable length : default 60 + /// It means the max counts of rope units, not the max length in pixels. /// public int MaxCableLength = 60; /// - /// Lamp item mass : default 8 + /// The mass of the hanging item(usually the light fixture at the bottom) : default 8 /// - public float SingleLampMass = 8; + public float HangingItemMass = 8; /// - /// Cable mass : default 0.5f + /// Unit mass : default 0.5f /// public float RopeUnitMass = 0.5f; @@ -38,16 +35,86 @@ public abstract class HangingTile : ModTile, ITileFluentlyDrawn /// public int MaxWireStyle = 2; + /// + /// The distance between joints when there is no external force. + /// + public float UnitLength = 6f; + /// /// Elasticity of cable : default 150 /// public float Elasticity = 150; /// - /// Allow rotating joint to adjust length : default true + /// The maximum time (in frames) for the adjusting visual effect to last. default 60f. + /// + public float AdjustingVisualTimeMax = 60f; + + /// + /// Allow right-click the top to adjust length : default true /// public bool LengthAdjustable = true; + /// + /// If true, player can press "up" when passing the rope to grasp. + /// Then, player will absorb to the bottom of the rope and can swing on it. + /// + public bool CanGrasp = false; + + /// + /// Be valid only when CanGrasp is true. default 48f. The range of detecting the rope tip when player press "up" to grasp. + /// + public float GraspDetectRange = 48f; + + /// + /// How far should start drawing the rope in an area out of screen. + /// + public float DrawOffScreenRange = 1200f; + + public string BulbTexturePath; + + /// + /// + /// Winch position and rope.

+ /// 1 point contains 1 rope at most. + ///
+ public Dictionary RopesOfAllThisTileInTheWorld = new Dictionary(); + + /// + /// Current Player who is handling with the HangingTile winched at a certain Point.

+ /// 1 winch can be modified by only 1 player simultanrously. + ///
+ public Dictionary WinchAdjustingPlayers = new Dictionary(); + + /// + /// A mousePos-player Dictionary to prevent generating multiple knob VFX.

+ /// 1 winch can display more than 1 knob VFXs in multi-player mode. + ///
+ public Dictionary MouseOverWinchPlayers = new Dictionary(); + + /// + /// Current Player who grasping the rope of HangingTile winched at a certain Point.

+ /// Be valid only when CanGrasp is true.

+ /// 1 rope can be grasped by only 1 player. + ///
+ public static Dictionary RopeGraspingPlayer = new Dictionary(); + + public struct DrawStack + { + public Texture2D Texture; + + public IEnumerable Vertices; + + public PrimitiveType PType; + + public DrawStack(Texture2D texture, IEnumerable vertices, PrimitiveType pType) + { + Texture = texture; + Vertices = vertices; + PType = pType; + } + } + public override void SetStaticDefaults() { Main.tileFrameImportant[Type] = true; @@ -60,17 +127,57 @@ public override void SetStaticDefaults() TileObjectData.newTile.UsesCustomCanPlace = true; AddMapEntry(new Color(59, 67, 67)); + InitHanging(); } /// - /// Winch position and rope + /// Override to customize the values.

+ /// defaults:

+ /// MaxCableLength = 60;

+ /// HangingItemMass = 8;

+ /// RopeUnitMass = 0.5f;

+ /// MaxWireStyle = 2;

+ /// Elasticity = 150;

+ /// LengthAdjustable = true;

+ /// CanGrasp = false; ///
- public Dictionary RopesOfAllThisTileInTheWorld = new Dictionary(); + public virtual void InitHanging() + { + } + + /// + /// 在刚打开按钮时的行为 + /// + /// HangingTile实例ä½ç½® + /// 正在æ“作的玩家 + public virtual void OnAdjustmentStart(Point fixPoint, Player player) + { + } /// - /// Winch position and rope + /// 调整长度时的行为 /// - public Dictionary ChainPlayer = new Dictionary(); + /// ä½ç½®åæ ‡ + /// æ“作玩家 + /// 长度增é‡,值为0代表这帧没å˜åŒ–,如果ä¸éœ€è¦å¤„ç†0请在值为0时直接return + public virtual void OnAdjustmentUpdate(Point fixPoint, Player player, int deltaLength) + { + Rope rope; + RopesOfAllThisTileInTheWorld.TryGetValue(fixPoint, out rope); + if (rope != null) + { + UpdateRopeAdjustment(rope, fixPoint); + } + } + + /// + /// 结æŸè°ƒæ•´æ—¶çš„行为 + /// + /// ä½ç½®åæ ‡ + /// æ“作玩家 + public virtual void OnAdjustmentEnd(Point fixPoint, Player player) + { + } public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) { @@ -79,6 +186,12 @@ public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBre return base.TileFrame(i, j, ref resetFrame, ref noBreak); } + public override void PlaceInWorld(int i, int j, Item item) + { + Tile tile = Main.tile[i, j]; + tile.TileFrameY = 18; + } + public override void HitWire(int i, int j) { Tile tile = Main.tile[i, j]; @@ -88,7 +201,7 @@ public override void HitWire(int i, int j) tile.TileFrameX = 0; tile.TileFrameY += 18; } - int style = tile.TileFrameX / 18 + (tile.TileFrameY / 18) * 4; + int style = tile.TileFrameX / 18 + tile.TileFrameY / 18 * 4; MaxWireStyle = Math.Min(MaxWireStyle, 16); if (style >= MaxWireStyle) { @@ -108,7 +221,7 @@ public override void KillTile(int i, int j, ref bool fail, ref bool effectOnly, } /// - /// é è¿‘æ—¶æ ¹æ®TE挂绳 + /// Add rope by TileEntity when approaching. /// /// /// @@ -123,490 +236,534 @@ public override void NearbyEffects(int i, int j, bool closer) } /// - /// æŒ‚ä¸Šç»³å­ + /// It should not check the grasping logic of players in any drawing function. /// - /// - /// - /// - public virtual void AddRope(int i, int j) + public virtual void CheckPlayerGrasp(Point pos) { - Rope rope = ConnectRope(i, j); - if (rope == null) + Rope rope; + RopesOfAllThisTileInTheWorld.TryGetValue(pos, out rope); + if (rope is null) { return; } - if (RopesOfAllThisTileInTheWorld.ContainsKey(new Point(i, j))) + if (!RopeGraspingPlayer.ContainsKey(pos)) { return; } - var masses = rope.Masses; - RopesOfAllThisTileInTheWorld.Add(new Point(i, j), rope); - TryGetCableEntityAs(i, j, out CableEneity cableEneity); - if (cableEneity == null) + Player graspPlayer = RopeGraspingPlayer[pos]; + if (graspPlayer is null) { - TileEntity.PlaceEntityNet(i, j, ModContent.TileEntityType()); - TryGetCableEntityAs(i, j, out cableEneity); + return; } - } + UpdateGraspingPlayer(graspPlayer, rope, pos); - /// - /// 挂绳 - /// - /// - /// - /// - /// - /// - public virtual Rope ConnectRope(int i, int j) - { - Tile tile = Main.tile[i, j]; - int counts = MaxCableLength; - int restCount = tile.TileFrameY; - Rope rope = Rope.Create_Fixed_Start_Heavy_End(new Point(i, j).ToWorldCoordinates(), counts, Elasticity, RopeUnitMass, SingleLampMass, MaxCableLength - restCount); - return rope; - } - - public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) - { - Color lightColor = Lighting.GetColor(i, j); - var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); - if (Main.drawToScreen) + if (!RopeGraspingPlayer.ContainsKey(pos) || RopeGraspingPlayer[pos] != graspPlayer) { - zero = Vector2.Zero; + return; } - spriteBatch.Draw(ModAsset.HangingWinch.Value, new Vector2(i, j) * 16 - Main.screenPosition + zero, new Rectangle(0, 0, 16, 16), lightColor, 0, Vector2.zeroVector, 1, SpriteEffects.None, 0); - - TileFluentDrawManager.AddFluentPoint(this, i, j); - return false; - } - - public override void DrawEffects(int i, int j, SpriteBatch spriteBatch, ref TileDrawInfo drawData) - { - base.DrawEffects(i, j, spriteBatch, ref drawData); - } - public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) - { - Rope rope; - RopesOfAllThisTileInTheWorld.TryGetValue(pos, out rope); - if (rope != null) + // Check Remove Player + if (graspPlayer is null || !graspPlayer.active || graspPlayer.controlJump || graspPlayer.mount.Active) { - DrawCable(rope, pos, spriteBatch, tileDrawing); + RemovePlayerFromRope(graspPlayer, rope, pos); } } - public string BulbTexturePath; - /// - /// 绘制挂物 + /// Move the player.
+ /// Animate the player.
+ /// Swing the rope.
+ /// Check switch rope. ///
+ /// /// /// - /// - /// - /// - public virtual void DrawCable(Rope rope, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing, Color color = default(Color)) + public void UpdateGraspingPlayer(Player player, Rope rope, Point pos) { - // 回声涂料 - if (!TileDrawing.IsVisible(Main.tile[pos])) + var masses = rope.Masses; + var vineEndPosition = masses[^1].Position; + + // Player Kinematics + player.Center = vineEndPosition; + player.velocity *= 0; + player.gravity *= 0; + + // Player Animation + float rot = 0; + if (masses.Length > 2) { - return; + rot = (masses[^2].Position - masses[^1].Position).ToRotation() + MathHelper.PiOver2; + } + player.fullRotation = rot; + player.SetCompositeArmBack(true, Player.CompositeArmStretchAmount.Full, MathHelper.Pi); + if (!player.controlUseItem && !player.controlUseTile) + { + player.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, rot); } - var tile = Main.tile[pos]; - ushort type = tile.TileType; - int paint = Main.tile[pos].TileColor; - Texture2D tex = PaintedTextureSystem.TryGetPaintedTexture(BulbTexturePath, type, 1, paint, tileDrawing); + // Swing + Vector2 ropeDir = (masses[0].Position - masses[^1].Position).NormalizeSafe(); + Vector2 pushDir = ropeDir.RotatedBy(MathHelper.PiOver2); + if (player.controlLeft && ropeDir.X < 0.6f) + { + PushRope(ref rope, -pushDir * 4); + } + if (player.controlRight && ropeDir.X > -0.6f) + { + PushRope(ref rope, pushDir * 4); + } - // 获å–å‘绳端物å—ä¿¡æ¯ - var masses = rope.Masses; - for (int i = 0; i < masses.Length; i++) + // Switch Ropes + if (player.controlDown) { - Mass thisMass = masses[i]; - if (i < MaxCableLength - tile.TileFrameY) + CheckSwitchRope(player, rope, pos); + } + + // Collision + if (Collision.SolidCollision(player.position, player.width, player.height)) + { + RemovePlayerFromRope(player, rope, pos); + } + if (player.controlHook) + { + RemovePlayerFromRope(player, rope, pos); + } + } + + public void CheckSwitchRope(Player player, Rope rope, Point pos) + { + float minDistance = GraspDetectRange + 10; + Rope targetRope = null; + Point targetPoint = new Point(0, 0); + foreach (var hangingTile in TileLoader.tiles.OfType()) + { + // Exclude the current type. + if (hangingTile == this) { - thisMass.IsStatic = true; - thisMass.Position = pos.ToWorldCoordinates(); continue; } - else - { - thisMass.IsStatic = false; - } - int totalPushTime = 80; - float pushForcePerFrame = 1.26f; - float windCycle = 0; - if (tileDrawing.InAPlaceWithWind((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f), 1, 1)) - { - windCycle = tileDrawing.GetWindCycle((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f), tileDrawing._sunflowerWindCounter); - } - - float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f), 1, 1, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); - windCycle += highestWindGridPushComplex; - if (!Main.gamePaused) + bool findCloser = false; + foreach (var rope_new in hangingTile.RopesOfAllThisTileInTheWorld.Values) { - if (i < masses.Length - 1) - { - rope.ApplyForceSpecial(i, new Vector2(windCycle / 4.0f, 0.4f * thisMass.Value)); - } - else + Vector2 ropeTipPos = rope_new.Masses.Last().Position; + Vector2 playerToTip = ropeTipPos - player.Center; + if (playerToTip.Length() < minDistance) { - rope.ApplyForceSpecial(i, new Vector2(windCycle * 10.0f, 0.4f * thisMass.Value)); + minDistance = playerToTip.Length(); + targetRope = rope_new; + findCloser = true; } } - - // 支æŒå‘光涂料 - Color tileLight; - if (color != default) - { - tileLight = color; - } - else - { - tileLight = Lighting.GetColor((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f)); - } - - Vector2 toNextMass; - if (i < masses.Length - 1) + if (findCloser) { - Mass nextMass = masses[i + 1]; - toNextMass = nextMass.Position - thisMass.Position; + targetPoint = hangingTile.RopesOfAllThisTileInTheWorld.FirstOrDefault(kv => kv.Value == targetRope).Key; } - else + } + foreach (var rope_new in RopesOfAllThisTileInTheWorld.Values) + { + // Exclude the current rope. + if (RopesOfAllThisTileInTheWorld.ContainsKey(pos) && RopesOfAllThisTileInTheWorld[pos] == rope_new) { - Mass passedMass = masses[i - 1]; - toNextMass = thisMass.Position - passedMass.Position; + continue; } - Vector2 drawPos = thisMass.Position - Main.screenPosition; - if (i < masses.Length - 1) + bool findCloser = false; + Vector2 ropeTipPos = rope_new.Masses.Last().Position; + Vector2 playerToTip = ropeTipPos - player.Center; + if (playerToTip.Length() < minDistance) { - spriteBatch.Draw(tex, drawPos, new Rectangle(8 * (i % 4), 0, 8, 10), tileLight, toNextMass.ToRotation() - MathHelper.PiOver2, new Vector2(4f, 0), 1f, SpriteEffects.None, 0); + minDistance = playerToTip.Length(); + targetRope = rope_new; + findCloser = true; } - else + if (findCloser) { - spriteBatch.Draw(tex, drawPos, new Rectangle(0, 12, 32, 40), tileLight, toNextMass.ToRotation() - MathHelper.PiOver2, new Vector2(16f, 0), 1f, SpriteEffects.None, 0); - Lighting.AddLight(drawPos + Main.screenPosition, new Vector3(0.8f, 0.8f, 0.2f)); + targetPoint = RopesOfAllThisTileInTheWorld.FirstOrDefault(kv => kv.Value == targetRope).Key; } } + if (targetRope is null) + { + return; + } + RemovePlayerFromRope(player, rope, pos); + AddPlayerToRope(player, targetRope, targetPoint); } - /// - /// Try to get the cable entity bound at (, ). - /// - /// The type to get the entity as - /// The tile X-coordinate - /// The tile Y-coordinate - /// The found instance, if there was one. - /// if there was a instance, or if there was no entity present OR the entity was not a instance. - public static bool TryGetCableEntityAs(int i, int j, out T entity) - where T : TileEntity + public void AddPlayerToRope(Player player, Rope rope, Point tilePos) { - Point16 origin = new Point16(i, j); - - // TileEntity.ByPosition is a Dictionary which contains all placed TileEntity instances in the world - // TryGetValue is used to both check if the dictionary has the key, origin, and get the value from that key if it's there - if (TileEntity.ByPosition.TryGetValue(origin, out TileEntity existing) && existing is T existingAsT) + HangingTile_Player hTP = player.GetModPlayer(); + if (hTP is null) { - entity = existingAsT; - return true; + return; + } + if (hTP.SwitchVineCoolTimer > 0) + { + return; + } + hTP.SwitchVineCoolTimer = 30; + if (RopeGraspingPlayer.TryAdd(tilePos, player)) + { + hTP.Grasping = true; + PushRope(ref rope, player.velocity * 12f); + player.RemoveAllGrapplingHooks(); } + } - entity = null; - return false; + public void RemovePlayerFromRope(Player player, Rope rope, Point tilePos) + { + HangingTile_Player hTP = player.GetModPlayer(); + if (hTP is null) + { + return; + } + if (hTP.SwitchVineCoolTimer > 0) + { + return; + } + hTP.Grasping = false; + var masses = rope.Masses; + RopeGraspingPlayer.Remove(tilePos); + player.gravity = Player.defaultGravity; + Vector2 finalVel = masses[^1].Velocity * 3; + player.velocity = finalVel; + PushRope(ref rope, -finalVel * 16f); + player.fullRotation = 0f; } /// - /// é¼ æ ‡åˆ’è¿‡ç‚¹ä½ + /// Apply a force to the whole rope. /// - public Dictionary MouseOverPoint = new Dictionary(); - - public override void MouseOver(int i, int j) + /// + /// + public void PushRope(ref Rope rope, Vector2 force) { - if (LengthAdjustable) + var masses = rope.Masses; + for (int i = 0; i < masses.Length; i++) { - if (!MouseOverPoint.ContainsKey(Main.LocalPlayer)) - { - MouseOverPoint.Add(Main.LocalPlayer, new Point(i, j)); - if (Main.LocalPlayer.HeldItem.createTile == Type) - { - HangingTileLengthAdjustingSystem vfx = new HangingTileLengthAdjustingSystem { FixPoint = new Point(i, j), Active = true, Visible = true, Style = 0 }; - Ins.VFXManager.Add(vfx); - } - } - else if (MouseOverPoint[Main.LocalPlayer] != new Point(i, j)) - { - MouseOverPoint.Remove(Main.LocalPlayer); - } + float value = i / (float)masses.Length; + rope.ApplyForceSpecial(i, value * force); } } /// - /// Right click to adjust cable length. + /// Add the rope. /// /// /// - /// - public override bool RightClick(int i, int j) + /// + public virtual void AddRope(int i, int j) { - if (LengthAdjustable) + Point pos = new Point(i, j); + Tile tile = Main.tile[pos]; + int counts = MaxCableLength; + int restCount = tile.TileFrameY; + Rope rope = Rope.Create_Fixed_Start_Heavy_End(pos.ToWorldCoordinates(), counts, Elasticity, RopeUnitMass, HangingItemMass, MaxCableLength - restCount, UnitLength); + if (rope == null) { - // 旋转 - Tile tile = Main.tile[i, j]; - if (Main.LocalPlayer.HeldItem.createTile == Main.tile[i, j].TileType && !ChainPlayer.ContainsKey(new Point(i, j))) - { - HangingTileLengthAdjustingSystem vfx = new HangingTileLengthAdjustingSystem { FixPoint = new Point(i, j), Active = true, Visible = true, Style = 1, StartFrameY60 = tile.TileFrameY * 60 }; - Ins.VFXManager.Add(vfx); - SoundEngine.PlaySound(SoundID.Item17, new Vector2(i, j) * 16); - ChainPlayer.Add(new Point(i, j), Main.LocalPlayer); - } + return; } - return base.RightClick(i, j); - } + if (RopesOfAllThisTileInTheWorld.ContainsKey(pos)) + { + return; + } + RopesOfAllThisTileInTheWorld.Add(pos, rope); + TryGetCableEntityAs(i, j, out CableEneity cableEneity); + if (cableEneity == null) + { + TileEntity.PlaceEntityNet(i, j, ModContent.TileEntityType()); + TryGetCableEntityAs(i, j, out cableEneity); + } + UpdateRopeAdjustment(rope, pos); - public override void PlaceInWorld(int i, int j, Item item) - { - Tile tile = Main.tile[i, j]; - tile.TileFrameY = 18; + // Initialize the positions of masses. + var masses = rope.Masses; + Vector2 currentPos = Vector2.zeroVector; + for (int k = 0; k < masses.Length; k++) + { + Mass thisMass = masses[k]; + if (!thisMass.IsStatic) + { + currentPos += new Vector2(0, UnitLength); + masses[k].Position = pos.ToWorldCoordinates() + currentPos; + } + } } -} -[Pipeline(typeof(WCSPipeline))] -public class HangingTileLengthAdjustingSystem : Visual -{ - public override CodeLayer DrawLayer => CodeLayer.PreDrawFilter; - - public Texture2D Texture; - public Point FixPoint; - public int Style; - public float StartFrameY60; - public Vector2 StartRotation; - public float AccumulateRotation; - public Vector2 OldRotation; - - public override void OnSpawn() + /// + /// Highlight a knob which can adjust the rope. + /// + /// + /// + public override void MouseOver(int i, int j) { - StartRotation = Utils.SafeNormalize(FixPoint.ToWorldCoordinates() - Main.MouseWorld, new Vector2(0, -1)); - OldRotation = StartRotation; - AccumulateRotation = 0; - Texture = ModAsset.TileBlock.Value; + base.MouseOver(i, j); } - public override void Update() + public override void MouseOverFar(int i, int j) { Player player = Main.LocalPlayer; - int i = FixPoint.X; - int j = FixPoint.Y; - if (i < 20 || i > Main.maxTilesX - 20) + Point point = new Point(i, j); + if (!IsCanRightClick(i, j)) { - if (j < 20 || j > Main.maxTilesY - 20) - { - Active = false; - return; - } + return; } - Tile tile = Main.tile[i, j]; - HangingTile hangingTile = TileLoader.GetTile(tile.type) as HangingTile; - if (hangingTile == null) + if (LengthAdjustable && !RopeGraspingPlayer.ContainsKey(point)) { - Active = false; - return; + if (!MouseOverWinchPlayers.ContainsKey(player) && TileUtils.CanPlayerInteractWithTile(i, j, player)) + { + MouseOverWinchPlayers.Add(player, point); + HangingTileAdjustingHelper vfx = new HangingTileAdjustingHelper { FixPoint = point, Active = true, Visible = true, Style = 0 }; + Ins.VFXManager.Add(vfx); + } + else if (MouseOverWinchPlayers[player] != point) + { + MouseOverWinchPlayers.Remove(player); + } + if (MouseOverWinchPlayers.ContainsKey(player)) + { + if (Main.mouseRight && Main.mouseRightRelease) + { + if (LengthAdjustable && !RopeGraspingPlayer.ContainsKey(point)) + { + Tile tile = Main.tile[point]; + if (!WinchAdjustingPlayers.ContainsKey(point)) + { + OnAdjustmentStart(point, Main.LocalPlayer); + HangingTileUpdateSystem.WinchAdjustingPlayerTimers[point] = AdjustingVisualTimeMax; + HangingTileAdjustingHelper vfx = new HangingTileAdjustingHelper { FixPoint = point, Active = true, Visible = true, Style = 1, StartFrameY60 = tile.TileFrameY * 60 }; + vfx.RegisterCustomPanelDrawing(DrawDefaultPanel); + vfx.HandleRotation = (point.ToWorldCoordinates() - player.MouseWorld()).ToRotationSafe(); + vfx.InitialHandleRotation = vfx.HandleRotation; + vfx.Timer = 0; + Ins.VFXManager.Add(vfx); + SoundEngine.PlaySound(SoundID.Item17, point.ToWorldCoordinates()); + WinchAdjustingPlayers.Add(point, Main.LocalPlayer); + AdjustingVisualTimeMax = 30; + } + else + { + WinchAdjustingPlayers.Remove(point); + } + } + } + } } - if (hangingTile.ChainPlayer.ContainsKey(FixPoint)) + } + + /// + /// Right click to adjust cable length. + /// + /// + /// + /// + public override bool RightClick(int i, int j) + { + return base.RightClick(i, j); + } + + /// + /// 基于å³é”®å®žçŽ°è°ƒæ•´ç»³å­é•¿åº¦çš„功能,你å¯ä»¥è‡ªå®šä¹‰å¼€å¯è°ƒæ•´æ—‹é’®çš„æ¡ä»¶ï¼Œé»˜è®¤å½“æ‰‹æŒç‰©å“å’Œå³é”®ç‰©å—ç±»åž‹ç›¸åŒæ—¶è¿”回true。 + /// + /// å³é”®ä½ç½®çš„æ¨ªåæ ‡ + /// å³é”®ä½ç½®çš„çºµåæ ‡ + /// 值为true表示å…è®¸å¼€å¯æ—‹é’® + public virtual bool IsCanRightClick(int i, int j) + { + return Main.LocalPlayer.HeldItem.createTile == Main.tile[i, j].TileType; + } + + /// + /// The drawing part of the rope-adjusting-knob. é‡å†™æˆ‘æ¥é‡ç»˜æŒ‰é’®æ•ˆæžœ + /// + /// + /// + /// + /// + public virtual void DrawDefaultPanel(HangingTileAdjustingHelper hangingSystem, Player player, Color color, ref Queue drawStacks) + { + drawStacks = new Queue(); + DrawBackgroundPanel(hangingSystem, Color.White * 0.5f, ref drawStacks); + float maxCos = 0; + int maxK = 0; + Vector2 rotCenter = hangingSystem.FixPoint.ToWorldCoordinates(); + Vector2 cut = new Vector2(1, 0).RotatedBy(hangingSystem.HandleRotation + MathHelper.Pi); + + // Calculate the bloom effect of calibration tails. + for (int k = -10; k < 10; k++) { - Player player2; - hangingTile.ChainPlayer.TryGetValue(FixPoint, out player2); - if (player2 != player) + Vector2 cut2 = new Vector2(0, -1).RotatedBy(k / 20f * MathHelper.TwoPi); + float cosValue = Vector2.Dot(cut, cut2); + if (cosValue > maxCos) { - KillMe(hangingTile, player); - return; + maxCos = cosValue; + maxK = k; } } - if (player.HeldItem.createTile != tile.TileType) + + // Draw calibration tails. + Color newDrawColor = color; + float nowFrameY = hangingSystem.StartFrameY60 / 60f + hangingSystem.HandleRotation * 2; + if (nowFrameY < 5) { - KillMe(hangingTile, player); - return; + newDrawColor = Color.Lerp(color, new Color(1f, 0f, 0f, 0.8f), (5 - nowFrameY) / 4f); } - if ((Main.MouseWorld - FixPoint.ToWorldCoordinates()).Length() > 400) + if (nowFrameY > MaxCableLength - 5) { - KillMe(hangingTile, player); - return; + newDrawColor = Color.Lerp(color, new Color(1f, 0f, 0f, 0.8f), (nowFrameY - (MaxCableLength - 5)) / 4f); } - if (Style == 0) + float tK = 12f; + if (hangingSystem.TimeToKill > 0) { - int x = (int)(Main.MouseWorld.X / 16f); - int y = (int)(Main.MouseWorld.Y / 16f); - if (x != FixPoint.X || y != FixPoint.Y) - { - Active = false; - if (hangingTile.MouseOverPoint.ContainsKey(player)) - { - hangingTile.MouseOverPoint.Remove(player); - } - return; - } + tK = hangingSystem.TimeToKill; } - if (Style == 1) + float fade = Math.Min(hangingSystem.Timer, tK) / 12f; + for (int k = -10; k < 10; k++) { - if (!hangingTile.ChainPlayer.ContainsKey(FixPoint)) - { - KillMe(hangingTile, player); - return; - } - if (!hangingTile.ChainPlayer.ContainsKey(FixPoint)) - { - KillMe(hangingTile, player); - return; - } - float addAccRot = MathF.Asin(-Vector3.Cross(new Vector3(Utils.SafeNormalize(FixPoint.ToWorldCoordinates() - Main.MouseWorld, new Vector2(0, -1)), 0), new Vector3(OldRotation, 0)).Z); - AccumulateRotation += addAccRot; - OldRotation = Utils.SafeNormalize(FixPoint.ToWorldCoordinates() - Main.MouseWorld, new Vector2(0, -1)); - float nowFrameY = StartFrameY60 / 60f + AccumulateRotation * 2; - if (nowFrameY < 1) - { - AccumulateRotation -= addAccRot; - } - if (nowFrameY > hangingTile.MaxCableLength - 1) + Vector2 cut2 = new Vector2(0, -1).RotatedBy(k / 20f * MathHelper.TwoPi); + float cosValue = Vector2.Dot(cut, cut2); + + if (k == maxK) { - AccumulateRotation -= addAccRot; + DrawLine_Black(hangingSystem, rotCenter + cut2 * (4 * hangingSystem.PanelRange - 12), rotCenter + cut2 * (4 * hangingSystem.PanelRange + 36), 16, ref drawStacks); + DrawLine(rotCenter + cut2 * (4 * hangingSystem.PanelRange - 12), rotCenter + cut2 * (4 * hangingSystem.PanelRange + 36), 16, newDrawColor * fade, 1f, ref drawStacks); } - bool endChain = false; - if (nowFrameY < 2) + else { - endChain = true; + DrawLine(rotCenter + cut2 * 4 * hangingSystem.PanelRange, rotCenter + cut2 * (4 * hangingSystem.PanelRange + 24), 12, newDrawColor * fade, cosValue, ref drawStacks); } - if (nowFrameY > hangingTile.MaxCableLength - 2) + } + + // Draw bound. + DrawBound(hangingSystem, color, player, ref drawStacks); + DrawDirectionRing(hangingSystem, newDrawColor, hangingSystem.HandleRotation - MathHelper.PiOver2, ref drawStacks); + } + + public virtual void DrawBound(HangingTileAdjustingHelper hangingSystem, Color color, Player player, ref Queue drawStacks) + { + if (drawStacks == null) + { + drawStacks = new Queue(); + } + Vector2 rotCenter = hangingSystem.FixPoint.ToWorldCoordinates(); + if ((player.MouseWorld() - rotCenter).Length() > 240) + { + Vector2 cut3 = (player.MouseWorld() - rotCenter).NormalizeSafe(); + float colorValue = ((player.MouseWorld() - rotCenter).Length() - 240f) / 160f; + colorValue = Math.Min(colorValue, 1); + Color newDrawColor = Color.Lerp(color, new Color(1f, 0f, 0f, 0f), colorValue); + newDrawColor.A = 0; + float colorFade = 1f; + if (hangingSystem.TimeToKill > 0) { - endChain = true; + colorFade = hangingSystem.TimeToKill / 12f; } - if (tile.TileFrameY != (short)Math.Clamp(nowFrameY, 1, hangingTile.MaxCableLength - 1)) + Color backgroundColor = Color.White * 0.6f * colorFade; + newDrawColor *= colorFade; + Main.instance.MouseText("Drag out of circle to cancel", ItemRarityID.White); + + List bars_left = new List(); + List bars_right = new List(); + + List bars_left_black = new List(); + List bars_right_black = new List(); + for (int k = 0; k < 30; k++) { - if (!endChain) - { - SoundEngine.PlaySound(SoundID.Unlock.WithVolume(0.5f), FixPoint.ToWorldCoordinates()); - } - tile.TileFrameY = (short)Math.Clamp(nowFrameY, 1, hangingTile.MaxCableLength - 1); + float xCoord = (colorValue - k / 30f) * 0.8f; + xCoord = Math.Clamp(xCoord, 0, 1); + bars_left_black.Add(rotCenter + cut3.RotatedBy(k / 30f) * 400f, backgroundColor, new Vector3(xCoord, 0.5f, 0)); + bars_left_black.Add(rotCenter + cut3.RotatedBy(k / 30f) * 350f, backgroundColor, new Vector3(xCoord, 0.8f, 0)); + + bars_right_black.Add(rotCenter + cut3.RotatedBy(-k / 30f) * 400f, backgroundColor, new Vector3(xCoord, 0.5f, 0)); + bars_right_black.Add(rotCenter + cut3.RotatedBy(-k / 30f) * 350f, backgroundColor, new Vector3(xCoord, 0.8f, 0)); + + bars_left.Add(rotCenter + cut3.RotatedBy(k / 30f) * 400f, newDrawColor, new Vector3(xCoord, 0.5f, 0)); + bars_left.Add(rotCenter + cut3.RotatedBy(k / 30f) * 350f, newDrawColor, new Vector3(xCoord, 0.8f, 0)); + + bars_right.Add(rotCenter + cut3.RotatedBy(-k / 30f) * 400f, newDrawColor, new Vector3(xCoord, 0.5f, 0)); + bars_right.Add(rotCenter + cut3.RotatedBy(-k / 30f) * 350f, newDrawColor, new Vector3(xCoord, 0.8f, 0)); } - int x = (int)(Main.MouseWorld.X / 16f); - int y = (int)(Main.MouseWorld.Y / 16f); - if (Main.mouseRight && Main.mouseRightRelease && (x != FixPoint.X || y != FixPoint.Y)) + drawStacks.Enqueue(new DrawStack(ModAsset.SparkDark.Value, bars_left_black, PrimitiveType.TriangleStrip)); + drawStacks.Enqueue(new DrawStack(ModAsset.SparkDark.Value, bars_right_black, PrimitiveType.TriangleStrip)); + + drawStacks.Enqueue(new DrawStack(ModAsset.SparkLight.Value, bars_left, PrimitiveType.TriangleStrip)); + drawStacks.Enqueue(new DrawStack(ModAsset.SparkLight.Value, bars_right, PrimitiveType.TriangleStrip)); + + List text_bars = new List(); + Color textColor = Color.White; + for (int k = -30; k < 30; k++) { - KillMe(hangingTile, player); - return; + float xCoord = -k / 15f; + float fade = (30 * colorValue - Math.Abs(k)) / 15f; + fade = Math.Clamp(fade, 0f, 1f); + fade = MathF.Sin(fade); + text_bars.Add(rotCenter + cut3.RotatedBy(k / 30f) * 420f, textColor * fade * colorFade, new Vector3(xCoord, 1f, 0)); + text_bars.Add(rotCenter + cut3.RotatedBy(k / 30f) * 400f, textColor * fade * colorFade, new Vector3(xCoord, 0f, 0)); } + drawStacks.Enqueue(new DrawStack(ModAsset.HangingExit.Value, text_bars, PrimitiveType.TriangleStrip)); } - base.Update(); } - public void KillMe(HangingTile hangingTile, Player owner) + public virtual void DrawDirectionRing(HangingTileAdjustingHelper hangingSystem, Color color, float rotation, ref Queue drawStacks) { - Active = false; - if (hangingTile.MouseOverPoint.ContainsKey(owner)) + if (drawStacks == null) { - hangingTile.MouseOverPoint.Remove(owner); + drawStacks = new Queue(); } - if (hangingTile.ChainPlayer.ContainsKey(FixPoint)) + color.A = 0; + Vector2 pos = hangingSystem.FixPoint.ToWorldCoordinates(); + List bars = new List(); + for (int k = 0; k <= 60; k++) { - hangingTile.ChainPlayer.Remove(FixPoint); + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 24).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), color, new Vector3(0.5f, k / 15f, 0)); + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 0).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), color, new Vector3(0.3f, k / 15f, 0)); } - } - - public override void Draw() - { - int i = FixPoint.X; - int j = FixPoint.Y; - if (i < 20 || i > Main.maxTilesX - 20) + drawStacks.Enqueue(new DrawStack(ModAsset.StarSlash.Value, bars, PrimitiveType.TriangleStrip)); + bars = new List(); + for (int k = 0; k <= 60; k++) { - if (j < 20 || j > Main.maxTilesY - 20) - { - Active = false; - return; - } + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 12).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), color, new Vector3(0.5f, k / 30f, 0)); + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 0).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), color, new Vector3(0.3f, k / 30f, 0)); } - Player player = Main.LocalPlayer; - Tile tile = Main.tile[i, j]; - HangingTile hangingTile = TileLoader.GetTile(tile.type) as HangingTile; - if (hangingTile == null) + drawStacks.Enqueue(new DrawStack(ModAsset.StarSlash.Value, bars, PrimitiveType.TriangleStrip)); + bars = new List(); + for (int k = 0; k <= 60; k++) { - Active = false; - return; + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 22).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), color, new Vector3(0.5f, k / 60f, 0)); + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 12).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), color, new Vector3(0.3f, k / 60f, 0)); } - Color drawColor = Color.Lerp(new Color(0.75f, 0.75f, 1f, 0.5f), new Color(0.85f, 0.85f, 0.75f, 0.5f), MathF.Sin((float)Main.timeForVisualEffects * 0.08f) * 0.5f + 0.5f); - Color origDrawColor = drawColor; - if (Style == 1) + drawStacks.Enqueue(new DrawStack(ModAsset.StarSlash.Value, bars, PrimitiveType.TriangleStrip)); + bars = new List(); + for (int k = 0; k <= 60; k++) { - float nowFrameY = StartFrameY60 / 60f + AccumulateRotation * 2; - if (nowFrameY < 5) - { - drawColor = Color.Lerp(drawColor, new Color(1f, 0f, 0f, 0.8f), (5 - nowFrameY) / 4f); - } - if (nowFrameY > hangingTile.MaxCableLength - 5) - { - drawColor = Color.Lerp(drawColor, new Color(1f, 0f, 0f, 0.8f), (nowFrameY - (hangingTile.MaxCableLength - 5)) / 4f); - } + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 26).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), color, new Vector3(0.5f, 0.5f, 0)); + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 24).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), color, new Vector3(0.5f, 0.5f, 0)); } + drawStacks.Enqueue(new DrawStack(ModAsset.StarSlash.Value, bars, PrimitiveType.TriangleStrip)); + } - // ä¸åŒç§ç±»ç‰©å—标红 - if (player.HeldItem.createTile != tile.type) + public virtual void DrawBackgroundPanel(HangingTileAdjustingHelper hangingSystem, Color color, ref Queue drawStacks) + { + if (drawStacks == null) { - drawColor = new Color(1f, 0, 0, 0.5f); - Main.instance.MouseText("Different Type Error", ItemRarityID.Red); + drawStacks = new Queue(); } - Ins.Batch.BindTexture(Texture); - - Vector2 rotCenter = FixPoint.ToWorldCoordinates(); - Vector2 cut = -Utils.SafeNormalize(rotCenter - Main.MouseWorld, new Vector2(0, -1)); - if (hangingTile.RopesOfAllThisTileInTheWorld.ContainsKey(FixPoint)) + Vector2 pos = hangingSystem.FixPoint.ToWorldCoordinates(); + List bars = new List(); + for (int k = 0; k <= 60; k++) { - if (Style == 1) - { - float maxCos = 0; - int maxK = 0; - for (int k = -10; k < 10; k++) - { - Vector2 cut2 = new Vector2(0, -1).RotatedBy(k / 20f * MathHelper.TwoPi); - float cosValue = Vector2.Dot(cut, cut2); - if (cosValue > maxCos) - { - maxCos = cosValue; - maxK = k; - } - Color newDrawColor = origDrawColor; - float thisFrameY = StartFrameY60 / 60f + (AccumulateRotation + k / 20f * MathHelper.TwoPi) * 2; - if (thisFrameY < 5) - { - newDrawColor = Color.Lerp(origDrawColor, new Color(1f, 0f, 0f, 0.8f), (5 - thisFrameY) / 4f); - } - if (thisFrameY > hangingTile.MaxCableLength - 5) - { - newDrawColor = Color.Lerp(origDrawColor, new Color(1f, 0f, 0f, 0.8f), (thisFrameY - (hangingTile.MaxCableLength - 5)) / 4f); - } - DrawLine(rotCenter + cut2 * 15, rotCenter + cut2 * 20, 1.5f, newDrawColor); - } - Vector2 cut3 = new Vector2(0, -1).RotatedBy(maxK / 20f * MathHelper.TwoPi); - DrawLine(rotCenter + cut3 * 12, rotCenter + cut3 * 26, 2, drawColor); - if ((Main.MouseWorld - rotCenter).Length() > 240) - { - for (int k = -10; k < 10; k++) - { - Vector2 cut4 = cut.RotatedBy((k - 0.5f) * 0.04f); - Vector2 cut5 = cut.RotatedBy((k + 0.5f) * 0.04f); - float colorValue = ((Main.MouseWorld - rotCenter).Length() - 240f) / 160f; - Color newDrawColor = origDrawColor; - newDrawColor = Color.Lerp(origDrawColor, new Color(1f, 0f, 0f, 0.8f), colorValue); - colorValue *= (100f - k * k) / 100f; - DrawLine(rotCenter + cut4 * 390f, rotCenter + cut5 * 390f, 2f, newDrawColor * colorValue * 2); - } - Main.instance.MouseText("Drag out of circle to cancel", ItemRarityID.White); - } - } + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 70).RotatedBy(k / 60f * MathHelper.TwoPi), color, new Vector3(k / 60f, 0, 0)); + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 0).RotatedBy(k / 60f * MathHelper.TwoPi), color, new Vector3(k / 60f, 0.5f, 0)); } - DrawBlockBound(FixPoint.X, FixPoint.Y, drawColor, AccumulateRotation); + drawStacks.Enqueue(new DrawStack(ModAsset.Trail_7_black.Value, bars, PrimitiveType.TriangleStrip)); } - public void DrawBlockBound(int i, int j, Color color, float rotation) + public virtual void DrawBlockBound(HangingTileAdjustingHelper hangingSystem, Color color, float rotation, ref Queue drawStacks) { - Vector2 pos = new Vector2(i, j) * 16 + new Vector2(8); + if (drawStacks == null) + { + drawStacks = new Queue(); + } + Vector2 pos = hangingSystem.FixPoint.ToWorldCoordinates(); List bars = new List() { new Vertex2D(pos + new Vector2(-8, -8).RotatedBy(rotation), color, new Vector3(0, 0, 0)), @@ -617,65 +774,288 @@ public void DrawBlockBound(int i, int j, Color color, float rotation) new Vertex2D(pos + new Vector2(8, -8).RotatedBy(rotation), color, new Vector3(1, 0, 0)), new Vertex2D(pos + new Vector2(8, 8).RotatedBy(rotation), color, new Vector3(1, 1, 0)), }; - - Ins.Batch.Draw(bars, PrimitiveType.TriangleList); + drawStacks.Enqueue(new DrawStack(ModAsset.TileBlock.Value, bars, PrimitiveType.TriangleList)); } - public void DrawLine(Vector2 pos1, Vector2 pos2, float width, Color color) + public virtual void DrawLine(Vector2 pos1, Vector2 pos2, float width, Color color, float highlight, ref Queue drawStacks) { + if (drawStacks == null) + { + drawStacks = new Queue(); + } Vector2 normal = Utils.SafeNormalize(pos1 - pos2, Vector2.zeroVector).RotatedBy(MathHelper.PiOver2) * width / 2f; List bars = new List() { new Vertex2D(pos1 + normal, color, new Vector3(0, 0, 0)), - new Vertex2D(pos2 + normal, color, new Vector3(0.1f, 0, 0)), + new Vertex2D(pos2 + normal, color, new Vector3(1, 0, 0)), new Vertex2D(pos1 - normal, color, new Vector3(0, 1, 0)), new Vertex2D(pos1 - normal, color, new Vector3(0, 1, 0)), - new Vertex2D(pos2 + normal, color, new Vector3(0.1f, 0, 0)), - new Vertex2D(pos2 - normal, color, new Vector3(0.1f, 1, 0)), + new Vertex2D(pos2 + normal, color, new Vector3(1, 0, 0)), + new Vertex2D(pos2 - normal, color, new Vector3(1, 1, 0)), }; + drawStacks.Enqueue(new DrawStack(ModAsset.SquarePiece.Value, bars, PrimitiveType.TriangleList)); + if (highlight > 0) + { + Color bloomColor = color * highlight; + bloomColor.A = 0; + bars = new List() + { + new Vertex2D(pos1 + normal, bloomColor, new Vector3(0, 0, 0)), + new Vertex2D(pos2 + normal, bloomColor, new Vector3(1, 0, 0)), + new Vertex2D(pos1 - normal, bloomColor, new Vector3(0, 1, 0)), - Ins.Batch.Draw(bars, PrimitiveType.TriangleList); + new Vertex2D(pos1 - normal, bloomColor, new Vector3(0, 1, 0)), + new Vertex2D(pos2 + normal, bloomColor, new Vector3(1, 0, 0)), + new Vertex2D(pos2 - normal, bloomColor, new Vector3(1, 1, 0)), + }; + drawStacks.Enqueue(new DrawStack(ModAsset.SquareBloom.Value, bars, PrimitiveType.TriangleList)); + } + } + + public virtual void DrawLine_Black(HangingTileAdjustingHelper hangingSystem, Vector2 pos1, Vector2 pos2, float width, ref Queue drawStacks) + { + if (drawStacks == null) + { + drawStacks = new Queue(); + } + Vector2 normal = Utils.SafeNormalize(pos1 - pos2, Vector2.zeroVector).RotatedBy(MathHelper.PiOver2) * width / 2f; + Color bloomColor = Color.White; + float tK = 12f; + if (hangingSystem.TimeToKill > 0) + { + tK = hangingSystem.TimeToKill; + } + float fade = Math.Min(hangingSystem.Timer, tK) / 12f; + bloomColor *= fade; + List bars = new List() + { + new Vertex2D(pos1 + normal, bloomColor, new Vector3(0, 0, 0)), + new Vertex2D(pos2 + normal, bloomColor, new Vector3(1, 0, 0)), + new Vertex2D(pos1 - normal, bloomColor, new Vector3(0, 1, 0)), + + new Vertex2D(pos1 - normal, bloomColor, new Vector3(0, 1, 0)), + new Vertex2D(pos2 + normal, bloomColor, new Vector3(1, 0, 0)), + new Vertex2D(pos2 - normal, bloomColor, new Vector3(1, 1, 0)), + }; + drawStacks.Enqueue(new DrawStack(ModAsset.SquareBloom_black.Value, bars, PrimitiveType.TriangleList)); + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + DrawWinch(i, j, spriteBatch); + TileFluentDrawManager.AddFluentPoint(this, i, j); + return false; + } + + public virtual void DrawWinch(int i, int j, SpriteBatch spriteBatch) + { + Color lightColor = Lighting.GetColor(i, j); + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + spriteBatch.Draw(ModAsset.HangingWinch.Value, new Vector2(i, j) * 16 - Main.screenPosition + zero, new Rectangle(0, 0, 16, 16), lightColor, 0, Vector2.zeroVector, 1, SpriteEffects.None, 0); + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + Rope rope; + RopesOfAllThisTileInTheWorld.TryGetValue(pos, out rope); + if (rope != null) + { + DrawCable(rope, pos, spriteBatch, tileDrawing); + if (CanGrasp && !Main.gamePaused) + { + CheckPlayerGrasp(pos); + } + } } -} -public class HangingTileUpdate : ModSystem -{ /// - /// 物å—质点系统 + /// Paint the hanging chains. /// - public static MassSpringContainer HangingTileMassSpringSystem = new MassSpringContainer(); - public static EulerSolver HangingTileEulerSolver = new EulerSolver(8); - public static PBDSolver HangingTilePBDSolver = new PBDSolver(8); + /// + /// + /// + /// + /// + public virtual void DrawCable(Rope rope, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing, Color color = default(Color)) + { + // 回声涂料 + if (!TileDrawing.IsVisible(Main.tile[pos])) + { + return; + } + + var tile = Main.tile[pos]; + ushort type = tile.TileType; + int paint = Main.tile[pos].TileColor; + string originalPath = @Texture; + string[] pathSegments = originalPath.Split("/"); + string trimmedTexturePath = Path.Combine(pathSegments.Skip(1).ToArray()); + Texture2D tex = PaintedTextureSystem.TryGetPaintedTexture(trimmedTexturePath, type, 1, paint, tileDrawing); + tex ??= (Texture2D)ModContent.Request(Texture); + + var masses = rope.Masses; + for (int i = 0; i < masses.Length; i++) + { + Mass thisMass = masses[i]; + int totalPushTime = 80; + float pushForcePerFrame = 1.26f; + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f), 1, 1)) + { + windCycle = tileDrawing.GetWindCycle((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f), tileDrawing._sunflowerWindCounter); + } + + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f), 1, 1, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + windCycle += highestWindGridPushComplex; + if (!Main.gamePaused) + { + if (i < masses.Length - 1) + { + rope.ApplyForceSpecial(i, new Vector2(windCycle / 4.0f, 0.4f * thisMass.Value)); + } + else + { + rope.ApplyForceSpecial(i, new Vector2(windCycle * 10.0f, 0.4f * thisMass.Value)); + } + } - public override void PostUpdateEverything() + // 支æŒå‘光涂料 + Color tileLight; + if (color != default) + { + tileLight = color; + } + else + { + tileLight = Lighting.GetColor((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f)); + } + + Vector2 toNextMass; + if (i < masses.Length - 1) + { + Mass nextMass = masses[i + 1]; + toNextMass = nextMass.Position - thisMass.Position; + } + else + { + Mass passedMass = masses[i - 1]; + toNextMass = thisMass.Position - passedMass.Position; + } + Vector2 drawPos = thisMass.Position - Main.screenPosition; + DrawRopeUnit(spriteBatch, tex, drawPos, pos, rope, i, toNextMass.ToRotation() - MathHelper.PiOver2, tileLight); + } + } + + public void UpdateRopeAdjustment(Rope rope, Point pos) { - HangingTileMassSpringSystem = new MassSpringContainer(); - foreach (var HangingTile in TileLoader.tiles.OfType()) + var masses = rope.Masses; + var tile = TileUtils.SafeGetTile(pos); + int currentHideUnitCount = MaxCableLength - tile.TileFrameY; + if (currentHideUnitCount >= MaxCableLength - 2) + { + currentHideUnitCount = MaxCableLength - 2; + } + int oldHideUnitCount = 0; + for (int i = 0; i < masses.Length; i++) { - foreach (var rope in HangingTile.RopesOfAllThisTileInTheWorld.Values) + Mass thisMass = masses[i]; + if (thisMass.IsStatic) + { + oldHideUnitCount++; + } + else { - HangingTileMassSpringSystem.AddMassSpringMesh(rope); + break; + } + } + for (int i = 0; i < masses.Length; i++) + { + Mass thisMass = masses[i]; + if (i <= currentHideUnitCount) + { + if (i == currentHideUnitCount) + { + Vector2 stride = pos.ToWorldCoordinates() - thisMass.Position; + for (int i2 = i; i2 < masses.Length; i2++) + { + masses[i2].Position += stride; + } + } + thisMass.IsStatic = true; + thisMass.Position = pos.ToWorldCoordinates(); + continue; + } + else + { + thisMass.IsStatic = false; + if (i < oldHideUnitCount) + { + thisMass.Position = pos.ToWorldCoordinates() + new Vector2(0, i - currentHideUnitCount) * UnitLength; + } + else if (i == oldHideUnitCount) + { + int deltaUnits = oldHideUnitCount - currentHideUnitCount - 1; + Vector2 stride = new Vector2(0, UnitLength * deltaUnits); + for (int i2 = i; i2 < masses.Length; i2++) + { + masses[i2].Position += stride; + } + } } } - HangingTileEulerSolver.Step(HangingTileMassSpringSystem, 1); } - public override void OnWorldLoad() + /// + /// Custom draw. + /// + /// + /// + /// Screen Position + /// + /// + /// + public virtual void DrawRopeUnit(SpriteBatch spriteBatch, Texture2D texture, Vector2 drawPos, Point tilePos, Rope rope, int index, float rotation, Color tileLight) { - foreach (var HangingTile in TileLoader.tiles.OfType()) + var masses = rope.Masses; + Rectangle frame = new Rectangle(8 * (index % 4), 0, 8, 10); + if (index < masses.Length - 1) { - HangingTile.RopesOfAllThisTileInTheWorld.Clear(); + spriteBatch.Draw(texture, drawPos, frame, tileLight, rotation, new Vector2(4f, 0), 1f, SpriteEffects.None, 0); + } + else + { + spriteBatch.Draw(texture, drawPos, new Rectangle(0, 12, 32, 40), tileLight, rotation, new Vector2(16f, 0), 1f, SpriteEffects.None, 0); + Lighting.AddLight(drawPos + Main.screenPosition, new Vector3(0.8f, 0.8f, 0.2f)); } - base.OnWorldLoad(); } - public override void OnWorldUnload() + /// + /// Try to get the cable entity bound at (, ). + /// + /// The type to get the entity as + /// The tile X-coordinate + /// The tile Y-coordinate + /// The found instance, if there was one. + /// if there was a instance, or if there was no entity present OR the entity was not a instance. + public static bool TryGetCableEntityAs(int i, int j, out T entity) + where T : TileEntity { - foreach (var HangingTile in TileLoader.tiles.OfType()) + Point16 origin = new Point16(i, j); + + // TileEntity.ByPosition is a Dictionary which contains all placed TileEntity instances in the world + // TryGetValue is used to both check if the dictionary has the key, origin, and get the value from that key if it's there + if (TileEntity.ByPosition.TryGetValue(origin, out TileEntity existing) && existing is T existingAsT) { - HangingTile.RopesOfAllThisTileInTheWorld.Clear(); + entity = existingAsT; + return true; } - base.OnWorldUnload(); + + entity = null; + return false; } } diff --git a/Sources/Everglow.Function/TileHelper/HangingTileAdjustingHelper.cs b/Sources/Everglow.Function/TileHelper/HangingTileAdjustingHelper.cs new file mode 100644 index 000000000..0f61934d5 --- /dev/null +++ b/Sources/Everglow.Function/TileHelper/HangingTileAdjustingHelper.cs @@ -0,0 +1,343 @@ +using Everglow.Commons.Enums; +using Everglow.Commons.Utilities; +using Everglow.Commons.Vertex; +using Everglow.Commons.VFX; +using Everglow.Commons.VFX.Pipelines; +using Terraria.Audio; +using static Everglow.Commons.TileHelper.HangingTile; + +namespace Everglow.Commons.TileHelper; + +[Pipeline(typeof(WCSPipeline_PointWrap))] +public class HangingTileAdjustingHelper : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PreDrawFilter; + + public Point FixPoint; + + /// + /// 0: mouse over;
+ /// 1: full system. + ///
+ public int Style; + public int Timer = 0; + public int TimeToKill = -1; + + public float StartFrameY60; + public float PanelRange = 0; + public float HandleRotation; + + public float InitialHandleRotation; + + public Vector2 OldMouseDirection = new Vector2(0, -1); + public Queue OldRotatedSpeeds = new Queue(); + + /// + /// Allow custon drawing styles. + /// + public delegate void CustomDrawPanel(HangingTileAdjustingHelper hangingAdj, Player player, Color color, ref Queue drawStacks); + + public event CustomDrawPanel CustomPanel; + + public override void OnSpawn() + { + Player player = Main.LocalPlayer; + } + + public override void Update() + { + Player player = Main.LocalPlayer; + int i = FixPoint.X; + int j = FixPoint.Y; + if (i < 20 || i > Main.maxTilesX - 20 || j < 20 || j > Main.maxTilesY - 20) + { + Active = false; + return; + } + Tile tile = Main.tile[i, j]; + HangingTile hangingTile = TileLoader.GetTile(tile.type) as HangingTile; + if (hangingTile == null) + { + Active = false; + return; + } + + // identify the player. + if (hangingTile.WinchAdjustingPlayers.ContainsKey(FixPoint)) + { + Player player2; + hangingTile.WinchAdjustingPlayers.TryGetValue(FixPoint, out player2); + if (player2 != player) + { + Active = false; + return; + } + } + + Timer++; + if (TimeToKill > 0) + { + TimeToKill--; + if (TimeToKill <= 0) + { + Kill(hangingTile, player); + } + } + + if (Timer < 12) + { + PanelRange = (MathF.Sin(Timer / 10f * MathHelper.Pi - MathHelper.PiOver2) + 1.2f) * 0.5f; + } + else + { + PanelRange = 1; + } + if (TimeToKill < 12 && TimeToKill > 0) + { + PanelRange *= (MathF.Sin(TimeToKill / 10f * MathHelper.Pi - MathHelper.PiOver2) + 1.2f) * 0.5f; + } + else + { + PanelRange *= 1; + } + + // åŠ¨æ€æ€§ï¼Œæ ¹æ®å­ç±»çš„判断æ¡ä»¶åŽ»æŽ§åˆ¶ + if (!hangingTile.IsCanRightClick(i, j)) + { + EndAdjustment(); + return; + } + if ((player.MouseWorld() - FixPoint.ToWorldCoordinates()).Length() > 400) + { + EndAdjustment(); + return; + } + + // Only display when mouse over. + if (Style == 0) + { + int x = (int)(player.MouseWorld().X / 16f); + int y = (int)(player.MouseWorld().Y / 16f); + if (x != FixPoint.X || y != FixPoint.Y) + { + Active = false; + if (hangingTile.MouseOverWinchPlayers.ContainsKey(player)) + { + hangingTile.MouseOverWinchPlayers.Remove(player); + } + return; + } + } + if (Style == 1) + { + if (!hangingTile.WinchAdjustingPlayers.ContainsKey(FixPoint)) + { + EndAdjustment(); + return; + } + if (!hangingTile.WinchAdjustingPlayers.ContainsKey(FixPoint)) + { + EndAdjustment(); + return; + } + float nowFrameY = StartFrameY60 / 60f + (HandleRotation - InitialHandleRotation) * 2; + bool endChain = false; + if (nowFrameY < 2) + { + endChain = true; + } + if (nowFrameY > hangingTile.MaxCableLength - 2) + { + endChain = true; + } + if (tile.TileFrameY != (short)Math.Clamp(nowFrameY, 1, hangingTile.MaxCableLength - 1)) + { + if (!endChain) + { + SoundEngine.PlaySound(SoundID.Unlock.WithVolume(0.5f), FixPoint.ToWorldCoordinates()); + } + + // æ¯æ¬¡é•¿åº¦å˜åŒ–都传回HangingTile + int oldFrameY = tile.TileFrameY; + tile.TileFrameY = (short)Math.Clamp(nowFrameY, 1, hangingTile.MaxCableLength - 1); + int deltaLength = tile.TileFrameY - oldFrameY; + hangingTile.OnAdjustmentUpdate(FixPoint, player, deltaLength); + HangingTileUpdateSystem.WinchAdjustingPlayerTimers[FixPoint] = hangingTile.AdjustingVisualTimeMax; + } + else + { + float threthod = hangingTile.AdjustingVisualTimeMax * 0.4f; + if (HangingTileUpdateSystem.WinchAdjustingPlayerTimers.ContainsKey(FixPoint) && HangingTileUpdateSystem.WinchAdjustingPlayerTimers[FixPoint] < threthod) + { + HangingTileUpdateSystem.WinchAdjustingPlayerTimers[FixPoint] = threthod; + } + } + + Vector2 handleDir = new Vector2(1, 0).RotatedBy(HandleRotation); + Vector2 newDir = Utils.SafeNormalize(FixPoint.ToWorldCoordinates() - player.MouseWorld(), new Vector2(0, -1)); + float addAccRot = MathF.Asin(-Vector3.Cross(new Vector3(newDir, 0), new Vector3(handleDir, 0)).Z); + float addOldToNewRot = MathF.Asin(-Vector3.Cross(new Vector3(newDir, 0), new Vector3(OldMouseDirection, 0)).Z); + OldMouseDirection = newDir; + OldRotatedSpeeds.Enqueue(addOldToNewRot); + if (OldRotatedSpeeds.Count > 3) + { + OldRotatedSpeeds.Dequeue(); + } + float cosValue = Vector2.Dot(handleDir, newDir); + if (nowFrameY >= 1 && nowFrameY <= hangingTile.MaxCableLength - 1) + { + HandleRotation += addAccRot; + } + else if (nowFrameY < 1 && RotatedClockwise() && cosValue > 0.8f) + { + HandleRotation += addAccRot; + } + else if (nowFrameY > hangingTile.MaxCableLength - 1 && RotatedCounterclockwise() && cosValue > 0.8f) + { + HandleRotation += addAccRot; + } + int x = (int)(player.MouseWorld().X / 16f); + int y = (int)(player.MouseWorld().Y / 16f); + if (Main.mouseRight && Main.mouseRightRelease && (x != FixPoint.X || y != FixPoint.Y)) + { + EndAdjustment(); + return; + } + } + base.Update(); + } + + public bool RotatedClockwise() + { + for (int i = 0; i < OldRotatedSpeeds.Count; i++) + { + if (OldRotatedSpeeds.ToArray()[i] <= 0) + { + return false; + } + } + return true; + } + + public bool RotatedCounterclockwise() + { + for (int i = 0; i < OldRotatedSpeeds.Count; i++) + { + if (OldRotatedSpeeds.ToArray()[i] >= 0) + { + return false; + } + } + return true; + } + + public void EndAdjustment() + { + if (TimeToKill < 0) + { + TimeToKill = 12; + } + } + + public void Kill(HangingTile hangingTile, Player owner) + { + Active = false; + if (hangingTile.MouseOverWinchPlayers.ContainsKey(owner)) + { + hangingTile.MouseOverWinchPlayers.Remove(owner); + } + if (hangingTile.WinchAdjustingPlayers.ContainsKey(FixPoint)) + { + hangingTile.WinchAdjustingPlayers.Remove(FixPoint); + } + hangingTile.OnAdjustmentEnd(FixPoint, owner); + } + + public override void Draw() + { + int i = FixPoint.X; + int j = FixPoint.Y; + if (i < 20 || i > Main.maxTilesX - 20) + { + if (j < 20 || j > Main.maxTilesY - 20) + { + Active = false; + return; + } + } + Player player = Main.LocalPlayer; + Tile tile = Main.tile[i, j]; + HangingTile hangingTile = TileLoader.GetTile(tile.type) as HangingTile; + if (hangingTile == null) + { + Active = false; + return; + } + Color drawColor = Color.Lerp(new Color(0.75f, 0.75f, 1f, 0.5f), new Color(0.85f, 0.85f, 0.75f, 0.5f), MathF.Sin((float)Main.timeForVisualEffects * 0.08f) * 0.5f + 0.5f); + Color origDrawColor = drawColor; + if (Style == 1) + { + float nowFrameY = StartFrameY60 / 60f + HandleRotation * 2; + if (nowFrameY < 5) + { + drawColor = Color.Lerp(drawColor, new Color(1f, 0f, 0f, 0.8f), (5 - nowFrameY) / 4f); + } + if (nowFrameY > hangingTile.MaxCableLength - 5) + { + drawColor = Color.Lerp(drawColor, new Color(1f, 0f, 0f, 0.8f), (nowFrameY - (hangingTile.MaxCableLength - 5)) / 4f); + } + } + + // If your HeldItem doesn't match with the tile type, it turns red. + if (!hangingTile.IsCanRightClick(i, j)) + { + drawColor = new Color(1f, 0, 0, 0.5f); + Main.instance.MouseText("Different Type Error", ItemRarityID.Red); + } + + // The circle panel + Vector2 rotCenter = FixPoint.ToWorldCoordinates(); + Vector2 cut = new Vector2(1, 0).RotatedBy(HandleRotation + MathHelper.Pi); + if (hangingTile.RopesOfAllThisTileInTheWorld.ContainsKey(FixPoint)) + { + if (Style == 1) + { + Queue drawStacks = new Queue(); + CustomPanel?.Invoke(this, player, origDrawColor, ref drawStacks); + while (drawStacks.Count > 0) + { + DrawStack currentDS = drawStacks.Dequeue(); + Ins.Batch.Draw(currentDS.Texture, currentDS.Vertices, currentDS.PType); + } + } + } + DrawBlockBound(FixPoint.X, FixPoint.Y, drawColor, HandleRotation); + } + + public void DrawBlockBound(int i, int j, Color color, float rotation) + { + Vector2 pos = new Vector2(i, j) * 16 + new Vector2(8); + List bars = new List() + { + new Vertex2D(pos + new Vector2(-8, -8).RotatedBy(rotation), color, new Vector3(0, 0, 0)), + new Vertex2D(pos + new Vector2(8, -8).RotatedBy(rotation), color, new Vector3(1, 0, 0)), + new Vertex2D(pos + new Vector2(-8, 8).RotatedBy(rotation), color, new Vector3(0, 1, 0)), + + new Vertex2D(pos + new Vector2(-8, 8).RotatedBy(rotation), color, new Vector3(0, 1, 0)), + new Vertex2D(pos + new Vector2(8, -8).RotatedBy(rotation), color, new Vector3(1, 0, 0)), + new Vertex2D(pos + new Vector2(8, 8).RotatedBy(rotation), color, new Vector3(1, 1, 0)), + }; + Ins.Batch.Draw(ModAsset.TileBlock.Value, bars, PrimitiveType.TriangleList); + } + + public void RegisterCustomPanelDrawing(CustomDrawPanel customDrawing) + { + CustomPanel += customDrawing; + } + + /// + public void UnregisterCustomPanelDrawing(CustomDrawPanel customDrawing) + { + CustomPanel -= customDrawing; + } +} diff --git a/Sources/Everglow.Function/TileHelper/HangingTilePlayer.cs b/Sources/Everglow.Function/TileHelper/HangingTilePlayer.cs new file mode 100644 index 000000000..f57901bbc --- /dev/null +++ b/Sources/Everglow.Function/TileHelper/HangingTilePlayer.cs @@ -0,0 +1,78 @@ +namespace Everglow.Commons.TileHelper; + +public class HangingTile_Player : ModPlayer +{ + public int SwitchVineCoolTimer = 0; + + public bool Grasping = false; + + public Vector2 OldGraspPos = default; + + public override void PostUpdate() + { + if (SwitchVineCoolTimer > 0) + { + SwitchVineCoolTimer--; + } + else + { + SwitchVineCoolTimer = 0; + } + GraspHangingTile(); + PreventMapFalling(); + if (Grasping) + { + OldGraspPos = Player.Center; + } + base.PostUpdate(); + } + + public void PreventMapFalling() + { + if (Main.mapFullscreen && Grasping) + { + if (OldGraspPos != default) + { + Player.Center = OldGraspPos; + } + } + } + + /// + /// 抓ä½hanging绳索,当玩家抓时,é历hanging中所有绳索的点,去抓ä½é‚£ä¸ªæ»¡è¶³èŒƒå›´å†…的绳索, + /// å‰ææ˜¯å®ƒå½“å‰ä¸åœ¨è°ƒæ•´çŠ¶æ€ + /// + public void GraspHangingTile() + { + if (!Player.mount.Active && Player.controlUp && !HangingTile.RopeGraspingPlayer.ContainsValue(Player)) + { + foreach (var hangingTile in TileLoader.tiles.OfType()) + { + if (hangingTile.CanGrasp) + { + foreach (var point in hangingTile.RopesOfAllThisTileInTheWorld.Keys) + { + // 点在调整ä¸èƒ½æŠ“ + if (hangingTile.WinchAdjustingPlayers.ContainsKey(point)) + { + continue; + } + var rope = hangingTile.RopesOfAllThisTileInTheWorld[point]; + Vector2 tipPos = rope.Masses.Last().Position; + if (Vector2.Distance(Player.Center, tipPos) <= hangingTile.GraspDetectRange) + { + Point targetPoint = hangingTile.RopesOfAllThisTileInTheWorld.FirstOrDefault(kv => kv.Value == rope).Key; + hangingTile.AddPlayerToRope(Player, rope, targetPoint); + Grasping = true; + break; + } + } + if (HangingTile.RopeGraspingPlayer.ContainsValue(Player)) + { + break; + } + } + } + } + } +} diff --git a/Sources/Everglow.Function/TileHelper/HangingTileUpdateSystem.cs b/Sources/Everglow.Function/TileHelper/HangingTileUpdateSystem.cs new file mode 100644 index 000000000..c22992fcf --- /dev/null +++ b/Sources/Everglow.Function/TileHelper/HangingTileUpdateSystem.cs @@ -0,0 +1,60 @@ +using Everglow.Commons.Physics.MassSpringSystem; + +namespace Everglow.Commons.TileHelper; + +/// +/// A ModSystem that manages the update of hanging tiles in the world. It handles the physics simulation of hanging tiles using a mass-spring system and updates their positions accordingly. This system is responsible for ensuring that hanging tiles behave realistically when interacted with or affected by external forces. +/// +public class HangingTileUpdateSystem : ModSystem +{ + public static MassSpringContainer HangingTileMassSpringSystem = new MassSpringContainer(); + public static EulerSolver HangingTileEulerSolver = new EulerSolver(8); + public static PBDSolver HangingTilePBDSolver = new PBDSolver(8); + + public static Dictionary WinchAdjustingPlayerTimers = new Dictionary(); + + public override void PostUpdateEverything() + { + HangingTileMassSpringSystem = new MassSpringContainer(); + foreach (var HangingTile in TileLoader.tiles.OfType()) + { + foreach (var rope in HangingTile.RopesOfAllThisTileInTheWorld.Values) + { + HangingTileMassSpringSystem.AddMassSpringMesh(rope); + } + } + HangingTileEulerSolver.Step(HangingTileMassSpringSystem, 1); + foreach(var k in WinchAdjustingPlayerTimers.Keys.ToList()) + { + WinchAdjustingPlayerTimers[k] -= 1; + if (WinchAdjustingPlayerTimers[k] <= 0) + { + WinchAdjustingPlayerTimers.Remove(k); + } + } + } + + public override void OnWorldLoad() + { + foreach (var hangingTile in TileLoader.tiles.OfType()) + { + hangingTile.RopesOfAllThisTileInTheWorld.Clear(); + hangingTile.WinchAdjustingPlayers.Clear(); + hangingTile.MouseOverWinchPlayers.Clear(); + } + HangingTile.RopeGraspingPlayer.Clear(); + base.OnWorldLoad(); + } + + public override void OnWorldUnload() + { + foreach (var hangingTile in TileLoader.tiles.OfType()) + { + hangingTile.RopesOfAllThisTileInTheWorld.Clear(); + hangingTile.WinchAdjustingPlayers.Clear(); + hangingTile.MouseOverWinchPlayers.Clear(); + } + HangingTile.RopeGraspingPlayer.Clear(); + base.OnWorldUnload(); + } +} diff --git a/Sources/Everglow.Function/TileHelper/ITileFluentlyDrawn.cs b/Sources/Everglow.Function/TileHelper/ITileFluentlyDrawn.cs index f1cc59001..7872c982f 100644 --- a/Sources/Everglow.Function/TileHelper/ITileFluentlyDrawn.cs +++ b/Sources/Everglow.Function/TileHelper/ITileFluentlyDrawn.cs @@ -18,6 +18,7 @@ public interface ITileFluentlyDrawn /// 工具类,风速和摇晃有关的都得é å®ƒ void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing); } + public struct BasicDrawInfo { public Vector2 DrawCenterPos; diff --git a/Sources/Everglow.Function/TileHelper/ITileOffsetOverScreenDrawn.cs b/Sources/Everglow.Function/TileHelper/ITileOffsetOverScreenDrawn.cs new file mode 100644 index 000000000..8cd14bf61 --- /dev/null +++ b/Sources/Everglow.Function/TileHelper/ITileOffsetOverScreenDrawn.cs @@ -0,0 +1,8 @@ +namespace Everglow.Commons.TileHelper; + +public interface ITileOffsetOverScreenDrawn +{ + public static List SpecialTilePositon = new List(); + + public int TileOffsetScreenRange(); +} diff --git a/Sources/Everglow.Function/TileHelper/ShapeDataTile.cs b/Sources/Everglow.Function/TileHelper/ShapeDataTile.cs index 3c5ac5201..a26683ebf 100644 --- a/Sources/Everglow.Function/TileHelper/ShapeDataTile.cs +++ b/Sources/Everglow.Function/TileHelper/ShapeDataTile.cs @@ -28,6 +28,11 @@ public override void SetStaticDefaults() } public int[,] PixelHasTile; + + /// + /// If top, bottom, left or right is not , it must be solid tile for valid placement. + /// + public int[,] PixelHasAttach; public int TotalWidth; public int TotalHeight; @@ -52,6 +57,7 @@ public override void Load() imageData.ProcessPixelRows(accessor => { PixelHasTile = new int[accessor.Width, accessor.Height]; + PixelHasAttach = new int[accessor.Width, accessor.Height]; TotalWidth = accessor.Width; TotalHeight = accessor.Height; for (int y = 0; y < accessor.Height; y++) @@ -61,6 +67,7 @@ public override void Load() { ref var pixel = ref pixelRow[x]; PixelHasTile[x, y] = pixel.R; + PixelHasAttach[x, y] |= pixel.G; } } }); @@ -122,6 +129,15 @@ public virtual void CustomDropItem(int i, int j) } } + /// + /// ä»Žå·¦ä¸Šè§’å®‰ç½®ä¸€ä¸ªé€ åž‹ç‰©å— + /// + /// + public virtual void PlaceOriginAtTopLeft(Point pos) + { + PlaceOriginAtTopLeft(pos.X, pos.Y); + } + /// /// ä»Žå·¦ä¸Šè§’å®‰ç½®ä¸€ä¸ªé€ åž‹ç‰©å— /// @@ -150,6 +166,15 @@ public virtual void PlaceOriginAtTopLeft(int x, int y) } } + /// + /// ä»Žå·¦ä¸‹è§’å®‰ç½®ä¸€ä¸ªé€ åž‹ç‰©å— + /// + /// + public virtual void PlaceOriginAtBottomLeft(Point pos) + { + PlaceOriginAtBottomLeft(pos.X, pos.Y); + } + /// /// ä»Žå·¦ä¸‹è§’å®‰ç½®ä¸€ä¸ªé€ åž‹ç‰©å— /// @@ -178,6 +203,32 @@ public virtual void PlaceOriginAtBottomLeft(int x, int y) } } + public virtual void PlaceAtTileObjectDataOrigin(int i, int j) + { + TileObjectData tileObjectData = TileObjectData.GetTileData(Type, Main.LocalPlayer.HeldItem.placeStyle); + i -= tileObjectData.Origin.X; + j -= tileObjectData.Origin.Y; + if (i + TotalWidth > Main.maxTilesX || i < 0 || j + TotalHeight > Main.maxTilesY || j < 0) + { + return; + } + for (int x = 0; x < TotalWidth; x++) + { + for (int y = 0; y < TotalHeight; y++) + { + if (PixelHasTile[x, y] >= 200) + { + Tile tile = Main.tile[x + i, y + j]; + tile.TileType = Type; + tile.TileFrameX = (short)(x * 18); + tile.TileFrameY = (short)(y * 18); + tile.HasTile = true; + } + } + } + NetMessage.SendTileSquare(-1, i, j, TotalWidth, TotalHeight); + } + /// /// 判定底部平å¦ä»¥åŠèƒ½å¦å®¹çº³ä¸‹å¼‚å½¢å— /// @@ -200,36 +251,14 @@ public bool CanPlaceAtBottomLeft(int x, int y) Tile tile = Main.tile[x + i, y - j]; if (tile.HasTile) { - bool fragile = false; - if (Main.tileCut[tile.TileType]) - { - fragile = true; - } - if (Main.tilePile[tile.TileType]) - { - fragile = true; - } - if (!fragile) + if (!TileFragile(tile)) { return false; } } if (j == 0) { - Tile tileBottom = Main.tile[x + i, y + 1]; - if (!tileBottom.HasTile) - { - return false; - } - if (tileBottom.Slope != SlopeType.Solid) - { - return false; - } - if (tileBottom.IsHalfBlock) - { - return false; - } - if (!(Main.tileSolidTop[tileBottom.TileType] || Main.tileSolid[tileBottom.TileType])) + if (!TileSolidWithNoSlope(x + i, y + 1)) { return false; } @@ -262,36 +291,60 @@ public bool CanPlaceAtTopLeft(int x, int y) Tile tile = Main.tile[x + i, y + j]; if (tile.HasTile) { - bool fragile = false; - if (Main.tileCut[tile.TileType]) - { - fragile = true; - } - if (Main.tilePile[tile.TileType]) - { - fragile = true; - } - if (!fragile) + if (!TileFragile(tile)) { return false; } } if (j == 0) { - Tile tileTop = Main.tile[x + i, y - 1]; - if (!tileTop.HasTile) + if (!TileSolidWithNoSlope(x + i, y - 1)) { return false; } - if (tileTop.Slope != SlopeType.Solid) - { - return false; - } - if (tileTop.IsHalfBlock) + } + } + } + } + return true; + } + + /// + /// Check collision when place the tile. + /// + /// + /// + /// + /// + public bool NoCollideInSolidGrid(int i, int j, bool checkAttach = true) + { + if (Main.dedServ) + { + return false; + } + TileObjectData tileObjectData = TileObjectData.GetTileData(Type, Main.LocalPlayer.HeldItem.placeStyle); + i -= tileObjectData.Origin.X; + j -= tileObjectData.Origin.Y; + for (int x = 0; x < TotalWidth; x++) + { + for (int y = 0; y < TotalHeight; y++) + { + if (PixelHasTile[x, y] >= 200) + { + var tile = TileUtils.SafeGetTile(i + x, j + y); + if (tile.HasTile) + { + if (!TileFragile(tile)) { return false; } - if (!(Main.tileSolidTop[tileTop.TileType] || Main.tileSolid[tileTop.TileType])) + } + } + if (checkAttach) + { + if (PixelHasAttach[x, y] > 200) + { + if (!ValidAttachCheck(i, j, x, y)) { return false; } @@ -301,4 +354,65 @@ public bool CanPlaceAtTopLeft(int x, int y) } return true; } + + public bool ValidAttachCheck(int i, int j, int x, int y) + { + if (!TileSolidWithNoSlope(i + x + 1, j + y) && PixelHasTile[x + 1, y] < 200) + { + return false; + } + if (!TileSolidWithNoSlope(i + x, j + y + 1) && PixelHasTile[x, y + 1] < 200) + { + return false; + } + if (!TileSolidWithNoSlope(i + x - 1, j + y) && PixelHasTile[x - 1, y] < 200) + { + return false; + } + if (!TileSolidWithNoSlope(i + x, j + y - 1) && PixelHasTile[x, y - 1] < 200) + { + return false; + } + return true; + } + + public bool TileFragile(Tile tile) + { + bool fragile = false; + if (Main.tileCut[tile.TileType]) + { + fragile = true; + } + if (Main.tilePile[tile.TileType]) + { + fragile = true; + } + return fragile; + } + + public bool TileSolidWithNoSlope(int i, int j) + { + return TileSolidWithNoSlope(TileUtils.SafeGetTile(i, j)); + } + + public bool TileSolidWithNoSlope(Tile tile) + { + if (!tile.HasTile) + { + return false; + } + if (tile.Slope != SlopeType.Solid) + { + return false; + } + if (tile.IsHalfBlock) + { + return false; + } + if (!(Main.tileSolidTop[tile.TileType] || Main.tileSolid[tile.TileType])) + { + return false; + } + return true; + } } diff --git a/Sources/Everglow.Function/UI/EverglowUISystem.cs b/Sources/Everglow.Function/UI/EverglowUISystem.cs index eca076977..8982813b0 100644 --- a/Sources/Everglow.Function/UI/EverglowUISystem.cs +++ b/Sources/Everglow.Function/UI/EverglowUISystem.cs @@ -73,7 +73,7 @@ public EverglowUISystem() ///
public void Load() { - var containers = from c in GetType().Assembly.GetTypes() + var containers = from c in Ins.ModuleManager.Types where !c.IsAbstract && c.IsSubclassOf(typeof(UIContainerElement)) select c; UIContainerElement element; diff --git a/Sources/Everglow.Function/UI/UIElements/UIItemSlot.cs b/Sources/Everglow.Function/UI/UIElements/UIItemSlot.cs index 2890a8cb7..864da5281 100644 --- a/Sources/Everglow.Function/UI/UIElements/UIItemSlot.cs +++ b/Sources/Everglow.Function/UI/UIElements/UIItemSlot.cs @@ -1,5 +1,6 @@ using ReLogic.Graphics; using Terraria.GameContent; +using Terraria.UI; namespace Everglow.Commons.UI.UIElements { @@ -69,7 +70,13 @@ public class UIItemSlot : BaseElement /// public float Opacity { get; set; } - public UIItemSlot(Texture2D texture = default(Texture2D)) : base() + /// + /// 是å¦ä¸ºå•†åº—ç‰©å“æ§½, åªè¦æ»¡è¶³æ¡ä»¶, å…许无穷å–出 + /// + public bool ShopSlot { get; set; } = false; + + public UIItemSlot(Texture2D texture = default(Texture2D)) + : base() { Opacity = 1f; ContainedItem = new Item(); @@ -77,7 +84,7 @@ public class UIItemSlot : BaseElement SlotBackTexture = texture == default(Texture2D) ? TextureAssets.InventoryBack.Value : texture; DrawColor = Color.White; CornerSize = new Vector2(10, 10); - Tooltip = ""; + Tooltip = string.Empty; Info.Width.SetValue(50f, 0f); Info.Height.SetValue(50f, 0f); } @@ -87,96 +94,110 @@ public override void LoadEvents() base.LoadEvents(); Events.OnLeftClick += element => { - //å¼€å¯èƒŒåŒ… - //Main.playerInventory = true; + // å¼€å¯èƒŒåŒ… + // Main.playerInventory = true; - //当鼠标没物å“,框里有物å“的时候 - if (Main.mouseItem.type == ItemID.None && ContainedItem != null && ContainedItem.type != ItemID.None) + // 当鼠标没物å“,框里有物å“的时候 + if (Main.mouseItem.IsAir && ContainedItem != null && ContainedItem.type != ItemID.None) { - //如果å¯ä»¥æ‹¿èµ·ç‰©å“ + // 如果å¯ä»¥æ‹¿èµ·ç‰©å“ if (CanTakeOutSlot == null || CanTakeOutSlot(ContainedItem)) { - //æ‹¿å‡ºç‰©å“ + // æ‹¿å‡ºç‰©å“ Main.mouseItem = ContainedItem.Clone(); - ContainedItem = new Item(); - ContainedItem.SetDefaults(0, true); + if (!ItemID.Sets.Deprecated[ContainedItem.type]) + { + Main.mouseItem.SetDefaults(ContainedItem.type); + Main.mouseItem.stack = ContainedItem.stack; + } + if (!ShopSlot) + { + ContainedItem = new Item(); + ContainedItem.SetDefaults(ItemID.None, true); + } - //调用委托 + // 调用委托 OnPickItem?.Invoke(this); - //è§¦å‘æ”¾ç‰©å“声音 - //SoundEngine.PlaySound(7, -1, -1, 1, 1f, 0.0f); + // è§¦å‘æ”¾ç‰©å“声音 + // SoundEngine.PlaySound(7, -1, -1, 1, 1f, 0.0f); } } - //当鼠标有物å“,框里没物å“的时候 + + // 当鼠标有物å“,框里没物å“的时候 else if (Main.mouseItem.type != ItemID.None && (ContainedItem == null || ContainedItem.type == ItemID.None)) { - //如果å¯ä»¥æ”¾å…¥ç‰©å“ + // 如果å¯ä»¥æ”¾å…¥ç‰©å“ if (CanPutInSlot == null || CanPutInSlot(Main.mouseItem)) { - //æ”¾å…¥ç‰©å“ + // æ”¾å…¥ç‰©å“ ContainedItem = Main.mouseItem.Clone(); Main.mouseItem = new Item(); - Main.mouseItem.SetDefaults(0, true); + Main.mouseItem.SetDefaults(ItemID.None, true); - //调用委托 + // 调用委托 OnPutItem?.Invoke(this); - //è§¦å‘æ”¾ç‰©å“声音 - //SoundEngine.PlaySound(7, -1, -1, 1, 1f, 0.0f); + // è§¦å‘æ”¾ç‰©å“声音 + // SoundEngine.PlaySound(7, -1, -1, 1, 1f, 0.0f); } } - //å½“é¼ æ ‡å’Œæ¡†éƒ½æœ‰ç‰©å“æ—¶ + + // å½“é¼ æ ‡å’Œæ¡†éƒ½æœ‰ç‰©å“æ—¶ else if (Main.mouseItem.type != ItemID.None && ContainedItem != null && ContainedItem.type != ItemID.None) { - //如果ä¸èƒ½æ”¾å…¥ç‰©å“ + // 如果ä¸èƒ½æ”¾å…¥ç‰©å“ if (!(CanPutInSlot == null || CanPutInSlot(Main.mouseItem))) { - //中断函数 + // 中断函数 return; } - //如果框里的物å“å’Œé¼ æ ‡çš„ç›¸åŒ + // 如果框里的物å“å’Œé¼ æ ‡çš„ç›¸åŒ if (Main.mouseItem.type == ContainedItem.type) { - //æ¡†é‡Œçš„ç‰©å“æ•°é‡åŠ ä¸Šé¼ æ ‡ç‰©å“æ•°é‡ + // æ¡†é‡Œçš„ç‰©å“æ•°é‡åŠ ä¸Šé¼ æ ‡ç‰©å“æ•°é‡ ContainedItem.stack += Main.mouseItem.stack; - //å¦‚æžœæ¡†é‡Œç‰©å“æ•°é‡å¤§äºŽæ•°é‡ä¸Šé™ + + // å¦‚æžœæ¡†é‡Œç‰©å“æ•°é‡å¤§äºŽæ•°é‡ä¸Šé™ if (ContainedItem.stack > ContainedItem.maxStack) { - //è®¡ç®—é¼ æ ‡ç‰©å“æ•°é‡ï¼Œå¹¶å°†æ¡†å†…ç‰©å“æ•°é‡ä¿®æ”¹ä¸ºæ•°é‡ä¸Šé™ + // è®¡ç®—é¼ æ ‡ç‰©å“æ•°é‡ï¼Œå¹¶å°†æ¡†å†…ç‰©å“æ•°é‡ä¿®æ”¹ä¸ºæ•°é‡ä¸Šé™ var exceed = ContainedItem.stack - ContainedItem.maxStack; ContainedItem.stack = ContainedItem.maxStack; Main.mouseItem.stack = exceed; } - //å之 + + // å之 else { - //æ¸…ç©ºé¼ æ ‡ç‰©å“ + // æ¸…ç©ºé¼ æ ‡ç‰©å“ Main.mouseItem = new Item(); } } - //如果å¯ä»¥æ”¾å…¥ç‰©å“ä¹Ÿèƒ½æ‹¿å‡ºç‰©å“ + + // 如果å¯ä»¥æ”¾å…¥ç‰©å“ä¹Ÿèƒ½æ‹¿å‡ºç‰©å“ else if ((CanPutInSlot == null || CanPutInSlot(Main.mouseItem)) && (CanTakeOutSlot == null || CanTakeOutSlot(ContainedItem))) { - //äº¤æ¢æ¡†å†…物å“å’Œé¼ æ ‡ç‰©å“ + // äº¤æ¢æ¡†å†…物å“å’Œé¼ æ ‡ç‰©å“ var tmp = Main.mouseItem.Clone(); Main.mouseItem = ContainedItem; ContainedItem = tmp; } - //è§¦å‘æ”¾ç‰©å“声音 - //SoundEngine.PlaySound(7, -1, -1, 1, 1f, 0.0f); + // è§¦å‘æ”¾ç‰©å“声音 + // SoundEngine.PlaySound(7, -1, -1, 1, 1f, 0.0f); } - //å之 + + // å之 else { - //中断函数 + // 中断函数 return; } - //调用委托 + // 调用委托 PostExchangeItem?.Invoke(this); }; } @@ -193,31 +214,27 @@ protected override void DrawSelf(SpriteBatch sb) float scale = Info.Size.X / 50f; DynamicSpriteFont font = FontAssets.MouseText.Value; - //调用原版的介ç»ç»˜åˆ¶ + + // 调用原版的介ç»ç»˜åˆ¶ if (ContainedItem != null && ContainsPoint(Main.MouseScreen) && ContainedItem.type != ItemID.None) { Main.hoverItemName = ContainedItem.Name; Main.HoverItem = ContainedItem.Clone(); } - //获å–当å‰UIéƒ¨ä»¶çš„ä¿¡æ¯ + + // 获å–当å‰UIéƒ¨ä»¶çš„ä¿¡æ¯ var DrawRectangle = Info.TotalHitBox; - //ç»˜åˆ¶ç‰©å“æ¡† - DrawAdvBox(sb, (int)DrawRectangle.X, (int)DrawRectangle.Y, - (int)DrawRectangle.Width, (int)DrawRectangle.Height, + + // ç»˜åˆ¶ç‰©å“æ¡† + DrawAdvBox(sb, DrawRectangle.X, DrawRectangle.Y, + DrawRectangle.Width, DrawRectangle.Height, DrawColor * Opacity, SlotBackTexture, CornerSize, 1f); if (ContainedItem != null && ContainedItem.type != ItemID.None) { var frame = Main.itemAnimations[ContainedItem.type] != null ? Main.itemAnimations[ContainedItem.type].GetFrame(TextureAssets.Item[ContainedItem.type].Value) : Item.GetDrawHitbox(ContainedItem.type, null); - //绘制物å“贴图 - sb.Draw(TextureAssets.Item[ContainedItem.type].Value, new Vector2(DrawRectangle.X + DrawRectangle.Width / 2, - DrawRectangle.Y + DrawRectangle.Height / 2) - (new Vector2(frame.Width, frame.Height) / 2f * scale), - new Rectangle?(frame), Color.White * Opacity, 0f, Vector2.Zero, scale, 0, 0); - - //绘制物å“左下角那个代表数é‡çš„æ•°å­— - if (ContainedItem.stack > 1) - { - sb.DrawString(font, ContainedItem.stack.ToString(), new Vector2(DrawRectangle.X + 10, DrawRectangle.Y + DrawRectangle.Height - 20), Color.White * Opacity, 0f, Vector2.Zero, scale * 0.8f, SpriteEffects.None, 0f); - } + Main.inventoryScale = 36 / 52f * Info.TotalHitBox.Width / 36f; + Item t_item = ContainedItem; + ItemSlot.Draw(sb, ref t_item, 21, new Vector2(DrawRectangle.X, DrawRectangle.Y)); } } @@ -254,13 +271,13 @@ public void DrawAdvBox(SpriteBatch sp, int x, int y, int w, int h, Color c, Text } sp.Draw(box, new Rectangle(x, y, width, height), new Rectangle(0, 0, width, height), c); sp.Draw(box, new Rectangle(x + width, y, w - width * 2, height), new Rectangle(width, 0, box.Width - width * 2, height), c); - sp.Draw(box, new Rectangle((x + w) - width, y, width, height), new Rectangle(box.Width - width, 0, width, height), c); + sp.Draw(box, new Rectangle(x + w - width, y, width, height), new Rectangle(box.Width - width, 0, width, height), c); sp.Draw(box, new Rectangle(x, y + height, width, h - height * 2), new Rectangle(0, height, width, box.Height - height * 2), c); sp.Draw(box, new Rectangle(x + width, y + height, w - width * 2, h - height * 2), new Rectangle(width, height, box.Width - width * 2, box.Height - height * 2), c); - sp.Draw(box, new Rectangle((x + w) - width, y + height, width, h - height * 2), new Rectangle(box.Width - width, height, width, box.Height - height * 2), c); - sp.Draw(box, new Rectangle(x, (y + h) - height, width, height), new Rectangle(0, box.Height - height, width, height), c); - sp.Draw(box, new Rectangle(x + width, (y + h) - height, w - width * 2, height), new Rectangle(width, box.Height - height, box.Width - width * 2, height), c); - sp.Draw(box, new Rectangle((x + w) - width, (y + h) - height, width, height), new Rectangle(box.Width - width, box.Height - height, width, height), c); + sp.Draw(box, new Rectangle(x + w - width, y + height, width, h - height * 2), new Rectangle(box.Width - width, height, width, box.Height - height * 2), c); + sp.Draw(box, new Rectangle(x, y + h - height, width, height), new Rectangle(0, box.Height - height, width, height), c); + sp.Draw(box, new Rectangle(x + width, y + h - height, w - width * 2, height), new Rectangle(width, box.Height - height, box.Width - width * 2, height), c); + sp.Draw(box, new Rectangle(x + w - width, y + h - height, width, height), new Rectangle(box.Width - width, box.Height - height, width, height), c); } } } diff --git a/Sources/Everglow.Function/UI/UISystem.cs b/Sources/Everglow.Function/UI/UISystem.cs index 9342a31f7..4a7ce4318 100644 --- a/Sources/Everglow.Function/UI/UISystem.cs +++ b/Sources/Everglow.Function/UI/UISystem.cs @@ -1,12 +1,15 @@ using Everglow.Commons.DataStructures; using Everglow.Commons.Enums; using Everglow.Commons.Utilities; +using MonoMod.Cil; using Terraria.UI; namespace Everglow.Commons.UI { public class UISystem : ModSystem { + private const int SpecialShopWhoAmI_Zero = 65536; + public static EverglowUISystem EverglowUISystem { get => Instance.system; @@ -26,6 +29,23 @@ public static UISystem Instance public bool TopResizing = false; public bool BottomResizing = false; + /// + /// The current special shop whoami. + /// + /// + /// -1: Disabled + /// + /// + /// 0: Furnace Shop + /// + /// + /// + public int CurrentSpecialShop = -1; + + public delegate void ChestUIDraw(UISystem system, SpriteBatch spriteBatch); + + public event ChestUIDraw PostDrawChestUI; + public RenderTarget2D UI_Screen = null; public UISystem() @@ -34,6 +54,10 @@ public UISystem() instance = this; } + public Chest CurrentShop = new Chest(false); + + public Chest OldChest = new Chest(false); + public override void Load() { base.Load(); @@ -41,6 +65,9 @@ public override void Load() On_Main.DrawInterface += HigherInterfaceVisualEffectSupport; On_Main.DrawCursor += ModifyUIBlockResizeCursor; On_Main.DrawThickCursor += ModifyUIBlockResizeThickCursor; + On_ChestUI.DrawSlots += On_ChestUI_DrawPanel; + On_Main.DrawInventory += On_Main_DrawInventory; + IL_Main.DrawInventory += IL_Main_DrawInventory; if (Main.netMode != NetmodeID.Server) { system.Load(); @@ -227,5 +254,56 @@ private void HigherInterfaceVisualEffectSupport(On_Main.orig_DrawInterface orig, UI_Screen = null; } } + + private void IL_Main_DrawInventory(ILContext il) + { + ILCursor c = new(il); + if (c.TryGotoNext( + MoveType.After, + x => x.MatchLdindU2(), + x => x.MatchLdelemU1(), + x => x.MatchBrtrue(out _), + x => x.MatchLdsfld(out _), + x => x.MatchLdsfld(out _), + x => x.MatchLdelemRef(), + x => x.MatchLdcI4(-1), + x => x.MatchStfld(out _), + x => x.MatchLdcI4(0), + x => x.MatchCall(out _), + x => x.MatchLdcI4(0), + x => x.MatchStloc(out _))) + { + c.EmitDelegate(CheckSpecialShopEnable_ModifyNpcShop); + } + } + + private void On_ChestUI_DrawPanel(On_ChestUI.orig_DrawSlots orig, SpriteBatch spriteBatch) + { + orig(spriteBatch); + PostDrawChestUI?.Invoke(this, spriteBatch); + } + + private void On_Main_DrawInventory(On_Main.orig_DrawInventory orig, Main self) + { + CheckSpecialShopEnable_ModifyNpcShop(); + orig(self); + DisposeSpecialShopEnable_ModifyNpcShop(); + } + + private void CheckSpecialShopEnable_ModifyNpcShop() + { + if (CurrentSpecialShop >= 0 && Main.npcShop == 0) + { + Main.npcShop = SpecialShopWhoAmI_Zero + CurrentSpecialShop; + } + } + + private void DisposeSpecialShopEnable_ModifyNpcShop() + { + if (Main.npcShop >= SpecialShopWhoAmI_Zero) + { + Main.npcShop = 0; + } + } } } diff --git a/Sources/Everglow.Function/Utilities/BackgroundHelper/BackgroundHigherPerformanceHelper.cs b/Sources/Everglow.Function/Utilities/BackgroundHelper/BackgroundHigherPerformanceHelper.cs index e563bb945..76cba3977 100644 --- a/Sources/Everglow.Function/Utilities/BackgroundHelper/BackgroundHigherPerformanceHelper.cs +++ b/Sources/Everglow.Function/Utilities/BackgroundHelper/BackgroundHigherPerformanceHelper.cs @@ -22,7 +22,8 @@ public static class BackgroundHigherPerformanceHelper public static void Add_TileBgVertice( BackgroundSlideBase bg, List tiles, - List bars) + List bars, + int samplingUnit = 1) { if (bg.UseColorStyle != 1) { @@ -62,7 +63,6 @@ public static void Add_TileBgVertice( int lastY = visibleTiles[0].Pos.Y; int lastX = visibleTiles[0].Pos.X; - int samplingUnit = 1; if (bg is UnderBackgroundBackgroundSlideBase) { UnderBackgroundBackgroundSlideBase ubg = bg as UnderBackgroundBackgroundSlideBase; @@ -263,6 +263,26 @@ public static void Add_TileBgVertice_NolightMap( CollectionsMarshal.SetCount(bars, currentSize); } + public static void Add_WorldPosVertex(BackgroundSlideBase bg, Vector2 position, Span span, ref int currentSize) + { + Vector2 screenCenter = Main.screenPosition + new Vector2(Main.screenWidth, Main.screenHeight) * 0.5f; + Vector2 move = (screenCenter - bg.WorldAnchor) / bg.Distance; + Vector2 texcoord_Move = move / bg.Texture.Size(); + Vector2 screenPoint = position - screenCenter; + Vector2 screen_move = screenPoint / bg.Texture.Size() + texcoord_Move; + + Color drawColor = GetColor(bg, position); + span[currentSize] = new Vertex2D(position - Main.screenPosition, drawColor, new Vector3(screen_move + new Vector2(0.5f), 0)); + currentSize++; + } + + public static void Add_WorldTriangle(BackgroundSlideBase bg, Vector2 v0, Vector2 v1, Vector2 v2, Span span, ref int currentSize) + { + Add_WorldPosVertex(bg, v0, span, ref currentSize); + Add_WorldPosVertex(bg, v1, span, ref currentSize); + Add_WorldPosVertex(bg, v2, span, ref currentSize); + } + private static Color GetColor(BackgroundSlideBase bg, Vector2 worldPos) { Color c = Color.White; diff --git a/Sources/Everglow.Function/Utilities/BackgroundHelper/BackgroundSlideBase.cs b/Sources/Everglow.Function/Utilities/BackgroundHelper/BackgroundSlideBase.cs index a84be2edd..54dc2c9c5 100644 --- a/Sources/Everglow.Function/Utilities/BackgroundHelper/BackgroundSlideBase.cs +++ b/Sources/Everglow.Function/Utilities/BackgroundHelper/BackgroundSlideBase.cs @@ -28,6 +28,13 @@ public abstract class BackgroundSlideBase /// public int UseColorStyle = 0; + /// + /// It has higher priority in ordering the layer of backgrounds then .
+ /// Larger overlap the smaller.
+ /// In most cases it should be 0. + ///
+ public int LayerPriority = 0; + public virtual bool AllowMultiple => false; /// @@ -243,6 +250,22 @@ public static void DrawVertexBackground(BackgroundSlideBase bg, PrimitiveType pr } } + public static void DrawVertexBackground(Texture2D texture, PrimitiveType primitiveType, List bars) + { + if (bars.Count > 2) + { + Main.graphics.graphicsDevice.Textures[0] = texture; + if (primitiveType == PrimitiveType.TriangleList) + { + Main.graphics.graphicsDevice.DrawUserPrimitives(primitiveType, bars.ToArray(), 0, bars.Count / 3); + } + if (primitiveType == PrimitiveType.TriangleStrip) + { + Main.graphics.graphicsDevice.DrawUserPrimitives(primitiveType, bars.ToArray(), 0, bars.Count - 2); + } + } + } + public class Effects { public static readonly Effect XClamp_YClamp_Shader = ModAsset.BgShader_X_Clamp_Y_Clamp.Value; diff --git a/Sources/Everglow.Function/Utilities/BackgroundHelper/BackgroundSystem.cs b/Sources/Everglow.Function/Utilities/BackgroundHelper/BackgroundSystem.cs index 9d05f5b36..188e09f9a 100644 --- a/Sources/Everglow.Function/Utilities/BackgroundHelper/BackgroundSystem.cs +++ b/Sources/Everglow.Function/Utilities/BackgroundHelper/BackgroundSystem.cs @@ -54,7 +54,7 @@ private void DrawBackground() Main.spriteBatch.End(); Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone, null, Main.Transform); Effect lastEffect = null; - foreach (var bg in backgroundSlides.OrderByDescending(b => b.Distance)) // Adapt to dynamic distance. + foreach (var bg in backgroundSlides.OrderBy(b => b.LayerPriority).ThenByDescending(b => b.Distance)) // Adapt to dynamic distance. { bool shouldChangeSpriteBatch = bg.Shader != lastEffect; if (shouldChangeSpriteBatch) @@ -109,5 +109,4 @@ public bool HasBgSlide(string uniqueName) { return backgroundSlides.Any(x => x.UniqueName == uniqueName); } - } diff --git a/Sources/Everglow.Function/Utilities/NPCUtils.cs b/Sources/Everglow.Function/Utilities/NPCUtils.cs index bb5671a79..64603770c 100644 --- a/Sources/Everglow.Function/Utilities/NPCUtils.cs +++ b/Sources/Everglow.Function/Utilities/NPCUtils.cs @@ -1,7 +1,5 @@ using Everglow.Commons.Mechanics.ElementalDebuff; using Everglow.Commons.Netcode.Packets; -using Mono.Cecil.Cil; -using MonoMod.Cil; namespace Everglow.Commons.Utilities; @@ -233,6 +231,14 @@ public static int GetVanillaDotDamage(this NPC npc, IEnumerable buffTypes) public static void SetLifeRegenExpectedLossPerSecond(this NPC npc, int value) => npc.lifeRegenExpectedLossPerSecond = Math.Max(npc.lifeRegenExpectedLossPerSecond, value); + public static void StrikeNPCWithCustomCombatText(this NPC npc, NPC.HitInfo hit, Color textColor, bool dot = false) + { + npc.HideStrikeDamage = true; + npc.StrikeNPC(hit); + npc.HideStrikeDamage = false; + CombatText.NewText(npc.Hitbox, textColor, hit.Damage, hit.Crit, dot); + } + #endregion #region Elemental Debuff @@ -332,4 +338,33 @@ public static ref StatModifier GetElementalResistance(this NPC npc, string type) ref npc.GetElementalDebuff(type).ElementalResistanceModifier; #endregion + + #region AI Utils + + /// + /// Find the nearet npc from a given position. + /// + /// + /// + /// + /// + public static NPC FindNearest(Vector2 position, int type, float maxDistance = 2048) + { + NPC target = null; + float distanceMin = maxDistance; + foreach (var npc in Main.npc) + { + if (npc is not null && npc.active && npc.type == type) + { + float distanceNPC = (npc.Center - position).Length(); + if (distanceNPC < distanceMin) + { + distanceMin = distanceNPC; + target = npc; + } + } + } + return target; + } + #endregion } diff --git a/Sources/Everglow.Function/Utilities/SpriteBatchUtils.cs b/Sources/Everglow.Function/Utilities/SpriteBatchUtils.cs new file mode 100644 index 000000000..f273f58bd --- /dev/null +++ b/Sources/Everglow.Function/Utilities/SpriteBatchUtils.cs @@ -0,0 +1,247 @@ +using System.Runtime.InteropServices; +using Everglow.Commons.Vertex; + +namespace Everglow.Commons.Utilities; + +public static class SpriteBatchUtils +{ + public static List DrawCurveStrip_EnvironmentLight(List curve, float width, float coord_x_min, float coord_x_max, float coord_y_min = 0, float coord_y_max = 1, bool curveHasScreenPos = false) + { + if (curve.Count < 2) + { + return []; + } + Vector2 lightSamplingOffset = Vector2.zeroVector; + if (!curveHasScreenPos) + { + lightSamplingOffset = Main.screenPosition; + } + List bars = new List(); + for (int i = 0; i < curve.Count; i++) + { + Vector2 pos = curve[i]; + Vector2 dir; + if (i == 0) + { + dir = curve[i + 1] - curve[i]; + } + else + { + dir = curve[i] - curve[i - 1]; + } + dir = dir.NormalizeSafe(); + Vector2 normal = new Vector2(dir.Y, -dir.X) * width / 2f; + float value = i / (float)(curve.Count - 1); + float coordX = float.Lerp(coord_x_min, coord_x_max, value); + AddVertexWithEnv_Light(bars, pos + normal + lightSamplingOffset, new Vector3(coordX, coord_y_min, 0)); + AddVertexWithEnv_Light(bars, pos - normal + lightSamplingOffset, new Vector3(coordX, coord_y_max, 0)); + } + return bars; + } + + public static Color GetEnv_Light(Vector2 worldPosition) + { + return Lighting.GetColor(worldPosition.ToTileCoordinates()); + } + + public static void AddVertexWithEnv_Light(List bars, Vector2 worldPos, Vector3 texCoord, bool removeScreenPos = true, float colorFade = 1f) + { + Vector2 offset = Vector2.Zero; + if (removeScreenPos) + { + offset = -Main.screenPosition; + } + bars.Add(worldPos + offset, GetEnv_Light(worldPos + Main.screenPosition + offset) * colorFade, texCoord); + } + + public static void AddVerticesForCircleRing(List bars, Vector2 position, float radius, float width, Color drawColor, float coorx_x_min, float coord_x_max, float coord_z = 0) + { + int currentSize = bars.Count; + int count = (int)(radius / 4 + 10); + CollectionsMarshal.SetCount(bars, count * 2 + 256); + Span span = CollectionsMarshal.AsSpan(bars); + for (int k = 0; k <= count; k++) + { + float value = k / (float)count; + float coordX = (float)Utils.Lerp(coorx_x_min, coord_x_max, value); + Vector2 pos0 = position + new Vector2(0, radius + width / 2f).RotatedBy(value * MathHelper.TwoPi); + Vector2 pos1 = position + new Vector2(0, radius - width / 2f).RotatedBy(value * MathHelper.TwoPi); + float maxCoordY = 1; + if (radius < width / 2f) + { + pos1 = position; + maxCoordY = 0.5f + radius / (width / 2f); + } + span[currentSize] = new Vertex2D(pos0, drawColor, new Vector3(coordX, 0, coord_z)); + currentSize++; + span[currentSize] = new Vertex2D(pos1, drawColor, new Vector3(coordX, maxCoordY, coord_z)); + currentSize++; + } + CollectionsMarshal.SetCount(bars, currentSize); + } + + /// + /// R:0-1
G:0-1
B:0-1 + ///
+ /// R:0-1
G:0-1
B:0-1 + /// H:0-360
S:0-1
V:0-1
+ public static Vector3 RGBToHSV(Vector3 rgb) + { + float r = rgb.X; + float g = rgb.Y; + float b = rgb.Z; + + float max = MathHelper.Max(MathHelper.Max(r, g), b); + float min = MathHelper.Min(MathHelper.Min(r, g), b); + float delta = max - min; + + float h = 0f; + float s = max == 0 ? 0f : delta / max; + float v = max; + + if (delta == 0) + { + h = 0f; + } + else + { + if (max == r) + { + h = ((g - b) / delta) % 6; + } + else if (max == g) + { + h = 2 + (b - r) / delta; + } + else if (max == b) + { + h = 4 + (r - g) / delta; + } + + h *= 60; + if (h < 0) + { + h += 360; + } + } + + return new Vector3(h, s, v); + } + + /// + /// H:0-360
S:0-1
V:0-1 + ///
+ /// H:0-360
S:0-1
V:0-1 + /// R:0-1
G:0-1
B:0-1
+ public static Vector3 HSVToRGB(Vector3 hsv) + { + float h = hsv.X; + float s = hsv.Y; + float v = hsv.Z; + + if (s == 0) + { + return new Vector3(v, v, v); + } + + h = h % 360f; + if (h < 0) + { + h += 360; + } + + float sector = h / 60f; + int sectorIndex = (int)Math.Floor(sector); + float fractional = sector - sectorIndex; + + float p = v * (1 - s); + float q = v * (1 - s * fractional); + float t = v * (1 - s * (1 - fractional)); + + switch (sectorIndex) + { + case 0: + return new Vector3(v, t, p); + case 1: + return new Vector3(q, v, p); + case 2: + return new Vector3(p, v, t); + case 3: + return new Vector3(p, q, v); + case 4: + return new Vector3(t, p, v); + default: + return new Vector3(v, p, q); + } + } + + /// + /// Transforms Vector3(H, S, V) to RGB and returns a Color with the specified alpha. + /// + /// H:0-360
S:0-1
V:0-1 + /// 0-1 + /// + public static Color HSVToRGB_Color(this Vector3 hsv, float a) + { + Vector3 rgb = HSVToRGB(hsv); + return new Color(rgb.X, rgb.Y, rgb.Z, a); + } + + /// + /// Add vertices just like what Main.spriteBatch.Draw does. But sampling environment light at each vertex. + /// + /// + /// + /// + /// + /// + /// + /// + public static void AddVertex_Grid(List bars, Vector2 position, Rectangle? frame, Vector2 origin, Texture2D tex, bool screenPos = false, int gridSize = 16, float rotation = 0, float alpha = 1f) + { + var drawPos = position; + Vector2 pos = drawPos; + if (screenPos) + { + pos += Main.screenPosition; + } + Rectangle frame2 = frame ?? tex.Frame(); + int xCount = frame2.Width / gridSize; + int yCount = frame2.Height / gridSize; + float unitX = frame2.Width / (float)xCount; + float unitY = frame2.Height / (float)yCount; + for (int x = 0; x < xCount; x++) + { + Vector2 offset_2 = (new Vector2(x * unitX, 0) - origin).RotatedBy(rotation); + Vector2 offset_1 = (new Vector2((x + 1) * unitX, 0) - origin).RotatedBy(rotation); + bars.Add(pos + offset_2, Color.Transparent, new Vector3(new Vector2(frame2.X + x * unitX, frame2.Y) / tex.Size(), 0)); + bars.Add(pos + offset_1, Color.Transparent, new Vector3(new Vector2(frame2.X + (x + 1) * unitX, frame2.Y) / tex.Size(), 0)); + for (int y = 0; y < yCount; y++) + { + Vector2 offset0 = (new Vector2(x * unitX, y * unitY) - origin).RotatedBy(rotation); + Vector2 offset1 = (new Vector2((x + 1) * unitX, y * unitY) - origin).RotatedBy(rotation); + Vector2 offset2 = (new Vector2(x * unitX, (y + 1) * unitY) - origin).RotatedBy(rotation); + Vector2 offset3 = (new Vector2((x + 1) * unitX, (y + 1) * unitY) - origin).RotatedBy(rotation); + + AddLightColorVertex(bars, pos + offset0, new Vector3(new Vector2(frame2.X + x * unitX, frame2.Y + y * unitY) / tex.Size(), 0), alpha, screenPos); + AddLightColorVertex(bars, pos + offset1, new Vector3(new Vector2(frame2.X + (x + 1) * unitX, frame2.Y + y * unitY) / tex.Size(), 0), alpha, screenPos); + AddLightColorVertex(bars, pos + offset2, new Vector3(new Vector2(frame2.X + x * unitX, frame2.Y + (y + 1) * unitY) / tex.Size(), 0), alpha, screenPos); + AddLightColorVertex(bars, pos + offset3, new Vector3(new Vector2(frame2.X + (x + 1) * unitX, frame2.Y + (y + 1) * unitY) / tex.Size(), 0), alpha, screenPos); + } + Vector2 offset4 = (new Vector2(x * unitX, yCount * unitY) - origin).RotatedBy(rotation); + Vector2 offset5 = (new Vector2((x + 1) * unitX, yCount * unitY) - origin).RotatedBy(rotation); + bars.Add(pos + offset4, Color.Transparent, new Vector3(new Vector2(frame2.X + x * unitX, frame2.Y + yCount * unitY) / tex.Size(), 0)); + bars.Add(pos + offset5, Color.Transparent, new Vector3(new Vector2(frame2.X + (x + 1) * unitX, frame2.Y + yCount * unitY) / tex.Size(), 0)); + } + } + + public static void AddLightColorVertex(List bars, Vector2 worldPos, Vector3 coord, float alpha = 1f, bool screenPos = false) + { + Color drawC = Lighting.GetColor(worldPos.ToTileCoordinates()) * alpha; + if (screenPos) + { + worldPos -= Main.screenPosition; + } + bars.Add(worldPos, drawC, coord); + } +} diff --git a/Sources/Everglow.Function/Utilities/TileUtils.Collision.cs b/Sources/Everglow.Function/Utilities/TileUtils.Collision.cs index 1e143336b..605ee1fab 100644 --- a/Sources/Everglow.Function/Utilities/TileUtils.Collision.cs +++ b/Sources/Everglow.Function/Utilities/TileUtils.Collision.cs @@ -187,4 +187,11 @@ public static bool IsAreaEmpty(int x, int y, int width, int height) { return IsAreaEmpty(new Point(x, y), new Point(width, height)); } + + public static bool CanPlayerInteractWithTile(int i, int j, Player player) + { + Item sItem = player.HeldItem.Clone(); + bool flag = player.position.X / 16f - player.lastTileRangeX - sItem.tileBoost <= i && (player.position.X + player.width) / 16f + player.lastTileRangeX + sItem.tileBoost - 1f >= i && player.position.Y / 16f - player.lastTileRangeY - sItem.tileBoost <= j; + return flag && (player.position.Y + player.height) / 16f + player.lastTileRangeY + sItem.tileBoost - 2f >= j; + } } diff --git a/Sources/Everglow.Function/Utilities/TileUtils.WorldGen.cs b/Sources/Everglow.Function/Utilities/TileUtils.WorldGen.cs new file mode 100644 index 000000000..79b905495 --- /dev/null +++ b/Sources/Everglow.Function/Utilities/TileUtils.WorldGen.cs @@ -0,0 +1,2534 @@ +using Everglow.Commons.TileHelper; +using MathNet.Numerics.LinearAlgebra.Factorization; +using Terraria.ObjectData; +using Terraria.Utilities; + +namespace Everglow.Commons.Utilities; + +public partial class TileUtils +{ + public static int[,] PerlinPixelR = new int[512, 512]; + public static int[,] PerlinPixelG = new int[512, 512]; + public static int[,] PerlinPixelB = new int[512, 512]; + + public static int[,] LargeSmokeTexturePixelR = new int[1024, 1024]; + public static int[,] LargeSmokeTexturePixelG = new int[1024, 1024]; + public static int[,] LargeSmokeTexturePixelB = new int[1024, 1024]; + + public static UnifiedRandom GenRand = new UnifiedRandom(); + + /// + /// 0: Forceful
+ /// 1: NoTile
+ /// 2: HasTile
+ /// 3: HasWall
+ /// 4: NoWall
+ /// 5: HasLiquid
+ /// 6: NoLiquid
+ /// 7: HasTileAndWall
+ /// 8: TileButNoWallOnly
+ /// 9: WallButNoTileOnly
+ /// 10: SolidBlock
+ /// 11: NoneSolidTile
+ ///
+ public enum TileChangeState + { + Forceful, + NoTile, + HasTile, + HasWall, + NoWall, + HasLiquid, + NoLiquid, + HasTileAndWall, + TileButNoWallOnly, + WallButNoTileOnly, + SolidBlock, + NoneSolidTile, + } + + public static bool CanChangeTile(Tile tile, int state) + { + switch (state) + { + case (int)TileChangeState.Forceful: + return true; + case (int)TileChangeState.NoTile: + if (!tile.HasTile) + { + return true; + } + break; + case (int)TileChangeState.HasTile: + if (tile.HasTile) + { + return true; + } + break; + case (int)TileChangeState.HasWall: + if (tile.wall > 0) + { + return true; + } + break; + case (int)TileChangeState.NoWall: + if (tile.wall <= 0) + { + return true; + } + break; + case (int)TileChangeState.HasLiquid: + if (tile.LiquidAmount > 0) + { + return true; + } + break; + case (int)TileChangeState.NoLiquid: + if (tile.LiquidAmount <= 0) + { + return true; + } + break; + case (int)TileChangeState.HasTileAndWall: + if (tile.wall > 0 && tile.HasTile) + { + return true; + } + break; + case (int)TileChangeState.TileButNoWallOnly: + if (tile.wall <= 0 && tile.HasTile) + { + return true; + } + break; + case (int)TileChangeState.WallButNoTileOnly: + if (tile.wall > 0 && !tile.HasTile) + { + return true; + } + break; + case (int)TileChangeState.SolidBlock: + if (tile.HasTile && IsTileSolid(tile)) + { + return true; + } + break; + case (int)TileChangeState.NoneSolidTile: + if (tile.HasTile && !IsTileSolid(tile)) + { + return true; + } + break; + } + + return false; + } + + public static void TotalInitialize() + { + GenRand = WorldGen.genRand; + FillPerlinPixel(); + } + + public static void FillPerlinPixel() + { + var imageData = ImageReader.Read(ModAsset.WorldGen_Noise_rgb_Mod); + Vector2 perlinCoordCenter = new Vector2(GenRand.NextFloat(0f, 1f), GenRand.NextFloat(0f, 1f)); + imageData.ProcessPixelRows(accessor => + { + for (int y = 0; y < accessor.Height; y++) + { + int newY = (int)(accessor.Height * perlinCoordCenter.Y + y) % accessor.Height; + var pixelRow = accessor.GetRowSpan(newY); + for (int x = 0; x < pixelRow.Length; x++) + { + int newX = (int)(accessor.Width * perlinCoordCenter.X + x) % accessor.Width; + ref var pixel = ref pixelRow[newX]; + PerlinPixelR[x, y] = pixel.R; + PerlinPixelG[x, y] = pixel.G; + PerlinPixelB[x, y] = pixel.B; + } + } + }); + + imageData = ImageReader.Read(ModAsset.WorldGenLarge_rgb_Mod); + perlinCoordCenter = new Vector2(GenRand.NextFloat(0f, 1f), GenRand.NextFloat(0f, 1f)); + imageData.ProcessPixelRows(accessor => + { + for (int y = 0; y < accessor.Height; y++) + { + int newY = (int)(accessor.Height * perlinCoordCenter.Y + y) % accessor.Height; + var pixelRow = accessor.GetRowSpan(newY); + for (int x = 0; x < pixelRow.Length; x++) + { + int newX = (int)(accessor.Width * perlinCoordCenter.X + x) % accessor.Width; + ref var pixel = ref pixelRow[newX]; + LargeSmokeTexturePixelR[x, y] = pixel.R; + LargeSmokeTexturePixelG[x, y] = pixel.G; + LargeSmokeTexturePixelB[x, y] = pixel.B; + } + } + }); + } + + /// + /// A float value based on the noise texture's red channel. + /// + /// 0f~1f + public static float GetPerlinPixelR(double x, double y) + { + return GetLerpTexturePixelValue(PerlinPixelR, x, y); + } + + /// + /// A float value based on the noise texture's green channel. + /// + /// 0f~1f + public static float GetPerlinPixelG(double x, double y) + { + return GetLerpTexturePixelValue(PerlinPixelG, x, y); + } + + /// + /// A float value based on the noise texture's blue channel. + /// + /// 0f~1f + public static float GetPerlinPixelB(double x, double y) + { + return GetLerpTexturePixelValue(PerlinPixelB, x, y); + } + + /// + /// A float value based on the noise texture's red channel. + /// + /// 0f~1f + public static float GetLargeSmokeTexturePixelR(double x, double y) + { + return GetLerpTexturePixelValue(LargeSmokeTexturePixelR, x, y); + } + + /// + /// A float value based on the noise texture's green channel. + /// + /// 0f~1f + public static float GetLargeSmokeTexturePixelG(double x, double y) + { + return GetLerpTexturePixelValue(LargeSmokeTexturePixelG, x, y); + } + + /// + /// A float value based on the noise texture's blue channel. + /// + /// 0f~1f + public static float GetLargeSmokeTexturePixelB(double x, double y) + { + return GetLerpTexturePixelValue(LargeSmokeTexturePixelB, x, y); + } + + public static float GetLerpTexturePixelValue(int[,] colorMap, double x, double y) + { + return colorMap[(int)(Math.Abs(x) % colorMap.GetLength(0)), (int)(Math.Abs(y) % colorMap.GetLength(1))] / 255f; + } + + /// + /// Use (x, y) as the top left corner to place a frame important tile area with given width and height, and set the frameX and frameY of each tile in this area according to their position in this area. + /// + /// + public static void PlaceFrameImportantTiles(int x, int y, int width, int height, int type, int startX = 0, int startY = 0) + { + if (x > Main.maxTilesX - width || x < 0 || y > Main.maxTilesY - height || y < 0) + { + return; + } + + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + Tile tile = Main.tile[x + i, y + j]; + tile.TileType = (ushort)type; + tile.TileFrameX = (short)(i * 18 + startX); + tile.TileFrameY = (short)(j * 18 + startY); + tile.HasTile = true; + } + } + } + + /// + /// place frame important tiles above the area with (x, y - 1) as the BOTTOM left corner and given width and height (It means that Y = y in most case should be solid tile), and set the frameX and frameY of each tile in this area according to their position in this area. + /// + /// TileFrameX at left side, +18 each tile towards right. + /// TileFrameX at top side, +18 each tile towards down. + public static void PlaceFrameImportantTilesAbove(int x, int y, int width, int height, int type, int startX = 0, int startY = 0) + { + if (x > Main.maxTilesX - width || x < 0 || y > Main.maxTilesY - height || y < 0) + { + return; + } + + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + Tile tile = Main.tile[x + i, y + j - height]; + tile.TileType = (ushort)type; + tile.TileFrameX = (short)(i * 18 + startX); + tile.TileFrameY = (short)(j * 18 + startY); + tile.HasTile = true; + } + } + } + + /// + /// Place frame important tiles at TileObjectData.Origin. + /// + /// + /// + /// + /// + public static void PlaceFrameImportantTilesAtTileObjectDataOrigin(Point tileCoord, int type, int startX = 0, int startY = 0) + { + int i = tileCoord.X; + int j = tileCoord.Y; + TileObjectData tileObjectData = TileObjectData.GetTileData(type, Main.LocalPlayer.HeldItem.placeStyle); + i -= tileObjectData.Origin.X; + j -= tileObjectData.Origin.Y; + int width = tileObjectData.Width; + int height = tileObjectData.Height; + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + var tile = SafeGetTile(x + i, y + j); + tile.TileType = (ushort)type; + tile.TileFrameX = (short)((x * 18) + startX); + tile.TileFrameY = (short)((y * 18) + startY); + tile.HasTile = true; + } + } + } + + /// True when the given point can be killed safely(without chest). + public static bool ChestSafe(int x, int y) + { + Tile tile = SafeGetTile(x, y); + Tile tileUp = SafeGetTile(x, y - 1); + if (!TileID.Sets.BasicChest[tile.TileType] && !TileID.Sets.BasicChest[tileUp.TileType]) + { + return true; + } + return false; + } + + /// Tile coordinate, no world coordinate. + /// + public static bool ChestSafe(Vector2 center) + { + return ChestSafe((int)center.X, (int)center.Y); + } + + /// True when the given tile can be killed safely(without chest). + public static bool ChestSafe(Tile tile) + { + return ChestSafe(tile.X(), tile.Y()); + } + + /// + /// Fill tiles by given area:(x0:left, y0:top, x1:right, y1:bottom) + /// + /// Left + /// Top + /// Right + /// Bottom + /// TileID: place the tile.
+ /// -1: Kill tile.
+ /// -2: ClearEverything + /// + public static void PlaceRectangleAreaOfBlock(int x0, int y0, int x1, int y1, int type, int force = 0) + { + if (x0 > x1) + { + (x0, x1) = (x1, x0); + } + if (y0 > y1) + { + (y0, y1) = (y1, y0); + } + for (int x = x0; x <= x1; x += 1) + { + for (int y = y0; y <= y1; y += 1) + { + Tile tile = SafeGetTile(x, y); + ChangeTile(tile, type, force); + } + } + } + + /// + /// Fill tiles by given area:(x, y, w, h) where (x, y) is the top left corner. + /// + /// + /// + /// + /// + /// + /// + public static void PlaceRectangleAreaOfBlock_XYWH(int x, int y, int w, int h, int type, int force = 0) + { + PlaceRectangleAreaOfBlock(x, y, x + w - 1, y + h - 1, type, force); + } + + /// + /// Fill tiles by given area. The pos is the top left corner and size is the width and height. So the area is (pos.X, pos.Y) to (pos.X + size.X, pos.Y + size.Y). + /// + /// Tile coord. + /// + /// TileID: place the tile.
+ /// -1: Kill tile.
+ /// -2: ClearEverything + /// + public static void PlaceRectangleAreaOfBlock(Vector2 pos, Vector2 size, int type, int force = 0) + { + PlaceRectangleAreaOfBlock((int)pos.X, (int)pos.Y, (int)(size + pos).X, (int)(size + pos).Y, type, force); + } + + /// + /// Set a center and radius of a circle in tile coordinate. + /// + /// Tile coord center in Vector2. + /// TileID: place the tile.
+ /// -1: Kill tile.
+ /// -2: ClearEverything + /// + public static void PlaceCircleAreaOfBlock(Vector2 center, float radius, int type, int force = 0) + { + int radiusI = (int)radius; + for (int x = -radiusI; x <= radiusI; x++) + { + for (int y = -radiusI; y <= radiusI; y++) + { + Tile tile = SafeGetTile(center + new Vector2(x, y)); + if (new Vector2(x, y).Length() <= radius) + { + ChangeTile(tile, type, force); + } + } + } + } + + /// + /// Set a center and radius of a circle in tile coordinate. + /// + /// Tile coord center in Vector2. + /// TileID: place the tile.
+ /// -1: Kill tile.
+ /// -2: ClearEverything + /// + public static void PlaceCircleAreaOfWall(Vector2 center, float radius, int type, int force = 0) + { + int radiusI = (int)radius; + for (int x = -radiusI; x <= radiusI; x++) + { + for (int y = -radiusI; y <= radiusI; y++) + { + Tile tile = SafeGetTile(center + new Vector2(x, y)); + if (new Vector2(x, y).Length() <= radius) + { + ChangeWall(tile, type, force); + } + } + } + } + + /// + /// Set a center and radius of a circle in tile coordinate. + /// + /// Tile coord center in Vector2. + /// TileID: place the tile.
+ /// -1: Kill tile.
+ /// -2: ClearEverything + /// + public static void PlaceCircleAreaOfLiquid(Vector2 center, float radius, int type, int force = 0) + { + int radiusI = (int)radius; + for (int x = -radiusI; x <= radiusI; x++) + { + for (int y = -radiusI; y <= radiusI; y++) + { + Tile tile = SafeGetTile(center + new Vector2(x, y)); + if (new Vector2(x, y).Length() <= radius) + { + ChangeLiquid(tile, type, force); + } + } + } + } + + /// + /// Set a center and radius of a circle in tile coordinate. + /// + /// TileID: place the tile.
+ /// -1: Kill tile.
+ /// -2: ClearEverything + /// + public static void PlaceCircleAreaOfBlock(Point center, float radius, int type, int force = 0) + { + PlaceCircleAreaOfBlock(center.ToVector2(), radius, type, force); + } + + /// + /// Set a center and radius of a circle in tile coordinate. + /// + /// TileID: place the tile.
+ /// -1: Kill tile.
+ /// -2: ClearEverything + /// + public static void PlaceCircleAreaOfWall(Point center, float radius, int type, int force = 0) + { + PlaceCircleAreaOfWall(center.ToVector2(), radius, type, force); + } + + /// + /// Set a center and radius of a circle in tile coordinate. + /// + /// TileID: place the tile.
+ /// -1: Kill tile.
+ /// -2: ClearEverything + /// + public static void PlaceCircleAreaOfLiquid(Point center, float radius, int type, int force = 0) + { + PlaceCircleAreaOfLiquid(center.ToVector2(), radius, type, force); + } + + /// + /// Get a list of tile coordinates in a circle area with random noise. + /// + /// the center of the circle + /// the radius of the circle + /// the max random noise that can be added to the radius + /// + public static List GetCircleAreaOfTilePosWithRandomNoise(Point pos, float radius, float noiseSize = 3f) + { + List tiles = new List(); + int x0CoordPerlin = GenRand.Next(512); + int y0CoordPerlin = GenRand.Next(512); + int radiusI = (int)radius; + for (int x = -radiusI; x <= radiusI; x++) + { + for (int y = -radiusI; y <= radiusI; y++) + { + float aValue = GetPerlinPixelR(x + x0CoordPerlin, y + y0CoordPerlin); + if (new Vector2(x, y).Length() <= radius - aValue * noiseSize) + { + tiles.Add(new Point(x, y) + pos); + } + } + } + return tiles; + } + + /// + /// Get a list of tile coordinates in a circle area with random noise. + /// + /// the center of the circle + /// the radius of the circle + /// the max random noise that can be added to the radius + /// + public static List GetCircleAreaOfTilePos(Point pos, float radius) + { + List tiles = new List(); + int radiusI = (int)(radius + 1); + for (int x = -radiusI; x <= radiusI; x++) + { + for (int y = -radiusI; y <= radiusI; y++) + { + if (new Vector2(x, y).Length() <= radius) + { + tiles.Add(new Point(x, y) + pos); + } + } + } + return tiles; + } + + /// + /// Transform the tile within the circle(center, radius) to the type, but with a random noise affect on the bound. + /// + /// Tile coord center in Vector2. + /// TileID: place the tile.
+ /// -1: Kill tile.
+ /// -2: ClearEverything + /// + public static void PlaceCircleAreaOfBlockWithRandomNoise(Vector2 center, float radius, int type, float noiseSize = 3f, int force = 0) + { + int x0CoordPerlin = GenRand.Next(512); + int y0CoordPerlin = GenRand.Next(512); + int radiusI = (int)radius; + for (int x = -radiusI; x <= radiusI; x++) + { + for (int y = -radiusI; y <= radiusI; y++) + { + float aValue = GetPerlinPixelR(x + x0CoordPerlin, y + y0CoordPerlin); + if (new Vector2(x, y).Length() <= radius - aValue * noiseSize) + { + Tile tile = SafeGetTile(center + new Vector2(x, y)); + ChangeTile(tile, type, force); + } + } + } + } + + /// + /// Transform the tile within the circle(center, radius) to the type, but with a random noise affect on the bound. + /// + /// TileID: place the tile.
+ /// -1: Kill tile.
+ /// -2: ClearEverything + /// + public static void PlaceCircleAreaOfBlockWithRandomNoise(Point center, float radius, int type, float noiseSize = 10f, int force = 0) + { + PlaceCircleAreaOfBlockWithRandomNoise(center.ToVector2(), radius, type, noiseSize, force); + } + + /// + /// Transform the wall within the circle(center, radius) to the type, but with a random noise affect on the bound. + /// + /// Tile coord + /// + /// + /// + /// + public static void PlaceCircleAreaOfWallWithRandomNoise(Point center, float radius, int type, float noiseSize = 10f, int force = 0) + { + PlaceCircleAreaOfWallWithRandomNoise(center.ToVector2(), radius, type, noiseSize, force); + } + + /// + /// Transform the wall within the circle(center, radius) to the type, but with a random noise affect on the bound. + /// + /// Tile coord + /// + /// + /// + /// + public static void PlaceCircleAreaOfWallWithRandomNoise(Vector2 center, float radius, int type, float noiseSize = 3f, int force = 0) + { + int x0CoordPerlin = GenRand.Next(512); + int y0CoordPerlin = GenRand.Next(512); + int radiusI = (int)radius; + for (int x = -radiusI; x <= radiusI; x++) + { + for (int y = -radiusI; y <= radiusI; y++) + { + float aValue = GetPerlinPixelR(x + x0CoordPerlin, y + y0CoordPerlin); + if (new Vector2(x, y).Length() <= radius - aValue * noiseSize) + { + Tile tile = SafeGetTile(center + new Vector2(x, y)); + ChangeWall(tile, type, force); + } + } + } + } + + /// + /// Kill the tile within the circle(center, radius), but with a random noise affect on the bound. + /// + /// Tile coord + /// + /// + /// -1: Kill tile.
+ /// -2: ClearEverything + /// + /// + public static void KillCircleAreaOfBlockWithRandomNoiseInCertainTypeOfTile(Vector2 center, float radius, List type_be_killed, int killStyle = -1, float noiseSize = 10f, int force = 0) + { + int x0CoordPerlin = GenRand.Next(512); + int y0CoordPerlin = GenRand.Next(512); + int radiusI = (int)radius; + for (int x = -radiusI; x <= radiusI; x++) + { + for (int y = -radiusI; y <= radiusI; y++) + { + float aValue = GetPerlinPixelR(x + x0CoordPerlin, y + y0CoordPerlin); + Tile tile = SafeGetTile(center + new Vector2(x, y)); + if (new Vector2(x, y).Length() <= radius - aValue * noiseSize && type_be_killed.Contains(tile.TileType)) + { + ChangeTile(tile, killStyle, force); + } + } + } + } + + /// + /// Kill the tile within the circle(center, radius), but with a random noise affect on the bound. + /// + /// Tile coord + /// + /// + /// -1: Kill tile.
+ /// -2: ClearEverything + /// + /// + public static void KillCircleAreaOfBlockWithRandomNoiseInCertainTypeOfTile(Point center, float radius, List type_be_killed, int killStyle = -1, float noiseSize = 10f, int force = 0) + { + KillCircleAreaOfBlockWithRandomNoiseInCertainTypeOfTile(center.ToVector2(), radius, type_be_killed, killStyle, noiseSize, force); + } + + /// + /// Kill the wall within the circle(center, radius), but with a random noise affect on the bound. + /// + /// + /// + /// + /// Default to 0, only wall will be removed. + /// + /// + public static void KillCircleAreaOfWallWithRandomNoiseInCertainType(Point center, float radius, List type_be_killed, int killStyle = 0, float noiseSize = 10f, int force = 0) + { + int x0CoordPerlin = GenRand.Next(512); + int y0CoordPerlin = GenRand.Next(512); + int radiusI = (int)radius; + for (int x = -radiusI; x <= radiusI; x++) + { + for (int y = -radiusI; y <= radiusI; y++) + { + float aValue = GetPerlinPixelR(x + x0CoordPerlin, y + y0CoordPerlin); + Tile tile = SafeGetTile(center + new Point(x, y)); + if (new Vector2(x, y).Length() <= radius - aValue * noiseSize && type_be_killed.Contains(tile.wall)) + { + ChangeWall(tile, killStyle, force); + } + } + } + } + + /// + /// Transform the tile within the polygon to the type. The polygon is a list of WORLD coordinates in Vector2, and the area is determined by the point-in-polygon test. + /// + /// WORLD coord + /// + /// + public static void PlacePolygonAreaOfBlock(List polygon, int type, int force = 0) + { + if (polygon.Count < 3) + { + return; + } + var bounds = MathUtils.GetPolygonAABBBound_Vector4(polygon); + for (int x = (int)bounds.X - 8; x < bounds.Z; x += 16) + { + for (int y = (int)bounds.Y - 8; y < bounds.W; y += 16) + { + if (MathUtils.IsPointInPolygon(polygon, new Vector2(x, y))) + { + Tile tile = SafeGetTile(new Vector2(x, y).ToTileCoordinates()); + ChangeTile(tile, type, force); + } + } + } + } + + /// + /// Transform the tiles within the polygon to the type. The polygon is a list of TILE coordinates in Point, and the area is determined by the point-in-polygon test. + /// + /// TILE coord + /// + /// + public static void PlacePolygonAreaOfBlock(List polygon, int type, int force = 0) + { + List polygon_Vector2 = new List(); + foreach (var point in polygon) + { + polygon_Vector2.Add(point.ToWorldCoordinates()); + } + PlacePolygonAreaOfBlock(polygon_Vector2, type, force); + } + + /// + /// Transform the walls within the polygon to the type. The polygon is a list of WORLD coordinates in Vector2, and the area is determined by the point-in-polygon test. + /// + /// WORLD coord + /// + /// + public static void PlacePolygonAreaOfWall(List polygon, int type, int force = 0) + { + if (polygon.Count < 3) + { + return; + } + var bounds = MathUtils.GetPolygonAABBBound_Vector4(polygon); + for (int x = (int)bounds.X; x <= bounds.Z; x += 16) + { + for (int y = (int)bounds.Y; y <= bounds.W; y += 16) + { + if (MathUtils.IsPointInPolygon(polygon, new Vector2(x, y))) + { + Tile tile = SafeGetTile(new Vector2(x, y).ToTileCoordinates()); + ChangeWall(tile, type, force); + } + } + } + } + + /// + /// Transform the liquid within the polygon to the type. The polygon is a list of WORLD coordinates in Vector2, and the area is determined by the point-in-polygon test. + /// + /// WORLD coord + /// + /// + public static void PlacePolygonAreaOfLiquid(List polygon, int type, int force = 0) + { + if (polygon.Count < 3) + { + return; + } + var bounds = MathUtils.GetPolygonAABBBound_Vector4(polygon); + for (int x = (int)bounds.X; x <= bounds.Z; x += 16) + { + for (int y = (int)bounds.Y; y <= bounds.W; y += 16) + { + if (MathUtils.IsPointInPolygon(polygon, new Vector2(x, y))) + { + Tile tile = SafeGetTile(new Vector2(x, y).ToTileCoordinates()); + ChangeLiquid(tile, type, force); + } + } + } + } + + /// + /// Transform the tile within the polygon to the type. The polygon is a list of TILE coordinates in Point, and the area is determined by the point-in-polygon test. + /// + /// TILE coord + /// + /// + public static void PlacePolygonAreaOfWall(List polygon, int type, int force = 0) + { + List polygon_Vector2 = new List(); + foreach (var point in polygon) + { + polygon_Vector2.Add(point.ToWorldCoordinates()); + } + PlacePolygonAreaOfWall(polygon_Vector2, type, force); + } + + /// + /// Automatically offset the polygon by the anchorPos, then transform the tile within the polygon to the type. The polygon is a list of WORLD coordinates in Vector2, and the area is determined by the point-in-polygon test. + /// + /// WORLD coord + /// + /// + /// + public static void PlacePolygonAreaOfBlockWithOffset(List polygon, Vector2 anchorPos, int type, int force = 0) + { + if (polygon.Count < 3) + { + return; + } + List newPolygon = polygon; + for (int i = 0; i < newPolygon.Count; i++) + { + newPolygon[i] += anchorPos; + } + PlacePolygonAreaOfBlock(newPolygon, type, force); + } + + /// + /// Automatically offset the polygon by the anchorPos, then transform the tile within the polygon to the type. The polygon is a list of TILE coordinates in Point, and the area is determined by the point-in-polygon test. + /// + /// TILE coord + /// + /// + /// + public static void PlacePolygonAreaOfBlockWithOffset(List polygon, Vector2 anchorPos, int type, int force = 0) + { + List polygon_Vector2 = new List(); + foreach (var point in polygon) + { + polygon_Vector2.Add(point.ToWorldCoordinates()); + } + PlacePolygonAreaOfBlockWithOffset(polygon_Vector2, anchorPos, type, force); + } + + /// + /// Transform the tiles at the edge of the polygon to the type. The polygon is a list of WORLD coordinates in Vector2, and the area is determined by the point-in-polygon test. + /// + /// WORLD coord + /// + /// WORLD coord + /// + public static void PlacePolygonBoundOfBlock(List polygon, int type, float thick, int force = 0) + { + if (polygon.Count < 3) + { + return; + } + for (int k = 0; k < polygon.Count; k++) + { + int nextIndex = k + 1; + if (nextIndex == polygon.Count) + { + nextIndex = 0; + } + PlaceLineBlock(polygon[k], polygon[nextIndex], thick, type, force); + } + } + + /// + /// Transform the tiles at the edge of the polygon to the type. The polygon is a list of TILE coordinates in Point, and the area is determined by the point-in-polygon test. + /// + /// TILE coord + /// + /// + /// + public static void PlacePolygonBoundOfBlock(List polygon, int type, float thick, int force = 0) + { + List polygon_Vector2 = new List(); + foreach (var point in polygon) + { + polygon_Vector2.Add(point.ToWorldCoordinates()); + } + PlacePolygonBoundOfBlock(polygon_Vector2, type, thick, force); + } + + /// + /// Transform the tiles at the edge of the polygon to the type. The polygon is a list of WORLD coordinates in Vector2, and the area is determined by the point-in-polygon test. + /// + /// WORLD coord + /// + /// WORLD coord + /// + public static void PlacePolygonBoundOfWall(List polygon, int type, float thick, int force = 0) + { + if (polygon.Count < 3) + { + return; + } + for (int k = 0; k < polygon.Count; k++) + { + int nextIndex = k + 1; + if (nextIndex == polygon.Count) + { + nextIndex = 0; + } + PlaceLineWall(polygon[k], polygon[nextIndex], thick, type, force); + } + } + + /// + /// Transform the tiles at the edge of the polygon to the type. The polygon is a list of TILE coordinates in Point, and the area is determined by the point-in-polygon test. + /// + /// TILE coord + /// + /// WORLD coord + /// + public static void PlacePolygonBoundOfWall(List polygon, int type, float thick, int force = 0) + { + List polygon_Vector2 = new List(); + foreach (var point in polygon) + { + polygon_Vector2.Add(point.ToWorldCoordinates()); + } + PlacePolygonBoundOfWall(polygon_Vector2, type, thick, force); + } + + /// + /// Transform the tiles beside the line(pos0, pos1) to the type. Notice that thick is in World Coord, 16 for a tile size. + /// + /// WORLD coord + /// WORLD coord + /// WORLD coord + /// + public static void PlaceLineBlock(Vector2 pos0, Vector2 pos1, float thick, int type, int force = 0) + { + Vector2 dir = pos0 - pos1; + if (dir == Vector2.zeroVector) + { + return; + } + Vector2 normalizedDir = dir.NormalizeSafe().RotatedBy(MathHelper.PiOver2); + List tiltRect = new List(); + tiltRect.Add(pos0 + normalizedDir * thick * 0.5f); + tiltRect.Add(pos1 + normalizedDir * thick * 0.5f); + tiltRect.Add(pos1 - normalizedDir * thick * 0.5f); + tiltRect.Add(pos0 - normalizedDir * thick * 0.5f); + PlacePolygonAreaOfBlock(tiltRect, type, force); + } + + /// + /// Transform the tiles beside the line(pos0, pos1) to the type. Notice that thick is in World Coord, 16 for a tile size. + /// + /// TILE coord + /// TILE coord + /// + /// + /// + public static void PlaceLineBlock(Point pos0, Point pos1, float thick, int type, int force = 0) + { + PlaceLineBlock(pos0.ToWorldCoordinates(), pos1.ToWorldCoordinates(), thick, type, force); + } + + /// + /// Transform the walls beside the line(pos0, pos1) to the type. Notice that thick is in World Coord, 16 for a tile size. + /// + /// WORLD coord + /// WORLD coord + /// WORLD coord + /// + /// + public static void PlaceLineWall(Vector2 pos0, Vector2 pos1, float thick, int type, int force = 0) + { + Vector2 dir = pos0 - pos1; + if (dir == Vector2.zeroVector) + { + return; + } + Vector2 normalizedDir = dir.NormalizeSafe().RotatedBy(MathHelper.PiOver2); + List tiltRect = new List(); + tiltRect.Add(pos0 + normalizedDir * thick * 0.5f); + tiltRect.Add(pos1 + normalizedDir * thick * 0.5f); + tiltRect.Add(pos1 - normalizedDir * thick * 0.5f); + tiltRect.Add(pos0 - normalizedDir * thick * 0.5f); + PlacePolygonAreaOfWall(tiltRect, type, force); + } + + /// + /// Transform the liquid beside the line(pos0, pos1) to the type. Notice that thick is in World Coord, 16 for a tile size. + /// + /// WORLD coord + /// WORLD coord + /// WORLD coord + /// + /// + public static void PlaceLineLiquid(Vector2 pos0, Vector2 pos1, float thick, int type, int force = 0) + { + Vector2 dir = pos0 - pos1; + if (dir == Vector2.zeroVector) + { + return; + } + Vector2 normalizedDir = dir.NormalizeSafe().RotatedBy(MathHelper.PiOver2); + List tiltRect = new List(); + tiltRect.Add(pos0 + normalizedDir * thick * 0.5f); + tiltRect.Add(pos1 + normalizedDir * thick * 0.5f); + tiltRect.Add(pos1 - normalizedDir * thick * 0.5f); + tiltRect.Add(pos0 - normalizedDir * thick * 0.5f); + PlacePolygonAreaOfLiquid(tiltRect, type, force); + } + + /// + /// Transform the walls beside the line(pos0, pos1) to the type. Notice that thick is in World Coord, 16 for a tile size. + /// + /// TILE coord + /// TILE coord + /// WORLD coord + /// + public static void PlaceLineWall(Point pos0, Point pos1, float thick, int type, int force = 0) + { + PlaceLineWall(pos0.ToWorldCoordinates(), pos1.ToWorldCoordinates(), thick, type, force); + } + + /// + /// Transform the liquid beside the line(pos0, pos1) to the type. Notice that thick is in World Coord, 16 for a tile size. + /// + /// TILE coord + /// TILE coord + /// WORLD coord + /// + public static void PlaceLineLiquid(Point pos0, Point pos1, float thick, int type, int force = 0) + { + PlaceLineLiquid(pos0.ToWorldCoordinates(), pos1.ToWorldCoordinates(), thick, type, force); + } + + /// + /// + /// + /// + /// + /// + public static void ChangeTile(Tile tile, int type, int force) + { + if (ChestSafe(tile) && CanChangeTile(tile, force)) + { + if (type >= 0) + { + tile.TileType = (ushort)type; + tile.HasTile = true; + } + else if (type == -1) + { + tile.HasTile = false; + } + else if (type == -2) + { + tile.ClearEverything(); + } + } + } + + public static void ChangeWall(Tile tile, int type, int force) + { + if (ChestSafe(tile) && CanChangeTile(tile, force)) + { + if (type >= 0) + { + tile.WallType = (ushort)type; + } + else if (type == -1) + { + tile.HasTile = false; + } + else if (type == -2) + { + tile.ClearEverything(); + } + } + } + + public static void ChangeLiquid(Tile tile, int type, int force) + { + if (ChestSafe(tile) && CanChangeTile(tile, force)) + { + if (type >= 0) + { + tile.LiquidType = (ushort)type; + } + else if (type == -1) + { + tile.HasTile = false; + } + else if (type == -2) + { + tile.ClearEverything(); + } + } + } + + /// + /// Smooth tiles by given area:(x0:left, y0:top, x1:right, y1:bottom) + /// + /// + /// + /// + /// + public static void SmoothTile_XXYY(int x0, int y0, int x1, int y1) + { + x0 = Math.Clamp(x0, 20, Main.maxTilesX - 20); + x1 = Math.Clamp(x1, 20, Main.maxTilesX - 20); + y0 = Math.Clamp(y0, 20, Main.maxTilesY - 20); + y1 = Math.Clamp(y1, 20, Main.maxTilesY - 20); + for (int x = x0; x <= x1; x += 1) + { + for (int y = y0; y <= y1; y += 1) + { + if (!ChestSafe(x, y)) + { + continue; + } + Tile.SmoothSlope(x, y, false, false); + WorldGen.TileFrame(x, y, true, false); + WorldGen.SquareWallFrame(x, y, true); + } + } + } + + /// + /// Smooth tiles by given area:(x, y, w, h) + /// + /// + /// + /// + /// + public static void SmoothTile_XYWH(int x, int y, int w, int h) + { + SmoothTile_XXYY(x, y, x + w, y + h); + } + + /// + /// Smooth tiles by given tile list. Note that the tile list should be in the same area, otherwise it may cause some unexpected result. + /// + /// + public static void SmoothTile_List(List tiles) + { + foreach (var pos in tiles) + { + if (!ChestSafe(pos.X, pos.Y)) + { + continue; + } + Tile.SmoothSlope(pos.X, pos.Y, false, false); + WorldGen.TileFrame(pos.X, pos.Y, true, true); + WorldGen.SquareWallFrame(pos.X, pos.Y, true); + } + } + + public static void SmoothTile_PolygonArea(List polygon_TilePos) + { + List polygon_WorldPos = new List(); + foreach (var point in polygon_TilePos) + { + polygon_WorldPos.Add(point.ToWorldCoordinates()); + } + SmoothTile_PolygonArea(polygon_WorldPos); + } + + public static void SmoothTile_PolygonArea(List polygon_WorldPos) + { + if (polygon_WorldPos.Count < 3) + { + return; + } + var bounds = MathUtils.GetPolygonAABBBound_Vector4(polygon_WorldPos); + for (int x = (int)bounds.X; x <= bounds.Z; x += 16) + { + for (int y = (int)bounds.Y; y <= bounds.W; y += 16) + { + if (MathUtils.IsPointInPolygon(polygon_WorldPos, new Vector2(x, y))) + { + var point = new Vector2(x, y).ToTileCoordinates(); + Tile.SmoothSlope(point.X, point.Y, false, false); + WorldGen.TileFrame(point.X, point.Y, true, true); + WorldGen.SquareWallFrame(point.X, point.Y, true); + } + } + } + } + + /// + /// Use BFS algorithm get the continue tiles from the check point. + /// + /// + /// If true, tile with no block but only wall will also be included. + /// + /// + public static List BFSContinueTile(Point checkPoint, bool includeWall = false, int maxCount = 512, List theseTypeOnly = default) + { + int maxContinueCount = maxCount; + (int, int)[] directions = + { + (0, 1), + (1, 0), + (0, -1), + (-1, 0), + }; + Queue queueChecked = new Queue(); + + // Add first point to the queue. + queueChecked.Enqueue(checkPoint); + List visited = new List(); + + while (queueChecked.Count > 0) + { + var tilePos = queueChecked.Dequeue(); + + foreach (var (dx, dy) in directions) + { + int checkX = tilePos.X + dx; + int checkY = tilePos.Y + dy; + Point point = new Point(checkX, checkY); + Tile tile = SafeGetTile(checkX, checkY); + + // Check bound and obstruction. + if (checkX >= 20 && checkX < Main.maxTilesX - 20 && checkY >= 20 && checkY < Main.maxTilesY - 20 && + (tile.HasTile || (includeWall && tile.WallType > WallID.None)) && !visited.Contains(point)) + { + if (theseTypeOnly == default) + { + queueChecked.Enqueue(point); + visited.Add(point); + } + else if (theseTypeOnly.Contains(tile.TileType)) + { + queueChecked.Enqueue(point); + visited.Add(point); + } + } + } + if (queueChecked.Count > maxContinueCount || visited.Count > maxContinueCount) + { + break; + } + } + return visited; + } + + public static List BFSContinueWall(Point checkPoint, int maxCount = 512, List theseTypeOnly = default) + { + int maxContinueCount = maxCount; + (int, int)[] directions = + { + (0, 1), + (1, 0), + (0, -1), + (-1, 0), + }; + Queue queueChecked = new Queue(); + + // Add first point to the queue. + queueChecked.Enqueue(checkPoint); + List visited = new List(); + + while (queueChecked.Count > 0) + { + var tilePos = queueChecked.Dequeue(); + + foreach (var (dx, dy) in directions) + { + int checkX = tilePos.X + dx; + int checkY = tilePos.Y + dy; + Point point = new Point(checkX, checkY); + Tile tile = SafeGetTile(checkX, checkY); + + // Check bound and obstruction. + if (checkX >= 20 && checkX < Main.maxTilesX - 20 && checkY >= 20 && checkY < Main.maxTilesY - 20 && + (tile.WallType > WallID.None || theseTypeOnly.Contains(WallID.None)) && !visited.Contains(point)) + { + if (theseTypeOnly == default) + { + queueChecked.Enqueue(point); + visited.Add(point); + } + else if (theseTypeOnly.Contains(tile.WallType)) + { + queueChecked.Enqueue(point); + visited.Add(point); + } + } + } + if (queueChecked.Count > maxContinueCount || visited.Count > maxContinueCount) + { + break; + } + } + return visited; + } + + /// + /// Use BFS algorithm get the continue tiles from the check point. + /// + /// + /// If true, tile is empty but has wall will NOT count as empty. + /// + /// + public static List BFSContinueEmpty(Point checkPoint, bool includeWall = false, int maxCount = 512, List ignoreTheseType = default) + { + int maxContinueCount = maxCount; + (int, int)[] directions = + { + (0, 1), + (1, 0), + (0, -1), + (-1, 0), + }; + Queue queueChecked = new Queue(); + + // Add first point to the queue. + queueChecked.Enqueue(checkPoint); + List visited = new List(); + + while (queueChecked.Count > 0) + { + var tilePos = queueChecked.Dequeue(); + + foreach (var (dx, dy) in directions) + { + int checkX = tilePos.X + dx; + int checkY = tilePos.Y + dy; + Point point = new Point(checkX, checkY); + Tile tile = SafeGetTile(checkX, checkY); + + // Check bound and obstruction. + bool flag0 = !tile.HasTile && (!includeWall || tile.WallType <= WallID.None); + bool flag1 = tile.HasTile && ignoreTheseType != default && ignoreTheseType.Contains(tile.TileType); + if (checkX >= 20 && checkX < Main.maxTilesX - 20 && checkY >= 20 && checkY < Main.maxTilesY - 20 && + (flag0 || flag1) && !visited.Contains(point)) + { + queueChecked.Enqueue(point); + visited.Add(point); + } + } + if (queueChecked.Count > maxContinueCount || visited.Count > maxContinueCount) + { + break; + } + } + return visited; + } + + public static List BFSSurface(Point checkPoint, int maxCount = 512, bool ignoreFrameImportant = true, List theseTypeOnly = default) + { + int maxContinueCount = maxCount; + (int, int)[] directions = + { + (0, 1), + (1, 0), + (0, -1), + (-1, 0), + + // (1, 1), + // (1, -1), + // (-1, -1), + // (-1, 1), + }; + Queue queueChecked = new Queue(); + + // Add first point to the queue. + queueChecked.Enqueue(checkPoint); + List visited_air = new List(); + List visited_tile = new List(); + while (queueChecked.Count > 0) + { + var tilePos = queueChecked.Dequeue(); + + foreach (var (dx, dy) in directions) + { + int checkX = tilePos.X + dx; + int checkY = tilePos.Y + dy; + Point point = new Point(checkX, checkY); + Tile tile = SafeGetTile(checkX, checkY); + Tile tile_up = SafeGetTile(checkX, checkY - 1); + Tile tile_bottom = SafeGetTile(checkX, checkY + 1); + Tile tile_left = SafeGetTile(checkX - 1, checkY); + Tile tile_right = SafeGetTile(checkX + 1, checkY); + + // Tile tile_upleft = SafeGetTile(checkX - 1, checkY - 1); + // Tile tile_bottomleft = SafeGetTile(checkX - 1, checkY + 1); + // Tile tile_upright = SafeGetTile(checkX + 1, checkY - 1); + // Tile tile_bottomright = SafeGetTile(checkX + 1, checkY - 1); + + // bool flag0 = !tile_upleft.HasTile || !tile_upright.HasTile || !tile_bottomleft.HasTile || !tile_bottomright.HasTile; + // Check bound and obstruction. + bool flag0 = checkX >= 20 && checkX < Main.maxTilesX - 20 && checkY >= 20 && checkY < Main.maxTilesY - 20; + bool flag1 = tile.HasTile && (visited_air.Contains(new Point(checkX, checkY - 1)) || visited_air.Contains(new Point(checkX, checkY + 1)) || visited_air.Contains(new Point(checkX - 1, checkY)) || visited_air.Contains(new Point(checkX + 1, checkY))); + bool flag2 = !tile.HasTile && (tile_up.HasTile || tile_bottom.HasTile || tile_left.HasTile || tile_right.HasTile); + bool flag3 = !ignoreFrameImportant || !Main.tileFrameImportant[tile.TileType]; + if (flag0 && (flag1 || flag2) && flag3 && !visited_air.Contains(point) && !visited_tile.Contains(point)) + { + if (theseTypeOnly == default) + { + queueChecked.Enqueue(point); + if (flag1) + { + visited_tile.Add(point); + } + if (flag2) + { + visited_air.Add(point); + } + } + else if (theseTypeOnly.Contains(tile.TileType)) + { + queueChecked.Enqueue(point); + if (flag1) + { + visited_tile.Add(point); + } + if (flag2) + { + visited_air.Add(point); + } + } + } + } + if (queueChecked.Count > maxContinueCount || visited_tile.Count + visited_air.Count > maxContinueCount) + { + break; + } + } + return visited_tile; + } + + public static List GenerateRandomSeeds(int xBoundLeft, int xBoundRight, int yBoundTop, int yBoundBottom, int expect_Count, float minDistance = 20) + { + List result = new List(); + HashSet used = new HashSet(); + + int width = xBoundRight - xBoundLeft; + int height = yBoundBottom - yBoundTop; + float cellSize = minDistance / (float)Math.Sqrt(2); + int gridW = (int)Math.Ceiling(width / cellSize) + 2; + int gridH = (int)Math.Ceiling(height / cellSize) + 2; + + Point?[,] grid = new Point?[gridW, gridH]; + List active = new List(); + + int startX = (xBoundLeft + xBoundRight) / 2; + int startY = (yBoundTop + yBoundBottom) / 2; + result.Add(new Point(startX, startY)); + used.Add(new Point(startX, startY)); + active.Add(new Point(startX, startY)); + SetGrid(grid, cellSize, xBoundLeft, yBoundTop, startX, startY); + + while (active.Count > 0 && result.Count < expect_Count) + { + int idx = Main.rand.Next(active.Count); + var current = active[idx]; + bool found = false; + + for (int i = 0; i < 8; i++) + { + float angle = Main.rand.NextFloat(0f, MathHelper.TwoPi); + float dist = Main.rand.NextFloat(minDistance, minDistance * 2f); + + int newX = current.X + (int)Math.Round(Math.Cos(angle) * dist); + int newY = current.Y + (int)Math.Round(Math.Sin(angle) * dist); + + if (newX < xBoundLeft || newX > xBoundRight || + newY < yBoundTop || newY > yBoundBottom) + { + continue; + } + + int gx = (int)((newX - xBoundLeft) / cellSize); + int gy = (int)((newY - yBoundTop) / cellSize); + + bool tooClose = false; + + for (int cx = Math.Max(0, gx - 1); cx <= Math.Min(gridW - 1, gx + 1); cx++) + { + for (int cy = Math.Max(0, gy - 1); cy <= Math.Min(gridH - 1, gy + 1); cy++) + { + var pt = grid[cx, cy]; + if (pt.HasValue) + { + float d = Vector2.Distance( + new Vector2(newX, newY), + new Vector2(pt.Value.X, pt.Value.Y)); + if (d < minDistance) + { + tooClose = true; + break; + } + } + } + if (tooClose) + { + break; + } + } + + if (!tooClose && !used.Contains(new Point(newX, newY))) + { + result.Add(new Point(newX, newY)); + used.Add(new Point(newX, newY)); + active.Add(new Point(newX, newY)); + SetGrid(grid, cellSize, xBoundLeft, yBoundTop, newX, newY); + found = true; + break; + } + } + + if (!found) + { + active.RemoveAt(idx); + } + } + + return result; + } + + private static void SetGrid(Point?[,] grid, float cellSize, int ox, int oy, int x, int y) + { + int gx = (int)((x - ox) / cellSize); + int gy = (int)((y - oy) / cellSize); + grid[gx, gy] = new Point(x, y); + } + + public static bool TileAtOriginPos(Tile tile) + { + int style = TileObjectData.GetTileStyle(tile); + TileObjectData tileObjectData = TileObjectData.GetTileData(tile.TileType, style); + return tile.TileFrameX - style * tileObjectData.Width * 18 == tileObjectData.Origin.X * 18 && tile.TileFrameY == tileObjectData.Origin.Y * 18; + } + + public static void PlaceWallAround(Tile tile, int wallType, bool middle = true, bool top = true, bool bottom = true, bool left = true, bool right = true) + { + PlaceWallAround(tile.X(), tile.Y(), wallType, middle, top, bottom, left, right); + } + + public static void PlaceWallAround(Point pos, int wallType, bool middle = true, bool top = true, bool bottom = true, bool left = true, bool right = true) + { + PlaceWallAround(pos.X, pos.Y, wallType, middle, top, bottom, left, right); + } + + public static void PlaceWallAround(int x, int y, int wallType, bool middle = true, bool top = true, bool bottom = true, bool left = true, bool right = true) + { + Tile tile = SafeGetTile(x, y); + if (middle) + { + tile.wall = (ushort)wallType; + } + Tile tile_top = SafeGetTile(x, y - 1); + if (top) + { + tile_top.wall = (ushort)wallType; + } + Tile tile_bottom = SafeGetTile(x, y + 1); + if (bottom) + { + tile_bottom.wall = (ushort)wallType; + } + Tile tile_left = SafeGetTile(x - 1, y); + if (left) + { + tile_left.wall = (ushort)wallType; + } + Tile tile_right = SafeGetTile(x + 1, y); + if (right) + { + tile_right.wall = (ushort)wallType; + } + } + + public static void PlaceTileAround(int x, int y, int tileType, bool middle = true, bool top = true, bool bottom = true, bool left = true, bool right = true, int force = 0) + { + Tile tile = SafeGetTile(x, y); + if (middle) + { + ChangeTile(tile, tileType, force); + } + Tile tile_top = SafeGetTile(x, y - 1); + if (top) + { + ChangeTile(tile_top, tileType, force); + } + Tile tile_bottom = SafeGetTile(x, y + 1); + if (bottom) + { + ChangeTile(tile_bottom, tileType, force); + } + Tile tile_left = SafeGetTile(x - 1, y); + if (left) + { + ChangeTile(tile_left, tileType, force); + } + Tile tile_right = SafeGetTile(x + 1, y); + if (right) + { + ChangeTile(tile_right, tileType, force); + } + } + + private static readonly (int, int)[] directionsLiquid = + { + (1, 0), + (0, 1), + (-1, 0), + }; + + /// + /// Fill water or other liquid below pos. pos : in World coord. + /// + /// + /// + /// + public static void FillLiquid(Point pos, int type = 0, int maxCount = 900) + { + Queue queueChecked = new Queue(); + + // 将起始点加入队列 + queueChecked.Enqueue(pos); + List visited = new List(); + + while (queueChecked.Count > 0) + { + var tilePos = queueChecked.Dequeue(); + + foreach (var (dx, dy) in directionsLiquid) + { + int checkX = tilePos.X + dx; + int checkY = tilePos.Y + dy; + Point point = new Point(checkX, checkY); + + // 检查边界和障ç¢ç‰© + if (checkX >= 20 && checkX < Main.maxTilesX - 20 && checkY >= 20 && checkY < Main.maxTilesY - 20 && + !Collision.IsWorldPointSolid(point.ToWorldCoordinates()) && !visited.Contains(point)) + { + queueChecked.Enqueue(point); + visited.Add(point); + } + } + if (queueChecked.Count > maxCount || visited.Count > maxCount) + { + break; + } + } + if (visited.Count < maxCount) + { + foreach (var checked_pos in visited) + { + Tile tile = SafeGetTile(checked_pos); + tile.LiquidType = (byte)type; + tile.LiquidAmount = 255; + } + } + } + + /// + /// Fill water or other liquid below center.center : in World coord. + /// + /// World coord + /// + public static void FillLiquid(Vector2 center, int type = 0, int maxCount = 900) + { + FillLiquid(center.ToTileCoordinates(), type, maxCount); + } + + /// + /// Fill water or other liquid below pos. + /// + /// + /// + /// + /// + public static void FillLiquid(int i, int j, int type = 0, int maxCount = 900) + { + FillLiquid(new Point(i, j), type, maxCount); + } + + /// + /// Fill water or other liquid below center.center : in tile coord. + /// + /// Tile coord + public static List BFSGetCanFillLiquidTiles(Vector2 center, int maxCount = 900) + { + return BFSGetCanFillLiquidTiles(center.ToTileCoordinates(), maxCount); + } + + /// + /// Fill water or other liquid below pos. pos : in tile coord. + /// + /// Tile coord + public static List BFSGetCanFillLiquidTiles(Point pos, int maxCount = 900) + { + Queue queueChecked = new Queue(); + + // 将起始点加入队列 + queueChecked.Enqueue(pos); + List visited = new List(); + + while (queueChecked.Count > 0) + { + var tilePos = queueChecked.Dequeue(); + + foreach (var (dx, dy) in directionsLiquid) + { + int checkX = tilePos.X + dx; + int checkY = tilePos.Y + dy; + Tile Tile = SafeGetTile(checkX, checkY); + Point point = new Point(checkX, checkY); + + // 检查边界和障ç¢ç‰© + if (checkX >= 20 && checkX < Main.maxTilesX - 20 && checkY >= 20 && checkY < Main.maxTilesY - 20 && + !Collision.IsWorldPointSolid(new Point(checkX, checkY).ToWorldCoordinates()) && !visited.Contains(point)) + { + queueChecked.Enqueue(new Point(checkX, checkY)); + visited.Add(point); + } + } + if (queueChecked.Count > maxCount || visited.Count > maxCount) + { + break; + } + } + return visited; + } + + public static List BFSGetCanFillLiquidTiles(int i, int j, int maxCount = 900) + { + return BFSGetCanFillLiquidTiles(new Point(i, j), maxCount); + } + + /// + /// Get the nearest tile of the type. type : tile type, -1 : empty tile, -2 : empty tile without wall. maxDistance : the max distance to check. return : the offset to the nearest tile of the type. if no tile of the type is found within maxDistance, return new Vector2(maxDistance + 1). + /// + /// + /// + /// + /// + /// + public static Vector2 ToNearestTypeOfTile(int x, int y, int type, float maxDistance = 100) + { + Vector2 direction = new Vector2(maxDistance + 1); + float minDis = maxDistance; + for (int i = -(int)maxDistance; i <= maxDistance; i++) + { + for (int j = -(int)maxDistance; j <= maxDistance; j++) + { + Tile tile = SafeGetTile(i + x, j + y); + bool flag0 = tile.HasTile && tile.TileType == type; + bool flag1 = type == -1 && !tile.HasTile; + bool flag2 = type == -2 && !tile.HasTile && tile.wall <= 0; + if (flag0 || flag1 || flag2) + { + Vector2 v1 = new Vector2(i, j); + if (v1.Length() < minDis) + { + minDis = v1.Length(); + direction = v1; + } + } + } + } + return direction * 16; + } + + /// + /// Get the nearest tile of the type. type : tile type, -1 : empty tile, -2 : empty tile without wall. maxDistance : the max distance to check. return : the offset to the nearest tile of the type. if no tile of the type is found within maxDistance, return Vector2.zeroVector. + /// + /// + /// + /// + /// + public static Vector2 ToNearestTypeOfTile(Vector2 worldPos, int type, float maxDistance = 100) + { + int x = worldPos.ToTileCoordinates().X; + int y = worldPos.ToTileCoordinates().Y; + return ToNearestTypeOfTile(x, y, type, maxDistance); + } + + /// + /// Return the summary of air-to-tile distances of given point to top and to bottom. + /// + /// + /// + /// + public static int CheckSpaceHeight(int x, int y) + { + int count = 0; + int x0 = x; + int y0 = y; + if (x0 > Main.maxTilesX || x0 < 0) + { + return count; + } + while (!SafeGetTile(x0, y0).HasTile) + { + if (y0 > Main.maxTilesY) + { + break; + } + y0++; + count++; + } + x0 = x; + y0 = y - 1; + while (!SafeGetTile(x0, y0).HasTile) + { + if (y0 < 0) + { + break; + } + y0--; + count++; + } + return count; + } + + /// + /// Return the summary of air-to-tile distances of given point to left and to right. + /// + /// + /// + /// + public static int CheckSpaceWidth(int x, int y) + { + int count = 0; + int x0 = x; + int y0 = y; + if (y0 > Main.maxTilesY || y0 < 0) + { + return count; + } + while (!SafeGetTile(x0, y0).HasTile) + { + if (x0 > Main.maxTilesX) + { + break; + } + x0++; + count++; + } + x0 = x - 1; + y0 = y; + while (!SafeGetTile(x0, y0).HasTile) + { + if (x0 < 0) + { + break; + } + x0--; + count++; + } + return count; + } + + /// + /// Return the air-to-tile distance from given point to LEFT. + /// + /// + /// + /// + public static int CheckSpaceLeft(int x, int y, bool ignore_none_solid = false) + { + int count = 0; + int x0 = x; + int y0 = y; + if (y0 > Main.maxTilesY || y0 < 0) + { + return count; + } + while (!SafeGetTile(x0, y0).HasTile || (!IsTileSolid(x0, y0) && ignore_none_solid)) + { + if (x0 < 0) + { + break; + } + x0--; + count++; + } + return count; + } + + /// + /// Return the air-to-tile distance from given point to RIGHT. + /// + /// + /// + /// + public static int CheckSpaceRight(int x, int y, bool ignore_none_solid = false) + { + int count = 0; + int x0 = x; + int y0 = y; + if (y0 > Main.maxTilesY || y0 < 0) + { + return count; + } + while (!SafeGetTile(x0, y0).HasTile || (!IsTileSolid(x0, y0) && ignore_none_solid)) + { + if (x0 > Main.maxTilesX) + { + break; + } + x0++; + count++; + } + return count; + } + + /// + /// Return the air-to-tile distance from given point to TOP. + /// + /// + /// + /// + public static int CheckSpaceUp(int x, int y, bool ignore_none_solid = false) + { + int count = 0; + int x0 = x; + int y0 = y; + if (x0 > Main.maxTilesX || x0 < 0) + { + return count; + } + while (!SafeGetTile(x0, y0).HasTile || (!IsTileSolid(x0, y0) && ignore_none_solid)) + { + if (y0 < 0) + { + break; + } + y0--; + count++; + } + return count; + } + + /// + /// Return the air-to-tile distance from given point to BOTTOM. + /// + /// + /// + /// + public static int CheckSpaceDown(int x, int y, bool ignore_none_solid = false) + { + int count = 0; + int x0 = x; + int y0 = y; + if (y0 > Main.maxTilesY || y0 < 0) + { + return count; + } + while (!SafeGetTile(x0, y0).HasTile || (!IsTileSolid(x0, y0) && ignore_none_solid)) + { + if (y0 > Main.maxTilesY) + { + break; + } + y0++; + count++; + } + return count; + } + + public static int CheckSpaceHeight(Point pos) + { + return CheckSpaceHeight(pos.X, pos.Y); + } + + public static int CheckSpaceWidth(Point pos) + { + return CheckSpaceWidth(pos.X, pos.Y); + } + + public static int CheckSpaceLeft(Point pos, bool ignore_none_solid = false) + { + return CheckSpaceLeft(pos.X, pos.Y, ignore_none_solid); + } + + public static int CheckSpaceRight(Point pos, bool ignore_none_solid = false) + { + return CheckSpaceRight(pos.X, pos.Y, ignore_none_solid); + } + + public static int CheckSpaceUp(Point pos, bool ignore_none_solid = false) + { + return CheckSpaceUp(pos.X, pos.Y, ignore_none_solid); + } + + public static int CheckSpaceDown(Point pos, bool ignore_none_solid = false) + { + return CheckSpaceDown(pos.X, pos.Y, ignore_none_solid); + } + + /// + /// Return the tile type if all tiles in the given area are the same, otherwise return -3.No any tile, return -1. If the area is out of world, return -4. + /// + /// + /// + /// + /// + /// + public static int GetUniformTile(int x, int y, int w, int h) + { + if (x < 0 || y < 0 || x + w > Main.maxTilesX || y + h > Main.maxTilesY) + { + return -4; + } + + Tile tile = SafeGetTile(x, y); + int targetId = tile.TileType; + if (!tile.HasTile) + { + targetId = -1; + } + for (int px = x; px < x + w; px++) + { + for (int py = y; py < y + h; py++) + { + Tile checkTile = SafeGetTile(px, py); + int checkType = checkTile.TileType; + if (!checkTile.HasTile) + { + checkType = -1; + } + if (checkType != targetId) + { + return -3; + } + } + } + + return targetId; + } + + /// + /// Return the tile type if all tiles in the given area are the same, otherwise return -3.No any tile, return -1. If the area is out of world, return -4. + /// + /// + /// + /// + /// + public static int GetUniformTile(Point point, int w, int h) + { + return GetUniformTile(point.X, point.Y, w, h); + } + + /// + /// Fill liquid in the given area. Type: vanilla Liquid.ID. + /// + /// + /// + /// + /// + public static void PlaceRectangleAreaOfLiquid_XYWH(int x, int y, int w, int h, int type) + { + for (int i = x; i <= x + w; i++) + { + for (int j = y; j <= y + h; j++) + { + Tile tile = SafeGetTile(i, j); + if (ChestSafe(x, y)) + { + tile.liquid = (byte)type; + tile.LiquidAmount = 255; + } + } + } + } + + /// + /// Fill all chest by given area if exist. + /// + /// + /// + /// + /// + /// + public static void FillChestXYWH(int x, int y, int width, int height, List contents) + { + for (int i = 0; i < width; i++) + { + for (int j = 0; j < height; j++) + { + WorldGenMisc.TryFillChest(x + i, y + j, contents); + } + } + } + + /// + /// Tile coord. Ignore platforms. + /// + /// + /// + public static bool IsTileSolid(Point point) + { + if (!WorldGen.InWorld(point.X, point.Y, 1)) + { + return false; + } + Tile tile = Main.tile[point.X, point.Y]; + return IsTileSolid(tile); + } + + public static bool IsTileSolid(int x, int y) + { + return IsTileSolid(new Point(x, y)); + } + + public static bool IsTileSolid(Tile tile) + { + if (tile == null || !tile.HasTile || tile.IsActuated || !Main.tileSolid[tile.TileType]) + { + return false; + } + if (tile.TileType > TileID.Dirt && (TileID.Sets.Platforms[tile.TileType] || tile.TileType == TileID.PlanterBox)) + { + return false; + } + return true; + } + + /// + /// Get the tile positions in the given polygon area. World coord. + /// + /// + /// + /// + /// + public static List GetPolygonAreaOfTilePos(List polygon) + { + List polygon_Pos = new List(); + if (polygon.Count < 3) + { + return polygon_Pos; + } + var bounds = MathUtils.GetPolygonAABBBound_Vector4(polygon); + bounds.X = bounds.X - bounds.X % 16 - 8; + bounds.Y = bounds.Y - bounds.Y % 16 - 8; + bounds.Z = bounds.Z - bounds.Z % 16 + 8; + bounds.W = bounds.W - bounds.W % 16 + 8; + for (int x = (int)bounds.X; x <= bounds.Z; x += 16) + { + for (int y = (int)bounds.Y; y <= bounds.W; y += 16) + { + if (MathUtils.IsPointInPolygon(polygon, new Vector2(x, y))) + { + polygon_Pos.Add(new Vector2(x, y).ToTileCoordinates()); + } + } + } + return polygon_Pos; + } + + /// + /// Get the tile positions in the given polygon area. Tile coord. + /// + /// + /// + /// + /// + public static List GetPolygonAreaOfTilePos(List polygon) + { + List polygon_Vector2 = new List(); + foreach (var point in polygon) + { + polygon_Vector2.Add(point.ToWorldCoordinates()); + } + return GetPolygonAreaOfTilePos(polygon_Vector2); + } + + /// + /// Get the tile positions in the given rectangle area. World coord. + /// + /// + /// + public static List GetAABBAreaOfTile(Vector2 worldPos, Vector2 size) + { + List tilePoses = new List(); + for (int x = worldPos.ToTileCoordinates().X; x <= (worldPos + size).ToTileCoordinates().X; x++) + { + for (int y = worldPos.ToTileCoordinates().Y; y <= (worldPos + size).ToTileCoordinates().Y; y++) + { + tilePoses.Add(new Point(x, y)); + } + } + return tilePoses; + } + + /// + /// Get the tile positions in the given rectangle area. Tile coord. + /// + /// + /// + public static List GetAABBAreaOfTile(int x, int y, int w, int h) + { + int minX = Math.Min(x, x + w); + int minY = Math.Min(y, y + h); + int maxX = Math.Max(x, x + w); + int maxY = Math.Max(y, y + h); + List tilePoses = new List(); + for (int i = minX; i <= maxX; i++) + { + for (int j = minY; j <= maxY; j++) + { + tilePoses.Add(new Point(i, j)); + } + } + return tilePoses; + } + + /// + /// Get the tile positions in the given rectangle area. Tile coord. + /// + /// + /// + public static List GetAABBAreaOfTile(Point start, Point end) + { + int minX = Math.Min(start.X, end.X); + int minY = Math.Min(start.Y, end.Y); + int maxX = Math.Max(start.X, end.X); + int maxY = Math.Max(start.Y, end.Y); + List tilePoses = new List(); + for (int x = minX; x <= maxX; x++) + { + for (int y = minY; y <= maxY; y++) + { + tilePoses.Add(new Point(x, y)); + } + } + return tilePoses; + } + + public static void PlaceTileListTowardDownUntilCollide(Point pos, int type, int max = 1024) + { + for (int t = 0; t < max; t++) + { + var tile = SafeGetTile(pos + new Point(0, t)); + if (!tile.HasTile || !Main.tileSolid[tile.TileType]) + { + tile.TileType = (ushort)type; + tile.HasTile = true; + } + else + { + break; + } + } + } + + public static void PlaceTileListTowardUpUntilCollide(Point pos, int type, int max = 1024) + { + for (int t = 0; t < max; t++) + { + var tile = SafeGetTile(pos + new Point(0, -t)); + if (!tile.HasTile) + { + tile.TileType = (ushort)type; + tile.HasTile = true; + } + else + { + break; + } + } + } + + public static void PlaceTileListTowardLeftUntilCollide(Point pos, int type, int max = 1024) + { + for (int t = 0; t < max; t++) + { + var tile = SafeGetTile(pos + new Point(-t, 0)); + if (!tile.HasTile) + { + tile.TileType = (ushort)type; + tile.HasTile = true; + } + else + { + break; + } + } + } + + public static void PlaceTileListTowardRightUntilCollide(Point pos, int type, int max = 1024) + { + for (int t = 0; t < max; t++) + { + var tile = SafeGetTile(pos + new Point(t, 0)); + if (!tile.HasTile) + { + tile.TileType = (ushort)type; + tile.HasTile = true; + } + else + { + break; + } + } + } + + public static Point PointLerp(Point pos0, Point pos1, float value) + { + return new Point((int)(pos0.X + (pos1.X - pos0.X) * value), (int)(pos0.Y + (pos1.Y - pos0.Y) * value)); + } + + /// + /// Get the centroid of the given points. + /// + /// + /// + public static Point GetCentroid(List points) + { + if (points.Count <= 0) + { + return default; + } + Point point = new Point(0, 0); + foreach (var p in points) + { + point += p; + } + return new Point(point.X / points.Count, point.Y / points.Count); + } + + /// + /// Find the nearest tile position with tile within 100 range. Return default if not found. + /// + /// + /// , Default to 10, SolidTile + /// + public static Point FindNearestTileWithin100Range(Point pos, int force = 10) + { + float minDis = 100; + Point point = default; + for (int i = -100; i <= 100; i++) + { + for (int j = -100; j <= 100; j++) + { + Tile tile = SafeGetTile(i + pos.X, j + pos.Y); + if (CanChangeTile(tile, force)) + { + Vector2 v1 = new Vector2(i, j); + if (v1.Length() < minDis) + { + minDis = v1.Length(); + point = new Point(i + pos.X, j + pos.Y); + } + } + } + } + return point; + } + + public static float PointDistance(Point p0, Point p1) + { + return Vector2.Distance(p0.ToVector2(), p1.ToVector2()); + } + + public static void ConnectWire(Point point0, Point point1, bool red = true, bool green = false, bool blue = false, bool yellow = false) + { + int distanceX = Math.Abs((point1 - point0).X); + int distanceY = Math.Abs((point1 - point0).Y); + Point check = point0; + int dirX = 1; + int dirY = 1; + if (point1.X < point0.X) + { + dirX = -1; + } + if (point1.Y < point0.Y) + { + dirY = -1; + } + for (int y = 0; y < distanceY; y++) + { + Tile tile = SafeGetTile(check); + tile.RedWire = red; + tile.GreenWire = green; + tile.BlueWire = blue; + tile.YellowWire = yellow; + check.Y += dirY; + } + for (int x = 0; x <= distanceX; x++) + { + Tile tile = SafeGetTile(check); + tile.RedWire = red; + tile.GreenWire = green; + tile.BlueWire = blue; + tile.YellowWire = yellow; + check.X += dirX; + } + } + + /// + /// Transform the tiles beside the curve to the type. Notice that thick is in World Coord, 16 for a tile size. + /// + /// Tile Coord + /// World Coord + /// + /// + public static void PlaceCurveBlock(List curve, float thick, int type, int force = 0) + { + for (int k = 0; k < curve.Count - 1; k++) + { + PlaceLineBlock(curve[k], curve[k + 1], thick, type, force); + if (k >= 1) + { + PlaceCircleAreaOfBlock(curve[k], thick / 32, type, force); + } + } + } + + /// + /// Transform the tiles beside the curve to the type. Notice that thick is in World Coord, 16 for a tile size. + /// + /// Tile Coord + /// World Coord + /// + /// + public static void PlaceCurveWall(List curve, float thick, int type, int force = 0) + { + for (int k = 0; k < curve.Count - 1; k++) + { + PlaceLineWall(curve[k], curve[k + 1], thick, type, force); + if (k >= 1) + { + PlaceCircleAreaOfWall(curve[k], thick / 32, type, force); + } + } + } + + /// + /// Transform the liquid beside the curve to the type. Notice that thick is in World Coord, 16 for a tile size. + /// + /// Tile Coord + /// World Coord + /// + /// + public static void PlaceCurveLiquid(List curve, float thick, int type, int force = 0) + { + for (int k = 0; k < curve.Count - 1; k++) + { + PlaceLineLiquid(curve[k], curve[k + 1], thick, type, force); + if (k >= 1) + { + PlaceCircleAreaOfLiquid(curve[k], thick / 32, type, force); + } + } + } + + /// + /// Transform the tiles beside the curve to the type. Notice that thick is in World Coord, 16 for a tile size. + /// + /// World Coord + /// World Coord + /// + /// + public static void PlaceCurveBlock(List curve, float thick, int type, int force = 0) + { + List curve_Point = new List(); + foreach (var pos in curve) + { + curve_Point.Add(pos.ToTileCoordinates()); + } + PlaceCurveBlock(curve_Point, thick, type, force); + } + + /// + /// Transform the tiles beside the curve to the type. Notice that thick is in World Coord, 16 for a tile size. + /// + /// World Coord + /// World Coord + /// + /// + public static void PlaceCurveWall(List curve, float thick, int type, int force = 0) + { + List curve_Point = new List(); + foreach (var pos in curve) + { + curve_Point.Add(pos.ToTileCoordinates()); + } + PlaceCurveWall(curve_Point, thick, type, force); + } + + /// + /// Transform the liquid beside the curve to the type. Notice that thick is in World Coord, 16 for a tile size. + /// + /// World Coord + /// World Coord + /// + /// + public static void PlaceCurveLiquid(List curve, float thick, int type, int force = 0) + { + List curve_Point = new List(); + foreach (var pos in curve) + { + curve_Point.Add(pos.ToTileCoordinates()); + } + PlaceCurveLiquid(curve_Point, thick, type, force); + } + + /// + /// Place a prefabricated MapIO anchored top left at (x, y). + /// + /// + /// + /// + public static void BuildMapIO(int x, int y, string path) + { + var mapIO = new MapIO(x, y); + mapIO.Read(ModIns.Mod.GetFileStream(path)); + var it = mapIO.GetEnumerator(); + while (it.MoveNext()) + { + WorldGen.SquareTileFrame(it.CurrentCoord.X, it.CurrentCoord.Y); + WorldGen.SquareWallFrame(it.CurrentCoord.X, it.CurrentCoord.Y); + } + } + + public static void BuildMapIO(Point point, string path) + { + BuildMapIO(point.X, point.Y, path); + } +} diff --git a/Sources/Everglow.Function/Utilities/TileUtils.cs b/Sources/Everglow.Function/Utilities/TileUtils.cs index 95169bc84..e0ef28da4 100644 --- a/Sources/Everglow.Function/Utilities/TileUtils.cs +++ b/Sources/Everglow.Function/Utilities/TileUtils.cs @@ -1,3 +1,8 @@ +using Everglow.Commons.Vertex; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + namespace Everglow.Commons.Utilities; public partial class TileUtils @@ -18,51 +23,74 @@ public static Tile SafeGetTile(int i, int j) => public static Tile SafeGetTile(Point point) => SafeGetTile(point.X, point.Y); - public static Tile SafeGetTile(Vector2 vector) => SafeGetTile((int)vector.X, (int)vector.Y); - /// - /// 以[x,y]为左上顶点放置大件连续物å—,此类物å—必须是18x18(ä¸ç®—分隔线就16x16)一帧的 + /// The vector is expected to be the tile coordinate, not world coordinate. (i.e. vector.X is expected to be i, and vector.Y is expected to be j) /// - /// + /// /// - public static void PlaceFrameImportantTiles(int x, int y, int width, int height, int type, int startX = 0, int startY = 0) + public static Tile SafeGetTile(Vector2 vector) => SafeGetTile((int)vector.X, (int)vector.Y); + + public static void DefaultToMultiTileAnchorBottom(int width, int height) { - if (x > Main.maxTilesX - width || x < 0 || y > Main.maxTilesY - height || y < 0) - { - return; - } + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = height; + TileObjectData.newTile.Width = width; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.CoordinateHeights = new int[height]; + Array.Fill(TileObjectData.newTile.CoordinateHeights, 16); + TileObjectData.newTile.CoordinateHeights[^1] = 18; + TileObjectData.newTile.CoordinateWidth = 16; + TileObjectData.newTile.Origin = new Point16(width / 2, height - 1); + TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.SolidTile, width, 0); + } - for (int i = 0; i < width; i++) - { - for (int j = 0; j < height; j++) - { - Tile tile = Main.tile[x + i, y + j]; - tile.TileType = (ushort)type; - tile.TileFrameX = (short)(i * 18 + startX); - tile.TileFrameY = (short)(j * 18 + startY); - tile.HasTile = true; - } - } + public static void DefaultToMultiTileAnchorTop(int width, int height) + { + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = height; + TileObjectData.newTile.Width = width; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.CoordinateHeights = new int[height]; + Array.Fill(TileObjectData.newTile.CoordinateHeights, 16); + TileObjectData.newTile.CoordinateHeights[^1] = 18; + TileObjectData.newTile.CoordinateWidth = 16; + TileObjectData.newTile.Origin = new Point16(width / 2, height - 1); + TileObjectData.newTile.AnchorTop = new AnchorData(AnchorType.SolidTile, width, 0); } - public static void PlaceFrameImportantTilesAbove(int x, int y, int width, int height, int type, int startX = 0, int startY = 0) + public static void DefaultToMultiTileWall(int width, int height) { - if (x > Main.maxTilesX - width || x < 0 || y > Main.maxTilesY - height || y < 0) - { - return; - } + TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3Wall); + TileObjectData.newTile.Height = height; + TileObjectData.newTile.Width = width; + TileObjectData.newTile.CoordinateHeights = new int[height]; + Array.Fill(TileObjectData.newTile.CoordinateHeights, 16); + TileObjectData.newTile.Origin = new Point16(width / 2, height / 2); + TileObjectData.newTile.StyleHorizontal = true; + } - for (int i = 0; i < width; i++) - { - for (int j = 0; j < height; j++) - { - Tile tile = Main.tile[x + i, y + j - height]; - tile.TileType = (ushort)type; - tile.TileFrameX = (short)(i * 18 + startX); - tile.TileFrameY = (short)(j * 18 + startY); - tile.HasTile = true; - } - } + public static int GetFixedRandomNumber(int x, int y, int max = 1024) + { + Random random = new Random(SafeGetTile(Math.Abs(x), Math.Abs(y)).GetHashCode()); + return random.Next(0, max); + } + + public static int GetFixedRandomNumber(Point point, int max = 1024) + { + Random random = new Random(SafeGetTile(point).GetHashCode()); + return random.Next(0, max); + } + + public static int GetFixedRandomNumber(Tile tile, int max = 1024) + { + Random random = new Random(tile.GetHashCode()); + return random.Next(0, max); + } + + public static int GetFixedRandomNumber_SingleSeed(int seed, int max = 1024) + { + Random random = new Random(seed); + return random.Next(0, max); } public static bool AreaHasTile(int x, int y, int width, int height, Func prediction = null) @@ -81,4 +109,78 @@ public static bool AreaHasTile(int x, int y, int width, int height, Func bars = new List(); + Vector2 pos = drawPos + Main.screenPosition; + Vector2 offset0 = (new Vector2(0, 0) - origin).RotatedBy(rotation); + Vector2 offset1 = (new Vector2(frame.Width, 0) - origin).RotatedBy(rotation); + Vector2 offset2 = (new Vector2(0, frame.Height) - origin).RotatedBy(rotation); + Vector2 offset3 = (new Vector2(frame.Width, frame.Height) - origin).RotatedBy(rotation); + + AddLightColorVertex(bars, pos + offset0, new Vector3(new Vector2(frame.X, frame.Y) / tex.Size(), 0)); + AddLightColorVertex(bars, pos + offset1, new Vector3(new Vector2(frame.X + frame.Width, frame.Y) / tex.Size(), 0)); + AddLightColorVertex(bars, pos + offset2, new Vector3(new Vector2(frame.X, frame.Y + frame.Height) / tex.Size(), 0)); + AddLightColorVertex(bars, pos + offset3, new Vector3(new Vector2(frame.X + frame.Width, frame.Y + frame.Height) / tex.Size(), 0)); + if (bars.Count > 2) + { + spriteBatch.GraphicsDevice.Textures[0] = tex; + spriteBatch.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + } + + public static void VertexDraw_Grid(Vector2 drawCenterPos, Rectangle frame, Vector2 origin, Texture2D tex, SpriteBatch spriteBatch, float rotation = 0, float alpha = 1f) + { + var drawPos = drawCenterPos; + List bars = new List(); + Vector2 pos = drawPos + Main.screenPosition; + int xCount = frame.Width / 16; + int yCount = frame.Height / 16; + float unitX = frame.Width / (float)xCount; + float unitY = frame.Height / (float)yCount; + for (int x = 0; x < xCount; x++) + { + for (int y = 0; y < yCount; y++) + { + Vector2 offset0 = (new Vector2(x * unitX, y * unitY) - origin).RotatedBy(rotation); + Vector2 offset1 = (new Vector2((x + 1) * unitX, y * unitY) - origin).RotatedBy(rotation); + Vector2 offset2 = (new Vector2(x * unitX, (y + 1) * unitY) - origin).RotatedBy(rotation); + Vector2 offset3 = (new Vector2((x + 1) * unitX, (y + 1) * unitY) - origin).RotatedBy(rotation); + + AddLightColorVertex(bars, pos + offset0, new Vector3(new Vector2(frame.X + x * unitX, frame.Y + y * unitY) / tex.Size(), 0), alpha); + AddLightColorVertex(bars, pos + offset1, new Vector3(new Vector2(frame.X + (x + 1) * unitX, frame.Y + y * unitY) / tex.Size(), 0), alpha); + AddLightColorVertex(bars, pos + offset2, new Vector3(new Vector2(frame.X + x * unitX, frame.Y + (y + 1) * unitY) / tex.Size(), 0), alpha); + AddLightColorVertex(bars, pos + offset3, new Vector3(new Vector2(frame.X + (x + 1) * unitX, frame.Y + (y + 1) * unitY) / tex.Size(), 0), alpha); + } + } + + if (bars.Count > 2) + { + spriteBatch.GraphicsDevice.Textures[0] = tex; + spriteBatch.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + } + + public static void AddLightColorVertex(List bars, Vector2 worldPos, Vector3 coord, float alpha = 1f) + { + Color drawC = Lighting.GetColor(worldPos.ToTileCoordinates()) * alpha; + bars.Add(worldPos - Main.screenPosition, drawC, coord); + } } diff --git a/Sources/Everglow.Function/Utilities/TileUtils_Initialization.cs b/Sources/Everglow.Function/Utilities/TileUtils_Initialization.cs new file mode 100644 index 000000000..33b5f55cd --- /dev/null +++ b/Sources/Everglow.Function/Utilities/TileUtils_Initialization.cs @@ -0,0 +1,9 @@ +namespace Everglow.Commons.Utilities; + +public class TileUtilsInit : ModSystem +{ + public override void Load() + { + TileUtils.TotalInitialize(); + } +} diff --git a/Sources/Modules/Yggdrasil/WorldGeneration/Noise_II_rgb.bmp b/Sources/Everglow.Function/Utilities/WorldGenLarge_rgb.bmp similarity index 90% rename from Sources/Modules/Yggdrasil/WorldGeneration/Noise_II_rgb.bmp rename to Sources/Everglow.Function/Utilities/WorldGenLarge_rgb.bmp index 04c2e2413..370b128fc 100644 Binary files a/Sources/Modules/Yggdrasil/WorldGeneration/Noise_II_rgb.bmp and b/Sources/Everglow.Function/Utilities/WorldGenLarge_rgb.bmp differ diff --git a/Sources/Everglow.Function/Utilities/WorldGen_Noise_rgb.bmp b/Sources/Everglow.Function/Utilities/WorldGen_Noise_rgb.bmp new file mode 100644 index 000000000..5a84375c6 Binary files /dev/null and b/Sources/Everglow.Function/Utilities/WorldGen_Noise_rgb.bmp differ diff --git a/Sources/Everglow.Function/VFX/Effects/ColorDissolve.fx b/Sources/Everglow.Function/VFX/Effects/ColorDissolve.fx new file mode 100644 index 000000000..862f5664e --- /dev/null +++ b/Sources/Everglow.Function/VFX/Effects/ColorDissolve.fx @@ -0,0 +1,61 @@ +sampler2D uImage0 : register(s0); +texture2D uDissolveNoise; +sampler2D uDissolveNoiseTex = sampler_state +{ + Texture = ; + MinFilter = Linear; + MagFilter = Linear; + AddressU = Wrap; + AddressV = Wrap; +}; +float4x4 uTransform; + +struct VSInput +{ + float2 Pos : POSITION0; + float4 Color : COLOR0; + float3 Texcoord : TEXCOORD0; +}; + +struct PSInput +{ + float4 Pos : SV_POSITION; + float4 Color : COLOR0; + float3 Texcoord : TEXCOORD0; +}; + +PSInput VertexShaderFunction(VSInput input) +{ + PSInput output; + output.Color = input.Color; + output.Texcoord = input.Texcoord; + output.Pos = mul(float4(input.Pos, 0, 1), uTransform); + return output; +} + +float4 PixelShaderFunction(PSInput input) : COLOR0 +{ + float4 tex = tex2D(uImage0, input.Texcoord.xy); + float4 heat = tex2D(uDissolveNoiseTex, input.Texcoord.xy); + if (!any(tex)) + { + return float4(0, 0, 0, 0); + } + if (input.Texcoord.z * 1.2 < heat.r) + { + return float4(0, 0, 0, 0); + } + else if (input.Texcoord.z * 1.2 < heat.r + 0.2) + { + return lerp(tex, float4(0, 0, 0, 1), 0.5f) * input.Color; + } + return tex * input.Color; +} +technique Technique1 +{ + pass Test + { + VertexShader = compile vs_3_0 VertexShaderFunction(); + PixelShader = compile ps_3_0 PixelShaderFunction(); + } +} diff --git a/Sources/Everglow.Function/VFX/Pipelines/ColorDissolvePipeline.cs b/Sources/Everglow.Function/VFX/Pipelines/ColorDissolvePipeline.cs new file mode 100644 index 000000000..165c2d5f3 --- /dev/null +++ b/Sources/Everglow.Function/VFX/Pipelines/ColorDissolvePipeline.cs @@ -0,0 +1,27 @@ +namespace Everglow.Commons.VFX.Pipelines; + +public class ColorDissolvePipeline : Pipeline +{ + public override void Load() + { + effect = ModAsset.ColorDissolve; + effect.Value.Parameters["uDissolveNoise"].SetValue(ModAsset.Noise_flame_0.Value); + } + + public override void BeginRender() + { + var effect = this.effect.Value; + var projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1); + var model = Matrix.CreateTranslation(new Vector3(-Main.screenPosition, 0)) * Main.GameViewMatrix.TransformationMatrix; + effect.Parameters["uTransform"].SetValue(model * projection); + + Main.graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap; + Ins.Batch.Begin(BlendState.AlphaBlend, DepthStencilState.None, SamplerState.PointWrap, RasterizerState.CullNone); + effect.CurrentTechnique.Passes[0].Apply(); + } + + public override void EndRender() + { + Ins.Batch.End(); + } +} diff --git a/Sources/Everglow.Function/VFX/Scene/BackgroundVFX.cs b/Sources/Everglow.Function/VFX/Scene/BackgroundVFX.cs deleted file mode 100644 index 6e75b707b..000000000 --- a/Sources/Everglow.Function/VFX/Scene/BackgroundVFX.cs +++ /dev/null @@ -1,114 +0,0 @@ -using Everglow.Commons.Enums; -using Everglow.Commons.Vertex; -using Everglow.Commons.VFX.Pipelines; - -namespace Everglow.Commons.VFX.Scene; - -[Pipeline(typeof(WCSPipeline))] -public abstract class BackgroundVFX : Visual -{ - public override CodeLayer DrawLayer => CodeLayer.PostDrawBG; - - public Vector2 position; - public Texture2D texture; - public Point originTile; - public int originType; - public int direction = 1; - - public override void Update() - { - if (originTile.X > 0 && originTile.X < Main.maxTilesX) - { - if (originTile.Y > 0 && originTile.Y < Main.maxTilesY) - { - Tile tile = Main.tile[originTile.X, originTile.Y]; - if (tile != null) - { - if (TileLoader.GetTile(tile.TileType) is ISceneTile) - { - if (tile.TileType == originType) - { - if (!tile.HasTile) - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - Vector2 checkPos = position; - if (VFXManager.InScreen(checkPos, 500)) - { - Visible = true; - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - - public override void Draw() - { - Color lightColor0 = Lighting.GetColor((int)position.X / 16, (int)position.Y / 16); - Color lightColor1 = Lighting.GetColor((int)(position.X + texture.Width) / 16, (int)position.Y / 16); - Color lightColor2 = Lighting.GetColor((int)position.X / 16, (int)(position.Y + texture.Height) / 16); - Color lightColor3 = Lighting.GetColor((int)(position.X + texture.Width) / 16, (int)(position.Y + texture.Height) / 16); - - Ins.Batch.BindTexture(texture); - List bars = new List() - { - new Vertex2D(position, lightColor0, new Vector3(0, 0, 0)), - new Vertex2D(position + new Vector2(texture.Width, 0), lightColor1, new Vector3(1, 0, 0)), - - new Vertex2D(position + new Vector2(0, texture.Height), lightColor2, new Vector3(0, 1, 0)), - new Vertex2D(position + new Vector2(texture.Width, texture.Height), lightColor3, new Vector3(1, 1, 0)), - }; - if (direction < 0) - { - bars = new List() - { - new Vertex2D(position, lightColor0, new Vector3(1, 0, 0)), - new Vertex2D(position + new Vector2(texture.Width, 0), lightColor1, new Vector3(0, 0, 0)), - - new Vertex2D(position + new Vector2(0, texture.Height), lightColor2, new Vector3(1, 1, 0)), - new Vertex2D(position + new Vector2(texture.Width, texture.Height), lightColor3, new Vector3(0, 1, 0)), - }; - } - Ins.Batch.Draw(bars, PrimitiveType.TriangleStrip); - } -} diff --git a/Sources/Everglow.Function/VFX/Scene/FlagLikeVFX.cs b/Sources/Everglow.Function/VFX/Scene/FlagLikeVFX.cs new file mode 100644 index 000000000..665467f53 --- /dev/null +++ b/Sources/Everglow.Function/VFX/Scene/FlagLikeVFX.cs @@ -0,0 +1,162 @@ +using Everglow.Commons.Enums; +using Everglow.Commons.Utilities; +using Everglow.Commons.Vertex; +using Everglow.Commons.VFX.Pipelines; + +namespace Everglow.Commons.VFX.Scene; + +/// +/// Texture must sized in any times of 16, such as 32x48, 16x16, 48x64... +/// +[Pipeline(typeof(WCSPipeline))] +public class FlagLikeVFX : TileVFX +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; + + public Vector2[,] Meshgrid; + + public Vector2 AnchorOffset = Vector2.zeroVector; + + public bool Flip_H = false; + + /// + /// This associate with the distort magnitude in wind push. + /// + public float Hardness = 1f; + + public void GenerateMeshgrid() + { + int width = Texture.Width / 16; + width += 1; + int height = Texture.Height / 16; + height += 1; + Meshgrid = new Vector2[width, height]; + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + Meshgrid[x, y] = new Vector2(x, y) * 16 + OriginTilePos.ToWorldCoordinates() + AnchorOffset; + } + } + } + + public override void Update() + { + if (Meshgrid == null || Meshgrid == default) + { + GenerateMeshgrid(); + } + for (int x = 0; x < Meshgrid.GetLength(0); x++) + { + for (int y = 0; y < Meshgrid.GetLength(1); y++) + { + Vector2 origPos = new Vector2(x, y) * 16 + OriginTilePos.ToWorldCoordinates() + AnchorOffset; + if (y > 0) + { + origPos.X = Meshgrid[x, y - 1].X; + Meshgrid[x, y].Y += MathF.Pow(Meshgrid.GetLength(1) - y, 2) * 0.006f; + } + Meshgrid[x, y] += GetWindPush(Meshgrid[x, y].X, Meshgrid[x, y].Y, Hardness); + Meshgrid[x, y] += (origPos - Meshgrid[x, y]) * 0.2f; + + if (y < Meshgrid.GetLength(1) - 1) + { + PushFrom(ref origPos, ref Meshgrid[x, y + 1]); + } + if (y > 0) + { + PushFrom(ref origPos, ref Meshgrid[x, y - 1]); + } + if (x < Meshgrid.GetLength(0) - 1) + { + PushFrom(ref origPos, ref Meshgrid[x + 1, y]); + } + if (x > 0) + { + PushFrom(ref origPos, ref Meshgrid[x - 1, y]); + } + } + } + base.Update(); + } + + public void PushFrom(ref Vector2 origPosition, ref Vector2 targetPos) + { + Vector2 totarget = targetPos - origPosition; + Vector2 force = totarget.NormalizeSafe() * (totarget.Length() - 16) * 1f; + origPosition += force; + targetPos -= force; + } + + public override void Draw() + { + if (Meshgrid == null || Meshgrid == default) + { + GenerateMeshgrid(); + } + List bars = new List(); + for (int x = 0; x < Meshgrid.GetLength(0) - 1; x++) + { + for (int y = 0; y < Meshgrid.GetLength(1) - 1; y++) + { + AddVertex(bars, x, y); + AddVertex(bars, x + 1, y); + AddVertex(bars, x, y + 1); + + AddVertex(bars, x, y + 1); + AddVertex(bars, x + 1, y); + AddVertex(bars, x + 1, y + 1); + } + } + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleList); + } + + public void AddVertex(List bars, int xIndex, int yIndex) + { + Vector2 position = Meshgrid[xIndex, yIndex]; + Vector2 texCoord = new Vector2(xIndex, yIndex) / Texture.Size() * 16; + if (Flip_H) + { + texCoord.X = 1 - texCoord.X; + } + bars.Add(position, Lighting.GetColor(position.ToTileCoordinates()), new Vector3(texCoord, 0)); + } + + public static Vector2 GetWindPush(Vector2 pos, float hardness) + { + return GetWindPush(pos.X, pos.Y, hardness); + } + + public static Vector2 GetWindPush(float x, float y, float hardness) + { + float noise = 0; + float timeValue = (float)Main.time * 0.08f; + + for (int i = 0; i < 8; i++) + { + noise += MathF.Sin((timeValue + x * 0.15f + i) * MathF.Pow(2, i)) * MathF.Pow(2, -i); + } + for (int j = 0; j < 8; j++) + { + noise += MathF.Sin((timeValue + y * 0.15f) + j * MathF.Pow(2, j)) * MathF.Pow(2, -j); + } + float pushX = noise * 1f * Main.windSpeedCurrent + Main.windSpeedCurrent * 4f; + if (Main.tile[new Vector2(x, y).ToTileCoordinates()].WallType > WallID.None) + { + pushX = 0f; + } + Vector2 addVel = Vector2.zeroVector; + foreach (var player in Main.player) + { + if (player is not null && player.active) + { + if (player.Hitbox.Contains(new Point((int)x, (int)y))) + { + addVel += player.velocity * 0.6f; + } + } + } + + return (new Vector2(pushX, 0) + addVel) * hardness; + } +} diff --git a/Sources/Everglow.Function/VFX/Scene/ForegroundVFX.cs b/Sources/Everglow.Function/VFX/Scene/ForegroundVFX.cs deleted file mode 100644 index 36c411703..000000000 --- a/Sources/Everglow.Function/VFX/Scene/ForegroundVFX.cs +++ /dev/null @@ -1,119 +0,0 @@ -using Everglow.Commons.Enums; -using Everglow.Commons.Vertex; -using Everglow.Commons.VFX.Pipelines; - -namespace Everglow.Commons.VFX.Scene; - -[Pipeline(typeof(WCSPipeline))] -public abstract class ForegroundVFX : Visual -{ - public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; - - public Vector2 position; - public Texture2D texture; - public Point originTile; - public int originType; - public int direction = 1; - public int OutScreenDistanceMax = 500; - - public override void OnSpawn() - { - } - - public override void Update() - { - if (originTile.X > 0 && originTile.X < Main.maxTilesX) - { - if (originTile.Y > 0 && originTile.Y < Main.maxTilesY) - { - Tile tile = Main.tile[originTile.X, originTile.Y]; - if (tile != null) - { - if (TileLoader.GetTile(tile.TileType) is ISceneTile) - { - if (tile.TileType == originType) - { - if (!tile.HasTile) - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - Vector2 checkPos = position; - if (VFXManager.InScreen(checkPos, OutScreenDistanceMax)) - { - Visible = true; - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - - public override void Draw() - { - Color lightColor0 = Lighting.GetColor((int)position.X / 16, (int)position.Y / 16); - Color lightColor1 = Lighting.GetColor((int)(position.X + texture.Width) / 16, (int)position.Y / 16); - Color lightColor2 = Lighting.GetColor((int)position.X / 16, (int)(position.Y + texture.Height) / 16); - Color lightColor3 = Lighting.GetColor((int)(position.X + texture.Width) / 16, (int)(position.Y + texture.Height) / 16); - - Ins.Batch.BindTexture(texture); - List bars = new List() - { - new Vertex2D(position, lightColor0, new Vector3(0, 0, 0)), - new Vertex2D(position + new Vector2(texture.Width, 0), lightColor1, new Vector3(1, 0, 0)), - - new Vertex2D(position + new Vector2(0, texture.Height), lightColor2, new Vector3(0, 1, 0)), - new Vertex2D(position + new Vector2(texture.Width, texture.Height), lightColor3, new Vector3(1, 1, 0)), - }; - if (direction < 0) - { - bars = new List() - { - new Vertex2D(position, lightColor0, new Vector3(1, 0, 0)), - new Vertex2D(position + new Vector2(texture.Width, 0), lightColor1, new Vector3(0, 0, 0)), - - new Vertex2D(position + new Vector2(0, texture.Height), lightColor2, new Vector3(1, 1, 0)), - new Vertex2D(position + new Vector2(texture.Width, texture.Height), lightColor3, new Vector3(0, 1, 0)), - }; - } - Ins.Batch.Draw(bars, PrimitiveType.TriangleStrip); - } -} diff --git a/Sources/Everglow.Function/VFX/Scene/SceneUtils.cs b/Sources/Everglow.Function/VFX/Scene/SceneUtils.cs new file mode 100644 index 000000000..028dddd1a --- /dev/null +++ b/Sources/Everglow.Function/VFX/Scene/SceneUtils.cs @@ -0,0 +1,126 @@ +using Everglow.Commons.Vertex; + +namespace Everglow.Commons.VFX.Scene; + +public class SceneUtils +{ + /// + /// Fill draw vertices that cover a tile.(TriangleList) + /// + /// + /// + /// + /// + /// + /// + public static void DrawTileCover(int i, int j, Texture2D texture, float startCoordX, float startCoordY, List bars, bool flipH, float colorFactors) + { + Vector2 drawPos0 = new Point(i, j).ToWorldCoordinates() - new Vector2(8); + Vector2 drawPos1 = drawPos0 + new Vector2(16, 0); + Vector2 drawPos2 = drawPos0 + new Vector2(0, 16); + Vector2 drawPos3 = drawPos0 + new Vector2(16, 16); + + Color light0 = Lighting.GetColor(drawPos0.ToTileCoordinates()) * colorFactors; + Color light1 = Lighting.GetColor(drawPos1.ToTileCoordinates()) * colorFactors; + Color light2 = Lighting.GetColor(drawPos2.ToTileCoordinates()) * colorFactors; + Color light3 = Lighting.GetColor(drawPos3.ToTileCoordinates()) * colorFactors; + + Vector2 size = new Vector2(16) / texture.Size(); + + float coordX0 = startCoordX; + float coordX1 = startCoordX + size.X; + if (flipH) + { + (coordX0, coordX1) = (coordX1, coordX0); + } + + bars.Add(drawPos0, light0, new Vector3(coordX0, startCoordY, 0)); + bars.Add(drawPos1, light1, new Vector3(coordX1, startCoordY, 0)); + bars.Add(drawPos3, light3, new Vector3(coordX1, startCoordY + size.Y, 0)); + + bars.Add(drawPos0, light0, new Vector3(coordX0, startCoordY, 0)); + bars.Add(drawPos3, light3, new Vector3(coordX1, startCoordY + size.Y, 0)); + bars.Add(drawPos2, light2, new Vector3(coordX0, startCoordY + size.Y, 0)); + } + + /// + /// Make sure the width and the height of the texture are the multiples of 16. + /// + /// + /// + /// + /// + public static void DrawMultiSceneTowardBottom(int i, int j, Texture2D texture, List bars, bool flipH, float colorFactors = 1) + { + for (int x = 0; x < texture.Width; x += 16) + { + for (int y = 0; y < texture.Height; y += 16) + { + if (flipH) + { + DrawTileCover(i - x / 16, j + y / 16, texture, x / (float)texture.Width, y / (float)texture.Height, bars, flipH, colorFactors); + } + else + { + DrawTileCover(i + x / 16, j + y / 16, texture, x / (float)texture.Width, y / (float)texture.Height, bars, flipH, colorFactors); + } + } + } + } + + //public static void DrawHangingFlagLike(Vector2 anchorPos, Texture2D texture, List bars, bool flipH, float colorFactors = 1) + //{ + // Vector2 halfSize = new Vector2(texture.Width * 0.5f, 0); + // for (int x = 0; x < texture.Width; x += 16) + // { + // for (int y = 0; y < texture.Height; y += 16) + // { + // if (x > texture.Width) + // { + // x = texture.Width; + // } + // if (y > texture.Height) + // { + // y = texture.Height; + // } + // DrawFlagLikeCover(anchorPos + new Vector2(x, y) - halfSize, texture, x / (float)texture.Width, y / (float)texture.Height, bars, false, colorFactors); + // } + // } + //} + + //public static void DrawFlagLikeCover(Vector2 worldPos, Texture2D texture, float startCoordX, float startCoordY, List bars, bool flipH, float colorFactors) + //{ + // Vector2 drawPos0 = worldPos - new Vector2(8); + // Vector2 drawPos1 = drawPos0 + new Vector2(16, 0); + // Vector2 drawPos2 = drawPos0 + new Vector2(0, 16); + // Vector2 drawPos3 = drawPos0 + new Vector2(16, 16); + + // Vector2 size = new Vector2(16) / texture.Size(); + // float weight0 = texture.Size().Y * (1 - startCoordY) / 16f; + // float weight1 = texture.Size().Y * (1 - (startCoordY + size.Y)) / 16f; + // drawPos0 += GetWindPushBalance(drawPos0, weight0); + // drawPos1 += GetWindPushBalance(drawPos1, weight0); + // drawPos2 += GetWindPushBalance(drawPos2, weight1); + // drawPos3 += GetWindPushBalance(drawPos3, weight1); + + // Color light0 = Lighting.GetColor(drawPos0.ToTileCoordinates()) * colorFactors; + // Color light1 = Lighting.GetColor(drawPos1.ToTileCoordinates()) * colorFactors; + // Color light2 = Lighting.GetColor(drawPos2.ToTileCoordinates()) * colorFactors; + // Color light3 = Lighting.GetColor(drawPos3.ToTileCoordinates()) * colorFactors; + + // float coordX0 = startCoordX; + // float coordX1 = startCoordX + size.X; + // if (flipH) + // { + // (coordX0, coordX1) = (coordX1, coordX0); + // } + + // bars.Add(drawPos0, light0, new Vector3(coordX0, startCoordY, 0)); + // bars.Add(drawPos1, light1, new Vector3(coordX1, startCoordY, 0)); + // bars.Add(drawPos3, light3, new Vector3(coordX1, startCoordY + size.Y, 0)); + + // bars.Add(drawPos0, light0, new Vector3(coordX0, startCoordY, 0)); + // bars.Add(drawPos3, light3, new Vector3(coordX1, startCoordY + size.Y, 0)); + // bars.Add(drawPos2, light2, new Vector3(coordX0, startCoordY + size.Y, 0)); + //} +} diff --git a/Sources/Everglow.Function/VFX/Scene/TileVFX.cs b/Sources/Everglow.Function/VFX/Scene/TileVFX.cs new file mode 100644 index 000000000..008e86864 --- /dev/null +++ b/Sources/Everglow.Function/VFX/Scene/TileVFX.cs @@ -0,0 +1,114 @@ +using Everglow.Commons.Enums; +using Everglow.Commons.Vertex; +using Everglow.Commons.VFX.Pipelines; + +namespace Everglow.Commons.VFX.Scene; + +[Pipeline(typeof(WCSPipeline))] +public abstract class TileVFX : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; + + public Vector2 Position; + public Texture2D Texture; + public Point OriginTilePos; + public int OriginTileType; + public int Direction = 1; + public float MaxDiatanceOutOfScreen = 500; + + public override void Update() + { + if (OriginTilePos.X > 0 && OriginTilePos.X < Main.maxTilesX) + { + if (OriginTilePos.Y > 0 && OriginTilePos.Y < Main.maxTilesY) + { + Tile tile = Main.tile[OriginTilePos.X, OriginTilePos.Y]; + if (tile != null) + { + if (TileLoader.GetTile(tile.TileType) is ISceneTile) + { + if (tile.TileType == OriginTileType) + { + if (!tile.HasTile) + { + Active = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; + return; + } + } + else + { + Active = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; + return; + } + } + else + { + Active = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; + return; + } + } + else + { + Active = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; + return; + } + } + else + { + Active = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; + return; + } + } + else + { + Active = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; + return; + } + Vector2 checkPos = Position; + if (VFXManager.InScreen(checkPos, MaxDiatanceOutOfScreen)) + { + Visible = true; + } + else + { + Active = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; + return; + } + } + + public override void Draw() + { + Color lightColor0 = Lighting.GetColor((int)Position.X / 16, (int)Position.Y / 16); + Color lightColor1 = Lighting.GetColor((int)(Position.X + Texture.Width) / 16, (int)Position.Y / 16); + Color lightColor2 = Lighting.GetColor((int)Position.X / 16, (int)(Position.Y + Texture.Height) / 16); + Color lightColor3 = Lighting.GetColor((int)(Position.X + Texture.Width) / 16, (int)(Position.Y + Texture.Height) / 16); + + List bars = new List() + { + new Vertex2D(Position, lightColor0, new Vector3(0, 0, 0)), + new Vertex2D(Position + new Vector2(Texture.Width, 0), lightColor1, new Vector3(1, 0, 0)), + + new Vertex2D(Position + new Vector2(0, Texture.Height), lightColor2, new Vector3(0, 1, 0)), + new Vertex2D(Position + new Vector2(Texture.Width, Texture.Height), lightColor3, new Vector3(1, 1, 0)), + }; + if (Direction < 0) + { + bars = new List() + { + new Vertex2D(Position, lightColor0, new Vector3(1, 0, 0)), + new Vertex2D(Position + new Vector2(Texture.Width, 0), lightColor1, new Vector3(0, 0, 0)), + + new Vertex2D(Position + new Vector2(0, Texture.Height), lightColor2, new Vector3(1, 1, 0)), + new Vertex2D(Position + new Vector2(Texture.Width, Texture.Height), lightColor3, new Vector3(0, 1, 0)), + }; + } + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleStrip); + } +} diff --git a/Sources/Everglow.Function/VFX/Scene/Tile_MirrorFaceVFX.cs b/Sources/Everglow.Function/VFX/Scene/Tile_MirrorFaceVFX.cs index 00aa57b81..c5827ec11 100644 --- a/Sources/Everglow.Function/VFX/Scene/Tile_MirrorFaceVFX.cs +++ b/Sources/Everglow.Function/VFX/Scene/Tile_MirrorFaceVFX.cs @@ -9,10 +9,10 @@ public abstract class Tile_MirrorFaceVFX : Visual { public override CodeLayer DrawLayer => CodeLayer.PostDrawProjectiles; - public Vector2 position; - public Texture2D texture; - public Point originTile; - public int originType; + public Vector2 Position; + public Texture2D Texture; + public Point OriginTilePos; + public int OriginTileType; public float DepthZ = -50; public override void OnSpawn() @@ -21,76 +21,76 @@ public override void OnSpawn() public override void Update() { - if (originTile.X > 0 && originTile.X < Main.maxTilesX) + if (OriginTilePos.X > 0 && OriginTilePos.X < Main.maxTilesX) { - if (originTile.Y > 0 && originTile.Y < Main.maxTilesY) + if (OriginTilePos.Y > 0 && OriginTilePos.Y < Main.maxTilesY) { - Tile tile = Main.tile[originTile.X, originTile.Y]; + Tile tile = Main.tile[OriginTilePos.X, OriginTilePos.Y]; if (tile != null) { if (TileLoader.GetTile(tile.TileType) is ISceneTile) { - if (tile.TileType == originType) + if (tile.TileType == OriginTileType) { if (!tile.HasTile) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; } - Vector2 checkPos = position + texture.Size() / 2; - if (VFXManager.InScreen(checkPos, Math.Max(texture.Width, texture.Height + 200))) + Vector2 checkPos = Position + Texture.Size() / 2; + if (VFXManager.InScreen(checkPos, Math.Max(Texture.Width, Texture.Height + 200))) { Visible = true; } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; } } public override void Draw() { Color color = Color.White; - Main.graphics.GraphicsDevice.Textures[1] = texture; + Main.graphics.GraphicsDevice.Textures[1] = Texture; float z = DepthZ; List bars = new List() { - new MirrorFaceVertex(new Vector3(position, z), color, new Vector3(0, 0, 0)), - new MirrorFaceVertex(new Vector3(position + new Vector2(texture.Width, 0), z), color, new Vector3(1, 0, 0)), + new MirrorFaceVertex(new Vector3(Position, z), color, new Vector3(0, 0, 0)), + new MirrorFaceVertex(new Vector3(Position + new Vector2(Texture.Width, 0), z), color, new Vector3(1, 0, 0)), - new MirrorFaceVertex(new Vector3(position + new Vector2(0, texture.Height), z), color, new Vector3(0, 1, 0)), - new MirrorFaceVertex(new Vector3(position + new Vector2(texture.Width, texture.Height), z), color, new Vector3(1, 1, 0)), + new MirrorFaceVertex(new Vector3(Position + new Vector2(0, Texture.Height), z), color, new Vector3(0, 1, 0)), + new MirrorFaceVertex(new Vector3(Position + new Vector2(Texture.Width, Texture.Height), z), color, new Vector3(1, 1, 0)), }; Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); } diff --git a/Sources/Everglow.UnitTests/Everglow.UnitTests.csproj b/Sources/Everglow.UnitTests/Everglow.UnitTests.csproj index 6cc1bcb03..793b67954 100644 --- a/Sources/Everglow.UnitTests/Everglow.UnitTests.csproj +++ b/Sources/Everglow.UnitTests/Everglow.UnitTests.csproj @@ -31,6 +31,8 @@ + + diff --git a/Sources/Everglow.UnitTests/Modules/Yggdrasil/Common/YggdrasilPlayerTests.cs b/Sources/Everglow.UnitTests/Modules/Yggdrasil/Common/YggdrasilPlayerTests.cs new file mode 100644 index 000000000..601cfa4e6 --- /dev/null +++ b/Sources/Everglow.UnitTests/Modules/Yggdrasil/Common/YggdrasilPlayerTests.cs @@ -0,0 +1,92 @@ +using System.Reflection; +using Everglow.Yggdrasil; +using Everglow.Yggdrasil.Common; +using SubworldLibrary; +using Terraria; +using Terraria.ModLoader; + +namespace Everglow.UnitTests.Modules.Yggdrasil.Common; + +[TestClass] +[DoNotParallelize] +public class YggdrasilPlayerTests +{ + private static readonly FieldInfo CurrentSubworldField = typeof(SubworldSystem).GetField("current", BindingFlags.NonPublic | BindingFlags.Static)!; + + private Subworld? originalSubworld; + private Player player = null!; + private YggdrasilPlayer modPlayer = null!; + + [TestInitialize] + public void Initialize() + { + Program.SavePath = string.Empty; + originalSubworld = (Subworld?)CurrentSubworldField.GetValue(null); + CurrentSubworldField.SetValue(null, null); + + player = new Player(); + modPlayer = (YggdrasilPlayer)new YggdrasilPlayer().NewInstance(player); + } + + [TestCleanup] + public void Cleanup() + { + CurrentSubworldField.SetValue(null, originalSubworld); + } + + [TestMethod] + public void ModifyMaxStats_InYggdrasil_ReplacesVanillaGrowthAndAddsPermanentBoosts() + { + player.ConsumedLifeCrystals = 15; + player.ConsumedLifeFruit = 20; + player.ConsumedManaCrystals = 9; + SetPermanentLifeBoosts(); + CurrentSubworldField.SetValue(null, new YggdrasilWorld()); + + modPlayer.ModifyMaxStats(out var health, out var mana); + + Assert.AreEqual(-237f, health.Base); + Assert.AreEqual(-144f, mana.Base); + Assert.AreEqual(263, (int)health.ApplyTo(500f)); + Assert.AreEqual(56, (int)mana.ApplyTo(200f)); + } + + [TestMethod] + public void ModifyMaxStats_OutsideYggdrasil_KeepsVanillaGrowthAndAddsPermanentBoosts() + { + player.ConsumedLifeCrystals = 15; + player.ConsumedLifeFruit = 20; + player.ConsumedManaCrystals = 9; + SetPermanentLifeBoosts(); + + modPlayer.ModifyMaxStats(out var health, out var mana); + + Assert.AreEqual(83f, health.Base); + Assert.AreEqual(0f, mana.Base); + Assert.AreEqual(583, (int)health.ApplyTo(500f)); + Assert.AreEqual(200, (int)mana.ApplyTo(200f)); + } + + [TestMethod] + public void ModifyMaxStats_ComposesAsBaseWithOtherModifiersRegardlessOfOrder() + { + player.ConsumedLifeCrystals = 1; + CurrentSubworldField.SetValue(null, new YggdrasilWorld()); + + modPlayer.ModifyMaxStats(out var health, out _); + var otherMod = new StatModifier(additive: 1.5f, multiplicative: 2f, flat: 7f, @base: 10f); + var yggdrasilFirst = health.CombineWith(otherMod); + var otherModFirst = otherMod.CombineWith(health); + + Assert.AreEqual(yggdrasilFirst, otherModFirst); + Assert.AreEqual(349, (int)yggdrasilFirst.ApplyTo(120f)); + } + + private void SetPermanentLifeBoosts() + { + modPlayer.ConsumedAntiHeavenSicknessPill = 5; + modPlayer.ConsumedJadeGlazeFruit = 2; + modPlayer.ConsumedSquamousCore = 1; + modPlayer.ConsumedLampBorerHoney = 3; + } +} diff --git a/Sources/Everglow/Localization/en-US/Mods.Everglow.Biomes.hjson b/Sources/Everglow/Localization/en-US/Mods.Everglow.Biomes.hjson index 93593950f..f83b10438 100644 --- a/Sources/Everglow/Localization/en-US/Mods.Everglow.Biomes.hjson +++ b/Sources/Everglow/Localization/en-US/Mods.Everglow.Biomes.hjson @@ -1,54 +1,54 @@ YggdrasilTownBiome: { DisplayName: Yggdrasil Town - TownNPCDialogueName: The Yggdrasil Town + TownNPCDialogueName: Yggdrasil Town } TuskBiome: { - DisplayName: Tusk Biome - TownNPCDialogueName: "" + DisplayName: Tusk Tableland + TownNPCDialogueName: the Tusk Tableland biome } TuskSurfaceBiome: { - DisplayName: Tusk Surface Biome - TownNPCDialogueName: "" + DisplayName: Surface Tusk Tuya + TownNPCDialogueName: the Surface Tusk Tableland biome } FireflyBiome: { - DisplayName: Firefly Biome - TownNPCDialogueName: "" + DisplayName: Everglowing Cocoon + TownNPCDialogueName: the Everglowing Cocoon } FurnaceAreaBiome: { - DisplayName: Furnace Area Biome - TownNPCDialogueName: "" + DisplayName: Yggdrasil Forge + TownNPCDialogueName: the Yggdrasil Forge } JellyBallHotbedBiome: { - DisplayName: Jelly Ball Hotbed Biome - TownNPCDialogueName: "" + DisplayName: Jellyball Hotbed + TownNPCDialogueName: the Jellyball Hotbed } LampWoodForest: { - DisplayName: Lamp Wood Forest - TownNPCDialogueName: "" + DisplayName: Lampwood Forest + TownNPCDialogueName: the Lampwood Forest biome } MidnightBayouBiome: { - DisplayName: Midnight Bayou Biome - TownNPCDialogueName: "" + DisplayName: Midnight Marsh + TownNPCDialogueName: the Midnight Marsh biome } TwilightForsetAndRelic: { - DisplayName: Twilight Forset And Relic - TownNPCDialogueName: "" + DisplayName: Twilight Forest + TownNPCDialogueName: the Twilight Forest biome } KelpCurtainBiome: { - DisplayName: Kelp Curtain Biome - TownNPCDialogueName: "" + DisplayName: Moss Mantle + TownNPCDialogueName: the Moss Mantle biome } HurricaneMazeBiome: { - DisplayName: Hurricane Maze Biome - TownNPCDialogueName: "" + DisplayName: Tempest Labyrinth + TownNPCDialogueName: the Tempest Labyrinth biome } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Biomes.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Biomes.hjson index df9c0ba5a..afd6d5e18 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Biomes.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Biomes.hjson @@ -4,51 +4,51 @@ YggdrasilTownBiome: { } TuskBiome: { - DisplayName: Tusk Biome - TownNPCDialogueName: "" + DisplayName: 颌骨å°åœ° + TownNPCDialogueName: 颌骨å°åœ° } TuskSurfaceBiome: { - DisplayName: Tusk Surface Biome - TownNPCDialogueName: "" + DisplayName: 颌骨å°åœ°åœ°é¢ + TownNPCDialogueName: 颌骨å°åœ°åœ°é¢ } FireflyBiome: { - DisplayName: Firefly Biome - TownNPCDialogueName: "" + DisplayName: æµè¤ä¹‹èŒ§ + TownNPCDialogueName: æµè¤ä¹‹èŒ§ } FurnaceAreaBiome: { - DisplayName: Furnace Area Biome - TownNPCDialogueName: "" + DisplayName: 天穹镇炉心区 + TownNPCDialogueName: 天穹镇炉心区 } JellyBallHotbedBiome: { - DisplayName: Jelly Ball Hotbed Biome - TownNPCDialogueName: "" + DisplayName: çƒå†»æ¸©åºŠ + TownNPCDialogueName: çƒå†»æ¸©åºŠ } LampWoodForest: { - DisplayName: Lamp Wood Forest - TownNPCDialogueName: "" + DisplayName: ç¯æœ¨æ£®æž— + TownNPCDialogueName: ç¯æœ¨æ£®æž— } MidnightBayouBiome: { - DisplayName: Midnight Bayou Biome - TownNPCDialogueName: "" + DisplayName: åˆå¤œæ²¼æ³½ + TownNPCDialogueName: åˆå¤œæ²¼æ³½ } TwilightForsetAndRelic: { - DisplayName: Twilight Forset And Relic - TownNPCDialogueName: "" + DisplayName: 暮光森林 + TownNPCDialogueName: 暮光森林 } KelpCurtainBiome: { - DisplayName: Kelp Curtain Biome - TownNPCDialogueName: "" + DisplayName: è‹è‹”帘幕 + TownNPCDialogueName: è‹è‹”帘幕 } HurricaneMazeBiome: { - DisplayName: Hurricane Maze Biome - TownNPCDialogueName: "" + DisplayName: 飓风迷宫 + TownNPCDialogueName: 飓风迷宫 } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Buffs.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Buffs.hjson index 4e0663b73..f338a7dc2 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Buffs.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Buffs.hjson @@ -1,983 +1,1460 @@ DevilHeartSetBuff: { DisplayName: 魔心过载 Description: - ''' - åœæ­¢è‡ªç„¶é­”力å†ç”Ÿå¹¶é™ä½Žé˜²å¾¡ - 但获得魔法伤害与暴击加æˆï¼ŒåŒæ—¶å¢žåŠ å¬å”¤æ  - ''' + ''' + åœæ­¢è‡ªç„¶é­”力å†ç”Ÿå¹¶é™ä½Žé˜²å¾¡ + 但获得魔法伤害与暴击加æˆï¼ŒåŒæ—¶å¢žåŠ å¬å”¤æ  + ''' } BloodSwordStrikeBuff: { - DisplayName: Blood Sword Strike Buff + DisplayName: 汲血剑 Description: "" } LifeRotten: { - DisplayName: Life Rotten + DisplayName: 生命è…化 Description: "" } BloodDrinking: { - DisplayName: Blood Drinking + DisplayName: 茹毛饮血 Description: "" } OnElectric: { - DisplayName: On Electric + DisplayName: 触电 Description: "" } StaminaEnergyBuff: { - DisplayName: Stamina Energy Buff - Description: "" + DisplayName: 能é‡é¥®æ–™ + Description: "使用刺剑时体力更多" } StarCrack: { - DisplayName: Star Crack + DisplayName: 裂星 Description: "" } AppleBuff: { - DisplayName: Apple Buff - Description: "" + DisplayName: 苹果 + Description: + ''' + 增加5%å‡ä¼¤!!! + 一天一苹果,医生远离我 + ''' } ApplePieBuff: { - DisplayName: Apple Pie Buff - Description: "" + DisplayName: 苹果派 + Description: + ''' + 加5%å‡ä¼¤,1生命回å¤!!! + 一天一苹果,医生远离我,苹果派也行 + ''' } ApricotBuff: { - DisplayName: Apricot Buff - Description: "" + DisplayName: æ + Description: + ''' + 增加4魔力å†ç”Ÿ!!! + 止渴润肺 + ''' } BaconBuff: { - DisplayName: Bacon Buff - Description: "" + DisplayName: 培根 + Description: + ''' + 加2生命回å¤ï¼Œæ‰€å—冷系伤害é™ä½Ž + ——法国人都是培根 + ''' } BananaBuff: { - DisplayName: Banana Buff - Description: "" + DisplayName: 香蕉 + Description: + ''' + 5%䏿¶ˆè€—å¼¹è¯ï¼Œå¢žåŠ 5%机枪类武器远程射速!!! + 低血压 + ''' } BananaSplitBuff: { - DisplayName: Banana Split Buff - Description: "" + DisplayName: 香蕉船 + Description: + ''' + 10%䏿¶ˆè€—å¼¹è¯ï¼Œå¢žåŠ 6%远程暴击!!! + 低血压 + ''' } BBQRibsBuff: { - DisplayName: BBQRibs Buff - Description: "" + DisplayName: 烧烤排骨 + Description: + ''' + 增加50最大生命值!!! + 滋阴补血 + ''' } BlackCurrantBuff: { - DisplayName: Black Currant Buff - Description: "" + DisplayName: 黑加仑 + Description: + ''' + 获得夜视ã€å±é™©æ„ŸçŸ¥èƒ½åŠ› + 改善视力 + ''' } BloodOrangeBuff: { - DisplayName: Blood Orange Buff - Description: "" + DisplayName: 血橙 + Description: + ''' + 增加25最大生命值!!! + è¿™é‡Œä¸æ˜¯å´½é¥¿ + ''' } BowlofSoupBuff: { - DisplayName: Bowlof Soup Buff - Description: "" + DisplayName: é±¼è‡æ±¤ + Description: + ''' + 增加40最大魔力值,5%魔法伤害 + 补脑 + ''' } BunnyStewBuff: { - DisplayName: Bunny Stew Buff - Description: "" + DisplayName: 炖兔兔 + Description: + ''' + 自动跳跃,æå‡è·³è·ƒèƒ½åŠ›!!!ï¼ + 没有任何兔å­åœ¨åˆ¶ä½œè¿‡ç¨‹ä¸­å—到伤害 + ''' } BurgerBuff: { - DisplayName: Burger Buff - Description: "" + DisplayName: 汉堡 + Description: + ''' + å‡å°‘移速,增加防御 + 热é‡ç‚¸å¼¹ + ''' } CherryBuff: { - DisplayName: Cherry Buff - Description: "" + DisplayName: 樱桃 + Description: + ''' + 死亡åŽäº§ç”Ÿçˆ†ç‚¸!!! + 你所热爱的,就是你的生活 + ''' } ChickenNuggetBuff: { - DisplayName: Chicken Nugget Buff - Description: "" + DisplayName: é¸¡å— + Description: + ''' + 增加1生命回å¤ã€4%攻速!!! + 数一数二的鸡å—ï¼ + ''' } ChocolateChipCookieBuff: { - DisplayName: Chocolate Chip Cookie Buff - Description: "" + DisplayName: 巧克力曲奇饼干 + Description: + ''' + 增加2点生命回å¤å’Œé­”åŠ›å›žå¤ + è¡¥å……èƒ½é‡ + ''' } ChristmasPuddingBuff: { - DisplayName: Christmas Pudding Buff - Description: "" + DisplayName: åœ£è¯žå¸ƒä¸ + Description: + ''' + 所有å¯å弹射弹多åå¼¹ä¸€æ¬¡ï¼ + Duang~Duang~Duang~ + ''' } CoconutBuff: { - DisplayName: Coconut Buff - Description: "" + DisplayName: æ¤°å­ + Description: + ''' + 增加4防御,3%å‡ä¼¤!!! + 我从å°å•ƒåˆ°å¤§ + ''' } CookedFishBuff: { - DisplayName: Cooked Fish Buff - Description: "" + DisplayName: 熟鱼 + Description: + ''' + 增加40魔力上é™,4%魔法暴击率!!! + 益气å¥è„¾ + ''' } CookedMarshmallowBuff: { - DisplayName: Cooked Marshmallow Buff - Description: "" + DisplayName: 熟棉花糖 + Description: + ''' + å‡å°‘75%最大掉è½é€Ÿåº¦,ä½†æ— æ³•æ“æŽ§ä¸‹è½é€Ÿåº¦!!! + 轻飘飘的 + ''' } CookedShrimpBuff: { - DisplayName: Cooked Shrimp Buff - Description: "" + DisplayName: 熟虾 + Description: + ''' + 增加10防御,4点盔甲穿é€!!! + 补钙 + ''' } DragonfruitBuff: { - DisplayName: Dragonfruit Buff - Description: "" + DisplayName: ç«é¾™æžœ + Description: + ''' + 攻击造æˆç€ç«ä»¥åŠæ¶‚æ²¹ + 红红ç«ç«æææƒšæƒš + ''' } ElderberryBuff: { - DisplayName: Elderberry Buff - Description: "" + DisplayName: 接骨木果 + Description: + ''' + ä½ å¯ä»¥çŸ­è·ç¦»å†²åˆº + 抗氧化 + ''' } EscargotBuff: { - DisplayName: Escargot Buff - Description: "" + DisplayName: 食用蜗牛 + Description: + ''' + 大大削弱移动力,增加50%å‡ä¼¤!!! + ç¥žé¾Ÿè¯æ°´? + ''' } FriedEggBuff: { - DisplayName: Fried Egg Buff - Description: "" + DisplayName: 煎蛋 + Description: + ''' + 增加6%伤害!!! + 蛋白质 + ''' } FriesBuff: { - DisplayName: Fries Buff - Description: "" + DisplayName: ç‚¸è–¯æ¡ + Description: + ''' + 加4防御,6%暴击!!! + é«˜æ²¹é«˜ç› + ''' } FroggleBunwichBuff: { - DisplayName: Froggle Bunwich Buff - Description: "" + DisplayName: 蛙腿三明治 + Description: + ''' + 自动跳跃,增加伤害,æå‡è·³è·ƒèƒ½åŠ›!!! + 你能真正å°åˆ°æ²¼æ³½çš„å‘³é“ + ''' } FruitSaladBuff: { - DisplayName: Fruit Salad Buff - Description: "" + DisplayName: 水果沙拉 + Description: + ''' + æå‡å¤§éƒ¨åˆ†å±žæ€§ + é•¿ä¹…çš„ç»´ç”Ÿç´ ï¼ + ''' } GingerbreadCookieBuff: { - DisplayName: Gingerbread Cookie Buff - Description: "" + DisplayName: 姜饼 + Description: + ''' + 增加2生命回å¤,ä¿æš–!!! + 驱寒排毒 + ''' } GoldenDelightBuff: { - DisplayName: Golden Delight Buff - Description: "" + DisplayName: 金美味 + Description: + ''' + 攻击造迈达斯,æå‡å¤§éƒ¨åˆ†å±žæ€§!!! + 金ç¿ç¿! + ''' } GrapefruitBuff: { - DisplayName: Grapefruit Buff - Description: "" + DisplayName: è‘¡è„æŸš + Description: + ''' + 加25%å¬å”¤ç‰©å‡»é€€!!! + æ‹’ç»è‚¾é€æ”¯ + ''' } GrapesBuff: { - DisplayName: Grapes Buff - Description: "" + DisplayName: è‘¡è„ + Description: + ''' + 增加1å¬å”¤æ ï¼Œå¹¸è¿å€¼åŠ 10%,å‡12防御!!! + 多å­å¤šç¦ + ''' } GrilledSquirrelBuff: { - DisplayName: Grilled Squirrel Buff - Description: "" + DisplayName: 烤æ¾é¼  + Description: + ''' + æå‡è·³è·ƒèƒ½åŠ› + 欢跃 + ''' } GrubSoupBuff: { - DisplayName: Grub Soup Buff - Description: "" + DisplayName: 蛆虫汤 + Description: + ''' + 增加30渔力,æ¯ç§’å‡2点生命!!! + åƒå•¥è¡¥å•¥ï¼Œå°±æ˜¯æœ‰ç‚¹æ¶å¿ƒ + ''' } HotdogBuff: { - DisplayName: Hotdog Buff - Description: "" + DisplayName: 热狗 + Description: + ''' + 增强短剑与长矛类武器!!! + å”~~ + ''' } IceCreamBuff: { - DisplayName: Ice Cream Buff - Description: "" + DisplayName: 冰淇淋 + Description: + ''' + å…ç–«ç€ç«å’Œç«å—!!! + åƒé›ªï¼ˆbushi + ''' } LemonBuff: { - DisplayName: Lemon Buff - Description: "" + DisplayName: 柠檬 + Description: + ''' + 增加4%远程暴击,仇æ¨å€¼å‡300 + 消炎美容 + ''' } LobsterTailBuff: { - DisplayName: Lobster Tail Buff - Description: "" + DisplayName: 龙虾尾 + Description: + ''' + 增加6防御,33%挖矿速度 + 壮阳 + ''' } MangoBuff: { - DisplayName: Mango Buff - Description: "" + DisplayName: 芒果 + Description: + ''' + å‡ç¼“因食物中毒而产生的æŒç»­å‡è¡€æ•ˆæžœ + 清胃解毒 + ''' } MarshmallowBuff: { - DisplayName: Marshmallow Buff - Description: "" + DisplayName: 棉花糖 + Description: + ''' + å¯ä»¥äºŒæ®µè·³ + åƒäº‘一样 + ''' } MonsterLasagnaBuff: { - DisplayName: Monster Lasagna Buff - Description: "" + DisplayName: 怪物åƒå±‚é¢ + Description: + ''' + 增加25%暴击率,但æ¯ç§’å‡3生命!!! + 弄熟的æ¶é­”还是æ¶é­”,在åƒå±‚饼中也ä¸ä¼šæ”¹å˜ + ''' } NachosBuff: { - DisplayName: Nachos Buff - Description: "" + DisplayName: 玉米片 + Description: + ''' + 爆炸类射弹爆炸范围增加ï¼ï¼ + 爆米花 + ''' } PadThaiBuff: { - DisplayName: Pad Thai Buff - Description: "" + DisplayName: æ³°å¼ç‚’é¢ + Description: + ''' + 增加50%å¬å”¤ç‰©å‡»é€€ + 异域风情 + ''' } PeachBuff: { - DisplayName: Peach Buff - Description: "" + DisplayName: æ¡ƒå­ + Description: + ''' + 增加心的拾å–范围,1ç”Ÿå‘½å›žå¤ + 在想peach + ''' } PhoBuff: { - DisplayName: Pho Buff - Description: "" + DisplayName: è¶Šå—æ²³ç²‰ + Description: + ''' + 增加8%å¬å”¤ç‰©ä¼¤å®³!!! + 异域风情 + ''' } PineappleBuff: { - DisplayName: Pineapple Buff - Description: "" + DisplayName: è è + Description: + ''' + 近战攻击者伤害玩家时会承å—一åŠä¼¤å®³!!! + è è碱 + ''' } PizzaBuff: { - DisplayName: Pizza Buff - Description: "" + DisplayName: æŠ«è¨ + Description: + ''' + 增加10点盔甲穿é€!!! + 会让æ„大利人破防的è èæŠ«è¨ + ''' } PlumBuff: { - DisplayName: Plum Buff - Description: "" + DisplayName: æŽå­ + Description: + ''' + 增加600仇æ¨å€¼ï¼Œ8%攻速!!! + 至于我的建议,还是å†ç­‰ç­‰å§! + ''' } PotatoChipsBuff: { - DisplayName: Potato Chips Buff - Description: "" + DisplayName: 薯片 + Description: + ''' + 增加4防御,8%伤害!!! + é«˜æ²¹é«˜ç› + ''' } PumpkinPieBuff: { - DisplayName: Pumpkin Pie Buff - Description: "" + DisplayName: å—瓜派 + Description: + ''' + 增加50最大生命值!!! + 丰收的喜悦 + ''' } RambutanBuff: { - DisplayName: Rambutan Buff - Description: "" + DisplayName: 红毛丹 + Description: + ''' + å…疫许多å‡ç›Š!!! + æé«˜å…ç–« + ''' } RoastedBirdBuff: { - DisplayName: Roasted Bird Buff - Description: "" + DisplayName: 烤鸟 + Description: + ''' + æå‡é£žè¡Œèƒ½åŠ›!!! + 我是一åªå°å°å°é¸Ÿ + ''' } RoastedDuckBuff: { - DisplayName: Roasted Duck Buff - Description: "" + DisplayName: 烤鸭 + Description: + ''' + å¯ä»¥åœ¨æ°´ä¸Šè¡Œèµ°ï¼Œæå‡é£žè¡Œèƒ½åŠ›!!! + 这是烤鸭 + ''' } SashimiBuff: { - DisplayName: Sashimi Buff - Description: "" + DisplayName: 生鱼片 + Description: + ''' + å¯ä»¥æ¸¸æ³³ï¼Œæ°´ä¸‹å‘¼å¸ï¼Œå¢žåŠ 15%伤害,但æ¯ç§’å‡å°‘2点生命!!! + å¯„ç”Ÿè™«ï¼ + ''' } SauteedFrogLegsBuff: { - DisplayName: Sauteed Frog Legs Buff - Description: "" + DisplayName: 炒蛙腿 + Description: + ''' + 自动跳跃,æå‡è·³è·ƒèƒ½åŠ›!!! + é’“ä¸åˆ°è›™è…¿ï¼Ÿé‚£å°±åƒå§ã€‚ + ''' } SeafoodDinnerBuff: { - DisplayName: Seafood Dinner Buff - Description: "" + DisplayName: æµ·é²œå¤§é¤ + Description: + ''' + 增加8%暴击,伤害,攻速,爆伤!!! + å¤Ÿç”ŸçŒ›ï¼ + ''' } ShrimpPoBoyBuff: { - DisplayName: Shrimp Po Boy Buff - Description: "" + DisplayName: 鲜虾三明治 + Description: + ''' + 增加6防御,25%挖矿速度 + 壮阳 + ''' } ShuckedOysterBuff: { - DisplayName: Shucked Oyster Buff - Description: "" + DisplayName: 去壳牡蛎 + Description: + ''' + å‡å°‘5防御,加10点盔甲穿é€ï¼Œæ¯ç§’å‡å°‘3点生命!!! + å¯„ç”Ÿè™«ï¼ + ''' } SpaghettiBuff: { - DisplayName: Spaghetti Buff - Description: "" + DisplayName: æ„å¤§åˆ©é¢ + Description: + ''' + 增加1哨兵æ !!! + 异域风情 + ''' } StarfruitBuff: { - DisplayName: Starfruit Buff - Description: "" + DisplayName: æ¨æ¡ƒ + Description: + ''' + 使用霰弹枪类武器时会多射出一å‘å­å¼¹ + 1437大å¸çš„æ·«å¨ + ''' } SteakBuff: { - DisplayName: Steak Buff - Description: "" + DisplayName: 牛排 + Description: + ''' + å‡å°‘20%魔力消耗!!! + ä¸Šæµ + ''' } SugarCookieBuff: { - DisplayName: Sugar Cookie Buff - Description: "" + DisplayName: 蜜糖饼干 + Description: + ''' + 增加5%远程伤害!!! + 养胃滋润 + ''' } AleBuff: { - DisplayName: Ale Buff - Description: "" + DisplayName: 麦芽酒 + Description: + ''' + 短时间内鞭å­çš„范围和速度æå‡è‡³1.5å€!!! + è€é…’ç–¯ + ''' } AppleJuiceBuff: { - DisplayName: Apple Juice Buff - Description: "" + DisplayName: è‹¹æžœæ± + Description: + ''' + 短时间内增加60%å‡ä¼¤!!! + 一天一苹果,医生远离我 + ''' } BananaDaiquiriBuff: { - DisplayName: Banana Daiquiri Buff - Description: "" + DisplayName: 冰冻香蕉代基里 + Description: + ''' + çŸ­æ—¶é—´å†…ä¸æ¶ˆè€—å­å¼¹ï¼Œå¤§å¹…增加远程伤害与暴击 + 低体温血压 + ''' } BloodyMoscatoBuff: { - DisplayName: Bloody Moscato Buff - Description: "" + DisplayName: 血腥éºé¦™è‘¡è„ + Description: + ''' + çŸ­æ—¶é—´å†…æ¯æ¬¡æ”»å‡»å›ž1点生命!!! + 血色 + ''' } CoffeeCupBuff: { - DisplayName: Coffee Cup Buff - Description: "" + DisplayName: å’–å•¡ + Description: + ''' + 短时间内大幅增加铺墙铺砖速度,高亮标记敌人ã€é™·é˜±å’Œå®è—,并散å‘光芒!!! + 社畜的å®ç‰© + ''' } CreamSodaBuff: { - DisplayName: Cream Soda Buff - Description: "" + DisplayName: å¥¶æ²¹è‹æ‰“æ°´ + Description: + ''' + 短时间内大幅增加近战能力,但æžå…¶å¸å¼•ä»‡æ¨ + å–·å°„ï¼ + ''' } FruitJuiceBuff: { - DisplayName: Fruit Juice Buff - Description: "" + DisplayName: æžœæ± + Description: + ''' + 短时间内幅大大æå‡å¤§éƒ¨åˆ†å±žæ€§ + ç»´ç”Ÿç´ ï¼ + ''' } GrapeJuiceBuff: { - DisplayName: Grape Juice Buff - Description: "" + DisplayName: è‘¡è„æ± + Description: + ''' + 短时间你å˜å¾—æžå…¶å¹¸è¿ + æµ“ç¼©çš„å¹¸ç¦ + ''' } LemonadeBuff: { - DisplayName: Lemonade Buff - Description: "" + DisplayName: 柠檬水 + Description: + ''' + 短时间内远程击退加å€,仇æ¨å€¼å‡2400 + 消炎美容 + ''' } MilkCartonBuff: { - DisplayName: Milk Carton Buff - Description: "" + DisplayName: 盒装牛奶 + Description: + ''' + 短时间内å…疫几乎所有debuff + 一奶解百毒 + ''' } MilkshakeBuff: { - DisplayName: Milkshake Buff - Description: "" + DisplayName: 奶昔 + Description: + ''' + 短时间内大幅加移速 + 节食å‡è‚¥ + ''' } PeachSangriaBuff: { - DisplayName: Peach Sangria Buff - Description: "" + DisplayName: æ¡ƒå­æžœé…’ + Description: + ''' + 短时间内大幅回å¤ç”Ÿå‘½ï¼Œå¢žåŠ å¿ƒçš„æ‹¾å–范围 + 我也是桃饱用户 + ''' } PinaColadaBuff: { - DisplayName: Pina Colada Buff - Description: "" + DisplayName: 椰林飘香 + Description: + ''' + 短时间内近战攻击者伤害玩家时会承å—10å€ï¼ˆä¸Šé™1000)伤害!!! + ä»Žä¸æ·»åŠ é¦™ç²¾å½“ç”Ÿæ¦¨ + ''' } PrismaticPunchBuff: { - DisplayName: Prismatic Punch Buff - Description: "" + DisplayName: 七彩潘趣酒 + Description: + ''' + 短时间内增加5å¬å”¤æ ï¼Œ5哨兵æ ï¼Œå¢žåŠ 50%å¬å”¤ä¼¤å®³ï¼Œå‡»é€€!!! + 高雅兴致 + ''' } SakeBuff: { - DisplayName: Sake Buff - Description: "" + DisplayName: 清酒 + Description: + ''' + 短时间内å‡å°‘18防御,大幅增加近战能力!!! + 纯度,太高了 + ''' } SmoothieofDarknessBuff: { - DisplayName: Smoothieof Darkness Buff - Description: "" + DisplayName: 暗黑奶昔 + Description: + ''' + 短时间内有60%çš„æ¦‚çŽ‡é—ªé¿æ”»å‡»!!! + è…¹é»‘ï¼ˆå­—é¢æ„义上) + ''' } TeacupBuff: { - DisplayName: Teacup Buff - Description: "" + DisplayName: 一æ¯èŒ¶ + Description: + ''' + 短时间内大幅增加魔力回å¤ï¼Œé­”法伤害,暴击!!! + 醇香四溢 + ''' } TropicalSmoothieBuff: { - DisplayName: Tropical Smoothie Buff - Description: "" + DisplayName: 热带奶昔 + Description: + ''' + 短时间内魔法攻击仅消耗一点魔力,大幅增加魔法伤害,暴击!!! + 热带风暴 + ''' } ArcticshellfishWarshipBuff: { - DisplayName: Arcticshellfish Warship Buff - Description: "" + DisplayName: 北æžè´å†›èˆ° + Description: + ''' + æå‡4防御 + 美味的北æžè´å†›èˆ° + ''' } BakedMusselBuff: { - DisplayName: Baked Mussel Buff - Description: "" + DisplayName: 炭烧é’å£è´ + Description: + ''' + 增加6%爆伤ã€4防御 + 似乎没那么生猛了 + ''' } BakedOysterBuff: { - DisplayName: Baked Oyster Buff - Description: "" + DisplayName: ç‚­çƒ§ç”Ÿèš + Description: + ''' + 增加4点盔甲穿é€ã€4防御 + è€é…’ç–¯ + ''' } CantaloupeJellyBuff: { - DisplayName: Cantaloupe Jelly Buff - Description: "" + DisplayName: 哈密瓜果冻 + Description: + ''' + å°„å¼¹å¯ä»¥å¤šç©¿é€ä¸€æ¬¡ + duang~duang~duang~ + ''' } CaramelPuddingBuff: { - DisplayName: Caramel Pudding Buff - Description: "" + DisplayName: ç„¦ç³–å¸ƒä¸ + Description: + ''' + å°„å¼¹å¯ä»¥å¤šå弹一次 + duang~duang~duang~ + ''' } CrabseedWarshipBuff: { - DisplayName: Crabseed Warship Buff - Description: "" + DisplayName: 蟹籽军舰 + Description: + ''' + æå‡æš´å‡»çއ + 美味的蟹籽军舰 + ''' } DurianBuff: { - DisplayName: Durian Buff - Description: "" + DisplayName: 榴莲 + Description: + ''' + 加快消化食物的速度 + 促进消化 + ''' } EggTartBuff: { - DisplayName: Egg Tart Buff - Description: "" + DisplayName: 蛋挞 + Description: + ''' + 增加5%暴击伤害 + 这酥皮ä¸é”™ + ''' } KiwiFruitBuff: { - DisplayName: Kiwi Fruit Buff - Description: "" + DisplayName: 猕猴桃 + Description: + ''' + 增大20%æ­¦å™¨å¤§å° + åˆç§°å¥‡å¼‚æžœ + ''' } KiwiIceCreamBuff: { - DisplayName: Kiwi Ice Cream Buff - Description: "" + DisplayName: 猕猴桃冰激凌 + Description: + ''' + 增大10%武器大å°ï¼ŒåŠ å¿«æ­¦å™¨æ”»é€Ÿ + å¥‡å¼‚çš„åŠ›é‡ + ''' } MangosteenBuff: { - DisplayName: Mangosteen Buff - Description: "" + DisplayName: 山竹 + Description: + ''' + æå‡å›žæ—‹é•–,悠悠çƒã€é“¾æž·ç±»æ­¦å™¨è·ç¦» + 补养之效 + ''' } MapoTofuBuff: { - DisplayName: Mapo Tofu Buff - Description: "" + DisplayName: éº»å©†è±†è… + Description: + ''' + TODO + ''' } OrangeIcecreamBuff: { - DisplayName: Orange Icecream Buff - Description: "" + DisplayName: 香橙冰激凌 + Description: + ''' + 延长无敌帧时间 + 真实存于心中 + ''' } SalmonInPepperBuff: { - DisplayName: Salmon In Pepper Buff - Description: "" + DisplayName: 椒ç›ä¸‰æ–‡é±¼ + Description: + ''' + æå‡é€Ÿåº¦,尤其是在水中 + 冰海之皇 + ''' } SalmonWarshipBuff: { - DisplayName: Salmon Warship Buff - Description: "" + DisplayName: 三文鱼军舰 + Description: + ''' + æå‡é€Ÿåº¦ + 美味的三文鱼军舰 + ''' } SeafoodPizzaBuff: { - DisplayName: Seafood Pizza Buff - Description: "" + DisplayName: æµ·é²œæŠ«è¨ + Description: + ''' + æå‡å¤§éƒ¨åˆ†å±žæ€§ + 一个人åƒå®Œè¿™ä¸ªå¯ä¸å®¹æ˜“ + ''' } StinkyTofuBuff: { - DisplayName: Stinky Tofu Buff - Description: "" + DisplayName: è‡­è±†è… + Description: + ''' + 使é è¿‘的敌怪混乱 + åˆé¦™åˆè‡­ + ''' } StrawberryBuff: { DisplayName: Strawberry Buff - Description: "" + Description: + ''' + 敌怪越近,造æˆçš„伤害越高 + å—人欢迎的水果 + ''' } StrawberryIcecreamBuff: { - DisplayName: Strawberry Icecream Buff - Description: "" + DisplayName: è‰èŽ“å†°æ¿€å‡Œ + Description: + ''' + 敌怪越近,造æˆçš„伤害越高 + å†°å†·å¦‚ä½ ï¼Œä¾æ—§ä»¤äººçˆ±ä¸å¿é‡Š + ''' } SweetshrimpSushiBuff: { - DisplayName: Sweetshrimp Sushi Buff - Description: "" + DisplayName: ç”œè™¾å¯¿å¸ + Description: + ''' + æå‡æ”»å‡» + ç¾Žå‘³çš„ç”œè™¾å¯¿å¸ + ''' } TamakoSushiBuff: { - DisplayName: Tamako Sushi Buff - Description: "" + DisplayName: 玉å­å¯¿å¸ + Description: + ''' + æå‡ç”Ÿå‘½å›žå¤ + 美味的玉å­å¯¿å¸ + ''' } WakameWarshipBuff: { - DisplayName: Wakame Warship Buff - Description: "" + DisplayName: 裙带èœå¯¿å¸ + Description: + ''' + æå‡é­”åŠ›å›žå¤ + 美味的裙带èœå¯¿å¸ + ''' } WatermelonBuff: { - DisplayName: Watermelon Buff - Description: "" + DisplayName: 西瓜 + Description: + ''' + 增强8%击退能力 + 最大的打击力度 + ''' } WatermelonPlateBuff: { - DisplayName: Watermelon Plate Buff - Description: "" + DisplayName: 西瓜拼盘 + Description: + ''' + æå‡6%暴击率和暴击伤害 + 朴实无åŽçš„æ‘†ç›˜ + ''' } BlueHawaiiBuff: { - DisplayName: Blue Hawaii Buff - Description: "" + DisplayName: è“色å¤å¨å¤· + Description: + ''' + 短时间内射弹速度获得æå‡ + æµ·é£Žå¹æ‹‚ + ''' } B_52Buff: { - DisplayName: B_52 Buff - Description: "" + DisplayName: B_52 + Description: + ''' + 短时间内大幅æå‡å‘å°„å™¨é€Ÿåº¦ã€æš´å‡»ã€ä¼¤å®³ + 轰炸机 + ''' } DreamYearningBuff: { - DisplayName: Dream Yearning Buff - Description: "" + DisplayName: 梦里人 + Description: + ''' + 短时间内射弹速度获得æå‡ + æ€å›å¿†å›ï¼Œé­‚牵梦è¦ï¼Œç¿ é”€é¦™æš–云å±ï¼Œæ›´å“ªå ªé…’醒 + ''' } DryMartiniBuff: { - DisplayName: Dry Martini Buff - Description: "" + DisplayName: 干马天尼 + Description: + ''' + 短时间大幅æå‡æ”»å‡» + ç»å…¸ä¹‹ä½œ + ''' } GreenStormBuff: { - DisplayName: Green Storm Buff - Description: "" + DisplayName: 绿å¶é£Žæš´ + Description: + ''' + 短时间交替射出å¶ç»¿æ°´æ™¶å’Œå­¢å­äº‘ + 别以为è‰ä¾¿å®œ,没上规模å‰,它比苹果核桃什么的都贵 + ''' } KiwiJuiceBuff: { - DisplayName: Kiwi Juice Buff - Description: "" + DisplayName: çŒ•çŒ´æ¡ƒæ± + Description: + ''' + çŸ­æ—¶é—´å†…å¤§å¹…å¢žå¤§æ­¦å™¨å¤§å° + 浓缩的奇异之力 + ''' } LonelyJellyfishBuff: { - DisplayName: Lonely Jellyfish Buff - Description: "" + DisplayName: å­¤ç‹¬çš„æ°´æ¯ + Description: + ''' + çŸ­æ—¶é—´å†…ä¸æ–­äºŽé¼ æ ‡å¤„ç”Ÿæˆæ°´æ¯ç”µåœˆï¼Œå¹¶ä¸”获得éšèº«èƒ½åŠ› + è§‚èµå®Œå°±ä¸€é¥®è€Œå°½å§ + ''' } OrangeJuiceBuff: { - DisplayName: Orange Juice Buff - Description: "" + DisplayName: æ©™æ± + Description: + ''' + 短时间内获得超长无敌帧 + 嗯,有点åƒLCL + ''' } PiercoldWindBuff: { - DisplayName: Piercold Wind Buff - Description: "" + DisplayName: ç²¾çµè²ä»• + Description: + ''' + 对ç¯ç¬¼æœˆæ•Œæ€ªç‰¹æ”» + 长啸出原野,凛然寒风生 + ''' } PurpleHooterBuff: { - DisplayName: Purple Hooter Buff - Description: "" + DisplayName: æ¢¦å¹»èŽ«å‰æ‰˜ + Description: + ''' + 对血月敌怪特攻 + 高贵与深沉 + ''' } QuinceMarryBuff: { - DisplayName: Quince Marry Buff - Description: "" + DisplayName: 血腥玛丽 + Description: + ''' + 对å—瓜月敌怪特攻 + 炙热与温柔 + ''' } RedWineBuff: { - DisplayName: Red Wine Buff - Description: "" + DisplayName: 红酒 + Description: + ''' + 对霜月敌怪特攻 + 上æµä¸Žä¼˜é›… + ''' } SunriseBuff: { - DisplayName: Sunrise Buff - Description: "" + DisplayName: 龙舌兰日出 + Description: + ''' + 对日食敌怪特攻 + 阳光与明媚 + ''' } TricolourBuff: { - DisplayName: Tricolour Buff - Description: "" + DisplayName: 环游世界 + Description: + ''' + å¯¹è€æ€ªä»†ä»Žç‰¹æ”» + 夿‚与专一 + ''' } WaterMelonJuiceBuff: { - DisplayName: Water Melon Juice Buff - Description: "" + DisplayName: è¥¿ç“œæ± + Description: + ''' + 短时间大幅增加击退与暴击 + 浓缩的打击力度 + ''' } ShortImmune12: { - DisplayName: Short Immune12 + DisplayName: 更短的无敌帧 Description: "" } ShortImmune3: { - DisplayName: Short Immune3 + DisplayName: 更短的无敌帧 Description: "" } ElementalResistanceReductionDebuffTest: { - DisplayName: Elemental Resistance Reduction Debuff Test + DisplayName: 元素抗性é™ä½Ž Description: "" } Petrification: { - DisplayName: Petrification + DisplayName: 石化 Description: "" } TuskCursed: { - DisplayName: Tusk Cursed + DisplayName: ç ç‰™çš„诅咒 Description: "" } TuskStaff: { - DisplayName: Tusk Staff - Description: "" + DisplayName: ç ç‰™æ³•æ– + Description: "飞ç ç‰™ä¸ºä½ è€Œæˆ˜" } FireflyInferno: { - DisplayName: Firefly Inferno + DisplayName: è¤ç«çƒˆç„° Description: "" } GlowMothBuff: { - DisplayName: Glow Moth Buff + DisplayName: 夜光飞蛾 Description: "" } OnMoth: { - DisplayName: On Moth + DisplayName: 被幻è¶è¤ç«æ‰‡æ ‡è®° Description: "" } ShadowPotionBuff: { - DisplayName: Shadow Potion Buff - Description: "" + DisplayName: æš—å½±è¯æ°´ + Description: "在暗处æå‡åŸºç¡€å±žæ€§" } Freeze: { - DisplayName: Freeze + DisplayName: 冰冻 Description: "" } LaserWormBuff: { - DisplayName: Laser Worm Buff + DisplayName: 激光虫 Description: "" } ShadowSupervisor: { - DisplayName: Shadow Supervisor + DisplayName: 暗夜观察者 Description: "" } MoonAndFragrans: { - DisplayName: Moon And Fragrans + DisplayName: 月夜æµèг Description: "" } MoonAndFragransII: { - DisplayName: Moon And FragransII + DisplayName: 月夜æµèг2 Description: "" } MoonAndFragransIII: { - DisplayName: Moon And FragransIII + DisplayName: 月夜æµèг3 Description: "" } BlueImmune: { - DisplayName: Blue Immune + DisplayName: å…ç–«è“ç« Description: "" } BrownImmune: { - DisplayName: Brown Immune + DisplayName: å…ç–«æ£•ç« Description: "" } GreenImmune: { - DisplayName: Green Immune + DisplayName: å…ç–«ç»¿ç« Description: "" } PinkImmune: { - DisplayName: Pink Immune + DisplayName: å…ç–«ç²‰ç« Description: "" } PurpleImmune: { - DisplayName: Purple Immune + DisplayName: å…ç–«ç´«ç« Description: "" } RedImmune: { - DisplayName: Red Immune + DisplayName: å…ç–«çº¢ç« Description: "" } WhiteImmune: { - DisplayName: White Immune + DisplayName: å…ç–«ç™½ç« Description: "" } YellowImmune: { - DisplayName: Yellow Immune + DisplayName: å…ç–«é»„ç« Description: "" } AcytaeaInferno: { - DisplayName: Acytaea Inferno + DisplayName: é›…æ–¯å¡”äºšçš„çƒˆç« Description: "" } CactusBallBuff: { - DisplayName: Cactus Ball Buff + DisplayName: ä»™äººæŽŒçƒ Description: "" } WaterBoltII: { - DisplayName: Water BoltII + DisplayName: æ°´ç®­II Description: "" } AmberStick: { - DisplayName: Amber Stick + DisplayName: 黿€§ç¥ç€ Description: "" } Armor15Cracked: { - DisplayName: Armor15 Cracked - Description: "" + DisplayName: 盔甲碎裂 + Description: "防御力é™ä½Ž15" } AuburnBell: { - DisplayName: Auburn Bell - Description: "" + DisplayName: 金棕铃铛 + Description: "金棕飞æ£ä¸ºä½ è€Œæˆ˜" } AuburnSelfReinforcing: { - DisplayName: Auburn Self Reinforcing - Description: "" + DisplayName: 金棕之力 + Description: "生命缓慢枯èŽä»¥æ¢å–+1å¬å”¤æ ä½" } BloodCultistBuff: { - DisplayName: Blood Cultist Buff - Description: "" + DisplayName: 血月教徒的ç¥ç¦ + Description: "生命缓慢回å¤" } Charred: { - DisplayName: Charred - Description: "" + DisplayName: 焚烧 + Description: "大幅é™ä½Žé˜²å¾¡å¹¶ä¸”生命高速æµå¤±" } CrossHair: { - DisplayName: Cross Hair + DisplayName: 头å‘äº¤å‰ Description: "" } CyanVineRingCrit: { - DisplayName: Cyan Vine Ring Crit - Description: "" + DisplayName: é’缎指环的ç¥ç¦ + Description: "暴击+4%" } DeadBeetleEggBuff: { - DisplayName: Dead Beetle Egg Buff - Description: "" + DisplayName: æ­»ç”²è™«åµ + Description: "å¤ç”Ÿçš„甲虫骨骼为你而战" } EvilMusicRemnant: { - DisplayName: Evil Music Remnant - Description: "" + DisplayName: 魔律残章 + Description: "ä½ å¥å“了远å¤é—è½çš„ä¹è°±" } GuideBuff: { - DisplayName: Guide Buff - Description: "" + DisplayName: 引领 + Description: "å‘出光芒" } HasHitByResistenceWireBayonet: { - DisplayName: Has Hit By Resistence Wire Bayonet + DisplayName: 被电阻刺剑命中 Description: "" } HexaCrystalWeak: { - DisplayName: Hexa Crystal Weak - Description: "" + DisplayName: 暮晶脆弱 + Description: "é­å—所有附带暮光晶体的攻击时å—到更多伤害" } IstafelsSunfireGraspFireBallBuff: { - DisplayName: Istafels Sunfire Grasp Fire Ball Buff - Description: "" + DisplayName: 伊斯塔裴尔的阳炎ç«çƒ + Description: "é€ æˆæ³•术伤害å¯ä»¥ç»™å®ƒå……能" } IstafelsSunfireGraspSkillBuff: { - DisplayName: Istafels Sunfire Grasp Skill Buff + DisplayName: 伊斯塔裴尔的阳炎战技 Description: "" } JellyBallStick: { - DisplayName: Jelly Ball Stick - Description: "" + DisplayName: é™·å…¥çƒå†» + Description: "速度大幅下é™" } MeltingSideGyroscopeBuff: { - DisplayName: Melting Side Gyroscope Buff - Description: "" + DisplayName: 熔边陀螺 + Description: "ç”¨éž­å­æŠ½æ‰“é™€èžºå¯ä»¥å……能" } Photolysis: { - DisplayName: Photolysis - Description: "" + DisplayName: 光解 + Description: "暴露在光线下会燃烧血液" } Plague: { - DisplayName: Plague + DisplayName: 瘟疫 Description: "" } RayBuff: { - DisplayName: Ray Buff + DisplayName: 射线 Description: "" } RustSlingshotBuffOne: { - DisplayName: Rust Slingshot Buff One + DisplayName: 锈弹弓 Description: "" } RustSlingshotBuffTwo: { - DisplayName: Rust Slingshot Buff Two + DisplayName: 锈弹弓2 Description: "" } RustSlingshotBuffThree: { - DisplayName: Rust Slingshot Buff Three + DisplayName: 锈弹弓3 Description: "" } SpritialDamage: { - DisplayName: Spritial Damage + DisplayName: 精神æŸä¼¤ Description: "" } YggdrasilStoneGyroscopeBuff: { - DisplayName: Yggdrasil Stone Gyroscope Buff - Description: "" + DisplayName: 天穹岩陀螺 + Description: "ç”¨éž­å­æŠ½æ‰“é™€èžºå¯ä»¥å……能" } BadrBuff: { - DisplayName: Badr Buff - Description: "" + DisplayName: å·´å¾·å°” + Description: "点亮å‰è¡Œçš„è·¯" } LampWoodSeedBuff: { - DisplayName: Lamp Wood Seed Buff - Description: "" + DisplayName: ç¯æœ¨ç§å­ + Description: "未å‘芽的光" } JellyBubbleMount: { - DisplayName: Jelly Bubble Mount - Description: "" + DisplayName: çƒå†»æ³¡æ³¡å骑 + Description: "ä¸ç¨³å®šæµ®ç©º" } CorrosiveDebuff: { - DisplayName: Corrosive Debuff - Description: "" + DisplayName: 侵蚀 + Description: "移速和防御下é™" } DevilHeartGyroscopeBuff: { - DisplayName: Devil Heart Gyroscope Buff - Description: "" + DisplayName: 魔心陀螺 + Description: "ç”¨éž­å­æŠ½æ‰“é™€èžºå¯ä»¥å……能" } DevilHeartWeaponBuff: { - DisplayName: Devil Heart Weapon Buff + DisplayName: 魔心武器ç¥ç¦ Description: "" } FractureDebuff: { - DisplayName: Fracture Debuff - Description: "" + DisplayName: 破绽 + Description: "å—伤时é¢å¤–å—到50%的伤害" } HardenedSkinBuff: { - DisplayName: Hardened Skin Buff - Description: "" + DisplayName: 硬化皮肤 + Description: "å—到伤害下é™90%" } LegumeGyroscopeBuff: { - DisplayName: Legume Gyroscope Buff - Description: "" + DisplayName: 裂èšé™€èžº + Description: "ç”¨éž­å­æŠ½æ‰“é™€èžºå¯ä»¥å……能" } LichenInfected: { - DisplayName: Lichen Infected - Description: "" + DisplayName: çœŸèŒæ„ŸæŸ“ + Description: "è¿™äº›ä¸œè¥¿ä¼šé€šè¿‡æ´»ç‰©ç¹æ®–" } LivingWoodplateBuff: { - DisplayName: Living Woodplate Buff - Description: "" + DisplayName: 活木甲 + Description: "增加防御,弄湿åŽè¿›ä¸€æ­¥å¼ºåŒ–效果且æ¢å¤ç”Ÿå‘½" } MolluscsSetBuff: { - DisplayName: Molluscs Set Buff - Description: "" + DisplayName: 软体的特性 + Description: + ''' + 获得水下呼å¸ï¼Œæ°´ä¸‹åŠ é€Ÿæ•ˆæžœ + æ ¹æ®å¤´ç›”ä¸åŒï¼ŒèŽ·å¾—ä»¥ä¸‹æ•ˆæžœ + çç è½¯ä½“: +2生命å†ç”Ÿï¼Œ+10%近战攻速 + 附苔软体: +15%æ¦‚çŽ‡ä¸æ¶ˆè€—å¼¹è¯ï¼Œ+3ç›”ç”²ç©¿é€ + ''' } MossCover: { - DisplayName: Moss Cover - Description: "" + DisplayName: 苔藓皮层 + Description: "防御+5å¹¶å…疫侵蚀" } RuinSetBuff: { - DisplayName: Ruin Set Buff - Description: "" + DisplayName: é—迹ç¥ç¦ + Description: "+25%移速和10%å¬å”¤ä¼¤å®³" } TheGreenSolarBuff: { - DisplayName: The Green Solar Buff - Description: "" + DisplayName: 绿阳之石 + Description: "你处于涅槃状æ€ï¼Œä¸ä¼šæ­»äº¡ä¸”ç¼ä¼¤é™„近敌人" } WitherbarkSetBuff: { - DisplayName: Witherbark Set Buff - Description: "" + DisplayName: 枯木的ç¥ç¦ + Description: "+3å¬å”¤æ ä½†æ˜¯å¬å”¤ä¼¤å®³-30%,枯木护å«ä¸ºä½ è€Œæˆ˜" } WoodlandWraithStaffBuff: { - DisplayName: Woodland Wraith Staff Buff - Description: "" + DisplayName: æ£®å®‡å¹½é­‚çš„é½¿èŒ + Description: "飞行的血齿èŒä¸ºä½ è€Œæˆ˜" } WoodlandWraithStaffMyceliumBuff: { - DisplayName: Woodland Wraith Staff Mycelium Buff - Description: "" + DisplayName: 森宇幽魂的èŒä¸ + Description: "缓慢回å¤ç”Ÿå‘½ï¼Œåœ¨å­¢å­äº‘区域中效果增强" } DeathFlame: { - DisplayName: Death Flame - Description: "" + DisplayName: æ­»ç¥žçƒˆç« + Description: "è¶ŠæŽ¥è¿‘æ­»äº¡è¶Šææƒ§æ­»äº¡" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Accessories.Wings.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Accessories.Wings.hjson index e34ed64ac..e27142fcd 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Accessories.Wings.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Accessories.Wings.hjson @@ -1,4 +1,4 @@ BlueyWings: { - DisplayName: Bluey Wings + DisplayName: è“æ²³ä¹‹ç¿¼ Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Accessories.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Accessories.hjson index 1287f8159..aeddeb15a 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Accessories.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Accessories.hjson @@ -1,404 +1,617 @@ StaminaItem: { - DisplayName: Stamina Item - Tooltip: "" + DisplayName: è€åŠ›æµ‹è¯•ç‰©å“ + Tooltip: "å¼€å‘者物å“" } EnergyBand: { - DisplayName: Energy Band - Tooltip: "" + DisplayName: 能é‡ç»·å¸¦ + Tooltip: "å‡å°‘25%体力消耗" } BloodGlucoseMonitor: { - DisplayName: Blood Glucose Monitor - Tooltip: "" + DisplayName: 血糖仪 + Tooltip: "显示饥饿值" } OsmoticPressureMonitor: { - DisplayName: Osmotic Pressure Monitor - Tooltip: "" + DisplayName: 渗é€åŽ‹æµ‹å®šä»ª + Tooltip: "显示渴度" } PlayerPenetrationTest: { - DisplayName: Player Penetration Test - Tooltip: "" + DisplayName: çŽ©å®¶ç©¿é€æµ‹è¯•ç‰©å“ + Tooltip: "å¼€å‘者物å“" } BurningFrozenHeart: { - DisplayName: Burning Frozen Heart - Tooltip: "" + DisplayName: 霜ç«ä¹‹å¿ƒ + Tooltip: "å…疫多数冷系伤害并å‘出霜ç«çš„å…‰" } PearlOfCyan: { - DisplayName: Pearl Of Cyan - Tooltip: "" + DisplayName: æ¾æ™¯çƒ + Tooltip: "暴击时附加4魔法伤害的æ¾é’ˆå助攻击" } SnowPineLockBox: { - DisplayName: Snow Pine Lock Box - Tooltip: "" + DisplayName: 有æ¾é¦™çš„é“ç›’ + Tooltip: "å¬å”¤æ¾æ ‘之çµå助作战" } TuskLace: { - DisplayName: Tusk Lace - Tooltip: "" + DisplayName: ç ç‰™é¡¹é“¾ + Tooltip: + ''' + 盔甲穿é€å¢žåŠ 5\n伤害和暴击增加5% + 一颗ç ç‰™è¢«ä»ŽçŒ›å…½å˜´é‡Œæ‰“了下æ¥,ä½ åˆæ•²ä¸‹äº†ä¸Šé¢çš„一å°éƒ¨åˆ† + ''' } FireflyBorageBadge: { - DisplayName: Firefly Borage Badge - Tooltip: "" + DisplayName: æµè¤é»‘花胸章 + Tooltip: "伤害+6%,速度+15%ï¼Œè…æª€å·¨è›¾å­˜åœ¨æ—¶æœ‰ç‰¹æ®Šæ•ˆæžœ" } MothEye: { - DisplayName: Moth Eye - Tooltip: "" + DisplayName: 蛾眼 + Tooltip: "å¬å”¤ä¼¤å®³+6%,å¬å”¤æ ä½+1,哨兵æ ä½+1,对æµè¤ç³»åˆ—武器有特殊效果" } BlueflowerBra: { - DisplayName: Blueflower Bra + DisplayName: è“花黑内衣 Tooltip: "" } BlueflowerCap: { - DisplayName: Blueflower Cap + DisplayName: è“花黑阔边帽 Tooltip: "" } BlueGel: { - DisplayName: Blue Gel - Tooltip: "" + DisplayName: è“æ˜Ÿå‡èƒ¶ + Tooltip: "+4魔力回å¤å’Œ30魔法上é™" } CorruptEye: { - DisplayName: Corrupt Eye - Tooltip: "" + DisplayName: è…化之眼 + Tooltip: "防御+5,伤害+4%,å…ç–«å’’ç«ï¼Œå—击åŽè¿¸å‘出若干咒ç«çƒ" } DukeTooth: { - DisplayName: Duke Tooth - Tooltip: "" + DisplayName: 猪龙鱼ç ç‰™åŠå  + Tooltip: "+12盔甲穿é€" } GoldLiquidPupil: { - DisplayName: Gold Liquid Pupil - Tooltip: "" + DisplayName: çµæ¶²çž³å­” + Tooltip: "å—击åŽç”Ÿæˆçµæ¶²ä¹‹çޝ" } GreenGel: { - DisplayName: Green Gel - Tooltip: "" + DisplayName: 绿心å‡èƒ¶ + Tooltip: "+4生命回å¤å’Œ30生命上é™" } JungleVitamin: { - DisplayName: Jungle Vitamin - Tooltip: "" + DisplayName: 丛林维生素 + Tooltip: "+50生命上é™" } Odd8Ring: { - DisplayName: Odd8 Ring - Tooltip: "" + DisplayName: 诡8指环 + Tooltip: "啿¬¡é€ æˆçš„æœ€ä½Žä¼¤å®³å˜ä¸º8" } RedGel: { - DisplayName: Red Gel - Tooltip: "" + DisplayName: 红尖å‡èƒ¶ + Tooltip: "暴击率+6%,暴击伤害+9%" } SilverWing: { - DisplayName: Silver Wing - Tooltip: "" + DisplayName: 银翼è¯ç«  + Tooltip: "暴击伤害+8%,3ç§’ä¸ä½¿ç”¨æ­¦å™¨åŽä¼¤å®³+40%" } WalnutClip: { - DisplayName: Walnut Clip - Tooltip: "" + DisplayName: èƒ¡æ¡ƒå¤¹å­ + Tooltip: "暴击伤害+16%ï¼Œç”Ÿå‘½å€¼ä½ŽäºŽä¸€åŠæ—¶å¢žåŠ æ‰€æœ‰ä¼¤å®³ï¼Œç”Ÿå‘½å€¼è¶Šä½Žå¹…åº¦è¶Šå¤§" } BlueTorchFlower: { - DisplayName: Blue Torch Flower - Tooltip: "" + DisplayName: ç¿ è“冰炬 + Tooltip: + ''' + 增加20é­”åŠ›ä¸Šé™ + 命中敌人回å¤2魔力,有0.2ç§’å†·å´ + 'ç«ç‚¬èŠ±çš„ä¸€ä¸ªå˜ç§' + ''' } CyanBranch: { - DisplayName: Cyan Branch - Tooltip: "" + DisplayName: 一æŸå¤©é’ + Tooltip: + ''' + å—击åŽ10秒增加8é—ªé¿èƒ½åŠ› + '它å分åšç¡¬ï¼Œä½†ä¹Ÿå¾ˆè„†å¼±' + ''' } CyanPedal: { - DisplayName: Cyan Pedal - Tooltip: "" + DisplayName: 四瓣ç‰ç’ƒ + Tooltip: + ''' + é—ªé¿èƒ½åŠ›å¢žåŠ 4 + '少的那一瓣化作你的勇气' + ''' } DarkHat: { - DisplayName: Dark Hat - Tooltip: "" + DisplayName: 罂粟花å é¥° + Tooltip: + ''' + 增加20é­”åŠ›ä¸Šé™ + 暴击率增加4%,暴击伤害增加12 + '除用于战斗和装饰ä¸å»ºè®®ä½¿ç”¨' + ''' } GoldRound: { - DisplayName: Gold Round - Tooltip: "" + DisplayName: 金ç›è½®ç›˜ + Tooltip: + ''' + +7防御,+7%伤害 + 'ä¼ ç»Ÿçš„æ³°æ‹‰äººé€šå¸¸é…æˆ´å®ƒæ¥ä¿æŒå¥åº·' + ''' } HotPinkCrown: { - DisplayName: Hot Pink Crown - Tooltip: "" + DisplayName: 活化éƒé‡‘香 + Tooltip: + ''' + 暴击伤害增加(最大生命值*5%)% + 'ç»è¿‡é£Žä¹‹ç²¾åŽçš„催化,它将对生命力åšå‡ºå应' + ''' } LightPurplePen: { - DisplayName: Light Purple Pen - Tooltip: "" + DisplayName: 紫豪中山兔 + Tooltip: + ''' + ä¼¤å®³ã€æš´å‡»çŽ‡å’Œè¿‘æˆ˜æ”»é€Ÿå„增加7% + '没有任何兔å­åœ¨åˆ¶ä½œè¿‡ç¨‹ä¸­å—到伤害' + ''' } ManyWhiteFlower: { - DisplayName: Many White Flower - Tooltip: "" + DisplayName: ç™½æ˜Ÿé”¦çƒ + Tooltip: + ''' + 近战攻速增加8%,近战伤害增加8% + '你䏿ƒ³è®©è¿™äº›ç¥žå¥‡åˆå¯çˆ±çš„花被æŸå' + ''' } OrangeCrown: { - DisplayName: Orange Crown - Tooltip: "" + DisplayName: åšéŸ§éƒé‡‘香 + Tooltip: + ''' + 防御力+(最大生命值*3%)% + '埃俄罗斯ç¥ç¦è¿‡çš„éƒé‡‘香,结构强度出奇的高' + ''' } OrangeStick: { - DisplayName: Orange Stick - Tooltip: "" + DisplayName: åšæ©™ç‹¼å°¾ + Tooltip: + ''' + å—击åŽ3秒获得5防御力和击退å…ç–« + '与大多数è‰ä¸åŒ,å®ƒåœ¨ç‹‚é£Žä¸­åšæŒºè€Œä¸æŠ˜è…°' + ''' } PinkFourPedal: { - DisplayName: Pink Four Pedal - Tooltip: "" + DisplayName: 四命轮回 + Tooltip: + ''' + 最大生命值增加40 + 'æ®è¯´å—伤的动物会去åƒå®ƒæ¥ç–—伤...事实确实如此,但好åƒå¯¹äººæ•ˆæžœä¸å¤§' + ''' } PurpleBall: { - DisplayName: Purple Ball - Tooltip: "" + DisplayName: 紫绣çƒåŠå  + Tooltip: + ''' + 命中身周的敌人会释放紫色花瓣爆炸 + èŠ±ç“£ä¼¤å®³éšæ”»å‡»çš„伤害增加 + 有0.5ç§’å†·å´ + '愤怒紫绣çƒ' + ''' } PurpleReedHalo: { - DisplayName: Purple Reed Halo - Tooltip: "" + DisplayName: 紫苇花冠 + Tooltip: + ''' + 生命上é™å¢žåŠ 30 + 魔力上é™å¢žåŠ 40 + '好闻åˆå¥½çœ‹' + ''' } RedTriangle: { - DisplayName: Red Triangle - Tooltip: "" + DisplayName: ä¸‰å°–çº¢ç‹ + Tooltip: + ''' + 暴击伤害增加18% + '在泰拉文化中,这是一ç§å…·æœ‰æ”»å‡»æ€§çš„形状' + ''' } SilverCupFlower: { - DisplayName: Silver Cup Flower - Tooltip: "" + DisplayName: çš‡å®¶é…’æ¯ + Tooltip: + ''' + +8防御 + 生命上é™å¢žåŠ 20 + 'æ›¾æœ‰ä¸€ä½æ®‹æš´çš„国王真的å°è¯•拿它当酒æ¯,他一滴也没å–上' + ''' } ThreeColorCrown: { - DisplayName: Three Color Crown - Tooltip: "" + DisplayName: 三色花环 + Tooltip: + ''' + 击中敌人åŽéšæœºèŽ·å¾—ä»¥ä¸‹ä¸‰ç§æ•ˆæžœä¹‹ä¸€,æŒç»­7ç§’ + 红:伤害增加22%,暴击率增加11% + ç´«:å…ç–«ç»å¤§å¤šæ•°å‡ç›Šæ•ˆæžœ + 魔力上é™å¢žåŠ 300 + 有30ç§’CD + '求别太幸è¿' + ''' } WhiteCrown: { - DisplayName: White Crown - Tooltip: "" + DisplayName: 希望之花 + Tooltip: + ''' + 奔跑速度增加(生命上é™*0.2%) + '一æžç´ ç™½çš„éƒé‡‘香,åƒåœ¨æ‚¼å¿µ...' + ''' } WhitePedal: { - DisplayName: White Pedal - Tooltip: "" + DisplayName: 光纱之瓣 + Tooltip: + ''' + é—ªé¿èƒ½åŠ›å¢žåŠ 2 + 暴击率增加4% + '它是如此轻薄' + ''' } WhiteWoodFlower: { - DisplayName: White Wood Flower - Tooltip: "" + DisplayName: 银耳花 + Tooltip: + ''' + å¬å”¤æ ä½å¢žåŠ 2 + '奇妙的共生关系' + ''' } YellowBellFlower: { - DisplayName: Yellow Bell Flower - Tooltip: "" + DisplayName: 金簇铃兰 + Tooltip: + ''' + 伤害增加(20%防御力)% + '稀有åˆå¥½çœ‹' + ''' } CrystalSkull: { - DisplayName: Crystal Skull - Tooltip: "" + DisplayName: 水晶颅骨 + Tooltip: + ''' + 让你完全ç†è§£é­”法书中所记载的法术,它强大得令人胆寒 + '以å‰çš„ç”¨æ³•å°±åƒæ‹¿æžªæ†å­å½“æ£æ£’敲人' + ''' } AnemoShell: { - DisplayName: Anemo Shell - Tooltip: "" + DisplayName: 气元素防撞壳 + Tooltip: + ''' + é­åˆ°è·Œè½ä¼¤å®³ä¹‹å‰ï¼Œå°†çީ家ç¨ç¨å¼¹èµ·ï¼ŒæŠµæ¶ˆæ­¤æ¬¡ä¼¤å®³ + 此效果冷å´60ç§’ + ''' } BloodTearCrystalCrown: { - DisplayName: Blood Tear Crystal Crown - Tooltip: "" + DisplayName: 滴血泪石冠 + Tooltip: + ''' + 生命上é™+60 + 生命值>84%æ—¶é¢å¤–增加1ç”Ÿå‘½å›žå¤ + ''' } CelesteStoneWaistPendant: { - DisplayName: Celeste Stone Waist Pendant - Tooltip: "" + DisplayName: å¤©è“æ™¶çŸ³æŒ‚å  + Tooltip: + ''' + 法力上é™+30 + 法力值处于40%~60%时增加2é­”æ³•å›žå¤ + ''' } CelticSeal: { - DisplayName: Celtic Seal - Tooltip: "" + DisplayName: 凯尔特å°å° + Tooltip: "æ¯å—到3次超过6点的伤害获得15点治疗" } ConcealSpell: { - DisplayName: Conceal Spell - Tooltip: "" + DisplayName: éšåŒ¿ç¬¦ç®“ + Tooltip: + ''' + 陿­¢æ—¶æ¯å¸§å……能1点,移动时0.05 + 能é‡è¾¾åˆ°600时获得"éšåŒ¿",éšå½¢ä¸”å…疫下一次攻击 + 但是å—击åŽèƒ½é‡æ¸…é›¶ + ''' } CyanVineRing: { - DisplayName: Cyan Vine Ring - Tooltip: "" + DisplayName: å¤é’缎指环 + Tooltip: "暴击率+4%,å—到伤害åŽ1秒内若造æˆä¼¤å®³åˆ™å†+4%,æŒç»­15ç§’" } ForsakenBoots: { - DisplayName: Forsaken Boots - Tooltip: "" + DisplayName: 失è½ä¹‹é´ + Tooltip: + ''' + 8%移速æå‡ + å…许玩家奔跑 + ''' } FragmentsOfWreckage: { - DisplayName: Fragments Of Wreckage - Tooltip: "" + DisplayName: 残骸碎片 + Tooltip: + ''' + å½“ç”Ÿå‘½å€¼ä¸æ»¡æ—¶ï¼Œæ ¹æ®æŸå¤±çš„生命值æé«˜å±žæ€§ï¼ŒæŸå¤±400生命时达到最大效果,最大效果如下 + +10% 近战速度 + +10% 伤害 + +12 防御 + +15% 挖矿速度 + ''' } FuneraryGoods: { - DisplayName: Funerary Goods - Tooltip: "" + DisplayName: é™ªè‘¬å“ + Tooltip: "å‡»æ€æ•Œäººæ—¶ï¼Œ1/8概率立刻æ¢å¤100魔力" } FurnaceIronGloves: { - DisplayName: Furnace Iron Gloves - Tooltip: "" + DisplayName: ç†”ç‚‰é“æ‰‹å¥— + Tooltip: "法术伤害附带5%伤害的浊燃æŸä¼¤" } IstafelsSunfireGrasp: { - DisplayName: Istafels Sunfire Grasp - Tooltip: "" + DisplayName: ä¼Šæ–¯å¡”è£´å°”çš„ç‚Žé˜³ä¹‹æ¡ + Tooltip: + ''' + +11%魔法伤害 + +5%暴击率 + 法术伤害附带5%伤害的浊燃æŸä¼¤ + 攻击有概率创造一个熔渣ç«çƒæ¼‚浮于玩家身边,法术攻击å¯ä¸ºç†”渣蓄能 + 达到一定储能的熔渣将自动射出ç«çƒæ”»å‡» + 当计é‡è¡¨è“„力完æˆåŽä¸‹ä¸€æ¬¡æ”»å‡»å°†æŽ·å‡ºè¿¸å‘的熔渣,造æˆå¤šæ®µçš„25无视防御与å‡ä¼¤çš„真实伤害,并造æˆ16秒“烧焦â€debuff。 + 冷崿—¶é—´150s + *烧焦:造æˆ18dps伤害并å‡å°‘目标11%防御,ä¸ä½ŽäºŽ0 + 传说技能:按下<å¿«æ·é”®>叿”¶é™„近所有的浊燃æŸä¼¤ï¼Œç«‹åˆ»ç»“算所有伤害并对被å‡ç›Šçš„目标伤害æå‡è‡³150%。æŒç»­20s, + boss战期间åªèƒ½ä½¿ç”¨ä¸€æ¬¡ + ''' } JellyBallInhibitor: { - DisplayName: Jelly Ball Inhibitor - Tooltip: "" + DisplayName: çƒå†»æŠ‘制剂 + Tooltip: "玩家对çƒå†»æ•Œäººé€ æˆçš„伤害æé«˜60%,å—到çƒå†»ç±»æ•Œäººçš„æŽ¥è§¦ä¼¤å®³é™ä½Žä¸º75%" } LampWoodPollenBottle: { - DisplayName: Lamp Wood Pollen Bottle - Tooltip: "" + DisplayName: ç¯æœ¨èŠ±ç²‰ç“¶ + Tooltip: "å…许三段跳,åŒç±»é¥°å“å¯å åŠ " } ManaThermalPipeline: { - DisplayName: Mana Thermal Pipeline - Tooltip: "" + DisplayName: 奥术热能管线 + Tooltip: "+5%魔法伤害,+4魔力å†ç”Ÿ" } RecoveryBand: { - DisplayName: Recovery Band - Tooltip: "" + DisplayName: æ¢å¤æ‰‹çޝ + Tooltip: "å—到ä¸ä½ŽäºŽ5ç‚¹çš„ä¼¤å®³æ—¶ï¼ŒåŒæ—¶æ¢å¤å°‘é‡ç”Ÿå‘½å€¼å’Œé­”力值" } RingOfMatter: { - DisplayName: Ring Of Matter - Tooltip: "" + DisplayName: 物质戒指 + Tooltip: + ''' + 装备时,根æ®çŽ©å®¶è£…å¤‡çž¬é—´æ‹¥æœ‰çš„é’±å¸æ•°é‡åŸºäºŽæ•ˆæžœï¼š + æé«˜ä¼¤å®³ï¼Œæé«˜é˜²å¾¡åŠ›ï¼Œä½†æ˜¯ç”Ÿå‘½ä¸Šé™å‡å°‘ + 钱越多效果越强,5é“‚é‡‘è¾¾åˆ°ä¸Šé™ + ''' } ShacklesBall: { - DisplayName: Shackles Ball - Tooltip: "" + DisplayName: 带çƒè„šé•£ + Tooltip: + ''' + 增加10%伤害å‡å…,但是速度ã€è·³è·ƒé€Ÿåº¦å‡å°‘15%,跳跃高度é™ä½Ž7%ï¼› + å…疫缓慢 + ''' } SkullCollection: { - DisplayName: Skull Collection - Tooltip: "" + DisplayName: å¤´éª¨æ”¶è— + Tooltip: "玩家近身存在敌怪时,玩家获得魔力å†ç”Ÿ" } SpicyShield: { - DisplayName: Spicy Shield - Tooltip: "" + DisplayName: 尖刺盾牌 + Tooltip: + ''' + 防御+4 + 伤害+4% + å—到伤害åŽèŽ·å¾—30ç§’çš„è†æ£˜æ•ˆæžœ + ''' } TelescopicPlatformAlpha: { - DisplayName: Telescopic Platform Alpha - Tooltip: "" + DisplayName: 伸缩平å°Î± + Tooltip: "åœ¨åœ°é¢æŒ‰Wå…许å‡èµ·ï¼Œå‡èµ·åŽæŒ‰S下é™ï¼Œä¸æ“ä½œä¿æŒæ‚¬åœã€‚最大高度15æ ¼" } TelescopicPlatformBeta: { - DisplayName: Telescopic Platform Beta - Tooltip: "" + DisplayName: 伸缩平å°Î² + Tooltip: "åœ¨åœ°é¢æŒ‰Wå…许å‡èµ·ï¼Œå‡èµ·åŽæŒ‰S下é™ï¼Œä¸æ“ä½œä¿æŒæ‚¬åœã€‚最大高度45æ ¼" } HeatEmblem: { - DisplayName: Heat Emblem - Tooltip: "" + DisplayName: 热能勋章 + Tooltip: + ''' + +2生命å†ç”Ÿ + 但是å—到伤害时,获得“ç€ç«äº†â€5ç§’ + ''' } HotAirBalloon: { - DisplayName: Hot Air Balloon - Tooltip: "" + DisplayName: çƒ­æ°”çƒ + Tooltip: "增加跳跃高度,ç«ç„°ç²’å­å°¾è¿¹" } MelterGear: { - DisplayName: Melter Gear - Tooltip: "" + DisplayName: 热熔齿轮 + Tooltip: "造æˆä¼¤å®³æ—¶ï¼Œå¯¹ç”Ÿç‰©é€ æˆâ€œç€ç«äº†â€5秒,但在攻击带有“ç€ç«äº†â€çš„生物时,有33%的概率对自己造æˆâ€œç‡ƒçƒ§â€5秒,在æˆåŠŸè§¦å‘åŽè€…åŽï¼Œè¿›å…¥å†·å´15ç§’" } MoltenCore: { - DisplayName: Molten Core - Tooltip: "" + DisplayName: ç†”ç«æ ¸å¿ƒ + Tooltip: + ''' + 当玩家处于“ç€ç«äº†â€ã€â€œç‡ƒçƒ§â€ã€â€œè¯…å’’ç„°â€çš„æ•ˆæžœçŠ¶æ€æ—¶ + æé«˜5%伤害å‡å…ã€5防御ã€5%暴击ã€5%伤害ã€5%速度ã€5%跳跃速度 + ''' } ThermalConductor: { - DisplayName: Thermal Conductor - Tooltip: "" + DisplayName: 热能传导器 + Tooltip: "æ¯60帧会进行一次判断,若玩家的魔力ä¸é«˜äºŽæœ€å¤§é­”力的20%,有33%的概率对玩家造æˆâ€œè¯…å’’ç„°â€3ç§’å¹¶æ¢å¤100魔力值" } AntiCorrosiveSole: { - DisplayName: Anti Corrosive Sole - Tooltip: "" + DisplayName: 抗è…蚀鞋底 + Tooltip: + ''' + +5%移速 + å…ç–«è…蚀 + ''' } CorrodedPearl: { - DisplayName: Corroded Pearl - Tooltip: "" + DisplayName: 被è…蚀的çç  + Tooltip: + ''' + å»¶é•¿æ°´ä¸‹å‘¼å¸æ—¶é—´50% + å°å¹…度æå‡åœ¨æ°´ä¸­çš„移动速度 + +5%å¬å”¤ä¼¤å®³ + ''' } EmptyFowlbeast: { - DisplayName: Empty Fowlbeast - Tooltip: "" + DisplayName: 空羽兽 + Tooltip: + ''' + +1仆从数é‡ï¼Œä»†ä»Žå¯é¢å¤–造æˆç­‰åŒäºŽçŽ©å®¶æœ€å¤§é­”æ³•å€¼7%的魔法伤害 + 玩家é¢å¤–å—到20%伤害 + ''' } ForestMino: { - DisplayName: Forest Mino - Tooltip: "" + DisplayName: 森之蓑衣 + Tooltip: + ''' + 4防御 + 在è‹è‹”帘幕时移动速度+25%,且敌人更难å‘现你 + ''' } GuppyShell: { - DisplayName: Guppy Shell - Tooltip: "" + DisplayName: 格普螺外壳 + Tooltip: + ''' + 2防御 + 站立ä¸åŠ¨æ—¶,获得10%å‡ä¼¤ï¼Œ+5%伤害,-5%移速 + ''' } HardenedWitherbarkHeart: { - DisplayName: Hardened Witherbark Heart - Tooltip: "" + DisplayName: ç¡¬åŒ–æž¯æœ¨å¿ƒè„ + Tooltip: + ''' + 10防御 + -40%冲刺速度,-10%移速 + 给予硬化皮肤增益,使得å—到的第一次伤害-90%,但是在å—击åŽï¼Œç»™äºˆ10秒破绽效果,é¢å¤–å—到50%伤害 + 破绽效果结æŸï¼Œé‡æ–°ç»™äºˆç¡¬åŒ–皮肤。 + ''' } LivingWoodplate: { - DisplayName: Living Woodplate - Tooltip: "" + DisplayName: 活木甲 + Tooltip: + ''' + +4防御 + 接触水时获得+8生命å†ç”Ÿï¼Œ40最大生命值,æŒç»­30ç§’ + ''' } OrfeoBoots: { - DisplayName: Orfeo Boots - Tooltip: "" + DisplayName: å¥¥è²æ¬§ä¹‹é´ + Tooltip: + ''' + å¯å¥”跑,速度æå‡12% + 在战斗中跑得更快并跳得更高 + ''' } RadialCarapace: { - DisplayName: Radial Carapace - Tooltip: "" + DisplayName: 放射状甲壳 + Tooltip: + ''' + 4防御,在水下时é¢å¤–æä¾›4防御 + é™ä½Ž5%移速,但是在水下的移速æå‡35% + ''' } TheGreenSolar: { - DisplayName: The Green Solar - Tooltip: "" + DisplayName: 绿阳之石 + Tooltip: + ''' + +20ç”Ÿå‘½ä¸Šé™ + å—到致命伤害åŽä¸ä¼šæ­»åŽ»è€Œæ˜¯è¿›å…¥æ¶…æ§ƒçŠ¶æ€ã€‚移速在3秒内衰å‡ä¸º0并进入无敌,æ¯ç§’回å¤5点最大生命值 + 在涅槃期间,散å‘太阳光辉ç¼çƒ§é™„近的敌人,造æˆâ€œç€ç«äº†â€ + 冷崿—¶é—´600ç§’ + ''' } ThornTurtleShell: { - DisplayName: Thorn Turtle Shell - Tooltip: "" + DisplayName: è†æ£˜é¾Ÿå£³ + Tooltip: + ''' + +6防御 + ç»™äºˆè†æ£˜æ•ˆæžœ + -7%移速 + -10%冲刺速度 + +5%伤害å‡å… + ''' } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Ammo.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Ammo.hjson index e0268f338..2d242ef0a 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Ammo.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Ammo.hjson @@ -1,9 +1,9 @@ CyanVineBullet: { - DisplayName: Cyan Vine Bullet + DisplayName: é’缎弹 Tooltip: "" } HuskburstBullet: { - DisplayName: Huskburst Bullet - Tooltip: "" + DisplayName: 果壳弹 + Tooltip: "击中åŽçˆ†è£‚出短è·ç¦»çš„å°åž‹å­å¼¹" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Armor.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Armor.hjson index bb5a6531b..bd1438126 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Armor.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Armor.hjson @@ -35,216 +35,222 @@ DevilHeartLeggings: { } FireflywoodBreastplate: { - DisplayName: Fireflywood Breastplate + DisplayName: æµè¤æ¿ç”² Tooltip: "" } FireflywoodHelmet: { - DisplayName: Fireflywood Helmet + DisplayName: æµè¤å¤´ç›” Tooltip: "" } FireflywoodLeggings: { - DisplayName: Fireflywood Leggings + DisplayName: æµè¤æŠ¤èƒ« Tooltip: "" } BlueflowerDress: { - DisplayName: Blueflower Dress + DisplayName: è“花黑裙 Tooltip: "" } ValiantBreastplate: { - DisplayName: Valiant Breastplate - Tooltip: "" + DisplayName: 勇者胸甲 + Tooltip: "这套盔甲往往是æ¥åˆ°å¤©ç©¹é•‡çš„人们的第一笔报酬" } ValiantHelmet: { - DisplayName: Valiant Helmet - Tooltip: "" + DisplayName: 勇者头盔 + Tooltip: "这套盔甲往往是æ¥åˆ°å¤©ç©¹é•‡çš„人们的第一笔报酬" } ValiantLeggings: { - DisplayName: Valiant Leggings - Tooltip: "" + DisplayName: 勇者护胫 + Tooltip: "这套盔甲往往是æ¥åˆ°å¤©ç©¹é•‡çš„人们的第一笔报酬" } TwilightWoodBreastplate: { - DisplayName: Twilight Wood Breastplate + DisplayName: 暮桉木æ¿ç”² Tooltip: "" } TwilightWoodHelmet: { - DisplayName: Twilight Wood Helmet + DisplayName: 暮桉木头盔 Tooltip: "" } TwilightWoodLeggings: { - DisplayName: Twilight Wood Leggings + DisplayName: 暮桉木护胫 Tooltip: "" } ConventionalEquipment: { - DisplayName: Conventional Equipment - Tooltip: "" + DisplayName: 标准护具 + Tooltip: "å…·å¤‡ä¸€å®šä¿æŠ¤æ€§ï¼Œåªæ˜¯ç©¿ç€æ¯«æ— èˆ’适度å¯è¨€" } SafetyHelmets: { - DisplayName: Safety Helmets - Tooltip: "" + DisplayName: 安全头盔 + Tooltip: "批é‡ç”Ÿäº§çš„å¤´ç›”ï¼Œè¿‡é•¿çš„ä»“å‚¨å‘¨æœŸä½¿ææ–™è€åŒ–" } StandardLeggings: { - DisplayName: Standard Leggings - Tooltip: "" + DisplayName: 制å¼é´å­ + Tooltip: "åªæœ‰ä¸¤ä¸ªç æ•°ï¼Œä¼¼ä¹Žæ— æ³•适酿‰€æœ‰äºº" } RockGreaves: { - DisplayName: Rock Greaves + DisplayName: 岩甲护腿 Tooltip: "" } RockHelmet: { - DisplayName: Rock Helmet + DisplayName: 岩甲头盔 Tooltip: "" } RockPlateMail: { - DisplayName: Rock Plate Mail + DisplayName: 岩甲æ¿ç”² Tooltip: "" } ConcentratingJacket: { - DisplayName: Concentrating Jacket + DisplayName: 充能夹克 Tooltip: "" } ExplorationHelmet: { - DisplayName: Exploration Helmet + DisplayName: 探照头盔 Tooltip: "" } OvineHairpin: { - DisplayName: Ovine Hairpin + DisplayName: ç¯ç å¤´é¥° Tooltip: "" } ShadowlessBoots: { - DisplayName: Shadowless Boots + DisplayName: æ— å½±é´å­ Tooltip: "" } LampWoodBreastplate: { - DisplayName: Lamp Wood Breastplate + DisplayName: ç¯æœ¨èƒ¸ç”² Tooltip: "" } LampWoodHelmet: { - DisplayName: Lamp Wood Helmet + DisplayName: ç¯æœ¨å¤´ç›” Tooltip: "" } LampWoodLeggings: { - DisplayName: Lamp Wood Leggings + DisplayName: ç¯æœ¨æŠ¤è…¿ Tooltip: "" } JellyBallBathingCap: { - DisplayName: Jelly Ball Bathing Cap + DisplayName: çƒå†»å¸½ Tooltip: "" } CyanBreastplate: { - DisplayName: Cyan Breastplate + DisplayName: é’缎甲 Tooltip: "" } CyanHeavylet: { - DisplayName: Cyan Heavylet + DisplayName: é’缎头盔 Tooltip: "" } CyanLeggings: { - DisplayName: Cyan Leggings + DisplayName: é’缎鞋 Tooltip: "" } CyanWarhelm: { - DisplayName: Cyan Warhelm + DisplayName: é’缎战盔 Tooltip: "" } BloodDrenchedRobe: { - DisplayName: Blood Drenched Robe - Tooltip: "" + DisplayName: æ²è¡€é•¿è¢ + Tooltip: + ''' + â€œä»–ä»¬ç”¨å®¿ä¸»é²œæ´»çš„é­”è„æ¸©å…»ç»‡å…½ï¼Œå†ç”¨ç»‡å…½ç¼–织鲜红的锦缎†+ ''' } BloodStainedVeil: { - DisplayName: Blood Stained Veil - Tooltip: "" + DisplayName: 染血纱帽 + Tooltip: + ''' + 传说虽是如此,眼å‰çš„衣装除了比较破旧,和法师长è¢å¹¶æ— äºŒè‡´ + ''' } AuburnBoots: { - DisplayName: Auburn Boots - Tooltip: "" + DisplayName: é‡‘æ£•é´ + Tooltip: "é£žæ£æ­»åŽï¼Œå”¯å‰©ä¸€æ”¯ç©ºç®¡ï¼Œç”šè‡³æ‰¾ä¸åˆ°å®ƒçš„é­”è„......ä¸è¿‡è¿™å…·å¤–壳还挺好看的" } AuburnBreastplate: { - DisplayName: Auburn Breastplate - Tooltip: "" + DisplayName: 金棕战甲 + Tooltip: "é£žæ£æ­»åŽï¼Œå”¯å‰©ä¸€æ”¯ç©ºç®¡ï¼Œç”šè‡³æ‰¾ä¸åˆ°å®ƒçš„é­”è„......ä¸è¿‡è¿™å…·å¤–壳还挺好看的" } AuburnHoodie: { - DisplayName: Auburn Hoodie - Tooltip: "" + DisplayName: 金棕兜帽 + Tooltip: "é£žæ£æ­»åŽï¼Œå”¯å‰©ä¸€æ”¯ç©ºç®¡ï¼Œç”šè‡³æ‰¾ä¸åˆ°å®ƒçš„é­”è„......ä¸è¿‡è¿™å…·å¤–壳还挺好看的" } WitherbarkBreastPlate: { - DisplayName: Witherbark Breast Plate + DisplayName: 枯木胸甲 Tooltip: "" } WitherbarkHelmet: { - DisplayName: Witherbark Helmet + DisplayName: 枯木头盔 Tooltip: "" } WitherbarkLeggings: { - DisplayName: Witherbark Leggings + DisplayName: 枯木护腿 Tooltip: "" } RuinLeggings: { - DisplayName: Ruin Leggings + DisplayName: 归墟护胫 Tooltip: "" } RuinMagicRobe: { - DisplayName: Ruin Magic Robe + DisplayName: å½’å¢Ÿå’’è¢ Tooltip: "" } RuinMask: { - DisplayName: Ruin Mask + DisplayName: 归墟é¢ç½© Tooltip: "" } MolluscsLeggings: { - DisplayName: Molluscs Leggings + DisplayName: 软体足部 Tooltip: "" } MossyMolluscsHelmet: { - DisplayName: Mossy Molluscs Helmet + DisplayName: 附苔软体头壳 Tooltip: "" } PearlMolluscsHelmet: { - DisplayName: Pearl Molluscs Helmet + DisplayName: çç è½¯ä½“头壳 Tooltip: "" } ShellMolluscsBreastPlate: { - DisplayName: Shell Molluscs Breast Plate + DisplayName: 软体外壳护甲 Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Critters.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Critters.hjson index eac1ba633..9c6aa20a8 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Critters.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Critters.hjson @@ -1,4 +1,4 @@ RiverSlugItem: { - DisplayName: River Slug Item + DisplayName: æ°´è›žè“ Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Fishing.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Fishing.hjson index b5783a940..7af598bd1 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Fishing.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Fishing.hjson @@ -1,34 +1,34 @@ GlowingFirefly: { - DisplayName: Glowing Firefly + DisplayName: æµè¤è¤ç«è™« Tooltip: "" } DimmyFish: { - DisplayName: Dimmy Fish + DisplayName: 熹光鱼 Tooltip: "" } Filefish: { - DisplayName: Filefish + DisplayName: 马é¢é±¼ Tooltip: "" } GrassCarp: { - DisplayName: Grass Carp + DisplayName: è‰é±¼ Tooltip: "" } GuidyFish: { - DisplayName: Guidy Fish + DisplayName: 领路鱼 Tooltip: "" } ThermostatRod: { - DisplayName: Thermostat Rod + DisplayName: 热能钓竿 Tooltip: "" } TwilightRod: { - DisplayName: Twilight Rod + DisplayName: 暮光钓竿 Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Materials.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Materials.hjson index bb555a602..28037db91 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Materials.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Materials.hjson @@ -1,214 +1,214 @@ StoneTusk: { - DisplayName: Stone Tusk + DisplayName: 石化ç ç‰™ Tooltip: "" } BlackStarShrub: { - DisplayName: Black Star Shrub + DisplayName: 黑星çŒä¸› Tooltip: "" } FireflyPigment: { - DisplayName: Firefly Pigment + DisplayName: æµè¤è‰²ç´  Tooltip: "" } GlowingPetal: { - DisplayName: Glowing Petal + DisplayName: è¤ç«èŠ±ç“£ Tooltip: "" } MothScaleDust: { - DisplayName: Moth Scale Dust + DisplayName: 飞蛾鳞片尘 Tooltip: "" } BlueFreeze: { - DisplayName: Blue Freeze + DisplayName: ç¿ è“æœµ Tooltip: "" } BluePedal: { - DisplayName: Blue Pedal + DisplayName: ç‰å¤©è‹£ Tooltip: "" } CyanHyacinth: { - DisplayName: Cyan Hyacinth + DisplayName: 天é’ç› Tooltip: "" } DarkPoppy: { - DisplayName: Dark Poppy + DisplayName: 暗红帽 Tooltip: "" } FlowerBrochure: { - DisplayName: Flower Brochure - Tooltip: "" + DisplayName: é‡ŽèŠ±æ”¶é›†æŒ‡å— + Tooltip: "æºå¸¦åŽå¯ä»¥æ”¶é›†é‡Žèб" } GoldCup: { - DisplayName: Gold Cup + DisplayName: 风摆铃 Tooltip: "" } GoldWhip: { - DisplayName: Gold Whip + DisplayName: 金鞭兰 Tooltip: "" } HotPinkTulip: { - DisplayName: Hot Pink Tulip + DisplayName: 粉酒æ¯èб Tooltip: "" } Lavender: { - DisplayName: Lavender + DisplayName: 紫笔头 Tooltip: "" } LightChrysanthemum: { - DisplayName: Light Chrysanthemum + DisplayName: é‡‘è½®èŠ Tooltip: "" } LightPurpleBalls: { - DisplayName: Light Purple Balls + DisplayName: 暮色绒 Tooltip: "" } OrangeSausage: { - DisplayName: Orange Sausage + DisplayName: ç‹ç»’è‰ Tooltip: "" } OrangeTulip: { - DisplayName: Orange Tulip + DisplayName: 橙酒æ¯èб Tooltip: "" } PinkSun: { - DisplayName: Pink Sun + DisplayName: 酱粉蓟 Tooltip: "" } PurplePhantom: { - DisplayName: Purple Phantom + DisplayName: å¹»è¶å…° Tooltip: "" } PurpleTail: { - DisplayName: Purple Tail + DisplayName: ç´«é£Žè‰ Tooltip: "" } RedFlame: { - DisplayName: Red Flame + DisplayName: 赤锦 Tooltip: "" } ShallowNight: { - DisplayName: Shallow Night + DisplayName: ç¼éœ„花 Tooltip: "" } SilverClock: { - DisplayName: Silver Clock + DisplayName: ä¹ç“£é“¶ Tooltip: "" } WhiteStar: { - DisplayName: White Star + DisplayName: 白锦星 Tooltip: "" } WhiteTulip: { - DisplayName: White Tulip + DisplayName: 白酒æ¯èб Tooltip: "" } WindMoveSeed: { - DisplayName: Wind Move Seed + DisplayName: é£ŽåŠ¨ä¹‹ç§ Tooltip: "" } AuburnRodSkeleton: { - DisplayName: Auburn Rod Skeleton + DisplayName: 金棕飞æ£éª¨ Tooltip: "" } BrokenMiningLamp: { - DisplayName: Broken Mining Lamp + DisplayName: æŸåçŸ¿ç¯ Tooltip: "" } CaterpillarJuice: { - DisplayName: Caterpillar Juice + DisplayName: è™«æ± Tooltip: "" } CelticKeyStone: { - DisplayName: Celtic Key Stone - Tooltip: "" + DisplayName: 凯尔特机关石 + Tooltip: "放入暮光森林的绿色城堡底部以打开密室" } CrystalNucleusOfJellyKing: { - DisplayName: Crystal Nucleus Of Jelly King + DisplayName: çƒå†»çŽ‹æ™¶æ ¸ Tooltip: "" } CyanVineBar: { - DisplayName: Cyan Vine Bar + DisplayName: é’锻锭 Tooltip: "" } LampFruit: { - DisplayName: Lamp Fruit + DisplayName: ç¯æžœ Tooltip: "" } LightBulbOvule: { - DisplayName: Light Bulb Ovule + DisplayName: ç¯å…‰èƒšç  Tooltip: "" } MagicosCrystal: { - DisplayName: Magicos Crystal + DisplayName: 纯能魔晶 Tooltip: "" } NylonRope: { - DisplayName: Nylon Rope + DisplayName: 尼龙绳 Tooltip: "" } RodWing: { - DisplayName: Rod Wing + DisplayName: 飞æ£é³ Tooltip: "" } TwilightCrystal: { - DisplayName: Twilight Crystal + DisplayName: 暮光水晶 Tooltip: "" } TwilightCrystalExteactedLiquid: { - DisplayName: Twilight Crystal Exteacted Liquid + DisplayName: 暮晶èƒå–æ¶² Tooltip: "" } UnstablePollen: { - DisplayName: Unstable Pollen + DisplayName: 脱稳花粉 Tooltip: "" } YggdrasilAmber: { - DisplayName: Yggdrasil Amber + DisplayName: 天穹ç¥ç€ Tooltip: "" } DevilHeartIronBar_Item: { - DisplayName: Devil Heart Iron Bar_ Item + DisplayName: 魔心é“é”­ Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Miscs.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Miscs.hjson index 480b7e9b2..e212ef5aa 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Miscs.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Miscs.hjson @@ -1,24 +1,24 @@ StarSeed: { - DisplayName: Star Seed + DisplayName: æ˜Ÿç§ Tooltip: "" } GoodNeighborCoin: { - DisplayName: Good Neighbor Coin + DisplayName: å¥½é‚»å±…å¸ Tooltip: "" } JellyBallFat: { - DisplayName: Jelly Ball Fat + DisplayName: çƒå†»è„‚ Tooltip: "" } StrongCorticalMembrane: { - DisplayName: Strong Cortical Membrane + DisplayName: 强韧的皮质膜 Tooltip: "" } YggdrasilPlayerRoomDoorKey: { - DisplayName: Yggdrasil Player Room Door Key + DisplayName: å¤©ç©¹é•‡åˆ†é…æˆ¿ä¹‹é’¥ Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Mounts.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Mounts.hjson index 209261cb4..7295cf81d 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Mounts.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Mounts.hjson @@ -1,4 +1,4 @@ JellyBubbleItem: { - DisplayName: Jelly Bubble Item + DisplayName: çƒå†»éž Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.PermanentBoosters.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.PermanentBoosters.hjson index 915ad743a..83116d2af 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.PermanentBoosters.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.PermanentBoosters.hjson @@ -1,24 +1,24 @@ PineNut: { - DisplayName: Pine Nut + DisplayName: 巨形æ¾å­ Tooltip: "" } AntiHeavenSicknessPill: { - DisplayName: Anti Heaven Sickness Pill + DisplayName: 抗天穹å应è¯ä¸¸ Tooltip: "" } LampBorerHoney: { - DisplayName: Lamp Borer Honey + DisplayName: 甘金蜜 Tooltip: "" } SquamousCore: { - DisplayName: Squamous Core + DisplayName: 龙鳞å¤å£³æ ¸å¿ƒ Tooltip: "" } JadeFruit: { - DisplayName: Jade Fruit + DisplayName: 绿ç‰ç’ƒæžœ Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Pets.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Pets.hjson index 1e3da22f7..99ab47194 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Pets.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Pets.hjson @@ -1,9 +1,9 @@ Badr: { - DisplayName: Badr + DisplayName: “巴德尔†Tooltip: "" } LampWoodSeed: { - DisplayName: Lamp Wood Seed + DisplayName: ç¯æœ¨ç§å­ Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Placeables.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Placeables.hjson index e4c5756ed..cfd61875b 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Placeables.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Placeables.hjson @@ -1,1394 +1,1430 @@ BottleOfNutShellFlowers: { - DisplayName: Bottle Of Nut Shell Flowers + DisplayName: 瓶中干花 Tooltip: "" } BronzeLamp_3_Item: { - DisplayName: Bronze Lamp_3_ Item + DisplayName: é’é“œä¸‰ç¯æŸ± Tooltip: "" } BronzeLamp_Item: { - DisplayName: Bronze Lamp_ Item + DisplayName: é’é“œç¯æŸ± Tooltip: "" } ChinesePartitionLamp: { - DisplayName: Chinese Partition Lamp + DisplayName: 中å¼å±é£Žç¯ Tooltip: "" } ChineseStyleFloorLamp: { - DisplayName: Chinese Style Floor Lamp + DisplayName: 中å¼åœ°ç¯ Tooltip: "" } DoubleArmsChineseStreetLamp: { - DisplayName: Double Arms Chinese Street Lamp + DisplayName: åŒåž‚中å¼è¡—ç¯ç¬¼ Tooltip: "" } FluoriteHangLamp: { - DisplayName: Fluorite Hang Lamp + DisplayName: è§å…‰åŠç¯ Tooltip: "" } FluoriteLampPost_Item: { - DisplayName: Fluorite Lamp Post_ Item + DisplayName: è§å…‰ç¯æŸ± Tooltip: "" } GiantBell: { - DisplayName: Giant Bell + DisplayName: 巨钟 Tooltip: "" } GiantCampFire: { - DisplayName: Giant Camp Fire + DisplayName: 巨型ç¯ç« Tooltip: "" } HangingSkyLantern: { - DisplayName: Hanging Sky Lantern + DisplayName: 挂å¼ç¯ç¬¼ Tooltip: "" } HexagonalCeilingLamp: { - DisplayName: Hexagonal Ceiling Lamp + DisplayName: å…­è§’å®«ç¯ Tooltip: "" } LapisLazuliDome_Item: { - DisplayName: Lapis Lazuli Dome_ Item + DisplayName: è“色穹顶 Tooltip: "" } LapisLazuliDome_mini_Item: { - DisplayName: Lapis Lazuli Dome_mini_ Item + DisplayName: å°åž‹è“色穹顶 Tooltip: "" } PierWithSlabs: { - DisplayName: Pier With Slabs + DisplayName: 石æ¿çŸ³å¢© Tooltip: "" } PierWithSlabsTop: { - DisplayName: Pier With Slabs Top + DisplayName: 石æ¿çŸ³å¢©é¡¶ Tooltip: "" } PlumBlossomInABowl: { - DisplayName: Plum Blossom InABowl + DisplayName: 一碗梅花 Tooltip: "" } SideHangingLantern_Red: { - DisplayName: Side Hanging Lantern_ Red + DisplayName: 侧挂红ç¯ç¬¼ Tooltip: "" } SideHangingLantern_White: { - DisplayName: Side Hanging Lantern_ White + DisplayName: 侧挂白ç¯ç¬¼ Tooltip: "" } StreetLantern: { - DisplayName: Street Lantern + DisplayName: 曲æ†ä¸­å¼è¡—ç¯ç¬¼ Tooltip: "" } WhiteCallaLily_Item: { - DisplayName: White Calla Lily_ Item + DisplayName: 白色马蹄莲 Tooltip: "" } WhiteLotusBonsai: { - DisplayName: White Lotus Bonsai + DisplayName: 白莲花盆景 Tooltip: "" } YellowDynastyShingles: { - DisplayName: Yellow Dynasty Shingles + DisplayName: 黄王æœç“¦ Tooltip: "" } BlueGlassbulbBand_item: { - DisplayName: Blue Glassbulb Band_item - Tooltip: "" + DisplayName: è“LEDç¯å¸¦ + Tooltip: + ''' + 放置物为绳头 + æ‰‹æŒæ­¤ç‰©å³é”®ç‚¹å‡»ç»³å¤´å¼•å‡ºç»³å­ + 把绳å­ç‰µå¼•到å¦ä¸€å¤„绳头å†å³é”®ç‚¹å‡»å³å¯å®ŒæˆæŒ‚绳 + 手æŒå…¶ä»–物å“,å³é”®ç‚¹å‡»æŒ‚å¥½äº†çš„ç»³å¤´å–æ¶ˆåŽŸç»³ + æ¯ä¸ªç»³å¤´å¯ä»¥å¼•出无数æ¡ç»³ï¼Œä½†æ˜¯åªèƒ½æŽ¥å—1æ¡ç»³ + 控制ç¯å…‰çš„电路需è¦é€šè¿‡å¼•出绳å­çš„绳头,接å—绳å­çš„绳头无效 + ''' } ChainCable_item: { - DisplayName: Chain Cable_item + DisplayName: 链绳 Tooltip: "" } GreenGlassbulbBand_item: { - DisplayName: Green Glassbulb Band_item - Tooltip: "" + DisplayName: 绿LEDç¯å¸¦ + Tooltip: + ''' + 放置物为绳头 + æ‰‹æŒæ­¤ç‰©å³é”®ç‚¹å‡»ç»³å¤´å¼•å‡ºç»³å­ + 把绳å­ç‰µå¼•到å¦ä¸€å¤„绳头å†å³é”®ç‚¹å‡»å³å¯å®ŒæˆæŒ‚绳 + 手æŒå…¶ä»–物å“,å³é”®ç‚¹å‡»æŒ‚å¥½äº†çš„ç»³å¤´å–æ¶ˆåŽŸç»³ + æ¯ä¸ªç»³å¤´å¯ä»¥å¼•出无数æ¡ç»³ï¼Œä½†æ˜¯åªèƒ½æŽ¥å—1æ¡ç»³ + 控制ç¯å…‰çš„电路需è¦é€šè¿‡å¼•出绳å­çš„绳头,接å—绳å­çš„绳头无效 + ''' } LightbulbBand_item: { - DisplayName: Lightbulb Band_item - Tooltip: "" + DisplayName: ç¯æ³¡ç¯å¸¦ + Tooltip: + ''' + 放置物为绳头 + æ‰‹æŒæ­¤ç‰©å³é”®ç‚¹å‡»ç»³å¤´å¼•å‡ºç»³å­ + 把绳å­ç‰µå¼•到å¦ä¸€å¤„绳头å†å³é”®ç‚¹å‡»å³å¯å®ŒæˆæŒ‚绳 + 手æŒå…¶ä»–物å“,å³é”®ç‚¹å‡»æŒ‚å¥½äº†çš„ç»³å¤´å–æ¶ˆåŽŸç»³ + æ¯ä¸ªç»³å¤´å¯ä»¥å¼•出无数æ¡ç»³ï¼Œä½†æ˜¯åªèƒ½æŽ¥å—1æ¡ç»³ + 控制ç¯å…‰çš„电路需è¦é€šè¿‡å¼•出绳å­çš„绳头,接å—绳å­çš„绳头无效 + ''' } RedGlassbulbBand_item: { - DisplayName: Red Glassbulb Band_item - Tooltip: "" + DisplayName: 红LEDç¯å¸¦ + Tooltip: + ''' + 放置物为绳头 + æ‰‹æŒæ­¤ç‰©å³é”®ç‚¹å‡»ç»³å¤´å¼•å‡ºç»³å­ + 把绳å­ç‰µå¼•到å¦ä¸€å¤„绳头å†å³é”®ç‚¹å‡»å³å¯å®ŒæˆæŒ‚绳 + 手æŒå…¶ä»–物å“,å³é”®ç‚¹å‡»æŒ‚å¥½äº†çš„ç»³å¤´å–æ¶ˆåŽŸç»³ + æ¯ä¸ªç»³å¤´å¯ä»¥å¼•出无数æ¡ç»³ï¼Œä½†æ˜¯åªèƒ½æŽ¥å—1æ¡ç»³ + 控制ç¯å…‰çš„电路需è¦é€šè¿‡å¼•出绳å­çš„绳头,接å—绳å­çš„绳头无效 + ''' } ChoppingBlock_Item: { - DisplayName: Chopping Block_ Item + DisplayName: åŽ¨ç”¨ç §æ¿ Tooltip: "" } CleaverRack_Item: { - DisplayName: Cleaver Rack_ Item + DisplayName: 刀具挂排 Tooltip: "" } CookwareRack_Item: { - DisplayName: Cookware Rack_ Item + DisplayName: 锅铲挂排 Tooltip: "" } Hob_Silver_Item: { - DisplayName: Hob_ Silver_ Item + DisplayName: 银色厨柜 Tooltip: "" } Refrigerator_Silver_Item: { - DisplayName: Refrigerator_ Silver_ Item + DisplayName: 银色冰箱 Tooltip: "" } Stove_Item: { - DisplayName: Stove_ Item + DisplayName: ç‚‰ç¶ Tooltip: "" } AirTileItem: { - DisplayName: Air Tile Item - Tooltip: "" + DisplayName: ç©ºå— + Tooltip: "å¼€å‘者物å“" } AirWallItem: { - DisplayName: Air Wall Item - Tooltip: "" + DisplayName: 空墙 + Tooltip: "å¼€å‘者物å“" } CableCarJoin_item: { - DisplayName: Cable Car Join_item + DisplayName: 缆车节点 Tooltip: "" } CreatPineTree: { - DisplayName: Creat Pine Tree - Tooltip: "" + DisplayName: å»ºé€ å·¨å¤§é›ªæ¾ + Tooltip: "å¼€å‘者物å“" } SnowPineChest: { - DisplayName: Snow Pine Chest + DisplayName: 雪æ¾å®ç®± Tooltip: "" } SnowPineChest_fresh: { - DisplayName: Snow Pine Chest_fresh + DisplayName: 雪æ¾å®ç®± Tooltip: "" } SnowPineChest_gold: { - DisplayName: Snow Pine Chest_gold + DisplayName: 雪æ¾å®ç®± Tooltip: "" } SnowPineDoor: { - DisplayName: Snow Pine Door + DisplayName: 雪æ¾é—¨ Tooltip: "" } SnowPineLeaveStaff: { - DisplayName: Snow Pine Leave Staff + DisplayName: 雪æ¾é’ˆå¶æ³•æ– Tooltip: "" } SnowPineLeavesWall: { - DisplayName: Snow Pine Leaves Wall + DisplayName: 雪æ¾é’ˆå¶å¢™ Tooltip: "" } SnowPineWoodStaff: { - DisplayName: Snow Pine Wood Staff + DisplayName: 雪æ¾åŽŸæœ¨æ³•æ– Tooltip: "" } SnowPineWoodWall: { - DisplayName: Snow Pine Wood Wall + DisplayName: é›ªæ¾æœ¨å¢™ Tooltip: "" } SungloChandelier: { - DisplayName: Sunglo Chandelier + DisplayName: æ¾èåŠç¯ Tooltip: "" } Thatched: { - DisplayName: Thatched + DisplayName: å±‹ç”¨èŒ…è‰ Tooltip: "" } ThatchedWall: { - DisplayName: Thatched Wall + DisplayName: 屋用茅è‰å¢™ Tooltip: "" } PineLiftWinch: { - DisplayName: Pine Lift Winch + DisplayName: æ¾æ ‘电梯 Tooltip: "" } BloodMossStone: { - DisplayName: Blood Moss Stone + DisplayName: 血苔石 Tooltip: "" } BloodyStoneWall: { - DisplayName: Bloody Stone Wall + DisplayName: 血苔石墙 Tooltip: "" } TuskFlesh_Item: { - DisplayName: Tusk Flesh_ Item + DisplayName: ç ç‰™é¾ˆå— Tooltip: "" } TuskStatusI: { - DisplayName: Tusk Status I + DisplayName: ç ç‰™çŸ³ç¢‘ Tooltip: "" } TuskStatusII: { - DisplayName: Tusk StatusII + DisplayName: ç ç‰™çŸ³ç¢‘ Tooltip: "" } TuskStatusIII: { - DisplayName: Tusk StatusIII + DisplayName: ç ç‰™çŸ³ç¢‘ Tooltip: "" } TuskStatusIV: { - DisplayName: Tusk StatusIV + DisplayName: ç ç‰™çŸ³ç¢‘ Tooltip: "" } BloodyTuskTrophy: { - DisplayName: Bloody Tusk Trophy + DisplayName: 鲜血ç ç‰™çºªå¿µç«  Tooltip: "" } TuskRelic: { - DisplayName: Tusk Relic + DisplayName: 鲜血ç ç‰™åœ£ç‰© Tooltip: "" } FireflyPylonItem: { - DisplayName: Firefly Pylon Item + DisplayName: æµè¤æ™¶å¡” Tooltip: "" } ShabbyPylonItem: { - DisplayName: Shabby Pylon Item + DisplayName: ç ´æ—§æ™¶å¡” Tooltip: "" } BlackVine: { - DisplayName: Black Vine + DisplayName: 黑藤 Tooltip: "" } CorruptOrbStonePost: { - DisplayName: Corrupt Orb Stone Post + DisplayName: è…化法术石柱 Tooltip: "" } CrimsonOrbStonePost: { - DisplayName: Crimson Orb Stone Post + DisplayName: 猩红法术石柱 Tooltip: "" } DarkCocoon: { - DisplayName: Dark Cocoon + DisplayName: 暗茧 Tooltip: "" } DarkCocoonWall: { - DisplayName: Dark Cocoon Wall + DisplayName: 暗茧墙 Tooltip: "" } DarkCocoonWithPetal: { - DisplayName: Dark Cocoon With Petal + DisplayName: 花瓣暗茧墙 Tooltip: "" } FireflyPiranhaBanner: { - DisplayName: Firefly Piranha Banner + DisplayName: æµè¤è™Žé±¼æ—— Tooltip: "" } GlowingReedSeed: { - DisplayName: Glowing Reed Seed + DisplayName: 夜光芦苇ç§å­ Tooltip: "" } GlowWood: { - DisplayName: Glow Wood + DisplayName: è¤ç«æœ¨ Tooltip: "" } GlowWoodWall: { - DisplayName: Glow Wood Wall + DisplayName: è¤ç«æœ¨å¢™ Tooltip: "" } LiveFluorescentLeafWall: { - DisplayName: Live Fluorescent Leaf Wall + DisplayName: 生命è¤ç«å¶å¢™ Tooltip: "" } LiveFluorescentWoodWall: { - DisplayName: Live Fluorescent Wood Wall + DisplayName: 生命è¤ç«æœ¨å¢™ Tooltip: "" } FluorescentLeafStaff: { - DisplayName: Fluorescent Leaf Staff + DisplayName: 生命è¤ç«å¶æ³•æ– Tooltip: "" } FluorescentWoodStaff: { - DisplayName: Fluorescent Wood Staff + DisplayName: 生命è¤ç«æœ¨æ³•æ– Tooltip: "" } GlowingDrop: { - DisplayName: Glowing Drop + DisplayName: è¤ç«åŠ Tooltip: "" } GlowWoodBathtub: { - DisplayName: Glow Wood Bathtub + DisplayName: è¤ç«æœ¨æµ´ç¼¸ Tooltip: "" } GlowWoodBed: { - DisplayName: Glow Wood Bed + DisplayName: è¤ç«æœ¨åºŠ Tooltip: "" } GlowWoodBookcase: { - DisplayName: Glow Wood Bookcase + DisplayName: è¤ç«æœ¨ä¹¦æž¶ Tooltip: "" } GlowWoodCampfire: { - DisplayName: Glow Wood Campfire + DisplayName: è¤ç«æœ¨ç¯ç« Tooltip: "" } GlowWoodCandelabra: { - DisplayName: Glow Wood Candelabra + DisplayName: è¤ç«æœ¨çƒ›å° Tooltip: "" } GlowWoodCandle: { - DisplayName: Glow Wood Candle + DisplayName: è¤ç«æœ¨èœ¡çƒ› Tooltip: "" } GlowWoodChair: { - DisplayName: Glow Wood Chair + DisplayName: è¤ç«æœ¨æ¤… Tooltip: "" } GlowWoodChandelier: { - DisplayName: Glow Wood Chandelier + DisplayName: è¤ç«æœ¨åŠç¯ Tooltip: "" } GlowWoodChandelierType2: { - DisplayName: Glow Wood Chandelier Type2 + DisplayName: è¤ç«æœ¨åŠç¯ Tooltip: "" } GlowWoodChandelierType3: { - DisplayName: Glow Wood Chandelier Type3 + DisplayName: è¤ç«æœ¨åŠç¯ Tooltip: "" } GlowWoodChandelierType4: { - DisplayName: Glow Wood Chandelier Type4 + DisplayName: è¤ç«æœ¨åŠç¯ Tooltip: "" } GlowWoodChest: { - DisplayName: Glow Wood Chest + DisplayName: è¤ç«æœ¨ç®± Tooltip: "" } GlowWoodClock: { - DisplayName: Glow Wood Clock + DisplayName: è¤ç«æœ¨é’Ÿ Tooltip: "" } GlowWoodDoor: { - DisplayName: Glow Wood Door + DisplayName: è¤ç«æœ¨é—¨ Tooltip: "" } GlowWoodDoorType2: { - DisplayName: Glow Wood Door Type2 + DisplayName: è¤ç«æœ¨é—¨ Tooltip: "" } GlowWoodDresser: { - DisplayName: Glow Wood Dresser + DisplayName: è¤ç«æœ¨æ¢³å¦†å° Tooltip: "" } GlowWoodDresserType2: { - DisplayName: Glow Wood Dresser Type2 + DisplayName: è¤ç«æœ¨æ¢³å¦†å° Tooltip: "" } GlowWoodLamp: { - DisplayName: Glow Wood Lamp + DisplayName: è¤ç«æœ¨ç¯ Tooltip: "" } GlowWoodLantern: { - DisplayName: Glow Wood Lantern + DisplayName: è¤ç«æœ¨ç¯ç¬¼ Tooltip: "" } GlowWoodLanternType2: { - DisplayName: Glow Wood Lantern Type2 + DisplayName: è¤ç«æœ¨ç¯ç¬¼ Tooltip: "" } GlowWoodMusicBox: { - DisplayName: Glow Wood Music Box + DisplayName: 八音盒(æµè¤ä¹‹åœ°ï¼‰ Tooltip: "" } GlowWoodPiano: { - DisplayName: Glow Wood Piano + DisplayName: è¤ç«æœ¨é’¢ç´ Tooltip: "" } GlowWoodPlatform: { - DisplayName: Glow Wood Platform + DisplayName: è¤ç«æœ¨å¹³å° Tooltip: "" } GlowWoodSink: { - DisplayName: Glow Wood Sink + DisplayName: è¤ç«æœ¨æ°´æ§½ Tooltip: "" } GlowWoodSinkType2: { - DisplayName: Glow Wood Sink Type2 + DisplayName: è¤ç«æœ¨æ°´æ§½ Tooltip: "" } GlowWoodSofa: { - DisplayName: Glow Wood Sofa + DisplayName: è¤ç«æœ¨æ²™å‘ Tooltip: "" } GlowWoodTable: { - DisplayName: Glow Wood Table + DisplayName: è¤ç«æœ¨æ¡Œ Tooltip: "" } GlowWoodToilet: { - DisplayName: Glow Wood Toilet + DisplayName: è¤ç«æœ¨é©¬æ¡¶ Tooltip: "" } GlowWoodTorch: { - DisplayName: Glow Wood Torch + DisplayName: è¤ç«æœ¨ç«æŠŠ Tooltip: "" } GlowWoodWorkBench: { - DisplayName: Glow Wood Work Bench + DisplayName: è¤ç«æœ¨å·¥ä½œå° Tooltip: "" } MothRelic: { - DisplayName: Moth Relic + DisplayName: è…æª€å·¨è›¾åœ£ç‰© Tooltip: "" } FireCrackerLauncher: { - DisplayName: Fire Cracker Launcher + DisplayName: 礼花弹å‘射管 Tooltip: "" } RoomBlackBox_Item: { - DisplayName: Room Black Box_ Item - Tooltip: "" + DisplayName: æˆ¿é—´ä¸–ç•Œçš„é»‘åŒ£å­ + Tooltip: "å¼€å‘者物å“" } WoodenRoomDoor_exit_Item: { - DisplayName: Wooden Room Door_exit_ Item - Tooltip: "" + DisplayName: 离开房间的木门 + Tooltip: "å³é”®ç¦»å¼€æˆ¿é—´" } WoodenRoomDoor_Item: { - DisplayName: Wooden Room Door_ Item - Tooltip: "" + DisplayName: 进入房间的木门 + Tooltip: "å³é”®è¿›å…¥ä¸€ä¸ªæœ¨åˆ¶çš„æˆ¿é—´" } ChineseKitchenDoor_Item: { - DisplayName: Chinese Kitchen Door_ Item - Tooltip: "" + DisplayName: 中å¼åŽ¨æˆ¿é—¨ + Tooltip: + ''' + å³é”®é—¨å¯ä»¥è¿›å…¥ä¸€ä¸ªä¸­å¼é£Žæ ¼çš„åŽ¨æˆ¿ï¼Œæ ¹æ®æç¤ºå¯ä»¥å¼€å¯é¤åŽ…ç»è¥æ¸¸æˆ + é¤åŽ…ç»è¥æ¸¸æˆå¯ä»¥è§£é”æ–°çš„èœè°± + ''' } RestaurantLogoBoard_Item: { - DisplayName: Restaurant Logo Board_ Item + DisplayName: é¤åŽ…æ ‡å¿— Tooltip: "" } ServingCounter_ChineseStyle_Item: { - DisplayName: Serving Counter_ Chinese Style_ Item - Tooltip: "" + DisplayName: 䏭弿œåŠ¡å° + Tooltip: "把符åˆè®¢å•çš„èœå“放上去或从上空丢过去以完æˆè®¢å•" } ExitUnionTile_Item: { - DisplayName: Exit Union Tile_ Item + DisplayName: 离开工会的门 Tooltip: "" } GiantFurnacePlaceItem: { - DisplayName: Giant Furnace Place Item - Tooltip: "" + DisplayName: 巨型炉心 + Tooltip: "真的超大一个" } CanteenDoor_Item: { - DisplayName: Canteen Door_ Item + DisplayName: 进入é¤åŽ…é—¨ Tooltip: "" } CanteenExit_Item: { - DisplayName: Canteen Exit_ Item + DisplayName: 离开é¤åŽ…é—¨ Tooltip: "" } CurrentEnergyTube_Item: { - DisplayName: Current Energy Tube_ Item + DisplayName: 能æµç®¡ Tooltip: "" } DarkForestSoil_Item: { - DisplayName: Dark Forest Soil_ Item + DisplayName: 暗森土壤 Tooltip: "" } DarkSludge_Item: { - DisplayName: Dark Sludge_ Item + DisplayName: 黑沼泥 Tooltip: "" } DilapidatedDangerSigns: { - DisplayName: Dilapidated Danger Signs + DisplayName: “å°å¿ƒåœ°æ»‘†Tooltip: "" } ExitSignBoard_Item: { - DisplayName: Exit Sign Board_ Item + DisplayName: å®‰å…¨å‡ºå£ Tooltip: "" } FemaleLampLeaves_Item: { - DisplayName: Female Lamp Leaves_ Item + DisplayName: ç¯æœ¨æ¯æ ‘原木 Tooltip: "" } FloorScaleForPlayers_Item: { - DisplayName: Floor Scale For Players_ Item - Tooltip: "" + DisplayName: 炉心区地磅 + Tooltip: "站上去åŽç‚‰å¿ƒåŒºçš„贡献程åºä¼šèŽ·å¾—çŽ©å®¶èº«ä»½" } FurnaceCopperGear_Large_Item: { - DisplayName: Furnace Copper Gear_ Large_ Item + DisplayName: 大型炉心铜齿轮 Tooltip: "" } FurnaceCopperGear_Middle_Item: { - DisplayName: Furnace Copper Gear_ Middle_ Item + DisplayName: 中型炉心铜齿轮 Tooltip: "" } FurnaceCopperPipe_Item: { - DisplayName: Furnace Copper Pipe_ Item + DisplayName: 炉心铜管 Tooltip: "" } FurnaceCopperPipe_Large_Corner_Item: { - DisplayName: Furnace Copper Pipe_ Large_ Corner_ Item + DisplayName: 炉心大铜管转角 Tooltip: "" } FurnaceCopperPipe_Large_Item: { - DisplayName: Furnace Copper Pipe_ Large_ Item + DisplayName: 炉心大铜管 Tooltip: "" } FurnaceEmergencyLamp_Item: { - DisplayName: Furnace Emergency Lamp_ Item + DisplayName: ç‚‰å¿ƒåº”æ€¥ç¯ Tooltip: "" } FurnaceHeatProofPlatingWall_Item: { - DisplayName: Furnace Heat Proof Plating Wall_ Item + DisplayName: 炉心强效隔热镀层墙 Tooltip: "" } FurnaceLavaband_Item: { - DisplayName: Furnace Lavaband_ Item + DisplayName: 炉心熔岩ç¯å¸¦ Tooltip: "" } FurnaceLavaLamp_Item: { - DisplayName: Furnace Lava Lamp_ Item + DisplayName: ç‚‰å¿ƒç†”å²©ç¯ Tooltip: "" } FurnacePlatingBlock: { - DisplayName: Furnace Plating Block + DisplayName: ç‚‰å¿ƒé•€å±‚å— Tooltip: "" } FurnaceTrapDoor_Item: { - DisplayName: Furnace Trap Door_ Item + DisplayName: 炉心活æ¿é—¨ Tooltip: "" } GreenRelicBrick_Item: { - DisplayName: Green Relic Brick_ Item + DisplayName: 绿é—迹砖 Tooltip: "" } GreyTownBrick_Item: { - DisplayName: Grey Town Brick_ Item + DisplayName: 城镇ç°çŸ³ç – Tooltip: "" } HeatProofPlatingWall_Item: { - DisplayName: Heat Proof Plating Wall_ Item + DisplayName: 炉心隔热镀层墙 Tooltip: "" } IronTrackScaffolding: { - DisplayName: Iron Track Scaffolding + DisplayName: 铿”¯æž¶ Tooltip: "" } Ishta_per_The_Venus_painting_Item: { - DisplayName: Ishta_per_ The_ Venus_painting_ Item + DisplayName: ä¼Šæ–¯å¡”è£´å°”çš„ç”»åƒ Tooltip: "" } JellyBallCube: { - DisplayName: Jelly Ball Cube + DisplayName: çƒå†»æ–¹å— Tooltip: "" } Lamorch_Item: { - DisplayName: Lamorch_ Item + DisplayName: ç¯æŠŠ Tooltip: "" } LampGrassSeed: { - DisplayName: Lamp Grass Seed + DisplayName: ç¯æœ¨æž—ç´«è‰ç±½ Tooltip: "" } LampWoodCrate_Item: { - DisplayName: Lamp Wood Crate_ Item + DisplayName: ç¯æœ¨åŒ£ Tooltip: "" } LampWood_Wood: { - DisplayName: Lamp Wood_ Wood + DisplayName: ç¯æœ¨ Tooltip: "" } LargeCrystalShowTable_Blue_Item: { - DisplayName: Large Crystal Show Table_ Blue_ Item + DisplayName: 大型暮晶æ“ä½œå° Tooltip: "" } LargeCrystalShowTable_Green_Item: { - DisplayName: Large Crystal Show Table_ Green_ Item + DisplayName: è“æ™¶ä½“å±•å° Tooltip: "" } LargeCrystalShowTable_Red_Item: { - DisplayName: Large Crystal Show Table_ Red_ Item + DisplayName: çº¢æ™¶ä½“å±•å° Tooltip: "" } MeltingButton_Item: { - DisplayName: Melting Button_ Item - Tooltip: "" + DisplayName: 熔炼按钮 + Tooltip: "æŒ‰ä¸‹åŽæŠŠç†”æ–™æ”¶çº³ç®±çš„ç‰©ä½“é”€æ¯ï¼Œè½¬åŒ–为热能并记录贡献点" } MeltingInputBox_Item: { - DisplayName: Melting Input Box_ Item + DisplayName: 熔料收纳箱 Tooltip: "" } MissionBoard_Item: { - DisplayName: Mission Board_ Item + DisplayName: ä»»åŠ¡æ‚¬èµæ¿ Tooltip: "" } MissionCounter_Item: { - DisplayName: Mission Counter_ Item + DisplayName: ä»»åŠ¡æŸœå° Tooltip: "" } RoadSignPost_ToArena_Item: { - DisplayName: Road Sign Post_ To Arena_ Item + DisplayName: 通往竞技场的路标 Tooltip: "" } RuinTorch: { - DisplayName: Ruin Torch + DisplayName: é—è¿¹ç«æŠŠ Tooltip: "" } SteamBoiler_Item: { - DisplayName: Steam Boiler_ Item + DisplayName: 蒸汽锅炉 Tooltip: "" } StoneBridge_Chest_item: { - DisplayName: Stone Bridge_ Chest_item + DisplayName: 石桥箱 Tooltip: "" } StoneDragonScaleWood: { - DisplayName: Stone Dragon Scale Wood + DisplayName: 石化龙鳞木 Tooltip: "" } TotalFurnaceScoreBoard_Item: { - DisplayName: Total Furnace Score Board_ Item + DisplayName: ç‚‰å¿ƒçƒ­å€¼è´¡çŒ®æ¿ Tooltip: "" } TownBrick_Gray_Item: { - DisplayName: Town Brick_ Gray_ Item + DisplayName: 城镇亮ç°ç – Tooltip: "" } TownBrick_Khaki_Item: { - DisplayName: Town Brick_ Khaki_ Item + DisplayName: 城镇å¡å…¶ç – Tooltip: "" } TownSteelBrick_Item: { - DisplayName: Town Steel Brick_ Item + DisplayName: 城镇贴镀层砖 Tooltip: "" } TwilightCrate_Item: { - DisplayName: Twilight Crate_ Item + DisplayName: 暮光匣 Tooltip: "" } TwilightEucalyptusWood_Item: { - DisplayName: Twilight Eucalyptus Wood_ Item + DisplayName: 暮光桉木 Tooltip: "" } UnionAcanthusWallLace_Item: { - DisplayName: Union Acanthus Wall Lace_ Item + DisplayName: 工会茛苕å¶é‡‘è¾¹ Tooltip: "" } UnionGiantChandelier_Item: { - DisplayName: Union Giant Chandelier_ Item + DisplayName: 工会巨型水晶åŠç¯ Tooltip: "" } UnionGiantChandelier_Style1_Item: { - DisplayName: Union Giant Chandelier_ Style1_ Item + DisplayName: 工会巨型åŠç¯ Tooltip: "" } UnionGoldAcanthusWall_Item: { - DisplayName: Union Gold Acanthus Wall_ Item + DisplayName: 工会茛苕å¶çº¹å¢™ Tooltip: "" } UnionLampPost_Style0_Item: { - DisplayName: Union Lamp Post_ Style0_ Item + DisplayName: 工会金å°ç¯ Tooltip: "" } UnionLampPost_Style1_Item: { - DisplayName: Union Lamp Post_ Style1_ Item + DisplayName: 工会ç‰ç’ƒå°ç¯ Tooltip: "" } UnionLampPost_Style2_Item: { - DisplayName: Union Lamp Post_ Style2_ Item + DisplayName: 工会雕åƒå°ç¯ Tooltip: "" } UnionMarblePost_Body_Khaki_Item: { - DisplayName: Union Marble Post_ Body_ Khaki_ Item + DisplayName: 工会å¡å…¶è‰²å¤§ç†çŸ³ç«‹æŸ±æŸ±ä½“ Tooltip: "" } UnionMarblePost_Bottom_Khaki_Item: { - DisplayName: Union Marble Post_ Bottom_ Khaki_ Item + DisplayName: 工会å¡å…¶è‰²å¤§ç†çŸ³ç«‹æŸ±åº•座 Tooltip: "" } UnionMarblePost_Top_Corinth_Khaki_Item: { - DisplayName: Union Marble Post_ Top_ Corinth_ Khaki_ Item + DisplayName: 工会柯林斯å¼å¡å…¶è‰²å¤§ç†çŸ³ç«‹æŸ±é¡¶ Tooltip: "" } UnionMarblePost_Top_Doric_Khaki_Item: { - DisplayName: Union Marble Post_ Top_ Doric_ Khaki_ Item + DisplayName: 工会多立克å¼å¡å…¶è‰²å¤§ç†çŸ³ç«‹æŸ±é¡¶ Tooltip: "" } UnionMarblePost_Top_Ionic_Khaki_Item: { - DisplayName: Union Marble Post_ Top_ Ionic_ Khaki_ Item + DisplayName: 工会罗马å¼å¡å…¶è‰²å¤§ç†çŸ³ç«‹æŸ±é¡¶ Tooltip: "" } UnionMarbleTile_Khaki_Item: { - DisplayName: Union Marble Tile_ Khaki_ Item + DisplayName: 工会å¡å…¶è‰²å¤§ç†çŸ³å— Tooltip: "" } UnionMarbleWall_Dark_Item: { - DisplayName: Union Marble Wall_ Dark_ Item + DisplayName: 工会暗色大ç†çŸ³å¢™ Tooltip: "" } UnionOfficeDoor_Item: { - DisplayName: Union Office Door_ Item + DisplayName: 工会办公室大门 Tooltip: "" } UnionSideLantern_Style0_Item: { - DisplayName: Union Side Lantern_ Style0_ Item + DisplayName: å·¥ä¼šé‡‘ä¾§ç¯ Tooltip: "" } UnionWallLamp_Style0_Item: { - DisplayName: Union Wall Lamp_ Style0_ Item + DisplayName: 工会大ç†çŸ³å£ç¯ Tooltip: "" } UnionWindow_Style0_Item: { - DisplayName: Union Window_ Style0_ Item + DisplayName: 工会窗 Tooltip: "" } Union_Y_Stairs_Item: { - DisplayName: Union_ Y_ Stairs_ Item + DisplayName: 工会Y形大楼梯 Tooltip: "" } UrbanCrate_Item: { - DisplayName: Urban Crate_ Item + DisplayName: 城镇匣 Tooltip: "" } YggdrasilCommandBlockItem: { - DisplayName: Yggdrasil Command Block Item + DisplayName: å¤©ç©¹å‘½ä»¤æ–¹å— Tooltip: "" } YggdrasilPlayerRoomDoor_Item: { - DisplayName: Yggdrasil Player Room Door_ Item + DisplayName: 天穹镇ä½å®…é—¨ Tooltip: "" } YggdrasilPlayerRoomDoor_Lock_Item: { - DisplayName: Yggdrasil Player Room Door_ Lock_ Item + DisplayName: 上é”天穹镇ä½å®…é—¨ Tooltip: "" } GreenRelicWall_Item: { - DisplayName: Green Relic Wall_ Item + DisplayName: 绿é—迹砖墙 Tooltip: "" } JellyBallSecretionWall_Item: { - DisplayName: Jelly Ball Secretion Wall_ Item + DisplayName: çƒå†»åˆ†æ³Œç‰©å¢™ Tooltip: "" } LampWoodWall_item: { - DisplayName: Lamp Wood Wall_item + DisplayName: ç¯æœ¨å¢™ Tooltip: "" } StoneDragonScaleWoodWall_Item: { - DisplayName: Stone Dragon Scale Wood Wall_ Item + DisplayName: 石化龙鳞木墙 Tooltip: "" } TownBrick_Gray_Wall_Item: { - DisplayName: Town Brick_ Gray_ Wall_ Item + DisplayName: 城镇亮ç°ç –墙 Tooltip: "" } TownBrick_Khaki_Wall_Item: { - DisplayName: Town Brick_ Khaki_ Wall_ Item + DisplayName: 城镇å¡å…¶ç –墙 Tooltip: "" } TwilightEucalyptusWoodWall_Item: { - DisplayName: Twilight Eucalyptus Wood Wall_ Item + DisplayName: 暮光桉木墙 Tooltip: "" } CyanVineOre: { - DisplayName: Cyan Vine Ore + DisplayName: é’缎矿 Tooltip: "" } RustBronzeTreasureChest_Item: { - DisplayName: Rust Bronze Treasure Chest_ Item + DisplayName: 锈铜å®ç®± Tooltip: "" } TwilightCrystalMill_Item: { - DisplayName: Twilight Crystal Mill_ Item + DisplayName: 暮晶磨 Tooltip: "" } TwilightEucalyptusBathtub: { - DisplayName: Twilight Eucalyptus Bathtub + DisplayName: 暮光桉浴缸 Tooltip: "" } TwilightEucalyptusBed: { - DisplayName: Twilight Eucalyptus Bed + DisplayName: 暮光桉床 Tooltip: "" } TwilightEucalyptusBookcase: { - DisplayName: Twilight Eucalyptus Bookcase + DisplayName: 暮光桉书架 Tooltip: "" } TwilightEucalyptusCandelabra: { - DisplayName: Twilight Eucalyptus Candelabra + DisplayName: æš®å…‰æ¡‰çƒ›å° Tooltip: "" } TwilightEucalyptusCandle: { - DisplayName: Twilight Eucalyptus Candle + DisplayName: 暮光桉蜡烛 Tooltip: "" } TwilightEucalyptusChair: { - DisplayName: Twilight Eucalyptus Chair + DisplayName: 暮光桉椅 Tooltip: "" } TwilightEucalyptusChandelier: { - DisplayName: Twilight Eucalyptus Chandelier + DisplayName: 暮光桉åŠç¯ Tooltip: "" } TwilightEucalyptusChest: { - DisplayName: Twilight Eucalyptus Chest + DisplayName: 暮光桉箱 Tooltip: "" } TwilightEucalyptusClock: { - DisplayName: Twilight Eucalyptus Clock + DisplayName: 暮光桉钟 Tooltip: "" } TwilightEucalyptusDoor: { - DisplayName: Twilight Eucalyptus Door + DisplayName: 暮光桉门 Tooltip: "" } TwilightEucalyptusDresser: { - DisplayName: Twilight Eucalyptus Dresser + DisplayName: æš®å…‰æ¡‰æ¢³å¦†å° Tooltip: "" } TwilightEucalyptusLamp: { - DisplayName: Twilight Eucalyptus Lamp + DisplayName: æš®å…‰æ¡‰ç¯ Tooltip: "" } TwilightEucalyptusLantern: { - DisplayName: Twilight Eucalyptus Lantern + DisplayName: 暮光桉ç¯ç¬¼ Tooltip: "" } TwilightEucalyptusPiano: { - DisplayName: Twilight Eucalyptus Piano + DisplayName: æš®å…‰æ¡‰é’¢ç´ Tooltip: "" } TwilightEucalyptusPlatform: { - DisplayName: Twilight Eucalyptus Platform + DisplayName: æš®å…‰æ¡‰å¹³å° Tooltip: "" } TwilightEucalyptusSink: { - DisplayName: Twilight Eucalyptus Sink + DisplayName: 暮光桉水槽 Tooltip: "" } TwilightEucalyptusSofa: { - DisplayName: Twilight Eucalyptus Sofa + DisplayName: æš®å…‰æ¡‰æ²™å‘ Tooltip: "" } TwilightEucalyptusSofa_Type2: { - DisplayName: Twilight Eucalyptus Sofa_ Type2 + DisplayName: æš®å…‰æ¡‰æ²™å‘ Tooltip: "" } TwilightEucalyptusTable: { - DisplayName: Twilight Eucalyptus Table + DisplayName: 暮光桉桌 Tooltip: "" } TwilightEucalyptusToilet: { - DisplayName: Twilight Eucalyptus Toilet + DisplayName: 暮光桉马桶 Tooltip: "" } TwilightEucalyptusWorkBench: { - DisplayName: Twilight Eucalyptus Work Bench + DisplayName: æš®å…‰æ¡‰å·¥ä½œå° Tooltip: "" } LampWoodBathtub: { - DisplayName: Lamp Wood Bathtub + DisplayName: ç¯æœ¨æµ´ç¼¸ Tooltip: "" } LampWoodBed: { - DisplayName: Lamp Wood Bed + DisplayName: ç¯æœ¨åºŠ Tooltip: "" } LampWoodBookcase: { - DisplayName: Lamp Wood Bookcase + DisplayName: ç¯æœ¨ä¹¦æž¶ Tooltip: "" } LampWoodCandelabra_Item: { - DisplayName: Lamp Wood Candelabra_ Item + DisplayName: ç¯æœ¨çƒ›å° Tooltip: "" } LampWoodCandle_Item: { - DisplayName: Lamp Wood Candle_ Item + DisplayName: ç¯æœ¨èœ¡çƒ› Tooltip: "" } LampWoodChair: { - DisplayName: Lamp Wood Chair + DisplayName: ç¯æœ¨æ¤… Tooltip: "" } LampWoodChandelier_Item: { - DisplayName: Lamp Wood Chandelier_ Item + DisplayName: ç¯æœ¨åŠç¯ Tooltip: "" } LampWoodClock: { - DisplayName: Lamp Wood Clock + DisplayName: ç¯æœ¨é’Ÿ Tooltip: "" } LampWoodDoor: { - DisplayName: Lamp Wood Door + DisplayName: ç¯æœ¨é—¨ Tooltip: "" } LampWoodDresser: { - DisplayName: Lamp Wood Dresser + DisplayName: ç¯æœ¨æ¢³å¦†å° Tooltip: "" } LampWoodLamp_Item: { - DisplayName: Lamp Wood Lamp_ Item + DisplayName: ç¯æœ¨ç¯ Tooltip: "" } LampWoodLantern: { - DisplayName: Lamp Wood Lantern + DisplayName: ç¯æœ¨ç¯ç¬¼ Tooltip: "" } LampWoodPiano: { - DisplayName: Lamp Wood Piano + DisplayName: ç¯æœ¨é’¢ç´ Tooltip: "" } LampWoodSink: { - DisplayName: Lamp Wood Sink + DisplayName: ç¯æœ¨æ°´æ§½ Tooltip: "" } LampWoodSofa: { - DisplayName: Lamp Wood Sofa + DisplayName: ç¯æœ¨æ²™å‘ Tooltip: "" } LampWoodTable: { - DisplayName: Lamp Wood Table + DisplayName: ç¯æœ¨æ¡Œ Tooltip: "" } LampWoodToilet: { - DisplayName: Lamp Wood Toilet + DisplayName: ç¯æœ¨é©¬æ¡¶ Tooltip: "" } LampWood_Chest_Item: { - DisplayName: Lamp Wood_ Chest_ Item + DisplayName: ç¯æœ¨ç®± Tooltip: "" } LampWood_Platform: { - DisplayName: Lamp Wood_ Platform + DisplayName: ç¯æœ¨å¹³å° Tooltip: "" } LampWood_workBench: { - DisplayName: Lamp Wood_work Bench + DisplayName: ç¯æœ¨å·¥ä½œå° Tooltip: "" } HeatproofBathtub_item: { - DisplayName: Heatproof Bathtub_item + DisplayName: 隔热浴缸 Tooltip: "" } HeatproofBed_item: { - DisplayName: Heatproof Bed_item + DisplayName: 隔热床 Tooltip: "" } HeatproofBookcase_item: { - DisplayName: Heatproof Bookcase_item + DisplayName: 隔热书架 Tooltip: "" } HeatproofCandelabra_item: { - DisplayName: Heatproof Candelabra_item + DisplayName: éš”çƒ­çƒ›å° Tooltip: "" } HeatproofCandle_item: { - DisplayName: Heatproof Candle_item + DisplayName: 隔热蜡烛 Tooltip: "" } HeatproofChair_item: { - DisplayName: Heatproof Chair_item + DisplayName: 隔热椅 Tooltip: "" } HeatproofChandelier_item: { - DisplayName: Heatproof Chandelier_item + DisplayName: 隔热åŠç¯ Tooltip: "" } HeatproofChest_item: { - DisplayName: Heatproof Chest_item + DisplayName: 隔热箱 Tooltip: "" } HeatproofClock_item: { - DisplayName: Heatproof Clock_item + DisplayName: 隔热钟 Tooltip: "" } HeatproofDoor_item: { - DisplayName: Heatproof Door_item + DisplayName: 隔热门 Tooltip: "" } HeatproofDresser_item: { - DisplayName: Heatproof Dresser_item + DisplayName: éš”çƒ­æ¢³å¦†å° Tooltip: "" } HeatproofLamp_item: { - DisplayName: Heatproof Lamp_item + DisplayName: éš”çƒ­ç¯ Tooltip: "" } HeatproofLantern_item: { - DisplayName: Heatproof Lantern_item + DisplayName: 隔热ç¯ç¬¼ Tooltip: "" } HeatproofPiano_item: { - DisplayName: Heatproof Piano_item + DisplayName: éš”çƒ­é’¢ç´ Tooltip: "" } HeatproofSink_item: { - DisplayName: Heatproof Sink_item + DisplayName: 隔热水槽 Tooltip: "" } HeatproofSofa_item: { - DisplayName: Heatproof Sofa_item + DisplayName: éš”çƒ­æ²™å‘ Tooltip: "" } HeatproofTable_item: { - DisplayName: Heatproof Table_item + DisplayName: 隔热桌 Tooltip: "" } HeatproofToilet_item: { - DisplayName: Heatproof Toilet_item + DisplayName: 隔热马桶 Tooltip: "" } HeatproofWorkbench_item: { - DisplayName: Heatproof Workbench_item + DisplayName: éš”çƒ­å·¥ä½œå° Tooltip: "" } SquamousShellRelic: { - DisplayName: Squamous Shell Relic + DisplayName: 龙鳞å¤å£³åœ£ç‰© Tooltip: "" } SquamousShellTrophy: { - DisplayName: Squamous Shell Trophy + DisplayName: 龙鳞å¤å£³çºªå¿µç«  Tooltip: "" } KelpMoss_largeCreate: { - DisplayName: Kelp Moss_large Create - Tooltip: "" + DisplayName: 放置大型雨帘苔 + Tooltip: "å¼€å‘者物å“" } AlgaeExtractor_Item: { - DisplayName: Algae Extractor_ Item + DisplayName: 藻类æå–机 Tooltip: "" } DarklakeBottomMud_Item: { - DisplayName: Darklake Bottom Mud_ Item + DisplayName: 暗湖底泥 Tooltip: "" } DecayingWood_Item: { - DisplayName: Decaying Wood_ Item + DisplayName: 朽木 Tooltip: "" } DevilHeartIronOre_Item: { - DisplayName: Devil Heart Iron Ore_ Item + DisplayName: 魔心é“矿 Tooltip: "" } DragonScaleWood: { - DisplayName: Dragon Scale Wood + DisplayName: 龙鳞木 Tooltip: "" } GeyserAirBudsItem: { - DisplayName: Geyser Air Buds Item + DisplayName: 间歇泉气苞 Tooltip: "" } GreenCourtBrick_Item: { - DisplayName: Green Court Brick_ Item + DisplayName: 绿王庭砖 Tooltip: "" } JadeizedBone_Item: { - DisplayName: Jadeized Bone_ Item + DisplayName: 玉化龙骨 Tooltip: "" } MossProneSandSoil: { - DisplayName: Moss Prone Sand Soil + DisplayName: 苔基砂土 Tooltip: "" } OldMoss: { - DisplayName: Old Moss + DisplayName: å¤è‹” Tooltip: "" } YggdrasilCyatheaWood: { - DisplayName: Yggdrasil Cyathea Wood + DisplayName: 天穹桫椤 Tooltip: "" } DragonScaleWoodWall_Item: { - DisplayName: Dragon Scale Wood Wall_ Item + DisplayName: 龙鳞木墙 Tooltip: "" } GreenCourtWall_Item: { - DisplayName: Green Court Wall_ Item + DisplayName: 绿王庭砖墙 Tooltip: "" } CyanWindGranite: { - DisplayName: Cyan Wind Granite + DisplayName: é’风岗岩 Tooltip: "" } BloodLightCrystal: { - DisplayName: Blood Light Crystal + DisplayName: 血解光石 Tooltip: "" } LiftLamp: { - DisplayName: Lift Lamp + DisplayName: ç”µæ¢¯ç¯ Tooltip: "" } LiftWinch: { - DisplayName: Lift Winch + DisplayName: 电梯绞盘 Tooltip: "" } YggdrasilGrayRock_Item: { - DisplayName: Yggdrasil Gray Rock_ Item + DisplayName: 天穹ç°å²© Tooltip: "" } YggdrasilWorldPylon_Item: { - DisplayName: Yggdrasil World Pylon_ Item + DisplayName: åŽŸåˆæ™¶å¡” Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Potions.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Potions.hjson index 795f1fd71..bee8cb40e 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Potions.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Potions.hjson @@ -1,19 +1,19 @@ EnergyDrink: { - DisplayName: Energy Drink + DisplayName: 能é‡é¥®æ–™ Tooltip: "" } ShadowPotion: { - DisplayName: Shadow Potion + DisplayName: æš—å½±è¯å‰‚ Tooltip: "" } GuidePotion: { - DisplayName: Guide Potion + DisplayName: å¼•è·¯è¯æ°´ Tooltip: "" } RayPotion: { - DisplayName: Ray Potion + DisplayName: éœžå…‰è¯æ°´ Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.SummonItems.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.SummonItems.hjson index 0a8d75541..2f2196b12 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.SummonItems.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.SummonItems.hjson @@ -1,9 +1,9 @@ EvilCocoon: { - DisplayName: Evil Cocoon + DisplayName: 邪茧 Tooltip: "" } JellyBallDaifuku: { - DisplayName: Jelly Ball Daifuku + DisplayName: çƒå†»å¤§ç¦ Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Tools.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Tools.hjson index e26a34c58..59fdae473 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Tools.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Tools.hjson @@ -1,64 +1,64 @@ DragonScaleHammer: { - DisplayName: Dragon Scale Hammer + DisplayName: 龙鳞木锤 Tooltip: "" } LampWoodHammer: { - DisplayName: Lamp Wood Hammer + DisplayName: ç¯æœ¨é”¤ Tooltip: "" } AmberFlowerHook: { - DisplayName: Amber Flower Hook + DisplayName: ç¥ç€èб钩 Tooltip: "" } ClimbingPickaxe: { - DisplayName: Climbing Pickaxe + DisplayName: æ”€çˆ¬é• Tooltip: "" } CyanVineAxe: { - DisplayName: Cyan Vine Axe + DisplayName: é’缎斧 Tooltip: "" } CyanVineHammer: { - DisplayName: Cyan Vine Hammer + DisplayName: é’缎锤 Tooltip: "" } CyanVinePickaxe: { - DisplayName: Cyan Vine Pickaxe + DisplayName: é’ç¼Žé• Tooltip: "" } FlappedHangGlider: { - DisplayName: Flapped Hang Glider + DisplayName: æŠ˜æŸæ»‘翔翼 Tooltip: "" } GlowstickLauncher: { - DisplayName: Glowstick Launcher + DisplayName: è§å…‰æ£’å‘射器 Tooltip: "" } HangGlider: { - DisplayName: Hang Glider + DisplayName: 滑翔翼 Tooltip: "" } MiningPowerPickaxe: { - DisplayName: Mining Power Pickaxe + DisplayName: çŸ¿ç”¨åŠ¨åŠ›é• Tooltip: "" } OldPickaxe: { - DisplayName: Old Pickaxe + DisplayName: æ—§é• Tooltip: "" } OldPortableLamp: { - DisplayName: Old Portable Lamp + DisplayName: æ—§æç¯ Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.TreasureBags.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.TreasureBags.hjson index ecd236a66..c2308f697 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.TreasureBags.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.TreasureBags.hjson @@ -1,14 +1,14 @@ TuskTreasureBag: { - DisplayName: Tusk Treasure Bag + DisplayName: 鲜血ç ç‰™å®è—袋 Tooltip: "" } CorruptMothTreasureBag: { - DisplayName: Corrupt Moth Treasure Bag + DisplayName: è…æª€å·¨è›¾å®è—袋 Tooltip: "" } SquamousShellTreasureBag: { - DisplayName: Squamous Shell Treasure Bag + DisplayName: 龙鳞å¤å£³å®è—袋 Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Vanity.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Vanity.hjson index 8d66d8c88..3fdddd152 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Vanity.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Vanity.hjson @@ -1,4 +1,4 @@ Acytaea_horn: { - DisplayName: Acytaea_horn + DisplayName: 雅斯塔亚的角 Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Magic.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Magic.hjson index 1a889f0eb..92731771c 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Magic.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Magic.hjson @@ -14,179 +14,214 @@ FeatheredStaff: { CyanAmberStaff: { DisplayName: é’ç¼Žæ•´æµæ– + Tooltip: å‘å°„æ··åˆäº†é’缎能é‡å’Œå¤©ç©¹ç¥ç€çš„ä¸ç¨³å®šç‰©è´¨å›¢å— } HandholdItem: { - DisplayName: Handhold Item + DisplayName: 手æŒå¼ç‰©å“ Tooltip: "" } CreamChocolateCupStaff: { - DisplayName: Cream Chocolate Cup Staff - Tooltip: "" + DisplayName: å¥¶æ²¹å·§å…‹åŠ›æ¯æ³•æ– + Tooltip: + ''' + å‘å°„ä¸åŒå½¢çŠ¶çš„å·§å…‹åŠ›å— + å³é”®å¯ä»¥ç”¨è¾ƒå¤§çš„æŽ¨åŠ›æŒ¤å‡ºä¸€æ¡å¥¶æ²¹ + ''' } FrostBomb: { - DisplayName: Frost Bomb - Tooltip: "" + DisplayName: 寒霜炸弹 + Tooltip: + ''' + 左键å‘å°„è½åœ°å³çˆ†çš„å°ç‚¸å¼¹ + å³é”®å‘射需è¦å°ç‚¸å¼¹è§¦å‘或接触敌人æ‰çˆ†ç‚¸çš„大炸弹 + çˆ†ç‚¸ä¼šç»™é™„è¿‘æ•Œäººé™„åŠ éœœç« + ''' } ToothMagicBall: { - DisplayName: Tooth Magic Ball - Tooltip: "" + DisplayName: ç ç‰™æ³•çƒ + Tooltip: "å‘射血团" } DreamWeaver: { - DisplayName: Dream Weaver - Tooltip: "" + DisplayName: 织梦ä¸é›¨ + Tooltip: "编造è“è‰²çš„é›¨ä¸æ”»å‡»æ•Œäºº" } DustOfCorrupt: { - DisplayName: Dust Of Corrupt - Tooltip: "" + DisplayName: è…化粉尘 + Tooltip: "喷出æŸç§å¤œå…‰é³žç¿…目的翅膀上的粉末,æ®è¯´ä¼šå¯¼è‡´è¿‡æ•" } FlowLightMissile: { - DisplayName: Flow Light Missile - Tooltip: "" + DisplayName: æµå…‰å¯¼å¼¹ + Tooltip: "å‘射直线轨迹的爆裂晶体,蓄力使å¨åŠ›æå‡" } GlowBeadGun: { - DisplayName: Glow Bead Gun - Tooltip: "" + DisplayName: è§å…‰è¿žç ç‚® + Tooltip: "蓄力以å‘射一连串的爆破å­" } NavyThunder: { - DisplayName: Navy Thunder - Tooltip: "" + DisplayName: è“焰炸雷 + Tooltip: "从黑色骷髅嘴里喷出è“色爆弹,需è¦ä¸€å®šæ—¶é—´æ‰ä¼šçˆ†ç‚¸" } LilyHarp: { - DisplayName: Lily Harp - Tooltip: "" + DisplayName: é“ƒå…°ç«–ç´ + Tooltip: "å¼¹å¥ä¼šè¿½è¸ªçš„音符" } BoneFeatherMagic: { - DisplayName: Bone Feather Magic - Tooltip: "" + DisplayName: 骨羽魔法书 + Tooltip: "è®°è½½ç€æŠŠéª¨ç¾½å½“ä½œé£žé•–å‘射的法术" } DarkFlower: { - DisplayName: Dark Flower - Tooltip: "" + DisplayName: 暗之花 + Tooltip: "射出暗影çƒ" } FeatherMagic: { - DisplayName: Feather Magic - Tooltip: "" + DisplayName: 羽魔法书 + Tooltip: "è®°è½½ç€æŠŠç¾½æ¯›å½“ä½œé£žé•–å‘射的法术" } FireFeatherMagic: { - DisplayName: Fire Feather Magic - Tooltip: "" + DisplayName: ç«ç¾½é­”法书 + Tooltip: "è®°è½½ç€æŠŠç«ç¾½å½“作飞镖å‘射的法术" } FreezeFeatherMagic: { - DisplayName: Freeze Feather Magic - Tooltip: "" + DisplayName: 冰羽魔法书 + Tooltip: "è®°è½½ç€æŠŠå†°ç¾½å½“ä½œé£žé•–å‘射的法术" } ThunderFlower: { - DisplayName: Thunder Flower - Tooltip: "" + DisplayName: 雷之花 + Tooltip: "射出电光çƒ" } LanternBombRemoteControl: { - DisplayName: Lantern Bomb Remote Control - Tooltip: "" + DisplayName: ç¯ç¬¼é¥æŽ§å™¨ + Tooltip: "å¼€å‘者物å“,内å«é«˜èƒ½ç‚¸å¼¹ï¼Œä¸æ°å½“使用å¯èƒ½ä¼šå¯¼è‡´æ¯å›¾" } AmberMagicOrb: { - DisplayName: Amber Magic Orb - Tooltip: "" + DisplayName: 天ç¥ç€æ³•çƒ + Tooltip: "å‘射若干个ç¥ç€ç ï¼Œç¥ç€ç å®¹æ˜“与其他ç¥ç€ç ç²˜è¿ž" } BloodySwamp: { - DisplayName: Bloody Swamp - Tooltip: "" + DisplayName: 浸血泥沼 + Tooltip: + ''' + å‘å°„æ³•æœ¯æ¨¡æ‹Ÿçš„è¡€æµ + å³é”®æ¶ˆè€—40法力å‘射一个加速回血的圆形领域 + ''' } HexaCrystalStaff: { - DisplayName: Hexa Crystal Staff - Tooltip: "" + DisplayName: å…­æ£±çŸ³èŠ±æ– + Tooltip: + ''' + 射出能分裂æˆ6个的è“色暮光晶体飞弹,附加暮光晶体脆弱 + ''' } MagicOfLightAndShadow: { - DisplayName: Magic Of Light And Shadow - Tooltip: "" + DisplayName: ç¯å½±æˆæ³• + Tooltip: "å‘å°„ä¸€æŸæ©˜é»„色光线,且能åå°„2æ¬¡ï¼Œæ¯æ¬¡åå°„å¨åŠ›å‡åŠ" } NightfireStaff: { - DisplayName: Nightfire Staff - Tooltip: "" + DisplayName: å¤œç«æ³•æ– + Tooltip: "射出夜ç«é£žå¼¹" } RockQuake: { - DisplayName: Rock Quake - Tooltip: "" + DisplayName: é‡å²©çˆ†è£‚ + Tooltip: "å‘射一æŸåŠ›åœºï¼Œä¸ä¼šç›´æŽ¥é€ æˆä¼¤å®³ï¼Œä½†æ˜¯ç©¿é€å®žä½“æ–¹å—æ—¶ä¼šä»Žæ–¹å—内部长出尖刺" } SmeltingStaff: { - DisplayName: Smelting Staff - Tooltip: "" + DisplayName: ç†”ç‚¼æ³•æ– + Tooltip: "æ‰‹æŒæ—¶å‘¨å›´ç«‹å³ç”Ÿæˆä¸€ä¸ªèƒ½ç‚¹ç‡ƒæ•Œäººçš„岩浆法环,在环内点击å³å¯è½°ç‚¸" } YggdrasilAmberLaser: { - DisplayName: Yggdrasil Amber Laser - Tooltip: "" + DisplayName: 天ç¥ç€å…‰æŸ + Tooltip: + ''' + å‘射一æŸç¥ç€è‰²çš„æ¿€å…‰ï¼Œå‡»ä¸­å®žä½“æ–¹å—åŽä¼šåœ¨ä¸Šé¢äº§ç”Ÿç¥ç€ç»“æ™¶ + ç¥ç€ç»“晶也能对路过滴人造æˆä¼¤å®³ + ''' } EyeOfAnabiosis: { - DisplayName: Eye Of Anabiosis - Tooltip: "" + DisplayName: éšç”Ÿä¹‹çœ¼ + Tooltip: + ''' + 手æŒå³å¼€å§‹å……能,12ç§’åŽå¯ä»¥æ”»å‡» + å‘å°„é’è“色追踪ç«ç„° + å¯ä»¥åŒæ—¶æ”»å‡»3个目标 + ''' } FlurryingBlades: { - DisplayName: Flurrying Blades - Tooltip: "" + DisplayName: 微风之刃 + Tooltip: "从书页中å·èµ·ä¸€ä¸ªé£Žåˆƒçƒï¼Œå¯¹è¿‘è·ç¦»ç›®æ ‡é€ æˆå¤šæ®µä¼¤å®³" } VitalizedRocks: { - DisplayName: Vitalized Rocks - Tooltip: "" + DisplayName: 显生岩核 + Tooltip: "从虚空中构造出大å°ä¸ä¸€çš„岩石éšåŽæŠ•æŽ·" } BronzeLotusLamp: { - DisplayName: Bronze Lotus Lamp - Tooltip: "" + DisplayName: é’é“œèŽ²èŠ±ç¯ + Tooltip: "å–·å°„é’莲地心ç«ï¼Œæœ‰æ¦‚率å‘射会爆炸的é’ç«èŠ±è•¾" } LightBeamStaff: { - DisplayName: Light Beam Staff - Tooltip: "" + DisplayName: ç¯æŸæ³•æ– + Tooltip: + ''' + å‘射一æŸå…‰ï¼Œé™„带光解效果,击中物å—åŽç•™ä¸‹ç…§æ˜Žä¿¡æ ‡ + "ç¯æŸç¬”ç›´ï¼Œåƒæžäº†åˆæ¥ä¹åˆ°è€…çš„å‘å¾€" + ''' } CyanVineStaff: { - DisplayName: Cyan Vine Staff - Tooltip: "" + DisplayName: é’ç¼Žæ³•æ– + Tooltip: "使用é’缎å‡å—进行简å•的法术攻击" } AncientSyringe: { - DisplayName: Ancient Syringe - Tooltip: "" + DisplayName: 夿—§çš„æ³¨å°„器 + Tooltip: "往敌人体内注射感染性孢å­" } BacterialAgent: { - DisplayName: Bacterial Agent - Tooltip: "" + DisplayName: ç»†èŒæº¶æ¶²ç“¶ + Tooltip: "æŠ•æŽ·å‡ºåŽ»åŽæ•£æ­¥æ„ŸæŸ“性孢å­" } DevilHeartStaff: { - DisplayName: Devil Heart Staff - Tooltip: "" + DisplayName: é­”å¿ƒæ³•æ– + Tooltip: "攻击8次åŽä¸‹æ¬¡æ”»å‡»ä¸ºç‰¹æ®Šæ”»å‡»ï¼Œå¨åŠ›åŠ å¤§ä¸”é™„å¸¦å‡‹äº¡æŸä¼¤" } SightOfTile: { - DisplayName: Sight Of Tile - Tooltip: "" + DisplayName: 物å—记录器 + Tooltip: + ''' + å¼€å‘者物å“,也供建筑家使用,å…许编辑物å—地图 + 已具有较完善的GUI和引导系统 + è­¦å‘Šï¼šè¯·å‹¿ç”¨äºŽåˆ‡å‰²ç®±å­ + ''' } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Melee.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Melee.hjson index 2bfd041e1..cb4a42839 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Melee.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Melee.hjson @@ -9,506 +9,563 @@ RodSpear: { } BloodGoldBayonet: { - DisplayName: Blood Gold Bayonet - Tooltip: "" + DisplayName: 血金刺剑 + Tooltip: + ''' + å‘½ä¸­æ•ŒäººåŽæœ‰1/25的概率å¸è¡€,å¸è¡€é‡ä¸ºé€ æˆä¼¤å®³çš„30% + 命中的敌人未死之å‰,你的生命回å¤+2 + å³é”®é‡å‡»ï¼šä»¥è‡ªèº«æŸå¤±15血为代价,对被命中的敌人施加æŒç»­3s的嗜血符å°,血金刺剑命中有符å°çš„æ•Œäººé€ æˆå›žè¡€ + 'æ®ä¸å®Œå…¨ç»Ÿè®¡ï¼Œå¤šæ•°å¸è¡€é¬¼å¹¶ä¸ä¼šå¸å–å²èޱ姆æ±' + ''' } BlossomThorn: { - DisplayName: Blossom Thorn - Tooltip: "" + DisplayName: çº¢æ¢…è½ + Tooltip: + ''' + 产生方å‘éšæœºçš„二级刺锋 + '兼具美观与锋芒' + ''' } BlueRibbonBayonet: { - DisplayName: Blue Ribbon Bayonet + DisplayName: è“缎带刺剑 Tooltip: "" } CopperBayonet: { - DisplayName: Copper Bayonet + DisplayName: 铜刺剑 Tooltip: "" } CrutchBayonet: { - DisplayName: Crutch Bayonet - Tooltip: "" + DisplayName: æ‹åˆºå‰‘ + Tooltip: + ''' + 第一次命中敌人åŽå¦‚果暴击则造æˆ270%的伤害 + '特务使用的武器,éžå¸¸é€‚åˆæš—æ€' + ''' } CurseFlameStabbingSword: { - DisplayName: Curse Flame Stabbing Sword - Tooltip: "" + DisplayName: å’’ç«åˆºå‰‘ + Tooltip: "用诅咒ç«ç„°ç‚¹ç‡ƒæ•Œäººï¼" } DreamStar: { - DisplayName: Dream Star - Tooltip: "" + DisplayName: 梦辰星刺 + Tooltip: + ''' + æ¯æ¬¡å‘½ä¸­éƒ½ä¼šç»™æ•Œäººæ ‡ä¸Š1层[角星标] + 5层[角星标]åˆæˆä¸€ä¸ª[星标],获得[星标]的敌人ä¸ä¼šå†èŽ·å¾—æ›´å¤š[角星标] + 对于åŒä¸€æŠŠ[梦辰星刺],场上最多存在两个被[星标]或角[星标]标记的敌人 + 两个[星标]çš„å‡ºçŽ°ä¼šåœ¨ä¸¤å¤„åŒæ—¶å¼•å‘220%å€çŽ‡çš„æ˜Ÿè¾‰çˆ†ç‚¸ï¼Œå¹¶æ‘§æ¯å…ˆè¢«æ ‡è®°çš„æ•Œäººçš„[星标] + 目标敌人若没有[星标],且场上已存在被你命中过但是[角星标]ä¸è¶³5个的敌人,也会在目标敌人和被[角星标]标记的角色处引å‘较å°çš„æ˜Ÿè¾‰çˆ†ç‚¸ï¼Œå¨åŠ›å–决于[角星标]层数 + 带有[星标]的敌人被击æ€ä¼šæŽ‰è½æ˜Ÿä¹‹ç§ï¼Œæ‹¾å–åŽä¸‹æ¬¡é€ æˆä¼¤å®³å¿…定暴击且伤害*264% + '读懂星空需è¦å¤æ‚深邃的ç†è®ºçŸ¥è¯†ï¼Œè§‚èµæ˜Ÿç©ºåªéœ€è¦ä¸€åªçœ¼ç›' + ''' } EnchantedBayonet: { - DisplayName: Enchanted Bayonet - Tooltip: "" + DisplayName: 附魔刺剑 + Tooltip: "å³é”®é‡å‡»ä¼šæ”¾å‡ºä¸å—é‡åŠ›çš„å‰‘æ°”" } EternalNight: { - DisplayName: Eternal Night - Tooltip: "" + DisplayName: 永夜刺剑 + Tooltip: "击中åŽå¯ä»¥é‡Šæ”¾è¿½é­‚影刺剑" } GoldenStabbingSword: { - DisplayName: Golden Stabbing Sword + DisplayName: 金刺剑 Tooltip: "" } HolyBayonet: { - DisplayName: Holy Bayonet + DisplayName: 神圣刺剑 Tooltip: "" } IchorBayonet: { - DisplayName: Ichor Bayonet + DisplayName: çµæ¶²åˆºå‰‘ Tooltip: "" } IronStabbingSword: { - DisplayName: Iron Stabbing Sword + DisplayName: é“刺剑 Tooltip: "" } LeadStabbingSword: { - DisplayName: Lead Stabbing Sword + DisplayName: 铅刺剑 Tooltip: "" } MechanicMosquito: { - DisplayName: Mechanic Mosquito - Tooltip: "" + DisplayName: 械蚊刺 + Tooltip: "å¬å”¤ä¸‰ä¸ªä¼šå¸è¡€çš„æœºæ¢°èšŠå­å助攻击,èšŠå­æ¯æ¬¡æ”»å‡»ä¼šèŽ·å¾—1点å¸è¡€ï¼Œæœ€å¤šç´¯ç§¯10点。使用结æŸä¹‹åŽï¼Œæ²»ç–—å¸è¡€ç´¯ç§¯çš„点数" } PlatinumStabbingSword: { - DisplayName: Platinum Stabbing Sword + DisplayName: 铂金刺剑 Tooltip: "" } PrisonFireBayonet: { - DisplayName: Prison Fire Bayonet - Tooltip: "" + DisplayName: 狱ç«åˆºå‰‘ + Tooltip: + ''' + ç‚¹ç‡ƒæ•Œäººï¼ + 在水里无法点燃,但是在熔岩里造æˆä¸¤å€ä¼¤å®³ + '切勿伤敌一万自æŸå…«åƒ' + ''' } RedRibbonBayonet: { - DisplayName: Red Ribbon Bayonet + DisplayName: 红缎带刺剑 Tooltip: "" } RottenGoldBayonet: { - DisplayName: Rotten Gold Bayonet - Tooltip: "" + DisplayName: 魔金刺剑 + Tooltip: + ''' + 命中åŽå‰Šå¼±ç›®æ ‡1点防御力 + 延时一秒在命中处生æˆä¸‰é“200%å€çŽ‡çš„é­”é‡‘å‰‘å…‰ + 对于åŒä¸€æŠŠ[魔金刺剑],ä¸Šè¿°ä¸¤ç§æ•ˆæžœ1秒最多触å‘1次,ä½†æ˜¯æ€»æ•°æ²¡æœ‰ä¸Šé™ + ''' } SilverStabbingSword: { - DisplayName: Silver Stabbing Sword + DisplayName: 银刺剑 Tooltip: "" } SwordfishBeak: { - DisplayName: Swordfish Beak - Tooltip: "" + DisplayName: 剑鱼长喙 + Tooltip: "对于水里的敌人造æˆä¼¤å®³ä¸‹é™40%,但是潮湿状æ€ä¸‹æ”»å‡»èŒƒå›´æ‰©å¤§50%,且体力消耗é™ä½Ž35%,对于干燥的敌人伤害æé«˜40%" } TinStabbingSword: { - DisplayName: Tin Stabbing Sword + DisplayName: 锡刺剑 Tooltip: "" } TungstenStabbingSword: { - DisplayName: Tungsten Stabbing Sword + DisplayName: 钨刺剑 Tooltip: "" } VegetationBayonet: { - DisplayName: Vegetation Bayonet - Tooltip: "" + DisplayName: 葱èŒåˆºå‰‘ + Tooltip: + ''' + 会造æˆä¸­æ¯’ + 使用6秒之åŽè‡ªå·±ä¹Ÿä¼šå˜å¾—狂野 + '看到那åªè™è äº†å—,它的蛋白质是牛肉的六å€' + ''' } VertebralSpur: { - DisplayName: Vertebral Spur - Tooltip: "" + DisplayName: 椎刺骨 + Tooltip: + ''' + 在与目标相对速度较大的情况下æå‡ä¼¤å®³ï¼Œæœ€å¤šä¸è¶…过500% + '粗糙的接触é¢é€ æˆçš„æ¯åéšé€Ÿåº¦çš„增加急剧æé«˜' + ''' } YoenLeZed: { - DisplayName: Yoen Le Zed - Tooltip: "" + DisplayName: 陨雷之劫刺剑 + Tooltip: + ''' + 攻击附带雷电,水中雷电伤害翻三å€ä¸”更容易传导 + 比考场忘带身份è¯è¿˜åˆºæ¿€ä¸€ç‚¹ + ''' } CheeseYoyo: { - DisplayName: Cheese Yoyo + DisplayName: èŠå£«çƒ Tooltip: "" } FryingPanItem: { - DisplayName: Frying Pan Item - Tooltip: "" + DisplayName: 平底锅 + Tooltip: + ''' + å³é”®å¯ä»¥é‡å‡» + ''' } VortexVanquisherItem: { - DisplayName: Vortex Vanquisher Item - Tooltip: "" + DisplayName: 贯虹之槊 + Tooltip: + ''' + å³é”®å¯ä»¥å¬å”¤[地心],并生æˆå¯ä»¥å¸æ”¶ä¼¤å®³çš„[玉璋护盾] + 中键å¬å”¤[天星],造æˆå¤§èŒƒå›´ä¼¤å®³å’ŒçŸ³åŒ– + ''' } PineStab: { - DisplayName: Pine Stab - Tooltip: "" + DisplayName: æ¾é’ˆåˆº + Tooltip: + ''' + åªè€—è´¹72%的体力,因为æ¾å¶å¾ˆè½» + 所以怪物的防御力3倿œ‰æ•ˆ + ''' } BloodyBoneYoyo: { - DisplayName: Bloody Bone Yoyo - Tooltip: "" + DisplayName: è¡€é«“çƒ + Tooltip: "会伸出触手攻击附近敌人" } ToothKnife: { - DisplayName: Tooth Knife + DisplayName: 齿刃 Tooltip: "" } ToothSpear: { - DisplayName: Tooth Spear + DisplayName: ç ç‰™çŸ› Tooltip: "" } GlowWoodSword: { - DisplayName: Glow Wood Sword + DisplayName: æµè¤æœ¨å‰‘ Tooltip: "" } MothYoyo: { - DisplayName: Moth Yoyo - Tooltip: "" + DisplayName: å¤œè›¾çƒ + Tooltip: "æ‚ æ‚ çƒé™„近会有è§å…‰é£žè›¾å¹»æ–¹" } ScaleWingBlade: { - DisplayName: Scale Wing Blade - Tooltip: "" + DisplayName: 鳞翅之刃 + Tooltip: "å³é”®å¯ä»¥é‡å‡»" } ComingGhost: { - DisplayName: Coming Ghost - Tooltip: "" + DisplayName: 诡弑 + Tooltip: "æ”»å‡»æ—¶æœ‰æ¦‚çŽ‡ç”¨é¬¼çˆªéšæœºæ— è§†è·ç¦»åœ°æ”»å‡»ä¸€ä¸ªæ•Œäºº" } CyanFrost: { - DisplayName: Cyan Frost - Tooltip: "" + DisplayName: é’霜剑 + Tooltip: "附带霜ç«" } Glow: { - DisplayName: Glow - Tooltip: "" + DisplayName: æµå…‰ + Tooltip: "ç å‡ºé‡‘色剑气并å¬å”¤è½ä¸‹çš„è“色星辉" } GoldRoundYoyo: { - DisplayName: Gold Round Yoyo + DisplayName: é‡‘è½®çƒ Tooltip: "" } PrimordialJadeWinged_Spear: { - DisplayName: Primordial Jade Winged_ Spear - Tooltip: "" + DisplayName: 和璞鸢 + Tooltip: "在一定高度使用时会改为下砸,å³é”®å¯ä»¥æœä»»æ„æ–¹å‘çªåˆº" } Sunflower: { - DisplayName: Sunflower + DisplayName: 呿—¥é£žç›˜ Tooltip: "" } World: { - DisplayName: World - Tooltip: "" + DisplayName: 世界斩裂 + Tooltip: + ''' + å³é”®å¯ä»¥åˆ‡æ¢è¿½é𿍡å¼å’Œæ–©åˆ‡æ¨¡å¼ + è¿½éšæ¨¡å¼ä¸‹[世界斩裂]会åœç•™åœ¨é¼ æ ‡ä½ç½®ï¼Œæ²¿ç€é¼ æ ‡çš„路线切割敌人 + 斩切模å¼ä¸‹[世界斩裂]会åå¤å¿«é€Ÿè´¯ç©¿é¼ æ ‡ + ''' } AdamantiteClub_Item: { - DisplayName: Adamantite Club_ Item - Tooltip: "" + DisplayName: ç²¾é‡‘æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } BorealWoodClub_Item: { - DisplayName: Boreal Wood Club_ Item - Tooltip: "" + DisplayName: çç æœ¨æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } CactusClub_Item: { - DisplayName: Cactus Club_ Item - Tooltip: "" + DisplayName: ä»™äººæŽŒæ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } ChlorophyteClub_Item: { - DisplayName: Chlorophyte Club_ Item - Tooltip: "" + DisplayName: å¶ç»¿æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } CobaltClub_Item: { - DisplayName: Cobalt Club_ Item - Tooltip: "" + DisplayName: é’´æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } CopperClub_Item: { - DisplayName: Copper Club_ Item - Tooltip: "" + DisplayName: é“œæ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } CorruptClub_Item: { - DisplayName: Corrupt Club_ Item - Tooltip: "" + DisplayName: é­”é‡‘æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } CrimsonClub_Item: { - DisplayName: Crimson Club_ Item - Tooltip: "" + DisplayName: è¡€é‡‘æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } CrystalClub_Item: { - DisplayName: Crystal Club_ Item - Tooltip: "" + DisplayName: æ°´æ™¶æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } CurseClub_Item: { - DisplayName: Curse Club_ Item - Tooltip: "" + DisplayName: å’’ç«æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } EbonwoodClub_Item: { - DisplayName: Ebonwood Club_ Item - Tooltip: "" + DisplayName: ä¹Œæœ¨æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } GoldClub_Item: { - DisplayName: Gold Club_ Item - Tooltip: "" + DisplayName: é‡‘æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } IchorClub_Item: { - DisplayName: Ichor Club_ Item - Tooltip: "" + DisplayName: çµæ¶²æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } IronClub_Item: { - DisplayName: Iron Club_ Item - Tooltip: "" + DisplayName: 铿£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } LeadClub_Item: { - DisplayName: Lead Club_ Item - Tooltip: "" + DisplayName: é“…æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } MeteorClub_Item: { - DisplayName: Meteor Club_ Item - Tooltip: "" + DisplayName: é™¨çŸ³æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } MythrilClub_Item: { - DisplayName: Mythril Club_ Item - Tooltip: "" + DisplayName: ç§˜é“¶æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } OrichalcumClub_Item: { - DisplayName: Orichalcum Club_ Item - Tooltip: "" + DisplayName: å±±é“œæ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } PalladiumClub_Item: { - DisplayName: Palladium Club_ Item - Tooltip: "" + DisplayName: é’¯é‡‘æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } PalmWoodClub_Item: { - DisplayName: Palm Wood Club_ Item - Tooltip: "" + DisplayName: æ£•æ¦ˆæœ¨æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } PearlwoodClub_Item: { - DisplayName: Pearlwood Club_ Item - Tooltip: "" + DisplayName: çç æœ¨æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } PlatinumClub_Item: { - DisplayName: Platinum Club_ Item - Tooltip: "" + DisplayName: é“‚é‡‘æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } RichMahoganyClub_Item: { - DisplayName: Rich Mahogany Club_ Item - Tooltip: "" + DisplayName: çº¢æœ¨æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } ShadewoodClub_Item: { - DisplayName: Shadewood Club_ Item - Tooltip: "" + DisplayName: æš—å½±æœ¨æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } SilverClub_Item: { - DisplayName: Silver Club_ Item - Tooltip: "" + DisplayName: é“¶æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } SpikeClub_Item: { - DisplayName: Spike Club_ Item - Tooltip: "" + DisplayName: å°–åˆºæ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } StarDancer_Item: { - DisplayName: Star Dancer_ Item - Tooltip: "" + DisplayName: æ˜Ÿèˆžè€…æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } TinClub_Item: { - DisplayName: Tin Club_ Item - Tooltip: "" + DisplayName: é”¡æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } TitaniumClub_Item: { - DisplayName: Titanium Club_ Item - Tooltip: "" + DisplayName: é’›é‡‘æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } TungstenClub_Item: { - DisplayName: Tungsten Club_ Item - Tooltip: "" + DisplayName: é’¨æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } WoodenClub_Item: { - DisplayName: Wooden Club_ Item - Tooltip: "" + DisplayName: æœ¨æ£æ£’ + Tooltip: "一定高度åŽå³é”®å¯ä¸‹ç ¸" } Acytaea_sword_Item: { - DisplayName: Acytaea_sword_ Item + DisplayName: 雅斯塔亚的剑 Tooltip: "" } CactusBall: { - DisplayName: Cactus Ball + DisplayName: ä»™äººæŽŒé“¾çƒ Tooltip: "" } AmberHeadedSpear: { - DisplayName: Amber Headed Spear + DisplayName: ç¥ç€çŸ› Tooltip: "" } AmethystHeadedSpear: { - DisplayName: Amethyst Headed Spear + DisplayName: 紫晶矛 Tooltip: "" } CeremonialBlade: { - DisplayName: Ceremonial Blade + DisplayName: 仪å¼ä½©åˆ€ Tooltip: "" } DarkMassacreDagger: { - DisplayName: Dark Massacre Dagger + DisplayName: 暗金屠æ€åˆ€ Tooltip: "" } MagicalBoomerang: { - DisplayName: Magical Boomerang - Tooltip: "" + DisplayName: 魔术回旋镖 + Tooltip: "å‘射出去åŽç‚¹å‡»ä½¿ä¹‹åˆ†è£‚为8个å­å›žæ—‹é•–" } QuenchingBlade: { - DisplayName: Quenching Blade + DisplayName: æ·¬ç«é’¢ç‰‡ Tooltip: "" } ResistanceWireBayonet: { - DisplayName: Resistance Wire Bayonet - Tooltip: "" + DisplayName: 电阻刺剑 + Tooltip: "ä¸ä½¿ç”¨æ—¶é€æ¸å……能并æå‡å¨åŠ›ï¼Œå‡»ä¸­æ•ŒäººåŽå¤±åŽ»å……èƒ½æ•ˆæžœ" } ScarpasScissors: { - DisplayName: Scarpas Scissors + DisplayName: æ–¯å¡å¸•的剪刀 Tooltip: "" } TopaztHeadedSpear: { - DisplayName: Topazt Headed Spear + DisplayName: 黄玉矛 Tooltip: "" } TwilightEucalyptusBlade: { - DisplayName: Twilight Eucalyptus Blade + DisplayName: 暮桉木刃 Tooltip: "" } TwilightEucalyptusBoomerangKnift: { - DisplayName: Twilight Eucalyptus Boomerang Knift + DisplayName: 暮桉木回旋刀 Tooltip: "" } TwilightEucalyptusCuffSickle: { - DisplayName: Twilight Eucalyptus Cuff Sickle - Tooltip: "" -} - -TwilightShamanStaff: { - DisplayName: Twilight Shaman Staff + DisplayName: 暮桉木袖刃 Tooltip: "" } HyperockSpear: { - DisplayName: Hyperock Spear + DisplayName: 天穹岩枪 Tooltip: "" } LampWoodSword: { - DisplayName: Lamp Wood Sword + DisplayName: ç¯æœ¨å‰‘ Tooltip: "" } LampWoodYoyo: { - DisplayName: Lamp Wood Yoyo + DisplayName: ç¯æœ¨çƒ Tooltip: "" } CyanVineShortsword: { - DisplayName: Cyan Vine Shortsword + DisplayName: é’缎短剑 Tooltip: "" } CyanVineSword: { - DisplayName: Cyan Vine Sword + DisplayName: é’缎剑 Tooltip: "" } BladeOfGreenMoss: { - DisplayName: Blade Of Green Moss + DisplayName: 绿苔之刃 Tooltip: "" } MeatLantern: { - DisplayName: Meat Lantern + DisplayName: 肉食性æç¯ Tooltip: "" } HandheldCircularSaw: { - DisplayName: Handheld Circular Saw + DisplayName: 手æŒå¼åœ†é”¯ Tooltip: "" } AcroporaSpear: { - DisplayName: Acropora Spear + DisplayName: 藻刃矛 Tooltip: "" } CharonDoubleSickle_Item: { - DisplayName: Charon Double Sickle_ Item + DisplayName: 碧绿åŒé•° Tooltip: "" } ShadowEulogist: { - DisplayName: Shadow Eulogist + DisplayName: 暗影赞颂者 Tooltip: "" } TrueDeathSickle: { - DisplayName: True Death Sickle - Tooltip: "" + DisplayName: 真·死神镰刀 + Tooltip: "用死ç«ç‚¹ç‡ƒæ•Œäºº" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Ranged.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Ranged.hjson index c18882fc8..3d7f55b47 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Ranged.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Ranged.hjson @@ -5,284 +5,303 @@ RazorbeakBow: { CyanVineBow: { DisplayName: é’缎弓 + Tooltip: "" } IcedSpear: { - DisplayName: Iced Spear + DisplayName: 冰尖投矛 Tooltip: "" } SpineGun: { - DisplayName: Spine Gun + DisplayName: 脊骨手枪 Tooltip: "" } ToothBow: { - DisplayName: Tooth Bow - Tooltip: "" + DisplayName: ç ç‰™å·¨å¼“ + Tooltip: "å‘射巨形ç ç‰™ç®­" } PhosphorescenceGun: { - DisplayName: Phosphorescence Gun + DisplayName: 磷光枪 Tooltip: "" } ShadowWingBow: { - DisplayName: Shadow Wing Bow - Tooltip: "" + DisplayName: 影翼巨弓 + Tooltip: "蓄力å‘射更多幻箭" } CloudGun: { - DisplayName: Cloud Gun - Tooltip: "" + DisplayName: 云导炮 + Tooltip: "å‘射云团" } SilveralGun: { - DisplayName: Silveral Gun + DisplayName: 银影手枪 Tooltip: "" } SilveralRifle: { - DisplayName: Silveral Rifle + DisplayName: 银影步枪 Tooltip: "" } AmbiguousNight: { - DisplayName: Ambiguous Night - Tooltip: "" + DisplayName: 幻夜弹弓 + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } AmethystSlingshot: { - DisplayName: Amethyst Slingshot - Tooltip: "" + DisplayName: 紫晶弹弓 + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } BorealWoodSlingshot: { - DisplayName: Boreal Wood Slingshot - Tooltip: "" + DisplayName: é’ˆå¶æœ¨å¼¹å¼“ + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } CactusSlingShot: { - DisplayName: Cactus Sling Shot - Tooltip: "" + DisplayName: 仙人掌弹弓 + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } DiamondSlingshot: { - DisplayName: Diamond Slingshot - Tooltip: "" + DisplayName: 钻石弹弓 + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } EbonwoodSlingshot: { - DisplayName: Ebonwood Slingshot - Tooltip: "" + DisplayName: 乌木弹弓 + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } EmeraldSlingshot: { - DisplayName: Emerald Slingshot - Tooltip: "" + DisplayName: 祖æ¯ç»¿å¼¹å¼“ + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } GelSlingshot: { - DisplayName: Gel Slingshot - Tooltip: "" + DisplayName: å‡èƒ¶å¼¹å¼“ + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } JungleSlingshot: { - DisplayName: Jungle Slingshot - Tooltip: "" + DisplayName: 丛林弹弓 + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } PalmWoodSlingshot: { - DisplayName: Palm Wood Slingshot - Tooltip: "" + DisplayName: 棕榈木弹弓 + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } PearlwoodSlingshot: { - DisplayName: Pearlwood Slingshot - Tooltip: "" + DisplayName: çç æœ¨å¼¹å¼“ + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } RichMahoganySlingshot: { - DisplayName: Rich Mahogany Slingshot - Tooltip: "" + DisplayName: 红木弹弓 + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } RubySlingshot: { - DisplayName: Ruby Slingshot - Tooltip: "" + DisplayName: 红å®çŸ³å¼¹å¼“ + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } SapphireSlingshot: { - DisplayName: Sapphire Slingshot - Tooltip: "" + DisplayName: è“å®çŸ³å¼¹å¼“ + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } ShadewoodSlingShot: { - DisplayName: Shadewood Sling Shot - Tooltip: "" + DisplayName: 暗影木弹弓 + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } StarSlingshot: { - DisplayName: Star Slingshot - Tooltip: "" + DisplayName: 星星弹弓 + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } TopazSlingshot: { - DisplayName: Topaz Slingshot - Tooltip: "" + DisplayName: 黄玉弹弓 + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } WoodSlingshot: { - DisplayName: Wood Slingshot - Tooltip: "" + DisplayName: 木弹弓 + Tooltip: "䏿¶ˆè€—å¼¹è¯ï¼Œè“„力æå‡å¨åŠ›" } CloudBall: { - DisplayName: Cloud Ball + DisplayName: 云团 Tooltip: "" } RampageShark: { - DisplayName: Rampage Shark - Tooltip: "" + DisplayName: å¤ä»‡é²¨ + Tooltip: "使用一定时间åŽè¿‡çƒ­ï¼Œå°„速æå‡ä½†æ˜¯å‡†åº¦ä¸‹é™" } TsunamiShark: { - DisplayName: Tsunami Shark - Tooltip: "" + DisplayName: 海啸鲨 + Tooltip: + ''' + å³é”®å¯ä»¥æ ‡è®°æ•Œäºº + 击中敌人åŽç”Ÿæˆé²¨é±¼å¯¼å¼¹ + 导弹会辅助攻击被标记敌人 + ''' } ArmorPiercingBlaster: { - DisplayName: Armor Piercing Blaster - Tooltip: "" + DisplayName: ç©¿ç”²çˆ†ç ´å­ + Tooltip: "丢出去åŽåœ¨æ•Œäººé è¿‘æ—¶æ‰çˆ†ç‚¸ï¼Œå‰Šå‡å…¶é˜²å¾¡åŠ›10ç§’" } Caltrop: { - DisplayName: Caltrop + DisplayName: é“蒺藜 Tooltip: "" } CeremonialRifle: { - DisplayName: Ceremonial Rifle + DisplayName: 仪å¼ç”¨æžª Tooltip: "" } GunOfAvarice: { - DisplayName: Gun Of Avarice - Tooltip: "" + DisplayName: 贪婪之铳 + Tooltip: + ''' + æ¯æ‰“完14å‘å­å¼¹è¿›è¡Œä¸€æ¬¡å¼¹åŒ£æ›´æ¢(45帧),期间无法攻击 + å¼¹åŒ£æ›´æ¢æˆåŠŸçŽ‡ä¸º80% + æˆåŠŸï¼šå¼¹åŒ£æ›´æ¢åŽç­‰çº§+1ä¼¤å®³è¾ƒä¹‹å‰æå‡25% + 失败:爆炸并å—åˆ°é¢æ¿ä¼¤å®³çš„2.8å€ä¼¤å®³ + æˆåŠŸæ•ˆæžœæœ€å¤šè¾¾åˆ°10级。 + å³é”®æ‰‹åŠ¨æ›´æ¢å¼¹åŒ£å¹¶ä½¿å¼¹åŒ£ç­‰çº§æ¸…é›¶ + æ¯æ¬¡å‘½ä¸­è®©æ•Œäººä»·å€¼+75铜 + ''' } Nehemoth: { - DisplayName: Nehemoth - Tooltip: "" + DisplayName: 低语者 + Tooltip: + '''. + å°†ç«æžªå­å¼¹å˜æˆé«˜é€Ÿç‰¹æ®Šå¼¹å¹•,无é™ç©¿é€ï¼Œå‘½ä¸­çš„生物有66%的概率获得瘟疫Debuff4ç§’ + 瘟疫能在敌人之间散步,造æˆç¾¤ä½“è¡€é‡æµå¤± + ''' } RustSlingshot: { - DisplayName: Rust Slingshot + DisplayName: 生锈弹弓 Tooltip: "" } SevenShotGun: { - DisplayName: Seven Shot Gun + DisplayName: 七å‘猎枪 Tooltip: "" } StoneJavelin: { - DisplayName: Stone Javelin + DisplayName: 岩石投矛 Tooltip: "" } RockSpikeBallista: { - DisplayName: Rock Spike Ballista + DisplayName: 碎裂投石 Tooltip: "" } BrittleRockSlingshot: { - DisplayName: Brittle Rock Slingshot + DisplayName: 碎石弹弓 Tooltip: "" } KissOfCthulhu: { - DisplayName: Kiss Of Cthulhu + DisplayName: å…‹è‹é²ä¹‹å» Tooltip: "" } BowOfEnlightment: { - DisplayName: Bow Of Enlightment + DisplayName: 坿˜Žä¹‹å¼“ Tooltip: "" } HandgunOfEnlightment: { - DisplayName: Handgun Of Enlightment + DisplayName: 坿˜Žæ‰‹æžª Tooltip: "" } LampWoodBow: { - DisplayName: Lamp Wood Bow + DisplayName: ç¯æœ¨å¼“ Tooltip: "" } CyanVineCrossBow: { - DisplayName: Cyan Vine Cross Bow + DisplayName: é’缎弩 Tooltip: "" } CyanVineFlintlock: { - DisplayName: Cyan Vine Flintlock + DisplayName: é’ç¼Žç‡§å‘æžª Tooltip: "" } CyanVineThrowingSpear: { - DisplayName: Cyan Vine Throwing Spear + DisplayName: é’缎投矛 Tooltip: "" } CaterpillarJuiceArrow: { - DisplayName: Caterpillar Juice Arrow + DisplayName: 虫æ±ç®­ Tooltip: "" } LightArrow: { - DisplayName: Light Arrow + DisplayName: ç¯æ²¹ç®­ Tooltip: "" } LightBullet: { - DisplayName: Light Bullet + DisplayName: ç¯æ²¹å¼¹ Tooltip: "" } RockArrow: { - DisplayName: Rock Arrow + DisplayName: 岩甲é‡ç®­ Tooltip: "" } GreenThornBallLauncher: { - DisplayName: Green Thorn Ball Launcher + DisplayName: é’刺çƒå‘射器 Tooltip: "" } MossyCyatheaBow: { - DisplayName: Mossy Cyathea Bow + DisplayName: é’苔桫椤弓 Tooltip: "" } DevilHeartBow: { - DisplayName: Devil Heart Bow + DisplayName: 魔心é“弓 Tooltip: "" } DevilHeartGun: { - DisplayName: Devil Heart Gun + DisplayName: 魔心手枪 Tooltip: "" } CyatheaArrow: { - DisplayName: Cyathea Arrow + DisplayName: 桫椤箭 Tooltip: "" } TerraViewerHowitzer: { - DisplayName: Terra Viewer Howitzer + DisplayName:泰拉观察者 Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Summon.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Summon.hjson index 89b46d4a5..958a9a2e9 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Summon.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.Items.Weapons.Summon.hjson @@ -13,86 +13,98 @@ AuburnBell: { } GrilledSquidTentacle: { - DisplayName: Grilled Squid Tentacle + DisplayName: 烤鱿鱼须 Tooltip: "" } ToothStaff: { - DisplayName: Tooth Staff - Tooltip: "" + DisplayName: ç ç‰™å¬å”¤æ– + Tooltip: "å¬å”¤ç ç‰™ä¸ºä½ è€Œæˆ˜" } DarknessFan: { - DisplayName: Darkness Fan - Tooltip: "" + DisplayName: å¹»è¶è¤ç«æ‰‡ + Tooltip: + ''' + å³é”®å¯ä»¥è¿œç¨‹æ”»å‡» + 标记最åŽä¸€ä¸ªè¢«å‡»ä¸­çš„æ•Œäºº + ''' } EvilChrysalis: { - DisplayName: Evil Chrysalis - Tooltip: "" + DisplayName: é‚ªèŒ§å­µåŒ–æ– + Tooltip: "å¬å”¤å°é£žè›¾ä½œæˆ˜" } XmasWhip: { - DisplayName: Xmas Whip + DisplayName: 圣诞树鞭 Tooltip: "" } ActivatedJellyGland: { - DisplayName: Activated Jelly Gland - Tooltip: "" + DisplayName: 活化çƒå†»è…ºä½“ + Tooltip: "å¬å”¤çƒå†»ä½œæˆ˜" } MeltingSideGyroscope: { - DisplayName: Melting Side Gyroscope + DisplayName: 熔边陀螺 Tooltip: "" } MidwinterNightmare: { - DisplayName: Midwinter Nightmare - Tooltip: "" + DisplayName: ç²¾çµæç¯ + Tooltip: + ''' + 哨兵,在地上å¬å”¤ä¸€å°¾éƒ¨æŒ‚有ç¯ç¬¼çš„矮树,当敌怪é è¿‘时,本体从地下伸出 + 有100%的近战伤害,20å¸§é—´éš”ï¼›åŒæ—¶æœ¬ä½“å‘射高速但短è·å¼¹å¹•攻击敌怪,造æˆ100%伤害,20帧间隔 + ''' } ThermoprobeStaff: { - DisplayName: Thermoprobe Staff - Tooltip: "" + DisplayName: 热探å•å…ƒæ– + Tooltip: + ''' + å¬å”¤1个浮游å•元,浮游å•元会对敌人å‘出ç«çƒã€‚æ¯ä¸ªæµ®æ¸¸å•元装有3å‘å¼¹è¯ï¼Œæ‰“å®Œé”€æ¯ + 最多拥有两å€å¬å”¤ä¸Šé™ä¸ªæµ®æ¸¸å•å…ƒ + ''' } WiltedForestLamp: { - DisplayName: Wilted Forest Lamp - Tooltip: "" + DisplayName: å‡‹é›¶æ£®ç¯ + Tooltip: "å¬å”¤èƒ½å‘射追踪法术的森ç¯ï¼Œé‡Šæ”¾ä¸€å®šæ³•术åŽä¼šè‡ªçˆ†é€ æˆèŒƒå›´å‡‹äº¡æŸä¼¤" } YggdrasilStoneGyroscope: { - DisplayName: Yggdrasil Stone Gyroscope + DisplayName: 天穹岩陀螺 Tooltip: "" } DeadBeetleEgg: { - DisplayName: Dead Beetle Egg + DisplayName: æ­»ç”²è™«åµ Tooltip: "" } EvilMusicRemnant: { - DisplayName: Evil Music Remnant + DisplayName: 魔律残章 Tooltip: "" } LegumeGyroscope: { - DisplayName: Legume Gyroscope + DisplayName: 裂èšé™€èžº Tooltip: "" } WoodlandWraithStaff: { - DisplayName: Woodland Wraith Staff + DisplayName: æ£®å®‡å¹½é­‚æ³•æ– Tooltip: "" } LichenTentacle: { - DisplayName: Lichen Tentacle + DisplayName: 真èŒè§¦æ‰‹ Tooltip: "" } DevilHeartGyroscope: { - DisplayName: Devil Heart Gyroscope + DisplayName: 魔心陀螺 Tooltip: "" } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.NPCs.TownNPCs.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.NPCs.TownNPCs.hjson index aa8604424..56d28ee91 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.NPCs.TownNPCs.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.NPCs.TownNPCs.hjson @@ -1,5 +1,5 @@ CanteenMaid: { - DisplayName: Betty, the Canteen Maid + DisplayName: é¤åޅ女仆è´è’‚ TownNPCMood: { Content: I feel pretty fine right now. @@ -22,25 +22,25 @@ CanteenMaid: { } Fevens: { - DisplayName: Fevens + DisplayName: éœæ–‡å£« } Guard_of_YggdrasilTown: { - DisplayName: Guard_of_ Yggdrasil Town + DisplayName: 天穹引路人 } Howard_Warden: { - DisplayName: Howard_ Warden + DisplayName: 警长éœåŽå¾· } InnKeeper: { - DisplayName: Inn Keeper + DisplayName: é…’é¦†è€æ¿æ ¼å°”æ ¼ } Restauranteur: { - DisplayName: Restauranteur + DisplayName: é¤åŽ…è€æ¿ç½—å°” } TeahouseLady: { - DisplayName: Teahouse Lady + DisplayName: èŒ¶é¦†è€æ¿å¨˜å¤œç’ƒ } diff --git a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.NPCs.hjson b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.NPCs.hjson index 939086613..d8c1f94b4 100644 --- a/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.NPCs.hjson +++ b/Sources/Everglow/Localization/zh-Hans/Mods.Everglow.NPCs.hjson @@ -19,209 +19,209 @@ ShadowstrikeCaterpillart.DisplayName: Arboreal Caterpillar WhisperingGhost.DisplayName: Whispering Ghost RapierMaster_Boss: { - DisplayName: Rapier Master_ Boss + DisplayName: 刺剑大师 } InfoRegisteryTestNPC: { - DisplayName: Info Registery TestNPC + DisplayName: 测试NPCéžæ¨¡ç»„内容 } BloodTusk: { - DisplayName: Blood Tusk + DisplayName: 鲜血ç ç‰™ } Living_Jawbone: { - DisplayName: Living_ Jawbone + DisplayName: 活颌骨 } GlowingHeal: { - DisplayName: Glowing Heal + DisplayName: 治愈性æµå…‰ } BlackStarFruit: { - DisplayName: Black Star Fruit + DisplayName: è¤ç¯æžœ } CentipedeHead: { - DisplayName: Centipede Head + DisplayName: æµè¤èœˆèš£ } CentipedeBody: { - DisplayName: Centipede Body + DisplayName: æµè¤èœˆèš£ } CentipedeTail: { - DisplayName: Centipede Tail + DisplayName: æµè¤èœˆèš£ } Dendroid_normal: { - DisplayName: Dendroid_normal + DisplayName: æµè¤æž¯æœ¨äºº } FireflyPiranha: { - DisplayName: Firefly Piranha + DisplayName: æµè¤è™Žé±¼ } FireflyPiranhaInfected: { - DisplayName: Firefly Piranha Infected + DisplayName: 感染æµè¤è™Žé±¼ } FireflyPiranhaInfected_small: { - DisplayName: Firefly Piranha Infected_small + DisplayName: 感染æµè¤è™Žé±¼ } FireflyPiranha_small: { - DisplayName: Firefly Piranha_small + DisplayName: æµè¤è™Žé±¼ } GlowingFirefly: { - DisplayName: Glowing Firefly + DisplayName: æµè¤è¤ç«è™« } LittleFireBulb: { - DisplayName: Little Fire Bulb + DisplayName: å°ç«æ»´ } CorruptMoth: { - DisplayName: Corrupt Moth + DisplayName: è…æª€å·¨è›¾ } EvilPack: { - DisplayName: Evil Pack + DisplayName: 巨大夜光茧 } SummonedButterfly: { - DisplayName: Summoned Butterfly + DisplayName: 幻影蛾 } ExplosiveLantern_growing: { - DisplayName: Explosive Lantern_growing + DisplayName: 爆破ç¯ç¬¼ } BloodLanternGhost: { - DisplayName: Blood Lantern Ghost + DisplayName: 血色ç¯ç¬¼ } BombLantern: { - DisplayName: Bomb Lantern + DisplayName: 炸弹ç¯ç¬¼ } CylindricalLantern: { - DisplayName: Cylindrical Lantern + DisplayName: ç«æŸ±ç¯ç¬¼ } FloatLantern: { - DisplayName: Float Lantern + DisplayName: 鬼ç¯ç¬¼ } RedPackBomber: { - DisplayName: Red Pack Bomber + DisplayName: 红包轰炸机 } LanternGhostKing: { - DisplayName: Lantern Ghost King + DisplayName: ç¯ç¬¼é¬¼çŽ‹ } BlueCore: { - DisplayName: Blue Core + DisplayName: è“æ ¸å¿ƒ } FlamingDashCore: { - DisplayName: Flaming Dash Core + DisplayName: ä¸ç­çš„花ç«å¹»é­‚心 } GreenCore: { - DisplayName: Green Core + DisplayName: 绿核心 } RedCore: { - DisplayName: Red Core + DisplayName: 红核心 } YellowCore: { - DisplayName: Yellow Core + DisplayName: 黄核心 } Acytaea: { - DisplayName: Acytaea + DisplayName: 雅斯塔亚 } Acytaea_Boss: { - DisplayName: Acytaea_ Boss + DisplayName: 雅斯塔亚 } BarkSpicyCaterpillar: { - DisplayName: Bark Spicy Caterpillar + DisplayName: 树皮刺毛虫 } BrownCaterpillar: { - DisplayName: Brown Caterpillar + DisplayName: 棕色毛虫 } CarapaceCaterpillar: { - DisplayName: Carapace Caterpillar + DisplayName: 石甲壳毛虫 } CrimsonSpell: { - DisplayName: Crimson Spell + DisplayName: 血月教徒 } CyanOreBeetle: { - DisplayName: Cyan Ore Beetle + DisplayName: é’缎甲虫 } DarkGlimmeringRods: { - DisplayName: Dark Glimmering Rods + DisplayName: é‡‘æ£•é£žæ£ } Guard_Slimy: { - DisplayName: Guard_ Slimy + DisplayName: å°å² } JellyBall: { - DisplayName: Jelly Ball + DisplayName: çƒå†» } LampFruitBorer: { - DisplayName: Lamp Fruit Borer + DisplayName: ç¯æžœèžŸ } LeafcutterAnt: { - DisplayName: Leafcutter Ant + DisplayName: 切å¶èš } LightBulb: { - DisplayName: Light Bulb + DisplayName: ç¯æ³¡èŠ±è‹ž } RockElemental: { - DisplayName: Rock Elemental + DisplayName: ç£çŸ³å…ƒç´  } ShadowstrikeCaterpillar: { - DisplayName: Shadowstrike Caterpillar + DisplayName: 夜行毛虫 } WhisperingGhost: { - DisplayName: Whispering Ghost + DisplayName: ä½Žè¯­å¹½çµ } Acytaea_yggdrasil: { - DisplayName: Acytaea_yggdrasil + DisplayName: 雅斯塔亚 } SquamousShell: { - DisplayName: Squamous Shell + DisplayName: 龙鳞å¤å£³ } KingJellyBall: { - DisplayName: King Jelly Ball + DisplayName: çƒå†»çŽ‹ } RiverSlug: { - DisplayName: River Slug + DisplayName: æ°´è›žè“ } TestNPC: { - DisplayName: TestNPC + DisplayName: 测试NPC } diff --git a/Sources/Everglow/build.txt b/Sources/Everglow/build.txt index a2f5b4fc1..9bbb415c5 100644 --- a/Sources/Everglow/build.txt +++ b/Sources/Everglow/build.txt @@ -1,4 +1,4 @@ displayName = Everglow | æµå…‰æ— é™… [Demonstration] author = Dream Chaser Group | å­¤èˆŸé€æ¢¦å›¢é˜Ÿ version = 0.2 -modReferences = SubworldLibrary +modReferences = SubworldLibrary,ModLiquidLib diff --git a/Sources/Modules/CagedDomain/Dusts/SluiceWallLamp_dust.cs b/Sources/Modules/CagedDomain/Dusts/SluiceWallLamp_dust.cs new file mode 100644 index 000000000..764e22b97 --- /dev/null +++ b/Sources/Modules/CagedDomain/Dusts/SluiceWallLamp_dust.cs @@ -0,0 +1,5 @@ +namespace Everglow.CagedDomain.Dusts; + +public class SluiceWallLamp_dust : ModDust +{ +} diff --git a/Sources/Modules/CagedDomain/Dusts/SluiceWallLamp_dust.png b/Sources/Modules/CagedDomain/Dusts/SluiceWallLamp_dust.png new file mode 100644 index 000000000..be1146d49 Binary files /dev/null and b/Sources/Modules/CagedDomain/Dusts/SluiceWallLamp_dust.png differ diff --git a/Sources/Modules/CagedDomain/Items/BarrierBlock_Item.cs b/Sources/Modules/CagedDomain/Items/BarrierBlock_Item.cs new file mode 100644 index 000000000..0d12f3002 --- /dev/null +++ b/Sources/Modules/CagedDomain/Items/BarrierBlock_Item.cs @@ -0,0 +1,15 @@ +using Everglow.CagedDomain.Tiles; + +namespace Everglow.CagedDomain.Items; + +public class BarrierBlock_Item : ModItem +{ + public override string LocalizationCategory => Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.useTime = 5; + Item.useAnimation = 5; + } +} diff --git a/Sources/Modules/CagedDomain/Items/BarrierBlock_Item.png b/Sources/Modules/CagedDomain/Items/BarrierBlock_Item.png new file mode 100644 index 000000000..b48159968 Binary files /dev/null and b/Sources/Modules/CagedDomain/Items/BarrierBlock_Item.png differ diff --git a/Sources/Modules/CagedDomain/Items/BarrierPlatform_Item.cs b/Sources/Modules/CagedDomain/Items/BarrierPlatform_Item.cs new file mode 100644 index 000000000..891b95e26 --- /dev/null +++ b/Sources/Modules/CagedDomain/Items/BarrierPlatform_Item.cs @@ -0,0 +1,30 @@ +using Everglow.CagedDomain.Tiles; +using Terraria.GameContent.Creative; + +namespace Everglow.CagedDomain.Items; + +public class BarrierPlatform_Item : ModItem +{ + public override string LocalizationCategory => Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetStaticDefaults() + { + CreativeItemSacrificesCatalog.Instance.SacrificeCountNeededByItemId[Type] = 200; + } + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 24; + Item.height = 18; + Item.useTime = 5; + Item.useAnimation = 5; + } + + public override void AddRecipes() + { + Recipe recipe = CreateRecipe(2); + recipe.AddIngredient(ModContent.ItemType(), 1); + recipe.Register(); + } +} diff --git a/Sources/Modules/CagedDomain/Items/BarrierPlatform_Item.png b/Sources/Modules/CagedDomain/Items/BarrierPlatform_Item.png new file mode 100644 index 000000000..38d840f9c Binary files /dev/null and b/Sources/Modules/CagedDomain/Items/BarrierPlatform_Item.png differ diff --git a/Sources/Modules/CagedDomain/Items/MorphoFrame_Item.cs b/Sources/Modules/CagedDomain/Items/MorphoFrame_Item.cs new file mode 100644 index 000000000..732797b84 --- /dev/null +++ b/Sources/Modules/CagedDomain/Items/MorphoFrame_Item.cs @@ -0,0 +1,15 @@ +using Everglow.CagedDomain.Tiles.OnWallTiles; + +namespace Everglow.CagedDomain.Items; + +public class MorphoFrame_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 26; + Item.height = 26; + } +} diff --git a/Sources/Modules/CagedDomain/Items/MorphoFrame_Item.png b/Sources/Modules/CagedDomain/Items/MorphoFrame_Item.png new file mode 100644 index 000000000..fd5d48ac7 Binary files /dev/null and b/Sources/Modules/CagedDomain/Items/MorphoFrame_Item.png differ diff --git a/Sources/Modules/CagedDomain/Items/NormalEscalator_Item.cs b/Sources/Modules/CagedDomain/Items/NormalEscalator_Item.cs new file mode 100644 index 000000000..fef83fbab --- /dev/null +++ b/Sources/Modules/CagedDomain/Items/NormalEscalator_Item.cs @@ -0,0 +1,43 @@ +using Everglow.CagedDomain.Tiles.Escalator; +using Terraria.GameInput; + +namespace Everglow.CagedDomain.Items; + +public class NormalEscalator_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public int PlaceState = 0; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 40; + Item.height = 34; + Item.value = 40000; + } + + public override void HoldItem(Player player) + { + if (PlayerInput.Triggers.JustReleased.MouseRight) + { + PlaceState = (PlaceState + 1) % 2; + } + switch (PlaceState) + { + case 0: + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 40; + Item.height = 34; + Item.value = 40000; + break; + case 1: + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 40; + Item.height = 34; + Item.value = 40000; + break; + } + Item.placeStyle = Math.Max(-player.direction, 0); + } +} diff --git a/Sources/Modules/CagedDomain/Items/NormalEscalator_Item.png b/Sources/Modules/CagedDomain/Items/NormalEscalator_Item.png new file mode 100644 index 000000000..ef523278e Binary files /dev/null and b/Sources/Modules/CagedDomain/Items/NormalEscalator_Item.png differ diff --git a/Sources/Modules/CagedDomain/Items/PierWithSlabsTop_Item.cs b/Sources/Modules/CagedDomain/Items/PierWithSlabsTop_Item.cs new file mode 100644 index 000000000..fa715a130 --- /dev/null +++ b/Sources/Modules/CagedDomain/Items/PierWithSlabsTop_Item.cs @@ -0,0 +1,38 @@ +using Everglow.CagedDomain.Tiles; + +namespace Everglow.CagedDomain.Items; + +public class PierWithSlabsTop_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 50; + Item.height = 34; + Item.value = 20000; + } + + public override void HoldItem(Player player) + { + Main.placementPreview = true; + } + + public override bool CanUseItem(Player player) + { + var pWST = TileLoader.GetTile(ModContent.TileType()) as PierWithSlabsTop; + if (pWST != null) + { + int x = (int)(Main.MouseWorld.X / 16); + int y = (int)(Main.MouseWorld.Y / 16); + if (pWST.NoCollideInSolidGrid(x, y, false)) + { + pWST.PlaceAtTileObjectDataOrigin(x, y); + Item.stack--; + return false; + } + } + return false; + } +} diff --git a/Sources/Modules/CagedDomain/Items/PierWithSlabsTop.png b/Sources/Modules/CagedDomain/Items/PierWithSlabsTop_Item.png similarity index 100% rename from Sources/Modules/CagedDomain/Items/PierWithSlabsTop.png rename to Sources/Modules/CagedDomain/Items/PierWithSlabsTop_Item.png diff --git a/Sources/Modules/CagedDomain/Items/PierWithSlabsTop.cs b/Sources/Modules/CagedDomain/Items/SluiceWallLamp_Item.cs similarity index 53% rename from Sources/Modules/CagedDomain/Items/PierWithSlabsTop.cs rename to Sources/Modules/CagedDomain/Items/SluiceWallLamp_Item.cs index 6a7a8204d..b09e0f221 100644 --- a/Sources/Modules/CagedDomain/Items/PierWithSlabsTop.cs +++ b/Sources/Modules/CagedDomain/Items/SluiceWallLamp_Item.cs @@ -1,14 +1,14 @@ namespace Everglow.CagedDomain.Items; -public class PierWithSlabsTop : ModItem +public class SluiceWallLamp_Item : ModItem { public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; public override void SetDefaults() { - Item.DefaultToPlaceableTile(ModContent.TileType()); - Item.width = 50; - Item.height = 34; - Item.value = 7086; + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 24; + Item.height = 18; + Item.value = 1000; } } diff --git a/Sources/Modules/CagedDomain/Items/SluiceWallLamp_Item.png b/Sources/Modules/CagedDomain/Items/SluiceWallLamp_Item.png new file mode 100644 index 000000000..de6be4057 Binary files /dev/null and b/Sources/Modules/CagedDomain/Items/SluiceWallLamp_Item.png differ diff --git a/Sources/Modules/CagedDomain/Items/WhiteCallaLily_Item.cs b/Sources/Modules/CagedDomain/Items/WhiteCallaLily_Item.cs index c520215c7..7a3100ba4 100644 --- a/Sources/Modules/CagedDomain/Items/WhiteCallaLily_Item.cs +++ b/Sources/Modules/CagedDomain/Items/WhiteCallaLily_Item.cs @@ -13,11 +13,6 @@ public override void SetDefaults() Item.height = 48; } - public override bool? UseItem(Player player) - { - return base.UseItem(player); - } - public override void HoldItem(Player player) { Item.placeStyle = Math.Max(player.direction, 0); diff --git a/Sources/Modules/CagedDomain/Items/WhiteCallaLily_Item.png b/Sources/Modules/CagedDomain/Items/WhiteCallaLily_Item.png index 17e5c656c..34e6da3bc 100644 Binary files a/Sources/Modules/CagedDomain/Items/WhiteCallaLily_Item.png and b/Sources/Modules/CagedDomain/Items/WhiteCallaLily_Item.png differ diff --git a/Sources/Modules/CagedDomain/Tiles/BarrierBlock.cs b/Sources/Modules/CagedDomain/Tiles/BarrierBlock.cs new file mode 100644 index 000000000..14f11fc5a --- /dev/null +++ b/Sources/Modules/CagedDomain/Tiles/BarrierBlock.cs @@ -0,0 +1,87 @@ +using Everglow.CagedDomain.Items; + +namespace Everglow.CagedDomain.Tiles; + +public class BarrierBlock : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileSolid[Type] = true; + Main.tileMergeDirt[Type] = true; + Main.tileBlockLight[Type] = false; + AddMapEntry(Color.Transparent); + MinPick = int.MaxValue; + } + + public override void PlaceInWorld(int i, int j, Item item) + { + var tile = Main.tile[i, j]; + tile.IsTileInvisible = true; + } + + public override void NumDust(int i, int j, bool fail, ref int num) => num = 0; + + public override bool CanKillTile(int i, int j, ref bool blockDamaged) => false; + + public override bool CanExplode(int i, int j) => false; + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + noBreak = true; + return base.TileFrame(i, j, ref resetFrame, ref noBreak); + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + if (PlayerHeldBarrierItem(Main.LocalPlayer)) + { + var tile = Main.tile[i, j]; + Vector2 zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + var frame = new Rectangle(tile.TileFrameX, tile.TileFrameY, 16, 16); + Texture2D tex = Commons.ModAsset.HalfTiles.Value; + var drawColor = new Color(1f, 0, 0, 0); + int count = 10; + if (tile.Slope == SlopeType.SlopeDownLeft) + { + frame = new Rectangle(36, 0, 16, 16); + } + if (tile.Slope == SlopeType.SlopeDownRight) + { + frame = new Rectangle(54, 0, 16, 16); + } + if (tile.Slope == SlopeType.SlopeUpLeft) + { + frame = new Rectangle(90, 0, 16, 16); + } + if (tile.Slope == SlopeType.SlopeUpRight) + { + frame = new Rectangle(72, 0, 16, 16); + } + if (tile.IsHalfBlock) + { + frame = new Rectangle(18, 0, 16, 16); + } + if (tile.Slope == SlopeType.Solid && !tile.IsHalfBlock) + { + tex = ModAsset.BarrierBlock_Visable.Value; + drawColor = Color.White; + count = 1; + } + for (int k = 0; k < count; k++) + { + spriteBatch.Draw(tex, new Vector2(i, j) * 16 - Main.screenPosition + zero, frame, drawColor, 0, new Vector2(0), 1f, SpriteEffects.None, 0); + } + } + return base.PreDraw(i, j, spriteBatch); + } + + public static bool PlayerHeldBarrierItem(Player player) + { + // return true; + return player.HeldItem.type == ModContent.ItemType() || player.HeldItem.type == ModContent.ItemType() || player.HeldItem.hammer > 0 | player.HeldItem.pick > 0; + } +} diff --git a/Sources/Modules/CagedDomain/Tiles/BarrierBlock.png b/Sources/Modules/CagedDomain/Tiles/BarrierBlock.png new file mode 100644 index 000000000..e8ffd1d5a Binary files /dev/null and b/Sources/Modules/CagedDomain/Tiles/BarrierBlock.png differ diff --git a/Sources/Modules/CagedDomain/Tiles/BarrierBlock_Visable.png b/Sources/Modules/CagedDomain/Tiles/BarrierBlock_Visable.png new file mode 100644 index 000000000..1717e2d17 Binary files /dev/null and b/Sources/Modules/CagedDomain/Tiles/BarrierBlock_Visable.png differ diff --git a/Sources/Modules/CagedDomain/Tiles/BarrierPlatform.cs b/Sources/Modules/CagedDomain/Tiles/BarrierPlatform.cs new file mode 100644 index 000000000..6775e354d --- /dev/null +++ b/Sources/Modules/CagedDomain/Tiles/BarrierPlatform.cs @@ -0,0 +1,73 @@ +using Terraria.ObjectData; + +namespace Everglow.CagedDomain.Tiles; + +public class BarrierPlatform : ModTile +{ + public override void SetStaticDefaults() + { + // Properties + Main.tileLighted[Type] = true; + Main.tileFrameImportant[Type] = true; + Main.tileSolidTop[Type] = true; + Main.tileSolid[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileTable[Type] = true; + Main.tileLavaDeath[Type] = true; + TileID.Sets.Platforms[Type] = true; + TileID.Sets.DisableSmartCursor[Type] = true; + + AddToArray(ref TileID.Sets.RoomNeeds.CountsAsDoor); + AddMapEntry(Color.Transparent); + AdjTiles = new int[] { TileID.Platforms }; + + // Placement + TileObjectData.newTile.CoordinateHeights = new[] { 16 }; + TileObjectData.newTile.CoordinateWidth = 16; + TileObjectData.newTile.CoordinatePadding = 2; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.StyleMultiplier = 27; + TileObjectData.newTile.StyleWrapLimit = 27; + TileObjectData.newTile.UsesCustomCanPlace = false; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.addTile(Type); + MinPick = int.MaxValue; + } + + public override void PlaceInWorld(int i, int j, Item item) + { + var tile = Main.tile[i, j]; + tile.IsTileInvisible = true; + } + + public override void PostSetDefaults() => Main.tileNoSunLight[Type] = false; + + public override void NumDust(int i, int j, bool fail, ref int num) => num = 0; + + public override bool CanKillTile(int i, int j, ref bool blockDamaged) => false; + + public override bool CanExplode(int i, int j) => false; + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + noBreak = true; + return base.TileFrame(i, j, ref resetFrame, ref noBreak); + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + if (BarrierBlock.PlayerHeldBarrierItem(Main.LocalPlayer)) + { + var tile = Main.tile[i, j]; + tile.IsTileInvisible = true; + Vector2 zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + var frame = new Rectangle(tile.TileFrameX, tile.TileFrameY, 16, 16); + spriteBatch.Draw(ModAsset.BarrierPlatform_Visable.Value, new Vector2(i, j) * 16 - Main.screenPosition + zero, frame, Color.White, 0, new Vector2(0), 1f, SpriteEffects.None, 0); + } + return base.PreDraw(i, j, spriteBatch); + } +} diff --git a/Sources/Modules/CagedDomain/Tiles/BarrierPlatform.png b/Sources/Modules/CagedDomain/Tiles/BarrierPlatform.png new file mode 100644 index 000000000..c2dc91e58 Binary files /dev/null and b/Sources/Modules/CagedDomain/Tiles/BarrierPlatform.png differ diff --git a/Sources/Modules/CagedDomain/Tiles/BarrierPlatform_Highlight.png b/Sources/Modules/CagedDomain/Tiles/BarrierPlatform_Highlight.png new file mode 100644 index 000000000..682fafa7f Binary files /dev/null and b/Sources/Modules/CagedDomain/Tiles/BarrierPlatform_Highlight.png differ diff --git a/Sources/Modules/CagedDomain/Tiles/BarrierPlatform_Visable.png b/Sources/Modules/CagedDomain/Tiles/BarrierPlatform_Visable.png new file mode 100644 index 000000000..d72d771c7 Binary files /dev/null and b/Sources/Modules/CagedDomain/Tiles/BarrierPlatform_Visable.png differ diff --git a/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator.cs b/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator.cs new file mode 100644 index 000000000..40fee92a9 --- /dev/null +++ b/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator.cs @@ -0,0 +1,76 @@ +using Everglow.CagedDomain.Items; +using Everglow.Commons.VFX.Scene; +using Terraria; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.CagedDomain.Tiles.Escalator; + +public class NormalEscalator : ModTile, ISceneTile +{ + public override void PostSetDefaults() + { + Main.tileSolid[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileFrameImportant[Type] = true; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.None, 0, 0); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.addTile(Type); + DustType = DustID.WoodFurniture; + AddMapEntry(new Color(153, 152, 151)); + HitSound = SoundID.DD2_SkeletonHurt; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } + + public void AddScene(int i, int j) + { + int dir = 1; + Tile tile = Main.tile[i, j]; + if (tile.TileFrameX == 18) + { + dir = -1; + } + var escalator_VFX = new NormalEscalator_VFX() + { + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Position = new Vector2(i * 16, j * 16), + Direction = dir, + State = tile.TileFrameY / 18, + Active = true, + Visible = true, + }; + Ins.VFXManager.Add(escalator_VFX); + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + Player player = Main.LocalPlayer; + if (player.HeldItem.type == ModContent.ItemType()) + { + Vector2 zero = new Vector2(Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + Tile tile = Main.tile[i, j]; + int dir = 1; + if (tile.TileFrameX == 18) + { + dir = -1; + } + Texture2D tex = Commons.ModAsset.TileBlock.Value; + for (int k = 1; k < 120; k++) + { + spriteBatch.Draw(tex, new Vector2(i + k * dir, j - k) * 16 - Main.screenPosition + zero, null, new Color(0f, 1f, 0f, 0f), 0, Vector2.zeroVector, 1f, SpriteEffects.None, 0); + } + } + } +} diff --git a/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator.png b/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator.png new file mode 100644 index 000000000..610a74f20 Binary files /dev/null and b/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator.png differ diff --git a/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator_Atlas.png b/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator_Atlas.png new file mode 100644 index 000000000..144e15458 Binary files /dev/null and b/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator_Atlas.png differ diff --git a/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator_Top.cs b/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator_Top.cs new file mode 100644 index 000000000..6de16be6c --- /dev/null +++ b/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator_Top.cs @@ -0,0 +1,28 @@ +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.CagedDomain.Tiles.Escalator; + +public class NormalEscalator_Top : ModTile +{ + public override void PostSetDefaults() + { + Main.tileSolid[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileFrameImportant[Type] = true; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.None, 0, 0); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.addTile(Type); + DustType = DustID.WoodFurniture; + AddMapEntry(new Color(153, 152, 151)); + HitSound = SoundID.DD2_SkeletonHurt; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator_Top.png b/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator_Top.png new file mode 100644 index 000000000..872edd9fd Binary files /dev/null and b/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator_Top.png differ diff --git a/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator_VFX.cs b/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator_VFX.cs new file mode 100644 index 000000000..b6e702760 --- /dev/null +++ b/Sources/Modules/CagedDomain/Tiles/Escalator/NormalEscalator_VFX.cs @@ -0,0 +1,380 @@ +using Everglow.Commons.Enums; +using Everglow.Commons.TileHelper; +using Everglow.Commons.Utilities; +using Everglow.Commons.Vertex; +using Everglow.Commons.VFX; +using Everglow.Commons.VFX.Pipelines; +using Everglow.Commons.VFX.Scene; + +namespace Everglow.CagedDomain.Tiles.Escalator; + +/// +/// An interactive escalator. +/// It connect the NormalEscalator and NormalEscalator_Top tiles by an oblique escalator. +/// Player should control 'Up' to attach to the escalator, and 'Down' to exit the escalator. +/// +[Pipeline(typeof(WCSPipeline))] +public class NormalEscalator_VFX : TileVFX +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; + + public Rectangle HanddrailStrap_Bottom = new Rectangle(0, 0, 88, 54); + public Rectangle HanddrailStrap_Medium = new Rectangle(92, 0, 44, 44); + public Rectangle HanddrailStrap_Top = new Rectangle(140, 0, 70, 44); + + public Rectangle ExteriorPanel_Bottom = new Rectangle(0, 60, 58, 16); + public Rectangle ExteriorPanel_Medium_Bottom = new Rectangle(136, 44, 30, 32); + public Rectangle ExteriorPanel_Medium = new Rectangle(80, 48, 26, 28); + public Rectangle ExteriorPanel_Medium_Top = new Rectangle(108, 50, 24, 24); + public Rectangle ExteriorPanel_Top = new Rectangle(166, 46, 44, 16); + + public Rectangle SelectedInterfaceHighlight = new Rectangle(166, 64, 18, 10); + + public Rectangle StepBlock = new Rectangle(60, 60, 18, 16); + + public List StepPositions = new List(); + + public List AttachingPlayers = new List(); + + public int TotalLength = 0; + + public float MoveingSpeed = 16f / 30f; + + public float StepValue = 0; + + public int State = 0; + + public enum WorkState + { + Upward, + Downward, + Cease, + } + + public override void Update() + { + if (TotalLength == 0) + { + for (int step = 0; step < 100; step++) + { + var tile = WorldGenMisc.SafeGetTile(OriginTilePos + new Point(Direction * step, -step)); + if (tile.TileType == ModContent.TileType()) + { + TotalLength = step; + break; + } + } + } + UpdateSteps(); + UpdatePlayerAttachment(); + UpdateStateControl(); + base.Update(); + } + + public void UpdatePlayerAttachment() + { + foreach (var player in Main.player) + { + if (player is not null && player.active) + { + // TODO: Optimization, check player collide with the exterior rectangle. + foreach (var blockPos in StepPositions) + { + Rectangle stepBox = new Rectangle((int)blockPos.X, (int)blockPos.Y, 16, 16); + + // Control 'Up';Not exist in the list;No mount;Collision; + if (player.controlUp && !AttachingPlayers.Contains(player) && player.mount.Type == -1 && stepBox.Intersects(player.Hitbox)) + { + AttachingPlayers.Add(player); + break; + } + } + } + } + + foreach (var player in AttachingPlayers) + { + if (player is null || !player.active) + { + AttachingPlayers.Remove(player); + break; + } + + // Control 'Down' to exit the escalator.. + if (player.controlDown) + { + AttachingPlayers.Remove(player); + break; + } + + bool safe = false; + for (int i = 0; i < StepPositions.Count; i++) + { + Vector2 blockPos = StepPositions[i]; + if (player.Bottom.X >= blockPos.X && player.Bottom.X < blockPos.X + 16) + { + // The speed rate constant: depends on the escalator speed (Updated by Main.time / 30f * 16) + // TODO: Player frame + + int stateDir = 1; + if (State == (int)WorkState.Downward) + { + stateDir = -1; + } + if (State == (int)WorkState.Cease) + { + stateDir = 0; + } + float relativeMoveX = MoveingSpeed * Direction * stateDir; + if (player.Bottom.Y > blockPos.Y) + { + float deltaY = blockPos.Y - player.Bottom.Y; + if (MathF.Abs(deltaY) > 15) + { + player.gfxOffY -= deltaY; + } + if (MathF.Abs(player.gfxOffY) > 16) + { + player.gfxOffY = 16; + } + player.Bottom = new Vector2(player.Bottom.X + relativeMoveX, blockPos.Y); + if (player.bodyFrame.Y == 280) + { + player.bodyFrame.Y = 0; + player.legFrame.Y = 0; + } + } + safe = true; + break; + } + } + if (!safe) + { + AttachingPlayers.Remove(player); + break; + } + } + } + + public void UpdateStateControl() + { + Rectangle controlBox = new Rectangle((int)Position.X - 1 - 35 * Direction, (int)Position.Y + 6, 18, 6); + if (controlBox.Contains(Main.MouseWorld.ToPoint())) + { + MouseIntersectControlInterface = true; + if (Main.mouseRight && Main.mouseRightRelease) + { + State++; + if (State > 2) + { + State = 0; + } + var tile = TileUtils.SafeGetTile(OriginTilePos); + tile.TileFrameY = (short)(State * 18); + } + return; + } + MouseIntersectControlInterface = false; + } + + public bool MouseIntersectControlInterface = false; + + public Rectangle CurrentAnimationPanel() + { + int animationValue = (int)(Main.time * 0.1f) % 3; + return new Rectangle(214, 8 * animationValue + State * 24, 18, 6); + } + + public Rectangle CurrentAnimationPane_Glow() + { + int animationValue = (int)(Main.time * 0.1f) % 3; + return new Rectangle(216, 8 * animationValue + State * 24, 14, 6); + } + + public override void Draw() + { + if (TotalLength == 0) + { + return; + } + if (Texture == null) + { + Texture = ModAsset.NormalEscalator_Atlas.Value; + } + + // Handdrail Straps + Vector2 totalOffset = new Vector2(0); + Vector2 drawPos = Position + totalOffset; + + DrawAPiece(drawPos + new Vector2(-36 - 26 * Direction, -50), HanddrailStrap_Bottom); + Vector2 piece_drawPos = drawPos + new Vector2(-14 - 4 * Direction, -50); + for (int i = 1; i < TotalLength; i++) + { + piece_drawPos += new Vector2(Direction * 16, -16); + DrawAPiece(piece_drawPos, HanddrailStrap_Medium); + } + if (Direction == 1) + { + DrawAPiece(drawPos + new Vector2(Direction, -1) * 16 * TotalLength + new Vector2(-18 * Direction, -42), HanddrailStrap_Top); + } + else + { + DrawAPiece(drawPos + new Vector2(Direction, -1) * 16 * TotalLength + new Vector2(-36, -42), HanddrailStrap_Top); + } + + // Steps + float stepValue = StepValue % 16; + + if (StepPositions != null && StepPositions.Count > 0) + { + for (int i = 0; i < StepPositions.Count; i++) + { + Rectangle stepFrame = StepBlock; + Vector2 offset = Vector2.zeroVector; + if (i == 0) + { + stepFrame = new Rectangle((int)(78 - stepValue), 60, (int)(stepValue + 2), 16); + if (Direction == -1) + { + offset = new Vector2(stepValue - 16, 0); + } + } + DrawAPiece(StepPositions[i] + offset, stepFrame); + } + } + + // Exterior Panels + DrawAPiece(drawPos + new Vector2(-21 - 27 * Direction, 0), ExteriorPanel_Bottom); + + DrawAPiece(drawPos + new Vector2(-1 - 35 * Direction, 6), CurrentAnimationPanel()); + DrawAPieceIgnoreEnvironment(drawPos + new Vector2(1 - 35 * Direction, 6), CurrentAnimationPane_Glow(), new Color(1f, 1f, 1f, 0f)); + if (MouseIntersectControlInterface) + { + DrawAPieceIgnoreEnvironment(drawPos + new Vector2(-1 - 35 * Direction, 4), SelectedInterfaceHighlight, new Color(1f, 1f, 1f, 1f)); + } + piece_drawPos = drawPos + new Vector2(-12, -4); + if (Direction == -1) + { + piece_drawPos = drawPos + new Vector2(2, -4); + } + for (int i = 0; i < TotalLength; i++) + { + Vector2 offset = Vector2.zeroVector; + piece_drawPos += new Vector2(Direction * 16, -16); + Rectangle frame = ExteriorPanel_Medium; + if (i == 0) + { + frame = ExteriorPanel_Medium_Bottom; + if (Direction == 1) + { + offset = new Vector2(-4, 0); + } + else + { + offset = Vector2.zeroVector; + } + } + if (i == TotalLength - 1) + { + frame = ExteriorPanel_Medium_Top; + + if (Direction == 1) + { + offset = new Vector2(-2, 4); + } + else + { + offset = new Vector2(4, 4); + } + } + DrawAPiece(piece_drawPos + offset, frame); + } + + DrawAPiece(drawPos + new Vector2(Direction, -1) * 16 * TotalLength + new Vector2(-14 + 12 * Direction, -2), ExteriorPanel_Top); + } + + public void DrawAPiece(Vector2 position, Rectangle frame) + { + List piece = new List(); + if (Direction == 1) + { + piece.Add(position, Lighting.GetColor(position.ToTileCoordinates()), new Vector3(frame.TopLeft() / Texture.Size(), 0)); + piece.Add(position + new Vector2(frame.Width, 0), Lighting.GetColor((position + new Vector2(frame.Width, 0)).ToTileCoordinates()), new Vector3(frame.TopRight() / Texture.Size(), 0)); + + piece.Add(position + new Vector2(0, frame.Height), Lighting.GetColor((position + new Vector2(0, frame.Height)).ToTileCoordinates()), new Vector3(frame.BottomLeft() / Texture.Size(), 0)); + piece.Add(position + new Vector2(frame.Width, frame.Height), Lighting.GetColor((position + new Vector2(frame.Width, frame.Height)).ToTileCoordinates()), new Vector3(frame.BottomRight() / Texture.Size(), 0)); + } + else + { + piece.Add(position, Lighting.GetColor(position.ToTileCoordinates()), new Vector3(frame.TopRight() / Texture.Size(), 0)); + piece.Add(position + new Vector2(frame.Width, 0), Lighting.GetColor((position + new Vector2(frame.Width, 0)).ToTileCoordinates()), new Vector3(frame.TopLeft() / Texture.Size(), 0)); + + piece.Add(position + new Vector2(0, frame.Height), Lighting.GetColor((position + new Vector2(0, frame.Height)).ToTileCoordinates()), new Vector3(frame.BottomRight() / Texture.Size(), 0)); + piece.Add(position + new Vector2(frame.Width, frame.Height), Lighting.GetColor((position + new Vector2(frame.Width, frame.Height)).ToTileCoordinates()), new Vector3(frame.BottomLeft() / Texture.Size(), 0)); + } + Ins.Batch.Draw(Texture, piece, PrimitiveType.TriangleStrip); + } + + public void DrawAPieceIgnoreEnvironment(Vector2 position, Rectangle frame, Color color) + { + List piece = new List(); + if (Direction == 1) + { + piece.Add(position, color, new Vector3(frame.TopLeft() / Texture.Size(), 0)); + piece.Add(position + new Vector2(frame.Width, 0), color, new Vector3(frame.TopRight() / Texture.Size(), 0)); + + piece.Add(position + new Vector2(0, frame.Height), color, new Vector3(frame.BottomLeft() / Texture.Size(), 0)); + piece.Add(position + new Vector2(frame.Width, frame.Height), color, new Vector3(frame.BottomRight() / Texture.Size(), 0)); + } + else + { + piece.Add(position, color, new Vector3(frame.TopRight() / Texture.Size(), 0)); + piece.Add(position + new Vector2(frame.Width, 0), color, new Vector3(frame.TopLeft() / Texture.Size(), 0)); + + piece.Add(position + new Vector2(0, frame.Height), color, new Vector3(frame.BottomRight() / Texture.Size(), 0)); + piece.Add(position + new Vector2(frame.Width, frame.Height), color, new Vector3(frame.BottomLeft() / Texture.Size(), 0)); + } + Ins.Batch.Draw(Texture, piece, PrimitiveType.TriangleStrip); + } + + public void UpdateSteps() + { + StepPositions = new List(); + if (State == (int)WorkState.Upward) + { + StepValue += MoveingSpeed; + if (StepValue > 32000) + { + StepValue -= 16000; + } + } + else if (State == (int)WorkState.Downward) + { + StepValue -= MoveingSpeed; + if (StepValue < 0) + { + StepValue += 16000; + } + } + float stepValue = StepValue % 16; + Vector2 piece_drawPos = Position + new Vector2(-76 * Direction, 62) + new Vector2(Direction, -1) * stepValue; + for (int i = -3; i < TotalLength + 1; i++) + { + Vector2 offset = Vector2.zeroVector; + if (i == TotalLength) + { + offset = new Vector2(0, stepValue); + } + if (i <= -1) + { + offset = new Vector2(0, stepValue + 16 * i); + } + if (i == -3) + { + offset += new Vector2(16 - stepValue, 0); + } + piece_drawPos += new Vector2(Direction * 16, -16); + StepPositions.Add(piece_drawPos + offset); + } + } +} diff --git a/Sources/Modules/CagedDomain/Tiles/GiantBell.png b/Sources/Modules/CagedDomain/Tiles/GiantBell.png index d1b8cdfcb..a69843afc 100644 Binary files a/Sources/Modules/CagedDomain/Tiles/GiantBell.png and b/Sources/Modules/CagedDomain/Tiles/GiantBell.png differ diff --git a/Sources/Modules/CagedDomain/Tiles/GiantCampFire.cs b/Sources/Modules/CagedDomain/Tiles/GiantCampFire.cs index d922b8e45..69f25eb61 100644 --- a/Sources/Modules/CagedDomain/Tiles/GiantCampFire.cs +++ b/Sources/Modules/CagedDomain/Tiles/GiantCampFire.cs @@ -24,7 +24,7 @@ public override void PostSetDefaults() 16, 16, 16, - 18 + 18, }; TileObjectData.newTile.CoordinateWidth = 16; TileObjectData.newTile.Origin = new Point16(2, 1); @@ -32,16 +32,18 @@ public override void PostSetDefaults() DustType = DustID.WoodFurniture; AddMapEntry(new Color(91, 62, 39)); } + public void AddScene(int i, int j) { Tile tile = Main.tile[i, j]; if (tile.TileFrameX == 36 && tile.TileFrameY == 18) { - GiantCampFire_flame_fore flame = new GiantCampFire_flame_fore { position = new Vector2(i, j) * 16 + new Vector2(8), Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + GiantCampFire_flame_fore flame = new GiantCampFire_flame_fore { Position = new Vector2(i, j) * 16 + new Vector2(8), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(flame); } } + public override void NearbyEffects(int i, int j, bool closer) { Tile tile = Main.tile[i, j]; @@ -58,7 +60,7 @@ public override void NearbyEffects(int i, int j, bool closer) maxTime = Main.rand.Next(37, 195), scale = Main.rand.NextFloat(0.1f, Main.rand.NextFloat(12.1f, 27.0f)), rotation = Main.rand.NextFloat(6.283f), - ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), Main.rand.NextFloat(-0.003f, 0.003f) } + ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), Main.rand.NextFloat(-0.003f, 0.003f) }, }; Ins.VFXManager.Add(spark); } @@ -73,7 +75,7 @@ public override void NearbyEffects(int i, int j, bool closer) maxTime = Main.rand.Next(37, 305), scale = Main.rand.NextFloat(40, 100), rotation = Main.rand.NextFloat(6.283f), - ai = new float[] { Main.rand.NextFloat(-0.05f, -0.01f), 0 } + ai = new float[] { Main.rand.NextFloat(-0.05f, -0.01f), 0 }, }; Ins.VFXManager.Add(somg); } @@ -81,12 +83,14 @@ public override void NearbyEffects(int i, int j, bool closer) base.NearbyEffects(i, j, closer); } } + public class GiantCampFire_flame_fore_Pipeline : Pipeline { public override void Load() { effect = ModAsset.GiantCampFire_shader; } + public override void BeginRender() { var effect = this.effect.Value; @@ -101,23 +105,27 @@ public override void BeginRender() Ins.Batch.Begin(BlendState.AlphaBlend, DepthStencilState.None, SamplerState.PointWrap, RasterizerState.CullNone); effect.CurrentTechnique.Passes[0].Apply(); } + public override void EndRender() { Ins.Batch.End(); } } + [Pipeline(typeof(GiantCampFire_flame_fore_Pipeline), typeof(BloomPipeline))] -public class GiantCampFire_flame_fore : ForegroundVFX +public class GiantCampFire_flame_fore : TileVFX { public override void OnSpawn() { - texture = Commons.ModAsset.Noise_flame_0.Value; + Texture = Commons.ModAsset.Noise_flame_0.Value; } + public override void Update() { - Lighting.AddLight(position, new Vector3(1, 0.7f, 0.2f) * 2); + Lighting.AddLight(Position, new Vector3(1, 0.7f, 0.2f) * 2); base.Update(); } + public override void Draw() { float timeValue = (float)Main.time * 0.014f; @@ -135,12 +143,12 @@ public override void Draw() colorG = MathF.Pow(value, 0.4f); } float xValue = 9 * MathF.Sin(value * 32 + timeValue * 16) * value + value * value * Main.windSpeedCurrent * 870f; - bars.Add(position + new Vector2(30 * (1 - value) + xValue, -t * 9f), new Color(colorR, colorG, value, 0f), new Vector3(0, value * 1.3f - timeValue, zValue)); - bars.Add(position + new Vector2(-30 * (1 - value) + xValue, -t * 9f), new Color(colorR, colorG, value, 0f), new Vector3(1, value * 1.3f - timeValue, zValue)); + bars.Add(Position + new Vector2(30 * (1 - value) + xValue, -t * 9f), new Color(colorR, colorG, value, 0f), new Vector3(0, value * 1.3f - timeValue, zValue)); + bars.Add(Position + new Vector2(-30 * (1 - value) + xValue, -t * 9f), new Color(colorR, colorG, value, 0f), new Vector3(1, value * 1.3f - timeValue, zValue)); if (t == 39) { - bars.Add(position + new Vector2(xValue, -t * 9f), new Color(0, colorG, 1, 0f), new Vector3(0, value * 1.3f - timeValue, zValue)); - bars.Add(position + new Vector2(xValue, -t * 9f), new Color(0, colorG, 1, 0f), new Vector3(1, value * 1.3f - timeValue, zValue)); + bars.Add(Position + new Vector2(xValue, -t * 9f), new Color(0, colorG, 1, 0f), new Vector3(0, value * 1.3f - timeValue, zValue)); + bars.Add(Position + new Vector2(xValue, -t * 9f), new Color(0, colorG, 1, 0f), new Vector3(1, value * 1.3f - timeValue, zValue)); } } for (int t = 0; t < 40; t++) @@ -154,16 +162,16 @@ public override void Draw() float xValue = 12 * MathF.Sin(value * 32 + timeValue * 16) * value + value * value * Main.windSpeedCurrent * 870f; if (t == 0) { - bars.Add(position + new Vector2(30 * (1 - value) + xValue, -t * 12f), new Color(0, colorG, 1, 0f), new Vector3(0, value * 1.3f - timeValue, zValue)); - bars.Add(position + new Vector2(-30 * (1 - value) + xValue, -t * 12f), new Color(0, colorG, 1, 0f), new Vector3(1, value * 1.3f - timeValue, zValue)); + bars.Add(Position + new Vector2(30 * (1 - value) + xValue, -t * 12f), new Color(0, colorG, 1, 0f), new Vector3(0, value * 1.3f - timeValue, zValue)); + bars.Add(Position + new Vector2(-30 * (1 - value) + xValue, -t * 12f), new Color(0, colorG, 1, 0f), new Vector3(1, value * 1.3f - timeValue, zValue)); colorG = MathF.Pow(value, 0.4f); } - bars.Add(position + new Vector2(30 * (1 - value) + xValue, -t * 12f), new Color(colorR, colorG, value, 0f), new Vector3(0, value * 1.3f - timeValue, zValue)); - bars.Add(position + new Vector2(-30 * (1 - value) + xValue, -t * 12f), new Color(colorR, colorG, value, 0f), new Vector3(1, value * 1.3f - timeValue, zValue)); + bars.Add(Position + new Vector2(30 * (1 - value) + xValue, -t * 12f), new Color(colorR, colorG, value, 0f), new Vector3(0, value * 1.3f - timeValue, zValue)); + bars.Add(Position + new Vector2(-30 * (1 - value) + xValue, -t * 12f), new Color(colorR, colorG, value, 0f), new Vector3(1, value * 1.3f - timeValue, zValue)); if (t == 39) { - bars.Add(position + new Vector2(xValue, -t * 9f), new Color(0, 0, 1, 0f), new Vector3(0, value * 1.3f - timeValue, zValue)); - bars.Add(position + new Vector2(xValue, -t * 9f), new Color(0, 0, 1, 0f), new Vector3(1, value * 1.3f - timeValue, zValue)); + bars.Add(Position + new Vector2(xValue, -t * 9f), new Color(0, 0, 1, 0f), new Vector3(0, value * 1.3f - timeValue, zValue)); + bars.Add(Position + new Vector2(xValue, -t * 9f), new Color(0, 0, 1, 0f), new Vector3(1, value * 1.3f - timeValue, zValue)); } } for (int t = 0; t < 20; t++) @@ -177,12 +185,12 @@ public override void Draw() float xValue = 3 * MathF.Sin(value * 32 + timeValue * 16) * value - value * 50; if (t == 0) { - bars.Add(position + new Vector2(12 * (1 - value) + xValue, t * 3.5f - 15), new Color(0, colorG, 1, 0f), new Vector3(0, value * 0.73f + timeValue * 0.75f, zValue)); - bars.Add(position + new Vector2(-25 * (1 - value) + xValue, t * 3.5f - 15), new Color(0, colorG, 1, 0f), new Vector3(1, value * 0.73f + timeValue * 0.75f, zValue)); + bars.Add(Position + new Vector2(12 * (1 - value) + xValue, t * 3.5f - 15), new Color(0, colorG, 1, 0f), new Vector3(0, value * 0.73f + timeValue * 0.75f, zValue)); + bars.Add(Position + new Vector2(-25 * (1 - value) + xValue, t * 3.5f - 15), new Color(0, colorG, 1, 0f), new Vector3(1, value * 0.73f + timeValue * 0.75f, zValue)); colorG = MathF.Pow(value, 0.4f); } - bars.Add(position + new Vector2(12 * (1 - value) + xValue, t * 2.5f - 15), new Color(colorR, colorG, value, 0f), new Vector3(0, value * 0.73f + timeValue * 0.75f, zValue)); - bars.Add(position + new Vector2(-25 * (1 - value) + xValue, t * 2.5f - 15), new Color(colorR, colorG, value, 0f), new Vector3(1, value * 0.73f + timeValue * 0.75f, zValue)); + bars.Add(Position + new Vector2(12 * (1 - value) + xValue, t * 2.5f - 15), new Color(colorR, colorG, value, 0f), new Vector3(0, value * 0.73f + timeValue * 0.75f, zValue)); + bars.Add(Position + new Vector2(-25 * (1 - value) + xValue, t * 2.5f - 15), new Color(colorR, colorG, value, 0f), new Vector3(1, value * 0.73f + timeValue * 0.75f, zValue)); } for (int t = 0; t < 20; t++) { @@ -197,8 +205,8 @@ public override void Draw() colorG = MathF.Pow(value, 0.4f); } float xValue = 3 * MathF.Sin(value * 32 + timeValue * 16) * value - value * 10; - bars.Add(position + new Vector2(-20 * (1 - value) + xValue, t * 3.5f - 15), new Color(colorR, colorG, value, 0f), new Vector3(0, value * 0.54f + timeValue * 0.95f, zValue)); - bars.Add(position + new Vector2(22 * (1 - value) + xValue, t * 3.5f - 15), new Color(colorR, colorG, value, 0f), new Vector3(1, value * 0.54f + timeValue * 0.95f, zValue)); + bars.Add(Position + new Vector2(-20 * (1 - value) + xValue, t * 3.5f - 15), new Color(colorR, colorG, value, 0f), new Vector3(0, value * 0.54f + timeValue * 0.95f, zValue)); + bars.Add(Position + new Vector2(22 * (1 - value) + xValue, t * 3.5f - 15), new Color(colorR, colorG, value, 0f), new Vector3(1, value * 0.54f + timeValue * 0.95f, zValue)); } for (int t = 0; t < 20; t++) { @@ -213,8 +221,8 @@ public override void Draw() colorG = MathF.Pow(value, 0.4f); } float xValue = 3 * MathF.Sin(value * 32 + timeValue * 16) * value + value * 40; - bars.Add(position + new Vector2(-7 * (1 - value) + xValue, t * 2.5f - 15), new Color(colorR, colorG, value, 0f), new Vector3(0, value * 0.63f + timeValue * 1.05f, zValue)); - bars.Add(position + new Vector2(25 * (1 - value) + xValue, t * 2.5f - 15), new Color(colorR, colorG, value, 0f), new Vector3(1, value * 0.63f + timeValue * 1.05f, zValue)); + bars.Add(Position + new Vector2(-7 * (1 - value) + xValue, t * 2.5f - 15), new Color(colorR, colorG, value, 0f), new Vector3(0, value * 0.63f + timeValue * 1.05f, zValue)); + bars.Add(Position + new Vector2(25 * (1 - value) + xValue, t * 2.5f - 15), new Color(colorR, colorG, value, 0f), new Vector3(1, value * 0.63f + timeValue * 1.05f, zValue)); } Ins.Batch.Draw(bars, PrimitiveType.TriangleStrip); } diff --git a/Sources/Modules/CagedDomain/Tiles/HangingTiles/HangingFluoriteLamp.cs b/Sources/Modules/CagedDomain/Tiles/HangingTiles/HangingFluoriteLamp.cs index ab0b8af88..b42a2b1dc 100644 --- a/Sources/Modules/CagedDomain/Tiles/HangingTiles/HangingFluoriteLamp.cs +++ b/Sources/Modules/CagedDomain/Tiles/HangingTiles/HangingFluoriteLamp.cs @@ -9,7 +9,7 @@ public class HangingFluoriteLamp : HangingTile public override void PostSetDefaults() { RopeUnitMass = 0.6f; - SingleLampMass = 200f; + HangingItemMass = 200f; MaxWireStyle = 1; Elasticity = 70f; } diff --git a/Sources/Modules/CagedDomain/Tiles/OnWallTiles/MorphoFrame.cs b/Sources/Modules/CagedDomain/Tiles/OnWallTiles/MorphoFrame.cs new file mode 100644 index 000000000..74d77d7e4 --- /dev/null +++ b/Sources/Modules/CagedDomain/Tiles/OnWallTiles/MorphoFrame.cs @@ -0,0 +1,33 @@ +using Terraria.ObjectData; + +namespace Everglow.CagedDomain.Tiles.OnWallTiles; + +public class MorphoFrame : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileNoAttach[Type] = false; + Main.tileWaterDeath[Type] = false; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3Wall); + TileObjectData.newTile.Height = 3; + TileObjectData.newTile.Width = 3; + TileObjectData.newTile.CoordinateHeights = new int[3]; + Array.Fill(TileObjectData.newTile.CoordinateHeights, 16); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + + TileObjectData.addTile(Type); + DustType = DustID.Glass; + AddMapEntry(new Color(21, 21, 22)); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/CagedDomain/Tiles/OnWallTiles/MorphoFrame.png b/Sources/Modules/CagedDomain/Tiles/OnWallTiles/MorphoFrame.png new file mode 100644 index 000000000..34a5f927f Binary files /dev/null and b/Sources/Modules/CagedDomain/Tiles/OnWallTiles/MorphoFrame.png differ diff --git a/Sources/Modules/CagedDomain/Tiles/PierWithSlabsTop.cs b/Sources/Modules/CagedDomain/Tiles/PierWithSlabsTop.cs index e1402d73d..b3ef7d58f 100644 --- a/Sources/Modules/CagedDomain/Tiles/PierWithSlabsTop.cs +++ b/Sources/Modules/CagedDomain/Tiles/PierWithSlabsTop.cs @@ -1,13 +1,16 @@ +using Everglow.Commons.TileHelper; using Terraria.DataStructures; using Terraria.Enums; using Terraria.ObjectData; namespace Everglow.CagedDomain.Tiles; -public class PierWithSlabsTop : ModTile +public class PierWithSlabsTop : ShapeDataTile { public override void SetStaticDefaults() { + TotalWidth = 13; + TotalHeight = 8; Main.tileFrameImportant[Type] = true; Main.tileSolid[Type] = true; Main.tileBlockLight[Type] = false; @@ -15,35 +18,29 @@ public override void SetStaticDefaults() TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); TileObjectData.newTile.Height = 8; TileObjectData.newTile.Width = 13; - TileObjectData.newTile.CoordinateHeights = new int[] - { - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16 - }; + TileObjectData.newTile.CoordinateHeights = new int[8]; + Array.Fill(TileObjectData.newTile.CoordinateHeights, 16); TileObjectData.newTile.AnchorTop = new AnchorData(AnchorType.SolidTile, TileObjectData.newTile.Width, 0); - TileObjectData.newAlternate.AnchorAlternateTiles = new[] { (int)Type, (int)ModContent.TileType() }; - TileObjectData.newTile.AnchorBottom = default; - TileObjectData.newTile.Origin = new Point16(1, 0); + TileObjectData.newTile.AnchorBottom = AnchorData.Empty; + TileObjectData.newTile.Origin = new Point16(6, 0); TileObjectData.addTile(Type); + // Etc AddMapEntry(new Color(86, 86, 86)); } + public override void NumDust(int i, int j, bool fail, ref int num) { num = 0; } - public override bool CanExplode(int i, int j) - { - return false; - } - public override bool CanKillTile(int i, int j, ref bool blockDamaged) - { - return false; - } + + //public override bool CanExplode(int i, int j) + //{ + // return false; + //} + + //public override bool CanKillTile(int i, int j, ref bool blockDamaged) + //{ + // return false; + //} } diff --git a/Sources/Modules/CagedDomain/Tiles/PierWithSlabsTop_shape.bmp b/Sources/Modules/CagedDomain/Tiles/PierWithSlabsTop_shape.bmp new file mode 100644 index 000000000..43c7b05a3 Binary files /dev/null and b/Sources/Modules/CagedDomain/Tiles/PierWithSlabsTop_shape.bmp differ diff --git a/Sources/Modules/CagedDomain/Tiles/SluiceWallLamp.cs b/Sources/Modules/CagedDomain/Tiles/SluiceWallLamp.cs new file mode 100644 index 000000000..364bc7292 --- /dev/null +++ b/Sources/Modules/CagedDomain/Tiles/SluiceWallLamp.cs @@ -0,0 +1,55 @@ +using Everglow.CagedDomain.Dusts; +using Everglow.Commons.Utilities; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.CagedDomain.Tiles; + +public class SluiceWallLamp : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileNoAttach[Type] = false; + Main.tileWaterDeath[Type] = false; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3Wall); + TileObjectData.newTile.Height = 2; + TileObjectData.newTile.Width = 3; + + TileObjectData.newTile.CoordinateHeights = new int[2]; + Array.Fill(TileObjectData.newTile.CoordinateHeights, 16); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.newTile.Origin = new(1, 0); + + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(255, 217, 142)); + } + + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + var tile = Main.tile[i, j]; + if (tile.TileFrameX < 54) + { + r = 1.3f; + g = 1.1f; + b = 0.6f; + } + else + { + r = 0f; + g = 0f; + b = 0f; + } + } + + public override void HitWire(int i, int j) + { + FurnitureUtils.LightHitwire(i, j, Type, 3, 2); + } +} diff --git a/Sources/Modules/CagedDomain/Tiles/SluiceWallLamp.png b/Sources/Modules/CagedDomain/Tiles/SluiceWallLamp.png new file mode 100644 index 000000000..798a9a109 Binary files /dev/null and b/Sources/Modules/CagedDomain/Tiles/SluiceWallLamp.png differ diff --git a/Sources/Modules/Example/Items/ExampleRopeItem.cs b/Sources/Modules/Example/Items/ExampleRopeItem.cs index 88bb5ea88..6184afaf4 100644 --- a/Sources/Modules/Example/Items/ExampleRopeItem.cs +++ b/Sources/Modules/Example/Items/ExampleRopeItem.cs @@ -18,7 +18,7 @@ public override void HoldItem(Player player) AddRope(); } ItemRope.Masses[0].Position = Main.MouseWorld; - ItemRope.ApplyForce_Gravity(); + //ItemRope.ApplyForce_Gravity(); ItemRope.ApplyForce_VelocityDecay(0.2f); // Experimental codes. @@ -82,7 +82,7 @@ public override void PostDrawInInventory(SpriteBatch spriteBatch, Vector2 positi public void AddRope() { - ItemRope = Rope.Create_Vine(Main.MouseWorld, 10, 2, 1); + ItemRope = Rope.Create_Vine(Main.MouseWorld, 30, 2, 1, 15); // Rope.Create_Fixed_StartPos(Main.MouseWorld, 20, 5, 0.5f, 20); EularSys.AddMassSpringMesh(ItemRope); diff --git a/Sources/Modules/Minortopography/GiantPinetree/GiantPinetreeGenPass.cs b/Sources/Modules/Minortopography/GiantPinetree/GiantPinetreeGenPass.cs index 223b50a13..8b532ba60 100644 --- a/Sources/Modules/Minortopography/GiantPinetree/GiantPinetreeGenPass.cs +++ b/Sources/Modules/Minortopography/GiantPinetree/GiantPinetreeGenPass.cs @@ -151,7 +151,7 @@ public static void BuildGiantPinetree() RemoveDestroyedTrees(positonX, positonY); // 平滑木头部分 - SmoothTile(positonX - 60, positonY - 20, 120, 250, ModContent.TileType()); + SmoothTile_XXYY(positonX - 60, positonY - 20, 120, 250, ModContent.TileType()); DistributePineCone(new Point16(positonX, positonY - 10), 40, 40); DistributePineCone(new Point16(positonX, positonY - 60), 20, 20); DistributePineNeedle(new Point16(positonX, positonY), 120, 120); @@ -1219,7 +1219,7 @@ public static void RemoveDestroyedTrees(int i, int j) /// /// /// - private static void SmoothTile(int x = 0, int y = 0, int width = 0, int height = 0, int tileType = -1) + private static void SmoothTile_XXYY(int x = 0, int y = 0, int width = 0, int height = 0, int tileType = -1) { for (int i = 0; i < width; i += 1) { diff --git a/Sources/Modules/Yggdrasil/CityOfMagicFlute/Projectiles/Ranged/TerraViewerHowitzer_grenade_fall_explosion.cs b/Sources/Modules/Yggdrasil/CityOfMagicFlute/Projectiles/Ranged/TerraViewerHowitzer_grenade_fall_explosion.cs index d2589cbd2..0f4d2870a 100644 --- a/Sources/Modules/Yggdrasil/CityOfMagicFlute/Projectiles/Ranged/TerraViewerHowitzer_grenade_fall_explosion.cs +++ b/Sources/Modules/Yggdrasil/CityOfMagicFlute/Projectiles/Ranged/TerraViewerHowitzer_grenade_fall_explosion.cs @@ -24,12 +24,11 @@ public override void SetDefaults() Projectile.usesLocalNPCImmunity = true; Projectile.localNPCHitCooldown = 20; Projectile.DamageType = DamageClass.Magic; - ProjectileID.Sets.DrawScreenCheckFluff[Projectile.type] = 14400; } - public void Spark() + public void Spark(int count) { - for (int g = 0; g < 120; g++) + for (int x = 0; x < count; x++) { Vector2 newVelocity = new Vector2(0, Main.rand.NextFloat(2f, 22f)).RotatedByRandom(MathHelper.TwoPi); var spark = new FireSparkDust @@ -47,56 +46,65 @@ public void Spark() } } - public void FlameII() + public void FlameII(int count) { - var newVelocity = new Vector2(0, -10); - Vector2 addPos = new Vector2(Main.rand.NextFloat(40), 0).RotatedByRandom(MathHelper.TwoPi); - var fire = new FireDust + for (int x = 0; x < count; x++) { - velocity = newVelocity, - Active = true, - Visible = true, - position = Projectile.Center + addPos - newVelocity, - maxTime = Main.rand.Next(30, 45), - scale = Main.rand.NextFloat(20f, 60f), - rotation = Main.rand.NextFloat(6.283f), - ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), addPos.X * 0.002f }, - }; - Ins.VFXManager.Add(fire); + var newVelocity = new Vector2(0, -10); + Vector2 addPos = new Vector2(Main.rand.NextFloat(40), 0).RotatedByRandom(MathHelper.TwoPi); + var fire = new FireDust + { + velocity = newVelocity, + Active = true, + Visible = true, + position = Projectile.Center + addPos - newVelocity, + maxTime = Main.rand.Next(30, 45), + scale = Main.rand.NextFloat(20f, 60f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), addPos.X * 0.002f }, + }; + Ins.VFXManager.Add(fire); + } } - public void LargeFlame() + public void LargeFlame(int count) { - Vector2 newVelocity = new Vector2(0, Main.rand.NextFloat(2f, 8f)).RotatedByRandom(MathHelper.TwoPi); - var somg = new MissleFlameDust + for (int x = 0; x < count; x++) { - velocity = newVelocity, - Active = true, - Visible = true, - position = Projectile.Center + new Vector2(Main.rand.NextFloat(40), 0).RotatedByRandom(6.283), - maxTime = Main.rand.Next(60, 75), - scale = Main.rand.NextFloat(80f, 160f), - rotation = Main.rand.NextFloat(6.283f), - ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), 0 }, - }; - Ins.VFXManager.Add(somg); + Vector2 newVelocity = new Vector2(0, MathF.Sqrt(Main.rand.NextFloat(1f)) * 12f).RotatedByRandom(MathHelper.TwoPi); + var somg = new MissleFlameDust + { + velocity = newVelocity, + Active = true, + Visible = true, + position = Projectile.Center + new Vector2(Main.rand.NextFloat(6), 0).RotatedByRandom(6.283), + maxTime = Main.rand.Next(90, 120), + scale = Main.rand.NextFloat(24f, 36f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), 0 }, + }; + Ins.VFXManager.Add(somg); + } } - public void SmallFlame() + public void SmallFlame(int count) { - Vector2 newVelocity = new Vector2(0, Main.rand.NextFloat(2f, 8f)).RotatedByRandom(MathHelper.TwoPi); - var somg = new MissleFlameDust + for (int x = 0; x < count; x++) { - velocity = newVelocity, - Active = true, - Visible = true, - position = Projectile.Center + new Vector2(Main.rand.NextFloat(60), 0).RotatedByRandom(6.283), - maxTime = Main.rand.Next(30, 45), - scale = Main.rand.NextFloat(50f, 90f), - rotation = Main.rand.NextFloat(6.283f), - ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), 0 }, - }; - Ins.VFXManager.Add(somg); + Vector2 newVelocity = new Vector2(0, MathF.Sqrt(Main.rand.NextFloat(1f)) * 8f).RotatedByRandom(MathHelper.TwoPi); + var somg = new MissleFlameDust + { + velocity = newVelocity, + Active = true, + Visible = true, + position = Projectile.Center + new Vector2(Main.rand.NextFloat(4), 0).RotatedByRandom(6.283), + maxTime = Main.rand.Next(50, 70), + scale = Main.rand.NextFloat(12f, 20f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), 0 }, + }; + Ins.VFXManager.Add(somg); + } } public override void OnSpawn(IEntitySource source) @@ -109,16 +117,9 @@ public override void AI() Projectile.velocity *= 0; if (Projectile.timeLeft == 190) { - Spark(); - - for (int x = 0; x < 35; x++) - { - LargeFlame(); - } - for (int x = 0; x < 75; x++) - { - SmallFlame(); - } + Spark(120); + LargeFlame(35); + SmallFlame(75); } if (Projectile.timeLeft <= 190) { @@ -130,10 +131,7 @@ public override void AI() } if (Projectile.timeLeft == 180) { - for (int x = 0; x < 35; x++) - { - FlameII(); - } + FlameII(35); } } @@ -199,6 +197,6 @@ public void DrawWarp(VFXBatch spriteBatch) } Texture2D t = Commons.ModAsset.Trail.Value; - DrawTexCircle_VFXBatch(spriteBatch, MathF.Sqrt(value) * 150f * Projectile.ai[0], 15 * (1 - value) * Projectile.ai[0], new Color(colorV, colorV * 0.012f, colorV, 0f), Projectile.Center - Main.screenPosition, t, Math.PI * 0.5); + DrawTexCircle_VFXBatch(spriteBatch, MathF.Sqrt(value) * 150f * Projectile.ai[0], 15 * (1 - value) * Projectile.ai[0], new Color(colorV, colorV * 0.6f, colorV, 0f), Projectile.Center - Main.screenPosition, t, Math.PI * 0.5); } } diff --git a/Sources/Modules/Yggdrasil/Common/BackgroundManager/BackgroundManager.cs b/Sources/Modules/Yggdrasil/Common/BackgroundManager/BackgroundManager.cs index 1324bfe67..b54141cb2 100644 --- a/Sources/Modules/Yggdrasil/Common/BackgroundManager/BackgroundManager.cs +++ b/Sources/Modules/Yggdrasil/Common/BackgroundManager/BackgroundManager.cs @@ -37,9 +37,14 @@ public void SpecialDraw(SpriteBatch spriteBatch) } } - public static void QuickDrawBG(Texture2D tex, float depth, Vector2 anchorWorldPos, Color baseColor, int yWorldCoordMin, int yWorldCoordMax, bool xClamp = false, bool yClamp = true) + public static void DrawBG_RestrictXY(Texture2D tex, float depth, Vector2 anchorWorldPos, Color baseColor, int xWorldCoordMin, int xWorldCoordMax, int yWorldCoordMin, int yWorldCoordMax, bool xClamp = false, bool yClamp = true) { - QuickDrawBG(tex, GetDrawFrame(tex, depth, anchorWorldPos), baseColor, yWorldCoordMin, yWorldCoordMax, false, true); + DrawBG_RestrictXY(tex, GetDrawFrame(tex, depth, anchorWorldPos), baseColor, xWorldCoordMin, xWorldCoordMax, yWorldCoordMin, yWorldCoordMax, xClamp, yClamp); + } + + public static void DrawBG_RestrictY(Texture2D tex, float depth, Vector2 anchorWorldPos, Color baseColor, int yWorldCoordMin, int yWorldCoordMax, bool xClamp = false, bool yClamp = true) + { + DrawBG_RestrictY(tex, GetDrawFrame(tex, depth, anchorWorldPos), baseColor, yWorldCoordMin, yWorldCoordMax, xClamp, yClamp); } /// @@ -53,26 +58,26 @@ public static void QuickDrawBG(Texture2D tex, float depth, Vector2 anchorWorldPo /// /// /// - public static void QuickDrawBG(Texture2D tex, Rectangle drawFrame, Color baseColor, int yWorldCoordMin, int yWorldCoordMax, bool xClamp = false, bool yClamp = true) + public static void DrawBG_RestrictY(Texture2D tex, Rectangle drawFrame, Color baseColor, int yWorldCoordMin, int yWorldCoordMax, bool xClamp = false, bool yClamp = true) { SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; Main.spriteBatch.End(); Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); - Effect bgW = ModAsset.BackgroundXWarp.Value; + Effect bg_wrapEffect = ModAsset.BackgroundXWarp.Value; if (xClamp && yClamp) { - bgW = ModAsset.BackgroundXYClamp.Value; + bg_wrapEffect = ModAsset.BackgroundXYClamp.Value; } if (xClamp && !yClamp) { - bgW = ModAsset.BackgroundYWarp.Value; + bg_wrapEffect = ModAsset.BackgroundYWarp.Value; } if (!xClamp && !yClamp) { - bgW = ModAsset.BackgroundXYWarp.Value; + bg_wrapEffect = ModAsset.BackgroundXYWarp.Value; } var projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1); @@ -81,9 +86,9 @@ public static void QuickDrawBG(Texture2D tex, Rectangle drawFrame, Color baseCol projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, 0, Main.screenHeight, 0, 1); } - bgW.Parameters["uTransform"].SetValue(projection); - bgW.Parameters["uTime"].SetValue(0.34f); - bgW.CurrentTechnique.Passes[0].Apply(); + bg_wrapEffect.Parameters["uTransform"].SetValue(projection); + bg_wrapEffect.Parameters["uTime"].SetValue(0.34f); + bg_wrapEffect.CurrentTechnique.Passes[0].Apply(); // å¤„ç†æŽ‰è¶…å‡ºåœ°å›¾ç•Œé™çš„部分 int drawMaxY = Main.screenHeight; @@ -101,7 +106,7 @@ public static void QuickDrawBG(Texture2D tex, Rectangle drawFrame, Color baseCol yClampValueUp = drawMinY / (float)Main.screenHeight; } - var CloseII = new List + var bg_vertices = new List { new Vertex2D(new Vector2(0, drawMinY), baseColor, new Vector3(drawFrame.X / (float)tex.Width, (drawFrame.Y + drawFrame.Height * yClampValueUp) / tex.Height, 0)), new Vertex2D(new Vector2(Main.screenWidth, drawMinY), baseColor, new Vector3((drawFrame.X + drawFrame.Width) / (float)tex.Width, (drawFrame.Y + drawFrame.Height * yClampValueUp) / tex.Height, 0)), @@ -111,11 +116,99 @@ public static void QuickDrawBG(Texture2D tex, Rectangle drawFrame, Color baseCol new Vertex2D(new Vector2(Main.screenWidth, drawMinY), baseColor, new Vector3((drawFrame.X + drawFrame.Width) / (float)tex.Width, (drawFrame.Y + drawFrame.Height * yClampValueUp) / tex.Height, 0)), new Vertex2D(new Vector2(Main.screenWidth, drawMaxY), baseColor, new Vector3((drawFrame.X + drawFrame.Width) / (float)tex.Width, (drawFrame.Y + drawFrame.Height * yClampValueDown) / tex.Height, 0)), }; - if (CloseII.Count > 2) + if (bg_vertices.Count > 2) + { + Main.graphics.GraphicsDevice.Textures[0] = tex; + Main.graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, bg_vertices.ToArray(), 0, 2); + } + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + } + + public static void DrawBG_RestrictXY(Texture2D tex, Rectangle drawFrame, Color baseColor, int xWorldCoordMin, int xWorldCoordMax, int yWorldCoordMin, int yWorldCoordMax, bool xClamp = false, bool yClamp = true) + { + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + Effect bg_wrapEffect = ModAsset.BackgroundXWarp.Value; + if (xClamp && yClamp) + { + bg_wrapEffect = ModAsset.BackgroundXYClamp.Value; + } + + if (xClamp && !yClamp) + { + bg_wrapEffect = ModAsset.BackgroundYWarp.Value; + } + + if (!xClamp && !yClamp) + { + bg_wrapEffect = ModAsset.BackgroundXYWarp.Value; + } + + var projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1); + if (Main.LocalPlayer.gravDir == -1) + { + projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, 0, Main.screenHeight, 0, 1); + } + + bg_wrapEffect.Parameters["uTransform"].SetValue(projection); + bg_wrapEffect.Parameters["uTime"].SetValue(0.34f); + bg_wrapEffect.CurrentTechnique.Passes[0].Apply(); + + // å¤„ç†æŽ‰è¶…å‡ºåœ°å›¾ç•Œé™çš„部分 + + int drawMaxX = Main.screenWidth; + int drawMinX = 0; + float xClampValueUp = 0f; + float xClampValueDown = 1f; + if (Main.screenPosition.X + Main.screenWidth > xWorldCoordMax) + { + drawMaxX = xWorldCoordMax - (int)Main.screenPosition.X; + xClampValueDown = (float)drawMaxX / Main.screenWidth; + } + if (Main.screenPosition.X < xWorldCoordMin) + { + drawMinX = xWorldCoordMin - (int)Main.screenPosition.X; + xClampValueUp = drawMinX / (float)Main.screenWidth; + } + + int drawMaxY = Main.screenHeight; + int drawMinY = 0; + float yClampValueUp = 0f; + float yClampValueDown = 1f; + if (Main.screenPosition.Y + Main.screenHeight > yWorldCoordMax) + { + drawMaxY = yWorldCoordMax - (int)Main.screenPosition.Y; + yClampValueDown = (float)drawMaxY / Main.screenHeight; + } + if (Main.screenPosition.Y < yWorldCoordMin) + { + drawMinY = yWorldCoordMin - (int)Main.screenPosition.Y; + yClampValueUp = drawMinY / (float)Main.screenHeight; + } + float xCoord0 = (drawFrame.X + drawFrame.Width * xClampValueUp) / tex.Width; + float xCoord1 = (drawFrame.X + drawFrame.Width * xClampValueDown) / tex.Width; + float yCoord0 = (drawFrame.Y + drawFrame.Height * yClampValueUp) / tex.Height; + float yCoord1 = (drawFrame.Y + drawFrame.Height * yClampValueDown) / tex.Height; + + var bg_vertices = new List + { + new Vertex2D(new Vector2(drawMinX, drawMinY), baseColor, new Vector3(xCoord0, yCoord0, 0)), + new Vertex2D(new Vector2(drawMaxX, drawMinY), baseColor, new Vector3(xCoord1, yCoord0, 0)), + new Vertex2D(new Vector2(drawMinX, drawMaxY), baseColor, new Vector3(xCoord0, yCoord1, 0)), + + new Vertex2D(new Vector2(drawMinX, drawMaxY), baseColor, new Vector3(xCoord0, yCoord1, 0)), + new Vertex2D(new Vector2(drawMaxX, drawMinY), baseColor, new Vector3(xCoord1, yCoord0, 0)), + new Vertex2D(new Vector2(drawMaxX, drawMaxY), baseColor, new Vector3(xCoord1, yCoord1, 0)), + }; + if (bg_vertices.Count > 2) { Main.graphics.GraphicsDevice.Textures[0] = tex; Main.graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap; - Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, CloseII.ToArray(), 0, 2); + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, bg_vertices.ToArray(), 0, 2); } Main.spriteBatch.End(); Main.spriteBatch.Begin(sBS); @@ -302,10 +395,10 @@ public static void DrawWaterfall(Vector2 drawCenter, float width, float height, projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, 0, Main.screenHeight, 0, 1); } - Effect bgW = ModAsset.BackgroundYWarp.Value; - bgW.Parameters["uTransform"].SetValue(projection); - bgW.Parameters["uTime"].SetValue(0.34f); - bgW.CurrentTechnique.Passes[0].Apply(); + Effect bg_wrapEffect = ModAsset.BackgroundYWarp.Value; + bg_wrapEffect.Parameters["uTransform"].SetValue(projection); + bg_wrapEffect.Parameters["uTime"].SetValue(0.34f); + bg_wrapEffect.CurrentTechnique.Passes[0].Apply(); float Time = (float)-Main.timeForVisualEffects / 40f; var WaterFallVertex = new List(); diff --git a/Sources/Modules/Yggdrasil/Common/Fish/FishGlobalItem.cs b/Sources/Modules/Yggdrasil/Common/Fish/FishGlobalItem.cs index 97c7066a4..fdf6d5022 100644 --- a/Sources/Modules/Yggdrasil/Common/Fish/FishGlobalItem.cs +++ b/Sources/Modules/Yggdrasil/Common/Fish/FishGlobalItem.cs @@ -31,6 +31,11 @@ public class FishGlobalItem : GlobalItem /// public bool Hookable = false; + /// + /// 生æˆè¿™ä¸ªç‰©å“çš„ FishableItem + /// + public FishableItem FishableInfo; + public int HoverTick = 0; public override bool InstancePerEntity => true; @@ -148,6 +153,26 @@ public void CheckRightClick(Item item) } } + public void UpdateOnVanillaLiquid(Item item, ref float gravity) + { + Point itemPos = item.Center.ToTileCoordinates(); + byte liquid = Main.tile[itemPos].LiquidAmount; + if (liquid > 0) + { + float percent = liquid / 255f; + float liqY = percent * 16f + itemPos.Y * 16f; + float delta = item.Center.Y - liqY; + if (delta < 0 || liquid == 255) + { + float ratio = Main.rand.NextFloat(1) + 0.5f; + float buoyancy = Math.Clamp(-delta / item.height * 2, 0, 1); + gravity *= -ratio * buoyancy; + item.velocity.Y *= 0.9f; + item.velocity.X = FloatSpeed; + } + } + } + public override void Update(Item item, ref float gravity, ref float maxFallSpeed) { if (!IsFishable(item)) @@ -162,21 +187,9 @@ public override void Update(Item item, ref float gravity, ref float maxFallSpeed Hookable = false; return; } - Point itemPos = item.Center.ToTileCoordinates(); - byte liquid = Main.tile[itemPos].LiquidAmount; - if (liquid > 0) + else { - float percent = liquid / 255f; - float liqY = percent * 16f + itemPos.Y * 16f; - float delta = item.Center.Y - liqY; - if (delta < 0) - { - float ratio = Main.rand.NextFloat(1) + .5f; - float buoyancy = Math.Clamp(-delta / item.height * 2, 0, 1); - gravity *= -ratio * buoyancy; - item.velocity.Y *= .9f; - item.velocity.X = FloatSpeed; - } + UpdateOnVanillaLiquid(item, ref gravity); } CheckHover(item); CheckHookable(item); @@ -184,6 +197,24 @@ public override void Update(Item item, ref float gravity, ref float maxFallSpeed base.Update(item, ref gravity, ref maxFallSpeed); } + public override void GrabRange(Item item, Player player, ref int grabRange) + { + if (Fishable && HookedBy == null) + { + grabRange = 0; + } + base.GrabRange(item, player, ref grabRange); + } + + public override bool CanPickup(Item item, Player player) + { + if (Fishable && HookedBy == null) + { + return false; + } + return base.CanPickup(item, player); + } + public override void PostDrawInWorld(Item item, SpriteBatch spriteBatch, Color lightColor, Color alphaColor, float rotation, float scale, int whoAmI) { Vector2 basePos = item.Center - Main.screenPosition; @@ -194,9 +225,9 @@ public override void PostDrawInWorld(Item item, SpriteBatch spriteBatch, Color l } if (Hovered && Hookable) { - var font = FontAssets.MouseText.Value; - string hint = "Right click to hook"; - Vector2 size = font.MeasureString(hint); + // var font = FontAssets.MouseText.Value; + // string hint = "Right click to hook"; + // Vector2 size = font.MeasureString(hint); // spriteBatch.DrawString(font, hint, basePos - size / 2 - new Vector2(0, item.height / 2 + 20), Color.Gold); } base.PostDrawInWorld(item, spriteBatch, lightColor, alphaColor, rotation, scale, whoAmI); diff --git a/Sources/Modules/Yggdrasil/Common/Fish/FishGlobalProjectile.cs b/Sources/Modules/Yggdrasil/Common/Fish/FishGlobalProjectile.cs deleted file mode 100644 index f442638cf..000000000 --- a/Sources/Modules/Yggdrasil/Common/Fish/FishGlobalProjectile.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Everglow.Yggdrasil.Common.Fish; - -public class FishGlobalProjectile : GlobalProjectile -{ - public override void PostAI(Projectile projectile) - { - } -} diff --git a/Sources/Modules/Yggdrasil/Common/Fish/FishSystem.cs b/Sources/Modules/Yggdrasil/Common/Fish/FishSystem.cs index ada117002..ad7d0c8fe 100644 --- a/Sources/Modules/Yggdrasil/Common/Fish/FishSystem.cs +++ b/Sources/Modules/Yggdrasil/Common/Fish/FishSystem.cs @@ -1,10 +1,9 @@ -using Everglow.Yggdrasil.WorldGeneration; - namespace Everglow.Yggdrasil.Common.Fish; public class FishSystem : ModSystem { public static Dictionary> FishMap = []; + public static HashSet LiquidList = []; /// /// 注册一ç§å¯ä»¥è¢«é’©å–的渔获,会自然生æˆåœ¨æŒ‡å®šç”Ÿæ€ç¾¤ç³»çš„æ°´é¢ä¸Š @@ -22,6 +21,15 @@ public static void RegisterFish(ModBiome biome, FishableItem item) value.Add(item); } + /// + /// æ³¨å†Œä¸€ç§æ¶²ä½“,在钓鱼时将会模拟原版液体的行为 + /// + /// 图å—çš„ ID + public static void RegisterLiquid(int liquid) + { + LiquidList.Add(liquid); + } + public List ShouldSpawnFish(Player player) { List toSpawn = []; @@ -32,7 +40,7 @@ public List ShouldSpawnFish(Player player) foreach (var item in kvp.Value) { float chance = Main.rand.NextFloat(1); - if (chance < item.chance) + if (chance < item.Chance) { toSpawn.Add(item); } diff --git a/Sources/Modules/Yggdrasil/Common/Fish/FishUtils.cs b/Sources/Modules/Yggdrasil/Common/Fish/FishUtils.cs deleted file mode 100644 index 94a3226d4..000000000 --- a/Sources/Modules/Yggdrasil/Common/Fish/FishUtils.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Everglow.Yggdrasil.Common.Fish; - -public static class FishUtils -{ -} diff --git a/Sources/Modules/Yggdrasil/Common/Fish/FishableItem.cs b/Sources/Modules/Yggdrasil/Common/Fish/FishableItem.cs index 6a22cf771..84a136ee1 100644 --- a/Sources/Modules/Yggdrasil/Common/Fish/FishableItem.cs +++ b/Sources/Modules/Yggdrasil/Common/Fish/FishableItem.cs @@ -10,11 +10,13 @@ namespace Everglow.Yggdrasil.Common.Fish; /// 生æˆä¸€ä¸ªå¯ä»¥è¢«é’“é±¼çš„ç‰©å“ /// /// ç‰©å“ id -/// 物å“ä¼šåœ¨ä»€ä¹ˆæ¶²ä½“ä¸Šç”Ÿæˆ +/// +/// 物å“会在什么液体上生æˆï¼ŒåŽŸç‰ˆæ¶²ä½“ä½¿ç”¨ LiquidID,ModLiquid 液体使用 LiquidLoader.LiquidType +/// /// ç‰©å“æ¯å¸§çš„ç”Ÿæˆæ¦‚率 public class FishableItem(int item, int liquid, float chance) { public int Item = item; public int Liquid = liquid; - public float chance = chance; + public float Chance = chance; } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/NPCSpawnManager.cs b/Sources/Modules/Yggdrasil/Common/NPCSpawnManager.cs similarity index 97% rename from Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/NPCSpawnManager.cs rename to Sources/Modules/Yggdrasil/Common/NPCSpawnManager.cs index 2d1f6e41c..c3e059654 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/NPCSpawnManager.cs +++ b/Sources/Modules/Yggdrasil/Common/NPCSpawnManager.cs @@ -1,11 +1,13 @@ using SubworldLibrary; -namespace Everglow.Yggdrasil.YggdrasilTown.NPCs; +namespace Everglow.Yggdrasil.Common; public class NPCSpawnManager : GlobalNPC { private static HashSet yggdrasilNPC = new HashSet(); + public static void RegisterNPC(int type) => yggdrasilNPC.Add(type); + public override void EditSpawnPool(IDictionary pool, NPCSpawnInfo spawnInfo) { if (!SubworldSystem.IsActive()) @@ -25,7 +27,6 @@ public override void EditSpawnPool(IDictionary pool, NPCSpawnInfo sp foreach (var pair in dict) { pool.Add(pair.Key, pair.Value); - } pool.Add(NPCID.BlueSlime, 0.1f); pool.Add(NPCID.GreenSlime, 0.1f); @@ -55,10 +56,8 @@ public override void EditSpawnPool(IDictionary pool, NPCSpawnInfo sp pool.Add(NPCID.HoppinJack, 0.1f); } } - - - } + public override void EditSpawnRate(Player player, ref int spawnRate, ref int maxSpawns) { if (SubworldSystem.IsActive()) @@ -77,6 +76,7 @@ public override void EditSpawnRate(Player player, ref int spawnRate, ref int max } } } + public static Vector2 FindTheIntersectionOfEllipseAndLine(float a, float b, float c, float d) { float a2 = (float)Math.Pow(a, 2); diff --git a/Sources/Modules/Yggdrasil/Common/YggdrasilBiomeTileCounter.cs b/Sources/Modules/Yggdrasil/Common/YggdrasilBiomeTileCounter.cs index 3453f08c2..02e49577a 100644 --- a/Sources/Modules/Yggdrasil/Common/YggdrasilBiomeTileCounter.cs +++ b/Sources/Modules/Yggdrasil/Common/YggdrasilBiomeTileCounter.cs @@ -1,6 +1,7 @@ using Everglow.Yggdrasil.YggdrasilTown.Tiles; using Everglow.Yggdrasil.YggdrasilTown.Tiles.LampWood; using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; namespace Everglow.Yggdrasil.Common; @@ -10,10 +11,14 @@ public class YggdrasilBiomeTileCounter : ModSystem public int TwilightGrassCount; public int JellyBallSecretionCount; + public int WaterSluiceRoomCount; + public override void TileCountsAvailable(ReadOnlySpan tileCounts) { DarkForestGrassCount = tileCounts[ModContent.TileType()]; TwilightGrassCount = tileCounts[ModContent.TileType()]; JellyBallSecretionCount = tileCounts[ModContent.TileType()]; + + WaterSluiceRoomCount = tileCounts[ModContent.TileType()]; } } diff --git a/Sources/Modules/Yggdrasil/Common/YggdrasilPlayer.cs b/Sources/Modules/Yggdrasil/Common/YggdrasilPlayer.cs index f5fcb659d..556eeb230 100644 --- a/Sources/Modules/Yggdrasil/Common/YggdrasilPlayer.cs +++ b/Sources/Modules/Yggdrasil/Common/YggdrasilPlayer.cs @@ -1,4 +1,3 @@ -using System.Reflection; using Everglow.Commons.Mechanics; using Everglow.Yggdrasil.KelpCurtain.Buffs; using Everglow.Yggdrasil.KelpCurtain.Cooldowns; @@ -104,32 +103,20 @@ public bool UseLampBorerHoney() public override bool CloneNewInstances => true; - public override void Load() + public override void ModifyMaxStats(out StatModifier health, out StatModifier mana) { - MonoModHooks.Add(typeof(PlayerLoader).GetMethod(nameof(PlayerLoader.ResetMaxStatsToVanilla), BindingFlags.Public | BindingFlags.Static), Hook_ResetMaxStatsToVanilla); - } + base.ModifyMaxStats(out health, out mana); - public static void Hook_ResetMaxStatsToVanilla(Action orig, Player player) - { - int lifeFix1 = 0, lifeFix2 = 0, lifeFix3 = 0, lifeFix4 = 0, manaFix1 = 0; - if (player.TryGetModPlayer(out YggdrasilPlayer modPlayer)) - { - lifeFix1 = AntiHeavenSicknessPill.LifeBonusTable.Take(modPlayer.ConsumedAntiHeavenSicknessPill).Sum(p => p.Value); - lifeFix2 = modPlayer.ConsumedJadeGlazeFruit * JadeFruit.LifePerJadeFruit; - lifeFix3 = modPlayer.ConsumedSquamousCore * SquamousCore.SquamousCoreLife; - lifeFix4 = modPlayer.ConsumedLampBorerHoney * LampBorerHoney.LifePerHoney; - } + health.Base += AntiHeavenSicknessPill.LifeBonusTable.Take(ConsumedAntiHeavenSicknessPill).Sum(p => p.Value); + health.Base += ConsumedJadeGlazeFruit * JadeFruit.LifePerJadeFruit; + health.Base += ConsumedSquamousCore * SquamousCore.SquamousCoreLife; + health.Base += ConsumedLampBorerHoney * LampBorerHoney.LifePerHoney; if (SubworldSystem.IsActive()) { - player.statLifeMax = 100 + player.ConsumedLifeCrystals * 4 + player.ConsumedLifeFruit * 1 + lifeFix1 + lifeFix2 + lifeFix3 + lifeFix4; - player.statManaMax = 20 + player.ConsumedManaCrystals * 4 + manaFix1 * 2; - } - else - { - orig(player); - player.statLifeMax += lifeFix1 + lifeFix2 + lifeFix3 + lifeFix4; - player.statManaMax += (int)(manaFix1 * 0.4f); + health.Base -= Player.ConsumedLifeCrystals * 16; + health.Base -= Player.ConsumedLifeFruit * 4; + mana.Base -= Player.ConsumedManaCrystals * 16; } } diff --git a/Sources/Modules/Yggdrasil/Everglow.Yggdrasil.csproj b/Sources/Modules/Yggdrasil/Everglow.Yggdrasil.csproj index 6a3565c34..4b963f832 100644 --- a/Sources/Modules/Yggdrasil/Everglow.Yggdrasil.csproj +++ b/Sources/Modules/Yggdrasil/Everglow.Yggdrasil.csproj @@ -11,4 +11,7 @@ + + + diff --git a/Sources/Modules/Yggdrasil/HurricaneMaze/Background/HurricaneMazeBackground.cs b/Sources/Modules/Yggdrasil/HurricaneMaze/Background/HurricaneMazeBackground.cs index ca36a094e..ab53cc001 100644 --- a/Sources/Modules/Yggdrasil/HurricaneMaze/Background/HurricaneMazeBackground.cs +++ b/Sources/Modules/Yggdrasil/HurricaneMaze/Background/HurricaneMazeBackground.cs @@ -78,9 +78,9 @@ private void DrawFarBG(Color baseColor) var texClose = ModAsset.HurricaneMazeClose.Value; var texMiddle = ModAsset.HurricaneMazeMiddle.Value; - BackgroundManager.QuickDrawBG(texSky, GetDrawRect(texSky.Size(), 0f), baseColor, 122000, 150000, true, true); - BackgroundManager.QuickDrawBG(texMiddle, GetDrawRect(texMiddle.Size(), 0.10f), baseColor, 122000, 150000, false, false); - BackgroundManager.QuickDrawBG(texClose, GetDrawRect(texClose.Size(), 0.35f), baseColor, 122000, 150000, false, false); + BackgroundManager.DrawBG_RestrictY(texSky, GetDrawRect(texSky.Size(), 0f), baseColor, 122000, 150000, true, true); + BackgroundManager.DrawBG_RestrictY(texMiddle, GetDrawRect(texMiddle.Size(), 0.10f), baseColor, 122000, 150000, false, false); + BackgroundManager.DrawBG_RestrictY(texClose, GetDrawRect(texClose.Size(), 0.35f), baseColor, 122000, 150000, false, false); } /// diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/BarnacleWall.png b/Sources/Modules/Yggdrasil/KelpCurtain/Background/BarnacleWall.png new file mode 100644 index 000000000..42d580117 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Background/BarnacleWall.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeBackground.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeBackground.cs index c15c66f99..7f305f877 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeBackground.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeBackground.cs @@ -1,4 +1,5 @@ -using Everglow.Commons.DataStructures; +using System.Runtime.InteropServices; +using Everglow.Commons.Utilities.BackgroundHelper; using Everglow.Yggdrasil.KelpCurtain.Biomes; namespace Everglow.Yggdrasil.KelpCurtain.Background; @@ -7,153 +8,74 @@ public class DeathJadeLakeBackground : ModSystem { public static Vector2 BiomeCenter = new Vector2(325, 18775) * 16; - public float alpha = 0f; + public float Alpha = 0f; - public override void PostUpdateEverything()// å¼€å¯åœ°ä¸‹èƒŒæ™¯ + public override void PostUpdateEverything() { const float increase = 0.02f; if (Main.LocalPlayer.InModBiome() && Main.BackgroundEnabled) { - DeathJadeLakeBiome dJLB = ModContent.GetInstance(); - if (dJLB != null && alpha == 0) + if (Alpha == 0) { - dJLB.GetLiquidSurfaceY(); + DeathJadeLakeBiome.GetLiquidSurfaceY(); } - if (alpha < 1) + if (Alpha < 1) { - alpha += increase; + Alpha += increase; } else { - alpha = 1; + Alpha = 1; } } else { - if (alpha > 0) + if (Alpha > 0) { - alpha -= increase; + Alpha -= increase; } else { - alpha = 0; + Alpha = 0; } } - } - - public static void DrawFarBG() - { - DeathJadeLakeBackground deathJadeLakeBackground = ModContent.GetInstance(); - if (deathJadeLakeBackground is null) + if (Alpha > 0) { - return; - } - Color baseColor = Color.White * deathJadeLakeBackground.alpha; - var texShore = ModAsset.DeathJadeLakeShore_Close.Value; + BackgroundSystem bgSystem = ModContent.GetInstance(); - var tex5 = ModAsset.DeathJadeLakeWater_5.Value; - var tex4 = ModAsset.DeathJadeLakeWater_4.Value; - var tex3 = ModAsset.DeathJadeLakeWater_3.Value; - var tex2 = ModAsset.DeathJadeLakeWater_2.Value; - int minY = (int)(Main.maxTilesY * 0.81f * 16); - int maxY = (int)(Main.maxTilesY * 0.92f * 16); - DrawLiquidSky(); - DrawBGLiquid(tex5, 0.4f); - DrawBGLiquid(tex4, 0.5f); - DrawBGLiquid(tex3, 0.6f); - DrawBGLiquid(tex2, 0.8f); - } + DeathJadeLakeWater_Sky lake_sky = new DeathJadeLakeWater_Sky(); + lake_sky.WorldAnchor = BiomeCenter; + bgSystem.AddBackgroundSlide(lake_sky); - public static void DrawLiquidSky() - { - DeathJadeLakeBackground deathJadeLakeBackground = ModContent.GetInstance(); - if (deathJadeLakeBackground is null) - { - return; - } - Color baseColor = Color.White * deathJadeLakeBackground.alpha; - DeathJadeLakeBiome dJLB = ModContent.GetInstance(); - if (dJLB == null) - { - return; - } - float drawTop = dJLB.LiquidSurfaceY; - if (drawTop - Main.screenPosition.Y < -Main.offScreenRange) - { - drawTop = -Main.offScreenRange + Main.screenPosition.Y; - } - float drawBottom = Main.screenPosition.Y + Main.screenHeight + Main.offScreenRange; - if (drawTop > drawBottom) - { - return; - } - var texSky = ModAsset.DeathJadeLakeWater_Sky.Value; - SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; - Main.spriteBatch.End(); - Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + DeathJadeLakeWater_5 lake_5 = new DeathJadeLakeWater_5(); + lake_5.WorldAnchor = BiomeCenter; + bgSystem.AddBackgroundSlide(lake_5); - var bars = new List(); - int yLayers = (int)((drawBottom - drawTop) / 16f); - for (int offsetY = 0; offsetY < yLayers; offsetY++) - { - float rightClamp = Main.screenWidth + Main.offScreenRange; - float rightBound = Main.maxTilesX * 16; - int tileY = (int)(drawTop / 16) + offsetY; - if (dJLB.RightBoundOfACertainY.ContainsKey(tileY)) - { - int rightX; - dJLB.RightBoundOfACertainY.TryGetValue(tileY, out rightX); - rightBound = rightX * 16; - } - rightBound -= Main.screenPosition.X; - if (rightClamp > rightBound) - { - rightClamp = rightBound; - } - bars.Add(new Vector2(-Main.offScreenRange, drawTop + offsetY * 16 - Main.screenPosition.Y), baseColor, new Vector3(0, 0.7f, 0)); - bars.Add(new Vector2(rightClamp, drawTop + offsetY * 16 - Main.screenPosition.Y), baseColor, new Vector3(1, 0.7f, 0)); - bars.Add(new Vector2(-Main.offScreenRange, drawTop + (offsetY + 1) * 16 - Main.screenPosition.Y), baseColor, new Vector3(0, 0.9f, 0)); + DeathJadeLakeWater_4 lake_4 = new DeathJadeLakeWater_4(); + lake_4.WorldAnchor = BiomeCenter; + bgSystem.AddBackgroundSlide(lake_4); - bars.Add(new Vector2(-Main.offScreenRange, drawTop + (offsetY + 1) * 16 - Main.screenPosition.Y), baseColor, new Vector3(0, 0.9f, 0)); - bars.Add(new Vector2(rightClamp, drawTop + offsetY * 16 - Main.screenPosition.Y), baseColor, new Vector3(1, 0.7f, 0)); - bars.Add(new Vector2(rightClamp, drawTop + (offsetY + 1) * 16 - Main.screenPosition.Y), baseColor, new Vector3(1, 0.9f, 0)); - } - if (bars.Count > 2) - { - Main.graphics.GraphicsDevice.Textures[0] = texSky; - Main.graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap; - Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, bars.ToArray(), 0, bars.Count / 3); + DeathJadeLakeWater_3 lake_3 = new DeathJadeLakeWater_3(); + lake_3.WorldAnchor = BiomeCenter; + bgSystem.AddBackgroundSlide(lake_3); + + DeathJadeLakeWater_2 lake_2 = new DeathJadeLakeWater_2(); + lake_2.WorldAnchor = BiomeCenter; + bgSystem.AddBackgroundSlide(lake_2); + + DeathJadeLakeWater_TyndallLight lake_TyndallLight = new DeathJadeLakeWater_TyndallLight(); + lake_TyndallLight.WorldAnchor = BiomeCenter; + bgSystem.AddBackgroundSlide(lake_TyndallLight); } - Main.spriteBatch.End(); - Main.spriteBatch.Begin(sBS); } /// - /// Draw a texture in the background layer. - /// Auto rasterize the area that out of yWorldCoord Clamp (yWorldCoordMin, yWorldCoordMax). - /// Liquid only. + /// Use high performance method to draw the background. /// - /// - /// - /// - /// - /// - /// - /// - public static void DrawBGLiquid(Texture2D tex, float moveScale) + /// + public static void DrawBackground(BackgroundSlideBase bg) { - DeathJadeLakeBackground deathJadeLakeBackground = ModContent.GetInstance(); - if (deathJadeLakeBackground is null) - { - return; - } - Color baseColor = Color.White * deathJadeLakeBackground.alpha; - DeathJadeLakeBiome dJLB = ModContent.GetInstance(); - if (dJLB == null) - { - return; - } - float drawTop = dJLB.LiquidSurfaceY; + float drawTop = DeathJadeLakeBiome.LiquidSurfaceY; if (drawTop - Main.screenPosition.Y < -Main.offScreenRange) { drawTop = -Main.offScreenRange + Main.screenPosition.Y; @@ -163,95 +85,39 @@ public static void DrawBGLiquid(Texture2D tex, float moveScale) { return; } - Vector2 totalOffset = (Main.screenPosition - BiomeCenter) * moveScale / 3000f; - - SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; - Main.spriteBatch.End(); - Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); - var bars = new List(); int yLayers = (int)((drawBottom - drawTop) / 16f); + int currentSize = bars.Count; + int estimatedCapacity = bars.Count + yLayers * 6 + 256; + if (bars.Capacity < estimatedCapacity) + { + bars.Capacity = estimatedCapacity; + } + CollectionsMarshal.SetCount(bars, estimatedCapacity); + Span span = CollectionsMarshal.AsSpan(bars); + for (int offsetY = 0; offsetY < yLayers; offsetY++) { - float rightClamp = Main.screenWidth + Main.offScreenRange; + float rightClamp = Main.screenWidth + Main.offScreenRange + Main.screenPosition.X; float rightBound = Main.maxTilesX * 16; int tileY = (int)(drawTop / 16) + offsetY; - if (dJLB.RightBoundOfACertainY.ContainsKey(tileY)) + if (DeathJadeLakeBiome.RightBoundOfACertainY.ContainsKey(tileY)) { int rightX; - dJLB.RightBoundOfACertainY.TryGetValue(tileY, out rightX); + DeathJadeLakeBiome.RightBoundOfACertainY.TryGetValue(tileY, out rightX); rightBound = rightX * 16; } - rightBound -= Main.screenPosition.X; if (rightClamp > rightBound) { rightClamp = rightBound; } - float topYcoord = offsetY * 16 / (float)tex.Height + totalOffset.Y - (-Main.offScreenRange + Main.screenPosition.Y - drawTop) / tex.Height; - float bottomYcoord = (offsetY + 1) * 16 / (float)tex.Height + totalOffset.Y - (-Main.offScreenRange + Main.screenPosition.Y - drawTop) / tex.Height; - if (topYcoord < 0) - { - topYcoord = 0; - } - if (bottomYcoord < 0) - { - bottomYcoord = 0; - } - if (topYcoord >= 1) - { - topYcoord = 0.999f; - } - if (bottomYcoord >= 1) - { - bottomYcoord = 0.999f; - } - float leftXcoord = totalOffset.X; - float rightXcoord = totalOffset.X + (rightClamp + Main.offScreenRange) / tex.Width; - bars.Add(new Vector2(-Main.offScreenRange, drawTop + offsetY * 16 - Main.screenPosition.Y), baseColor, new Vector3(leftXcoord, topYcoord, 0)); - bars.Add(new Vector2(rightClamp, drawTop + offsetY * 16 - Main.screenPosition.Y), baseColor, new Vector3(rightXcoord, topYcoord, 0)); - bars.Add(new Vector2(-Main.offScreenRange, drawTop + (offsetY + 1) * 16 - Main.screenPosition.Y), baseColor, new Vector3(leftXcoord, bottomYcoord, 0)); - - bars.Add(new Vector2(-Main.offScreenRange, drawTop + (offsetY + 1) * 16 - Main.screenPosition.Y), baseColor, new Vector3(leftXcoord, bottomYcoord, 0)); - bars.Add(new Vector2(rightClamp, drawTop + offsetY * 16 - Main.screenPosition.Y), baseColor, new Vector3(rightXcoord, topYcoord, 0)); - bars.Add(new Vector2(rightClamp, drawTop + (offsetY + 1) * 16 - Main.screenPosition.Y), baseColor, new Vector3(rightXcoord, bottomYcoord, 0)); - } - if (bars.Count > 2) - { - Main.graphics.GraphicsDevice.Textures[0] = tex; - Main.graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap; - Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, bars.ToArray(), 0, bars.Count / 3); - } - - Main.spriteBatch.End(); - Main.spriteBatch.Begin(sBS); - } - - public static Rectangle GetDrawRect(Vector2 texSize, float MoveStep) - { - Vector2 sampleTopleft = Vector2.Zero; - Vector2 sampleCenter = sampleTopleft + texSize / 2; - var screenSize = new Vector2(Main.screenWidth, Main.screenHeight); - Vector2 dCen = Main.screenPosition + new Vector2(Main.screenWidth, Main.screenHeight) / 2f; - Vector2 deltaPos = dCen - BiomeCenter; - deltaPos *= MoveStep; - int RX = (int)(sampleCenter.X - screenSize.X / 2f + deltaPos.X); - int RY = (int)(sampleCenter.Y - screenSize.Y / 2f + deltaPos.Y); - var rt = new Rectangle(RX, RY, (int)screenSize.X, (int)screenSize.Y); - return rt; - } - - public static void DrawBackground() - { - DeathJadeLakeBackground deathJadeLakeBackground = ModContent.GetInstance(); - if (deathJadeLakeBackground is null) - { - return; - } - if (deathJadeLakeBackground.alpha <= 0) - { - return; + float left = Main.screenPosition.X - Main.offScreenRange; + float top = tileY * 16; + BackgroundHigherPerformanceHelper.Add_WorldTriangle(bg, new Vector2(left, top), new Vector2(rightClamp, top), new Vector2(rightClamp, top + 16), span, ref currentSize); + BackgroundHigherPerformanceHelper.Add_WorldTriangle(bg, new Vector2(left, top), new Vector2(left, top + 16), new Vector2(rightClamp, top + 16), span, ref currentSize); } - DrawFarBG(); + CollectionsMarshal.SetCount(bars, currentSize); + BackgroundSlideBase.DrawVertexBackground(bg, PrimitiveType.TriangleList, bars); } } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_2.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_2.cs new file mode 100644 index 000000000..31dc3e1d0 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_2.cs @@ -0,0 +1,26 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain.Biomes; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class DeathJadeLakeWater_2 : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.DeathJadeLakeWater_2.Value; + Distance = 4f; + LayerPriority = 1; + Shader = Effects.XWrap_YClamp_Shader; + } + + public override bool CanActive() + { + return Main.LocalPlayer.InModBiome(); + } + + public override void Draw() + { + DeathJadeLakeBackground.DrawBackground(this); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_3.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_3.cs new file mode 100644 index 000000000..492eb1043 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_3.cs @@ -0,0 +1,26 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain.Biomes; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class DeathJadeLakeWater_3 : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.DeathJadeLakeWater_3.Value; + Distance = 8f; + LayerPriority = 1; + Shader = Effects.XWrap_YClamp_Shader; + } + + public override bool CanActive() + { + return Main.LocalPlayer.InModBiome(); + } + + public override void Draw() + { + DeathJadeLakeBackground.DrawBackground(this); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_4.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_4.cs new file mode 100644 index 000000000..e1e912b18 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_4.cs @@ -0,0 +1,26 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain.Biomes; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class DeathJadeLakeWater_4 : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.DeathJadeLakeWater_4.Value; + Distance = 24f; + LayerPriority = 1; + Shader = Effects.XWrap_YClamp_Shader; + } + + public override bool CanActive() + { + return Main.LocalPlayer.InModBiome(); + } + + public override void Draw() + { + DeathJadeLakeBackground.DrawBackground(this); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_5.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_5.cs new file mode 100644 index 000000000..007e22ce1 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_5.cs @@ -0,0 +1,26 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain.Biomes; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class DeathJadeLakeWater_5 : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.DeathJadeLakeWater_5.Value; + Distance = 48f; + LayerPriority = 1; + Shader = Effects.XWrap_YClamp_Shader; + } + + public override bool CanActive() + { + return Main.LocalPlayer.InModBiome(); + } + + public override void Draw() + { + DeathJadeLakeBackground.DrawBackground(this); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_Sky.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_Sky.cs new file mode 100644 index 000000000..64994dbf0 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_Sky.cs @@ -0,0 +1,26 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain.Biomes; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class DeathJadeLakeWater_Sky : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.DeathJadeLakeWater_Sky.Value; + Distance = 5000; + LayerPriority = 1; + Shader = Effects.XClamp_YWrap_Shader; + } + + public override bool CanActive() + { + return Main.LocalPlayer.InModBiome(); + } + + public override void Draw() + { + DeathJadeLakeBackground.DrawBackground(this); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_Sky.png b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_Sky.png index e795f15bd..f3ac343a9 100644 Binary files a/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_Sky.png and b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_Sky.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_TyndallLight.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_TyndallLight.cs new file mode 100644 index 000000000..243bb9480 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/DeathJadeLakeWater_TyndallLight.cs @@ -0,0 +1,90 @@ +using Everglow.Commons.DataStructures; +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain.Biomes; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class DeathJadeLakeWater_TyndallLight : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = Commons.ModAsset.Noise_perlin.Value; + Distance = 2.4f; + LayerPriority = 1; + Shader = Effects.XWrap_YWrap_Shader; + } + + public override bool CanActive() + { + return Main.LocalPlayer.InModBiome(); + } + + public override void Draw() + { + DeathJadeLakeBackground deathJadeLakeBackground = ModContent.GetInstance(); + if (deathJadeLakeBackground is null) + { + return; + } + Color baseColor = new Color(0.1f, 0.3f, 0.2f, 0f) * deathJadeLakeBackground.Alpha; + float drawTop = DeathJadeLakeBiome.LiquidSurfaceY; + if (drawTop - Main.screenPosition.Y < -Main.offScreenRange) + { + drawTop = -Main.offScreenRange + Main.screenPosition.Y; + } + float drawBottom = Main.screenPosition.Y + Main.screenHeight + Main.offScreenRange; + if (drawTop > drawBottom) + { + return; + } + Vector2 totalOffset = (Main.screenPosition - WorldAnchor) * 1f / Distance / 300f; + float timeValue = (float)(Main.time * 0.0005); + + var bars = new List(); + int yLayers = (int)((drawBottom - drawTop) / 16f); + + for (int offsetY = 0; offsetY < yLayers; offsetY++) + { + float rightClamp = Main.screenWidth + Main.offScreenRange; + float rightBound = Main.maxTilesX * 16; + int tileY = (int)(drawTop / 16) + offsetY; + if (DeathJadeLakeBiome.RightBoundOfACertainY.ContainsKey(tileY)) + { + int rightX; + DeathJadeLakeBiome.RightBoundOfACertainY.TryGetValue(tileY, out rightX); + rightBound = rightX * 16; + } + rightBound -= Main.screenPosition.X; + if (rightClamp > rightBound) + { + rightClamp = rightBound; + } + float tilt = -0.01f; + float tiltX0 = offsetY * tilt; + float tileX1 = (offsetY + 1) * tilt; + + float fade = 1 - offsetY * 0.02f; + if (fade <= 0) + { + break; + } + Color drawColor = baseColor * fade; + float leftXcoord = totalOffset.X; + float rightXcoord = totalOffset.X + (rightClamp + Main.offScreenRange) / Texture.Width; + bars.Add(new Vector2(-Main.offScreenRange, drawTop + offsetY * 16 - Main.screenPosition.Y), drawColor, new Vector3(leftXcoord + tiltX0, timeValue, 0)); + bars.Add(new Vector2(rightClamp, drawTop + offsetY * 16 - Main.screenPosition.Y), drawColor, new Vector3(rightXcoord + tiltX0, timeValue, 0)); + bars.Add(new Vector2(-Main.offScreenRange, drawTop + (offsetY + 1) * 16 - Main.screenPosition.Y), drawColor, new Vector3(leftXcoord + tileX1, timeValue, 0)); + + bars.Add(new Vector2(-Main.offScreenRange, drawTop + (offsetY + 1) * 16 - Main.screenPosition.Y), drawColor, new Vector3(leftXcoord + tileX1, timeValue, 0)); + bars.Add(new Vector2(rightClamp, drawTop + offsetY * 16 - Main.screenPosition.Y), drawColor, new Vector3(rightXcoord + tiltX0, timeValue, 0)); + bars.Add(new Vector2(rightClamp, drawTop + (offsetY + 1) * 16 - Main.screenPosition.Y), drawColor, new Vector3(rightXcoord + tileX1, timeValue, 0)); + } + if (bars.Count > 2) + { + Main.graphics.GraphicsDevice.Textures[0] = Texture; + Main.graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, bars.ToArray(), 0, bars.Count / 3); + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_close.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_close.cs new file mode 100644 index 000000000..f57fe3961 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_close.cs @@ -0,0 +1,37 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain.Biomes; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class IsleOfBloom_Underground_close : BackgroundSlideBase +{ + + public List BgTiles = new List(); + + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.IsleOfBloom_Underground_close.Value; + Distance = 1.15f; + UseColorStyle = 1; + LayerPriority = 2; + Shader = Effects.XWrap_YClamp_Shader; + } + + public override void Update() + { + base.Update(); + } + + public override void Draw() + { + var bars = new List(); + BackgroundHigherPerformanceHelper.Add_TileBgVertice(this, BgTiles, bars); + DrawVertexBackground(this, PrimitiveType.TriangleStrip, bars); + } + + public override bool CanActive() + { + return Main.LocalPlayer.InModBiome(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_close.png b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_close.png new file mode 100644 index 000000000..6d5d36cc5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_close.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_far.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_far.cs new file mode 100644 index 000000000..e5c5f902b --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_far.cs @@ -0,0 +1,37 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain.Biomes; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class IsleOfBloom_Underground_far : BackgroundSlideBase +{ + + public List BgTiles = new List(); + + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.IsleOfBloom_Underground_far.Value; + Distance = 2.4f; + UseColorStyle = 1; + LayerPriority = 2; + Shader = Effects.XWrap_YClamp_Shader; + } + + public override void Update() + { + base.Update(); + } + + public override void Draw() + { + var bars = new List(); + BackgroundHigherPerformanceHelper.Add_TileBgVertice(this, BgTiles, bars); + DrawVertexBackground(this, PrimitiveType.TriangleStrip, bars); + } + + public override bool CanActive() + { + return Main.LocalPlayer.InModBiome(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_far.png b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_far.png new file mode 100644 index 000000000..fabb590f5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_far.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_middle.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_middle.cs new file mode 100644 index 000000000..89db76410 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_middle.cs @@ -0,0 +1,36 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain.Biomes; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class IsleOfBloom_Underground_middle : BackgroundSlideBase +{ + public List BgTiles = new List(); + + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.IsleOfBloom_Underground_middle.Value; + Distance = 1.7f; + UseColorStyle = 1; + LayerPriority = 2; + Shader = Effects.XWrap_YClamp_Shader; + } + + public override void Update() + { + base.Update(); + } + + public override void Draw() + { + var bars = new List(); + BackgroundHigherPerformanceHelper.Add_TileBgVertice(this, BgTiles, bars); + DrawVertexBackground(this, PrimitiveType.TriangleStrip, bars); + } + + public override bool CanActive() + { + return Main.LocalPlayer.InModBiome(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_middle.png b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_middle.png new file mode 100644 index 000000000..d46baba65 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_middle.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_sky.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_sky.cs new file mode 100644 index 000000000..ba5a9054d --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_sky.cs @@ -0,0 +1,35 @@ +using Everglow.Commons.Mechanics.EliminateLight; +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain.Biomes; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class IsleOfBloom_Underground_sky : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.IsleOfBloom_Underground_sky.Value; + Distance = 2.8f; + UseColorStyle = 2; + LayerPriority = 2; + Shader = Effects.XWrap_YClamp_Shader; + } + + public override void Draw() + { + Main.spriteBatch.Draw(Texture, WorldAnchor - Main.screenPosition, null, Color.White, 0, Texture.Size() * 0.5f, new Vector2(4, 1), SpriteEffects.None, 0); + List polygon = new List(); + Vector2 centerPosWorld = YggdrasilWorld.KelpCurtain_IsleOfBloom_CaveCenter.ToWorldCoordinates() - new Vector2(0, 240); + polygon.Add(centerPosWorld + new Vector2(-100, -40) * 16); + polygon.Add(centerPosWorld + new Vector2(100, -40) * 16); + polygon.Add(centerPosWorld + new Vector2(130, 30) * 16); + polygon.Add(centerPosWorld + new Vector2(-130, 30) * 16); + EliminateLightManager.AddPolygon(polygon); + } + + public override bool CanActive() + { + return Main.LocalPlayer.InModBiome(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_sky.png b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_sky.png new file mode 100644 index 000000000..0c2b04daa Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Background/IsleOfBloom_Underground_sky.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainBackground.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainBackground.cs index 3a5965a36..ca7750748 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainBackground.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainBackground.cs @@ -1,12 +1,11 @@ using Everglow.Yggdrasil.Common.BackgroundManager; using Everglow.Yggdrasil.KelpCurtain.Biomes; -using SubworldLibrary; namespace Everglow.Yggdrasil.KelpCurtain.Background; public class KelpCurtainBackground : ModSystem { - public Vector2 BiomeCenter = new Vector2(9000, 157000); + public static Vector2 BiomeCenter = new Vector2(9000, 157000); public bool ZoneKelp = false; /// @@ -58,27 +57,52 @@ public override void PostUpdateEverything()// å¼€å¯åœ°ä¸‹èƒŒæ™¯ private void DrawFarBG(Color baseColor) { - var texSky = ModAsset.KelpCurtainSky.Value; - var texClose = ModAsset.KelpCurtainClose.Value; - var texC0 = ModAsset.KelpCurtainMiddleClose.Value; - var texC1 = ModAsset.KelpCurtainMiddle.Value; - var texC2 = ModAsset.KelpCurtainFar.Value; - int minY = (int)(Main.maxTilesY * 0.72f * 16); - int maxY = (int)(Main.maxTilesY * 0.9f * 16); - BackgroundManager.QuickDrawBG(texSky, GetDrawRect(texSky.Size(), 0f), baseColor, minY, maxY, true, true); - BackgroundManager.QuickDrawBG(texC2, GetDrawRect(texC2.Size(), 0.10f), baseColor, minY, maxY, false, false); - BackgroundManager.QuickDrawBG(texC1, GetDrawRect(texC1.Size(), 0.15f), baseColor, minY, maxY, false, false); - BackgroundManager.QuickDrawBG(texC0, GetDrawRect(texC1.Size(), 0.25f), baseColor, minY, maxY, false, false); - BackgroundManager.QuickDrawBG(texClose, GetDrawRect(texClose.Size(), 0.35f), baseColor, minY, maxY, false, false); - DrawSubBiomeBackground(); + //var texSky = ModAsset.KelpCurtainSky.Value; + //var texClose = ModAsset.KelpCurtainClose.Value; + //var texC0 = ModAsset.KelpCurtainMiddleClose.Value; + //var texC1 = ModAsset.KelpCurtainMiddle.Value; + //var texC2 = ModAsset.KelpCurtainFar.Value; + //int minY = (int)(Main.maxTilesY * 0.72f * 16); + //int maxY = (int)(Main.maxTilesY * 0.9f * 16); + //BackgroundManager.DrawBG_RestrictY(texSky, GetDrawRect(texSky.Size(), 0f), baseColor, minY, maxY, true, true); + //BackgroundManager.DrawBG_RestrictY(texC2, GetDrawRect(texC2.Size(), 0.10f), baseColor, minY, maxY, false, false); + //BackgroundManager.DrawBG_RestrictY(texC1, GetDrawRect(texC1.Size(), 0.15f), baseColor, minY, maxY, false, false); + //BackgroundManager.DrawBG_RestrictY(texC0, GetDrawRect(texC1.Size(), 0.25f), baseColor, minY, maxY, false, false); + //BackgroundManager.DrawBG_RestrictY(texClose, GetDrawRect(texClose.Size(), 0.35f), baseColor, minY, maxY, false, false); + //DrawSubBiomeBackground(); } public void DrawSubBiomeBackground() { - if (Main.LocalPlayer.InModBiome()) - { - DeathJadeLakeBackground.DrawBackground(); - } + //if (Main.LocalPlayer.InModBiome()) + //{ + // DeathJadeLakeBackground.DrawBackground(); + + // // Isle of Bloom Underground Cave. + // int isleOfBloom_Cave_minX = YggdrasilWorld.KelpCurtain_IsleOfBloom_CaveCenter.X - 130; + // int isleOfBloom_Cave_maxX = YggdrasilWorld.KelpCurtain_IsleOfBloom_CaveCenter.X + 130; + // isleOfBloom_Cave_minX *= 16; + // isleOfBloom_Cave_maxX *= 16; + // int isleOfBloom_Cave_minY = YggdrasilWorld.KelpCurtain_IsleOfBloom_CaveCenter.Y - 20; + // int isleOfBloom_Cave_maxY = YggdrasilWorld.KelpCurtain_IsleOfBloom_CaveCenter.Y + 10; + // isleOfBloom_Cave_minY *= 16; + // isleOfBloom_Cave_maxY *= 16; + // Vector2 screenCenter = Main.screenPosition + new Vector2(Main.screenWidth, Main.screenHeight) / 2f; + // Vector2 isleOfBloom_CaveCenter_World = YggdrasilWorld.KelpCurtain_IsleOfBloom_CaveCenter.ToWorldCoordinates(); + // List isleOfBloom_CavePolygon = new List(); + // isleOfBloom_CavePolygon.Add(isleOfBloom_CaveCenter_World + new Vector2(0, 320)); + // isleOfBloom_CavePolygon.Add(isleOfBloom_CaveCenter_World + new Vector2(130 * 16, 0)); + // isleOfBloom_CavePolygon.Add(isleOfBloom_CaveCenter_World + new Vector2(0, -320)); + // isleOfBloom_CavePolygon.Add(isleOfBloom_CaveCenter_World + new Vector2(-130 * 16, 0)); + // bool isleOfBloom_Cave_flag0 = MathUtils.IntersectsPolygonAABB(isleOfBloom_CavePolygon, Main.screenPosition, Main.screenPosition + new Vector2(Main.screenWidth, Main.screenHeight)); + // if (isleOfBloom_Cave_flag0) + // { + // BackgroundManager.DrawBG_RestrictXY(ModAsset.IsleOfBloom_Underground_sky.Value, float.PositiveInfinity, isleOfBloom_CaveCenter_World, Color.White, isleOfBloom_Cave_minX, isleOfBloom_Cave_maxX, isleOfBloom_Cave_minY, isleOfBloom_Cave_maxY + 160); + // BackgroundManager.DrawBG_RestrictXY(ModAsset.IsleOfBloom_Underground_far.Value, 4, isleOfBloom_CaveCenter_World, Color.White, isleOfBloom_Cave_minX, isleOfBloom_Cave_maxX, isleOfBloom_Cave_minY, isleOfBloom_Cave_maxY); + // BackgroundManager.DrawBG_RestrictXY(ModAsset.IsleOfBloom_Underground_middle.Value, 2, isleOfBloom_CaveCenter_World, Color.White, isleOfBloom_Cave_minX, isleOfBloom_Cave_maxX, isleOfBloom_Cave_minY, isleOfBloom_Cave_maxY); + // BackgroundManager.DrawBG_RestrictXY(ModAsset.IsleOfBloom_Underground_close.Value, 1.2f, isleOfBloom_CaveCenter_World, Color.White, isleOfBloom_Cave_minX, isleOfBloom_Cave_maxX, isleOfBloom_Cave_minY, isleOfBloom_Cave_maxY); + // } + //} } /// @@ -112,6 +136,6 @@ private void DrawBackground() } Color baseColor = Color.White * alpha; - DrawFarBG(baseColor); + //DrawFarBG(baseColor); } } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainClose.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainClose.cs new file mode 100644 index 000000000..0536c1ed2 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainClose.cs @@ -0,0 +1,19 @@ +using Everglow.Commons.Utilities.BackgroundHelper; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class KelpCurtainClose : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.KelpCurtainClose.Value; + Distance = 1 / 0.35f; + Shader = Effects.XWrap_YWrap_Shader; + } + + public override bool CanActive() + { + return Main.LocalPlayer.InModBiome(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainFar.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainFar.cs new file mode 100644 index 000000000..0f0199d78 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainFar.cs @@ -0,0 +1,19 @@ +using Everglow.Commons.Utilities.BackgroundHelper; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class KelpCurtainFar : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.KelpCurtainFar.Value; + Distance = 10f; + Shader = Effects.XWrap_YWrap_Shader; + } + + public override bool CanActive() + { + return Main.LocalPlayer.InModBiome(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainMiddle.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainMiddle.cs new file mode 100644 index 000000000..42fec427b --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainMiddle.cs @@ -0,0 +1,19 @@ +using Everglow.Commons.Utilities.BackgroundHelper; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class KelpCurtainMiddle : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.KelpCurtainMiddle.Value; + Distance = 1 / 0.15f; + Shader = Effects.XWrap_YWrap_Shader; + } + + public override bool CanActive() + { + return Main.LocalPlayer.InModBiome(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainMiddleClose.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainMiddleClose.cs new file mode 100644 index 000000000..ab8319083 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainMiddleClose.cs @@ -0,0 +1,19 @@ +using Everglow.Commons.Utilities.BackgroundHelper; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class KelpCurtainMiddleClose : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.KelpCurtainMiddleClose.Value; + Distance = 4; + Shader = Effects.XWrap_YWrap_Shader; + } + + public override bool CanActive() + { + return Main.LocalPlayer.InModBiome(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainSky.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainSky.cs new file mode 100644 index 000000000..508f2ce5e --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtainSky.cs @@ -0,0 +1,19 @@ +using Everglow.Commons.Utilities.BackgroundHelper; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class KelpCurtainSky : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.KelpCurtainSky.Value; + Distance = float.PositiveInfinity; + Shader = Effects.XWrap_YWrap_Shader; + } + + public override bool CanActive() + { + return Main.LocalPlayer.InModBiome(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtain_MapBackground.png b/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtain_MapBackground.png new file mode 100644 index 000000000..ff6b66a34 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Background/KelpCurtain_MapBackground.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/VampireMatCave.pdn b/Sources/Modules/Yggdrasil/KelpCurtain/Background/VampireMatCave.pdn new file mode 100644 index 000000000..d76f577de --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/VampireMatCave.pdn @@ -0,0 +1,189 @@ +PDN3P²ÿÿÿÿ PPaintDotNet.Data, Version=5.112.9563.32325, Culture=neutral, PublicKeyToken=nullPaintDotNet.Document +isDisposedlayerswidthheight savedWithuserMetadataItemsPaintDotNet.LayerListSystem.VersionæSystem.Collections.Generic.KeyValuePair`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]][] èè  PaintDotNet.LayerListparentArrayList+_itemsArrayList+_sizeArrayList+_versionPaintDotNet.Document  System.Version_Major_Minor_Build _Revisionp[%E~äSystem.Collections.Generic.KeyValuePair`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]øÿÿÿäSystem.Collections.Generic.KeyValuePair`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]keyvalue $exif.tag3[0] +Dõÿÿÿøÿÿÿ $exif.tag4[0] /òÿÿÿøÿÿÿ $exif.tag5[0]7ïÿÿÿøÿÿÿ $exif.tag6[0]7    PPaintDotNet.Core, Version=5.112.9563.32325, Culture=neutral, PublicKeyToken=nullPaintDotNet.BitmapLayer +propertiessurfaceLayer+isDisposed Layer+width Layer+heightLayer+properties-PaintDotNet.BitmapLayer+BitmapLayerPropertiesPaintDotNet.Surface!PaintDotNet.Layer+LayerProperties  èè   èè -PaintDotNet.BitmapLayer+BitmapLayerPropertiesblendOp&PaintDotNet.UserBlendOps+NormalBlendOp PaintDotNet.Surfacewidthheightstridescan0PaintDotNet.MemoryBlockèè  !PaintDotNet.Layer+LayerPropertiesnameuserMetadataItemsvisible isBackgroundopacity blendModeæSystem.Collections.Generic.KeyValuePair`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]][]PaintDotNet.LayerBlendMode +Background ÿßÿÿÿPaintDotNet.LayerBlendModevalue__ "èè  #$Layer 3 ÿÚÿÿÿßÿÿÿ&PaintDotNet.UserBlendOps+NormalBlendOpPaintDotNet.MemoryBlocklength64 hasParentdeferred  = äSystem.Collections.Generic.KeyValuePair`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"# = #‹ +íÃA ¡óozûV$T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªê|(Pò!#‹ +íÃA ¡óozûV$T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªê|(Pò!#‹ +íÃA ¡óozûV$T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªê|(Pò!#‹ +íÃA ¡óozûV$T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªê|(Pò!#‹ +íÃA ¡óozûV$T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªê|(Pò!#‹ +íÃA ¡óozûV$T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªê|(Pò!#‹ +íÃA ¡óozûV$T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªê|(Pò!#‹ +íÃA ¡óozûV$T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªê|(Pò!#‹ +íÃA ¡óozûV$T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªê|(Pò! #‹ +íÃA ¡óozûV$T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªê|(Pò! +#‹ +íÃA ¡óozûV$T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªê|(Pò! #‹ +íÃA ¡óozûV$T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªê|(Pò! #‹ +íÃA ¡óozûV$T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªê|(Pò! #‹ +íÃA ¡óozûV$T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªê|(Pò!#‹ +íÃA ¡óozûV$T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªê|(Pò!g‹ +íà àú7ý $T—ªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª¶õþ<ÝÐ ‹ +í=“ëÆE(q`©”8tä`vÙÿÿ³kTš÷úµºç bš}¶êÖrA4æ^¢æ\òõzýï…B!„B¡Gõ¯¿Ï©Ôüû·Ÿ¾éŸÿøË·ßõ±–Ü^ê¿^¯oû•ã~ÛµþóëšçOöµþÕø‰?;¿èù£ûÏž?ºÿìù£ûÏž?ºÿìù£ûÏž?ºÿìù£ùÉW=I-_r?Y/%÷id_¯Þj×Êdís‚éõj½5/‡_~\ðƒüà?øÁ~ðƒßçò›É×ÊáùžY?°rÜŧտ©þW¯/ñØ›Ãï|~\ðƒüà?øÁ~ðƒßgóÍ7ÂÆÚoöþ¾>îî×çÈqVùÜéG}on¿³ùµ|Â~ðƒüà?øÁ~ð‹Ï¯§òûV†^»_‹ùVë­öå9“Çö¼_iÿÿ;ë˼~qùéŒðƒüà?øÁ~ðƒü>‡ß(ŸVo} l›ñg»Ý|FÛ?ÉëüÃ~ðƒüà?øè~ðƒüà·_’ÏŠNZÿ±Î¿õ:;ÑÿÈë ~çú‡üà?øÁ~ðƒüà?­ò~x„B!„B=+½>P¶é5-ï¹:ßï­¡è5ݾü¾¸¢™õ™Ìþ³çî?{þèþ³çî?{þèþ³çî?{þèþ³çî?{þýËãW^ÛõïÕ|º~¤ý¢’QoÃÿ÷Ç™óG÷Ÿ=tÿÙóG÷Ÿ=tÿÙóG÷Ÿ=tÿÙóG÷Ÿ=ÿu®_Ÿ÷üõtG¾VÆìþ³çî?{þèþ³çî?{þèþ³çî?{þèþ³çî?{þhþåóz¿Ñ|3õ^û­}Fê³øÏž?ºÿìù£ûÏž?ºÿŒùÿöëÏ?(šÿìü>ÉöüÑýgÏÝöüQü×Çúóåô󽜳õ£í[õ¶Œþ³çî?{þèþ³çî?Sþ×ëõÒss=O?Ùv~Ÿè?{þèþ³çî?{þÓý×ûîu?ïóß­ã÷òµ¼xÇŸ©/³ûÏž?ºÿìù£ûÏž?ºÿ,ùËܼ7?/:Õv~Ÿê?{þèþ³çî?{þþëgÌi^¾Vƽz/‹å ÿäî?{þèþ³çî?Cþósø•?ºÿìù£ûÏž?ºÿìùOö_ÞïŽB!„B¡g%çúõ3äZ륦Ìñõ}ùQÉ6WŽ¡=ãŸüŸâ?{þèþ³çîÿSóÞ;¯:Ív~YügÏÝöüÑýgÏ¢ÅÚ¦óÕÇÞ{ ¤ô±j½¼§/÷•¿õãZÿïþ³çî?{þèþ³çî?CþÙùùiþ³óûdÿÙóG÷Ÿ=tÿÙóGñoe¹šÏjKæ“ûxõúq­Ç¿ÿ¿óG÷Ÿ=tÿÙóG÷ÿÉùgæær~~Šÿìü2øÏž?ºÿìù£ûÏžÿtÿúy¯M™¯—Íú[¿¿À«ó¼yí¯úÿï_cû‡_lÿð‹í~±ý:¿Ù{çu~~Šÿìüzþ¹þbç‡_ìüð‹??yL/×Ì{t;ò˜+õõq9'Výÿí¿îwšøÁ~ðƒü,ÿ«ósøÁ¯çŸë~ðƒü>›_}N>oí«?ëwv™­U¿ê¿ÇGïsšøÁ~ðƒü´ÿ:7_ýßsø=Ëë~ðƒüà§÷ñæòŸÏwå[õ_Î}‹‘~î4ÿðƒüà?øiï;æçð;;?×üà?ø}&¿ò~x„šÕÏ¿þü6=!„Ðç‰~ !t¢Ê|^®3”mÞ\^®IxÛKý¿û©[S×]¬õ½ž ÷Õë™ýgÏÝöüÑýgÏÝÿ'ç_¹w~’ÿìü2øÏž?ºÿìù£ûÏžÿtÿõ¾ô'ëgÕ«×yôçài^.)ù]tý_=ÿðƒüà?øÉöWççð;ƒ_ÿð‹í~±ýÃ/¶ÿÞù/Ï׌ïÌ'½IÅKÑȱÊïrNò_ÿ§aÔÿÕó?øÁ~ðƒß;ççðãúƒüà?øÝǯþ|='²½QIV/_ùÝZ?¨ëÖ1êßõîOô_ÏmËÿÕó?øÁ~ðƒŸô¿c~?®?øÁ~ðƒßóüjÖ•lº^fѹä>2Ÿn_¾waD§ù—ÏÝåÿäüðƒüà¿÷ó[™ŸÃï~'ø‡üà?øÁOû[á[êêyõ$Ï»ÜnñÑû´üáŸüÑýgÏÝöüÑýBþÕïV;Åv~™ýgÏÝöüÑýgϲÿë/:ƒ—ÍÒH>++þÉÿ)þ³çî?{þèþ?!ÿÕùùÓþ³óËì?{þèþ³çî?{þ“ü—÷»#„B!„BèYÍ®/Ô*kòûâäszŸ¢R/×(ê—±ÝZ·Xñ|šÿ²_o]ÅS©—Ç›=†¬·üéµ!ëüyþ¯ÖGÏÝöüÑýgÏÉÿÝýßìýó¨ýwÄþ?úø~ðƒßgøÏž?šÿ‘|Õ“ô×ò%÷“õRrŸ‘öGöõê­v­LÖ>;üϼÃ:å·üÿ¹¯ü­ëógñ±¶µü_­ž?ºÿìù£ûÏž?¢k»·¿WßÛwe~îùyNè¿-N«õ7ï ù[¯oøÁ~ðƒßgò›É×ÊáùžY?°rÜŧտnÿ£ãKïõ]~ë{?^½~\ë­Ü­úžÿ«õÑóG÷Ÿ=tÿÙóGôgÿ7;?oµyjÿ½r Æ/çø‡üà?øí“ŸôØXûÍÞß·ÆW;_Ÿ#ÇYåãù—Ï×ï¾kµ)ÿÖïïôê¼±£ç¿Çíîú¨ùá;?übçÿ~;û?97ŸŸ÷²Òï®gü?øÁ~ð;™_OÞ= k\3SßË·Zoµ/Ï™7óøìöï/u}Ýo¥ýú¸ŒI­zÉn…ßÕú;ùß~ðƒüN:ÿ«óó'ú¿YÝUÏø~ðƒüàw2¿Q>­,Þ8¥l›ñg»Ý|FÛ¿Ëo|©÷YÍ_ïµ®¯‘×ëîúÙ<§å‡üà¿«ü¼cêÇwÌÏGÚ?©ÿöÎíŽzÆ/ðƒüà¿ùÍðYÑIë?Öù·^gwú/cÇÖS?w×øÒËÙžv|¿ÝÝþ[çµúïÕÔû^-~Þ¾z=Gn«õ½üòØWê£çî?{þèþ³çêÿÎþoöþù»û¿žÿÕñÇÕú,ãýú€_,~\ðƒ_~òør|aµ]ÿ^å£ëGÚ/ò>k׫—méǽóþ„)«¾u½ècëñ¡7®ÔïmùïéjýÓùåw!Gô¿ØþáÛÿÕó¿¹ÿ{­ÌÏOê¿=^º}«ŸgüÒ÷ïÍÏáƒ×üà—‹_ë·Öÿ[mTÝ‘¯•ÑóoµeeѿۿuþFXÖöêØP¶_ÿ'säXõuŒ¼:?¸R¿;¿õZhå/cð“üÃ~ðËÃosÿ7ýÙíOöWÇŒ_æÇ/³ósøÅë~ðËÉO>ïeêñ™©÷Úï×^ýk¿wû×>¼õïXåwëþMý|¤Ök²îS_3¼wÔß™¿^­üõ3Nô?øÁïsùÝÐÿ-ÏÍŸèÿ¼ú«íÖk–¿wŒ~³ósøÅë~ðËů>ÖŸ/§Ÿïqš­mßʨ·YõšÃÓþ[ÞtûVv«}9¾´>ßxôÚ²êgµRg~ùÞÙˆþá?ø}.¿Ýýßìüüôþ{Wû^ýéùõküªëÿà‡×üàw¿ÖÚåþåý^¾Y>-/ÞñgêËcϯëùÙöWü·Î]=5—ŶJŽ{åö_íi”ߨvÔGÏÝöüÑýgÏÑÿhÿ¡·iWæç³íßávüÁøeŽŸÂ/?®?øÁo??kÝÒš§?ÁOŽUFø´øëÕ{Y,OžÝÞ¨Þé¿Wï1[cÏ‘ñe+Ç÷ï>-tÿÙóG÷Ÿ=ÿéþ­:Ë¿ÜϪ±ú¿™¹¹ül8+¿n¿•{—ÿ•ñã—q~Þü~1øqýÁ~{ùõææ£sô;ø•÷»#„B!„BèYɹ~ý ¹Ö:A©)süÞ}…ÆZÅí-¬u¸ÏYþ_Ïøå»Nðõûù¬5š/c»u~J½·ö3"íÿj}ôüÑýgÏÝöüý_í?Ͻ®Þ??­ÿ¶ÎŸ×3~jÿO÷ÏáŠß[ýÃ~ŸÆïuíç­þ5 k›æ3û^>y¬Z/ïéË}åoýXoFü—1Yýþ=¾zÊëøÖy·øz>gƇ½}[õV¶•z›Ç÷„üðƒüàwÅÿýßìÜÓøE8á‹ß;ýÃ~ŸÀoÓÜüõ¿Ö˜ÆãÓccý­ßáÕyÞ¼ö[þëÊœ~د~wíþ[lwŒ/õ5RëGÛmñß]¯}zNÉ?øÁ~+þïêÿfççO÷#íµøï¬Ï4~±ð‹Ãë~ð÷¿qnþz¿ã—9ÿ£ósøÉï]þáÛv~OÏÏwò“ûxã‹ÏŒç»òYþ­}Oòoÿ‹ÙñåNÿº~d|ëøe÷ü~ñÆŸðƒß'óÛ=7‚ßÿ„B!„B¡Uß/Xçðe›7——k*ÞöR/¿Ö«©ë.Öz^OÐûêõ˜HþG¾Ÿ·åÝZÓÒí~Ÿž·^3º¦¶»¾žÿ§ó_ý~å§ýÃ~ð;—ßýßì½së»Ï#ößÑúÿÝùWýëûCð‹ÅïÿÙóG÷ÿiùkß¶ãžù üôw¹éñŬzõ:þ|íÏËUU¿ûà)ÿúÿSzþ{¯ûÖø²Ö{ž<ÿÞg ŽÔ·Ú×™VêOÌoåjq;Í?üà¿sùÝÑÿÍÎÏŸêÿ,]í¿¿Ìû÷Þ¿ ¿ü¸þà¿ùÉþíʼü4~åuŸwò©çWoê}‹‘c=í_Þ_‘þ­ïbõÞßwŒ/«ÏV}νöw×[çÿ„üV[VøÁ~ð›9ÿwôOÌÏëy™éÿîè¿¿Ìû·îÁ/?®?øÁï{~Ý¿­ÎËOäWÿg½ž“™ñœnË»àå+¿+#«¾®¯´ÆduŸ§üË÷(ôü[cNëõ-÷oåÑÏ·ÖZcS]µýÑz­Óò÷Ž?øÁ~3ç_þ½£ÿ«ã‹+ós¯}Ïûjÿgóêøƒñ˼ÿÖü~çóãúƒüþ=ÿ½,º^¿¬öõkÅzÞòï½Öîhß«?=¿æÍ?ü࿳ù]íÿ®ÎÏßÙÿÝÑ_­Ï8~ñƧð‹ÁOîÃõ¿ŒüZýÛÊÜ<?ío…o©ë}®Ž|ϽÜnåÓû´üEðoq–¬-ÿ­:ùüL}ÍáÕ[Ç×í_­å÷îü½và?øÁoåü׺z¬«ýßìü¼Ç_ú‹Ø_­žÄ¿5F=Å?übûÏž?ºÿù{}ÜÌü<¿ë/:ƒ—Í’n_´¢ûoÕk–­Ü–ÿÞk¡n“¯µÑñ¥Îx¥~äõùîü£¼à?øÁoæüïîÿGÖGÏ?ât~¿3ùì?{þèþOÎ?ÚÇ­ÌÍOäWÞïŽB!„B¡g5»>2úý´úoùý´Ö=Š/c»µn±âYû—Çk­mXÚá¿ì·Òvmÿªÿ–?½6d?ÏÿÕúóÿÎô—ïŠæ~ðƒßyüô>«ýßì½sù½çïèÿþ¹ç¾à“‹ +í=,9o…oàÄØÄ¡#7qðvàÿÿÃÖ}µàrI‰ÔG‰”ÎÄÌTK‡z¤–(Uwýãßÿùü²ÿþýÇ?~üøã?ÿmÜŠÿýÇ?ýi³þEWý]ÿ–þ¯VüþøñçëÅÊu +ǹ­ŠŸ^¯k•É­êÿÁ~¾Ô~óüNê?ðûšß¿þþ›Ë~t~²ò³¶O—5FîOžcí£úËïRWü4~LŠTý»ðì/Õß +ýéXKÿ¬ôøË{ÊÿüËÿ—ÇûWýà~à‹Ÿt\;_ó/FçŽyË’øWèïÛò—´økÜ4¾â_ÁOš¯‚_~'õƒø}ÅÏ›—òóÔü¬íSÒ.ÍKøÿžõ)Ž•ý«W¯§ú­óK­}¯Ð/qjù÷ôÏúG¿XÍ~í;¤Ò~à~1ùÍŽ³ùùLü+ô[¯£ÕßÈ50ùó:ù¿\üNë?ðÛÍo47×òóøYùXØHçy÷÷¥ùÕlû,óºÊGc¢Í½V觯—¹g¯mðö±CÛnÿÈñ×=¼bà~à~»ëß2þysóñè÷\‡—¿Úÿµù‹%?¿¸üNê?ðÛÍoGn~¿ži{R\ÿ^|£þ+ʯ×=œ•úµùåªø-ú)»~³þÑã¯÷Â?ð?ð‹Pÿ#ùy´ñÏk»ü_›¿xósð‹Å/‹~ð?où3¹9ÏÏoãgå£qÐÖQêk}ÒÆ©öY×[Vë÷êÙ¥_â&1\í=~¾Î–M?øåÖ~¹õÏ”ß?Fîmß¿Wÿ®ùǬÿ+óëýíà“ßiýà~;øÍææ4?¿‘Ÿ‡ÏˆE]ÿÙÁÇR~ùßsÍú%^žòGü#Ç/›I?øßŠøéx~ûøyô{sóùùÊúçþZýzý_¿X÷ÏÁ/&¿ÓúÁüVó[‘›×üü~å~x ƒÁ`0 ƒÁ`g>î>ŸÎº' /þ½5¾F@_£þõ™:žõ™ú[ϬþÚu)“–OÝ7jůË×sè±êß‹Ÿ^{Æ?{üÙõ¿vý»ãçûlÑâÏÊovüóîŸKåkõ×ÒnÑoy>®tÎÈüó—1ýZ¿¿üÐÿÀï~«öÌÉÞùµüèüB{}&>îϯ#•_Lû®=‹ÿ ýô\éï–Iñ·Ú¯>?Ôæ•¼~[õß³Yÿ™øù÷Cyã¯Ïn:¥üÀ/2?m~ëêß;þ|ö<Êø×²Uã÷¬ÿlü=~ÿ]ú¥~ ~yø¡ÿ_f~«órK~ž™Ÿeý¿ÕÆ©ÿêþÕêc|­,’~~®Eƒg~Yë…—_ŽIÏ"’®U~—9h½ÎÈürÖ&þ§?m »ã?𻕟ÇÓüÖè÷Ž#Ÿ=2þñ±xvþù˘þV~~ñù¡ÿ_F~»òržŸßÄë£×‰ÏãÏ_—úWëšÿiý­\-~'ÕGï±äþu«Õ&êwÔ÷'O}­ðŸ¿æ£ñ×sNé?ð‹ÌOËÑÁo¾þGÆ¿Ñ{Û#ŒÒñÙògüwÅo‰ÝR»ô÷òsð‹ÍÏZ>ø_~»ór)?¿_ïûåè5-qzýùëš¿?Öò?¥_ã ½Fý¥Ø¥òéü’—OçÎ;ñý’³ñÓOÄ~àw;?>Ÿ¿5úGÆ¿™{ÛO«Ë?íŸuþ"õgðËÃϪüÀï4¿¯róùñk´®ï¯Õ´ë{üËßõ¾Éÿ¤þ^9­òk\Ò{K5ú™Gz\š_¶êÏ¿Gÿ¬öø³ë=þìúwÄßÛCF~RùÚøã½·]Óïi?=®¿wžôºTÿÖòWø¯Œßâ_Û¡æ¿S¿ö™ðËÁ¯§üÀ/ +¿“ùyv~ô|k|­-ñõüµ¾$i*¿é\+‚~é|KÛàñksÌÖÜ“ÇÏßzzNìßÝvý¯ÇŸ]ÿ®øµ9}´ø£ó“ü$ýô<ú÷l~Þ+_*Óë¯ÕWϼã÷¬ÿŽø{ü"Ì_´ûaÀ/?ô?ðËÀïËÜüF~å~w ƒÁ`0 ƒÁ`gæîÒóùú@ñ)9~o_A3ZæÈ5¸æQýÒ}‹ÞòG®±"~ið§p\ªŸâ¯­ýX¬øÓg÷ÍúkÏäÿÓ瞎üÀïE~­{ÜÁï3ý?FöÏ#ŽRýÎÌ?0±—o¹üâò+†þ~Qù}µo^÷ÎoåÇc‘Žñø¼÷òÑkUzO =—þæóùͬ~þì^~é{ƒ¬úWįéìÅCë¯wnË_Ò6â¯qÓøFˆüÀïa~ê÷Äß'ú]ù¹VþÉñoÕø-­³xý_¿ô¾OübóCÿ;?øéq›ßÎOŠe¶IeÑþEÏÑüùßÕ…þŸ–~¾vâÕ?¿Å¤k¯š_jõ;㯵Kú”øÁüå÷·ðûTÿgùùÎñoõüó?¿^?¿ØüNë?ð“t¹wþ +?i®&•ißh×ã÷Gh~š6­üLúwÄoicÕ¿Õ¦zFÛ×J®Sã!~ð¿—ùYósðÛ¢Y~Þ‹;Óøiü¢_êÇà—‡_$ý¯ÇŸ]ÿÊø#äç7ñ£×ìÍ;¼ß¯Ë¯9â_ÿ.u"ùg׿ÛFÿlýYý¥vߊòÁünâ7³‡~sú=¹¹”Ÿß8~gÿOé·ôað‹Ë/Šþ×ãÏ®uü§ró›ùÕ×´¼_ÓçÕ;:¿©ë­ùåˆ~Ëg¾Ð¿Ã_ª‹UóË^?õ—8Ò×¢Ä~à÷2?ïÜüÖè_ŸGÿFÇïYÿ—ç/žû`À/¿úÁ/·þü¾ÎÏ_áGÏÑæhæó«ý…Oý;ýgõsËZ•ÅßkQâ?ð{™Ÿgübçç™ÇïYÿ—ç/ž> ~ñøEÐ~¹õ¯æw"7¿™ß¯ÏÂ`0 ƒÁ`0 ;h%Ÿ§ë 嘖ËÓ5 íxñ§ÏÏÕ|꺋´^À×ø¹|=#«~­ü–viMˆ—oy¾±tN}>µuMŠ^{ÔGüÖç jëU§õƒøeà'í¿__ÿèøáÝ;/¦ÅËøyü0‘ú/øåáwZÿëñg׿*þ¯öÍ_ãÇŸ%Èç^ëùóxø÷àq}Z\Ô2é§qhí£×®4MÔŸoµWî¯ÅkÕ?ë?¿Ô>,L£è?ðËÂÏr,øé×ñŒ³÷¶ß:~gÿ£é×òsðËÁ/‚þ×ãÏ®Eü_çå/ñ+רç|ÕFõ•Ïüz>g÷Zåw=?Šþºo4¢ee~ÃÏå×â¾Rû’|´²GüwÆÏû@K?gA?ø_~39ú‹üFÇ¿hùùìøW}f瘿Œë—òsðËÃýüNó;ùyóøÕϬ×kzæC¼,mÿ@‹¯ü¦{üÜŸ>^»f='¢þ:/õÌ/éù½ù©0ÞŠåi×áÿ”?ã¿+~Kì–ú;¥üÀ/¿V~~z~îÿVÌi4ÓÊ×´ÏŒüš³óÌ_Æõ·îo¿øüÐÿÀï4¿/rsðûë¹#±q‹4O‘⓾_o¤­EÑOï]àeYôó¶ •ÏÛJ+ÆÕåŸöïÅßâ§õµHúÁü2ðÓöÐÁ¯_¾uüÛ•Ÿ9þí¿gý_ž¿ð> ~¹ø¡ÿßI~_샟üºçºÔ¿øõ¾ˆê¦Ç¥øø9-}™ô{ê¿çÏËï'½.é·–¿ÂeüÿÊQó?©üÀ/¿Ö}îà7?~ìœ×Ðú£ú2Žß³þÙã÷è·äçà—_Dý¯ÇŸ]¿Çÿ«{ÛÁïï¯X¯c+vK|R¬Ùô{û‡×¿Õ¶Zf_jǽþ;â·ö…zŒöµúÁü²òkí£ƒßÜø±óþö›ÆïYÿìñ{ôäçà‡_Dý¯ÇŸ]¿õÜ/rs)?‰_¹ßƒÁ`0 ƒÁ`0ØYó®/ŸšûÓï^°Zñ—öÈ~ +Ç¥u ¯æª‘êŸ}¾í¬þrÞHÝÕú›­ÿ–>¾6$ñ/ú¥u¡Y¯þ‘k¬ŠüÀüäkH{èà÷WýÞñctß!âø7³¿!ñÃüeœŸÖOÁ/?ô?ð;Á﫽óú9-ð³ó©qWmÕêÿô8?§òå×¥±ZÛ—…ćêä·l•~­íH&•¿¢þµø¤cš~©zýGã—¾wáëøÁüÀOŽ_û:ø£¹yÄñÏz®æ¯ñ›õ÷ðÿ"þ/øiýürðÛ©üÀOòÿ27çïI¯óóðíé’ú™gý@º¶5>ºÇBç¡´|éý_›ÿ¿B?m?Þ>VÔ¿gË_Òßû.¿7~¾ww"~ð?ðSóPñsèà×Ö,é/{ç5‘Ç¿™ù ç7ëÿúü¥•Ÿƒ_|~»ôƒøiþ_ææ£ùù­ü,|èý‘’&ûh|RYâãóÎzï-ßÂF:o…~«Ÿôÿ®úïŽÛ?{üÙõ¿výãoåçôŸlô:ÅFöÏ£Ž³óË¿Yÿ׿/½ýsð‹Ío‡~ð?;ÎÍégnÀ¯oÞïÇ£:J›ñ§×èù¾.½/¬Šß£‡¯þiì#ñÏúg?»þ×ãÏ®?jü|î~ãúgòóÌãßlù+ô÷øgž¿Xósð‹Éoµ~ð¿–}›×üüöò­ë5i mUûÔ8hë(õµÕú½÷™ìª)n©Vû{ã‰?øåŽüöÅ/Ýã~ö2«ÿÈ'ËøçµSþ·Î_z÷·ƒ_l~§ôƒß›ü¾ÎÍë{øÅë_;Úå3b«õ—ù¥çš;ë_Š×Sþˆù?süà—;~ðÛ¿5??ÝvåçÆ¿,þ·Î_zûçQêüÐÿ"é‘߉ܜ¿'½Æ¯ÜƒÁ`^ûí÷ß>³Ó±Â`0ì>Ã8ƒÁ"ZÉçé:ÿÃú‚özõ§Ï“Ó|ê¾ ?¯–OÏççòõˆŒúo©¿¬õŸ½ý€øeá×[Ÿ·ü‘½ó›ë/[ûúþ¥lW_~ô¿výVÿS{ç¯óãϲ¥×±ž?‡ ×§ÅE-»þìõ—½þ_×ÿzüÙõG¿wÏZtý«ùyË_uoû-õ—­ýG}ÿjåçàŸ_ý¯ÇŸ]Ïÿtnþ:¿rzΗñQmT_}®¼åZåw=?Šþr¬Øˆ–/˯>³üÑ~ÀüÀ¯ÅOÊÏ_åç­¿¨ù9Úî÷/-?¿ü4ýà~+ùÈÍéZáëüÊ뵬ò:-ÏjTŸ_ùM÷ø(ßÏ+]ƒŸQ]_ééù²|~ÍYþh?à~à×â×ÚCŸ§ü‘9Ïíõ—±ýG{ÿ²Î‰Á/&?ô?ðû‚ß©½óÛøñ}‰Q~õܑظ?…ÇEÏ¡ññò뺈·­EÑOï]ˆZþlýE®ÿÚøÅÕ~»ÔqøU~½òGæ®ZY Ï‹£¯ñsŠºFQ×~ +Ç¥u‹ÍÑôg¯¿z½ú½ ³þ-ÍÜ¾ŽŸÇ~à~óñ÷öÑoæg-ÇgÏo¨?ªmÖ?{üúÿ¶—~©ø…ÒÿzüÙõKçœøÌù­ü„P§ô[⫚¨¾V½Òó¨?5zŽ¥|˹š¿T®“tÎ*ýÙëÏû½ Zü˜T»ã¯Ïm?ð¿õüzùù­ü¬å¯ÎÍ)ÿÓãߊúmÿÙÛÏ(¿ÖšøÅç‡þ~»ùÈÍé=ß·ñ“òóýžøZqhº=ëR»ø´Ê\­ÿ†úÙ»“ü[Zx=¬Œ¿µgW¬¬…Uô3!àƒ_/~ð‹Ï¯•/ÜÎÏb_æç­˜£ÖßÈ5nk?V~­¾~ñùEÔ~÷ñ;‘›ßÊO wJ¿5>Kß’Îóîïóë®nŸ–ëŒòÑôg¯¿2_®ßÛ°Ú¿ê’rƒUñ÷Þøw4Ô{WÀ/¿^üà—‡ŸÔoçg<ïÇîüüÔø·¢þVûgl?~ÞÜübñ‹¦üîâwjß¼÷^”™Ÿçîü\û~ ƒÁ`0 ƒÁ`0ì ñõrŒ¯)pÓÖ~ýt×Àø/¿þ]ölŠyÖ×<ú¥ã_èoé*þôy|šOY‡‘>KAã×ÎåëIŒisýˆk™õ?¿Ö~³èߊø³ë¿%~©#fÒï­ÿÞøáÝ?Ï4þµlFÿëñWý½¾U?øåÖÿzü™ôŸÞ7§{Ê·ñ³Îc,úéõéüB*»þO_óäçÜßR~±ÞwÏè÷ðÙ¥ŸšäßjoüÚ|~¨Í+¹¾–þžÍúŸŒ¿õ¾‘Aÿëü ÿžøWôÃŒü¤ñc$?Ï:þ͌߳þÙã—ôkóÈúÁ/·þ×ãϨ?Bn.åç—ðûÛÏ +ýu­¢µþ/][Ò³º}¶ÍêâYÞ¿,mŒ–oaYË£ëKÕŸ×EëZåw™ƒ’9²I'µYÿÕñ—ç&³Æ¿2G¿ïùÕó£è¿1~+úaF~+òó¬ãßìø}üß _EÔ~¹õ¿Fý§ór>®_ÆOŒs•~ú:?¯Óß4Yýµò[çXü=ú9Ÿ/õÓs$î'µz%÷¯íBºÿ΂Ú><õµÂgüeÞß‹En~gùEÕ~n~Cý0+?müðæçYÇ¿Ùñ{Ö?{üÖÜ<ª~ðË­ÿõø³éš›ßÀO‹u…þú7ÿ~9þºT†¥þ5kùRŒüب~j^¯~±T¾»T>_òòé½—;ñý’;ã¯ûª³¹øåQ?øùã÷öÁÌü´ñÛŸsÿ¨ãßêñ;Ûø¿:þj½¹aTýà—[ÿëñgÓ*'·æ‡™ùµÞGõÓýéuíZÖ±Á⯕ßó/¯Ð¯ñÙ¡¿Uv-¿Æ%±­Fçôx/×dßj+üOÆß{?‰®ÿu~П?þ™>AÿHýóòGöÏ%ýüú§Ç¿Õãw¶ñuüղοÀ/·þ×ãϤÿdNÞ˳ó“â\¥ŸÎU,ñI=úZuTçWR,’¦Uú=|VéïùksÌÖÜÓ2¿lÅqbÿ.Zü–÷“Èú_ç÷ºþâíƒQô·Lòãú½ó§Œãߪñ;ëø¿*~mœEÿëü²ë=þ,úOäâüçV~½8Gõ—ûÝa0 ƒÁ`0 ƒ5º&P¿C®³Nð9¾´¯ÐZ/!çü¥~1ãÏ®ÿæøGû_ýZý÷ÆëÈþy–ñ¯U¿3ú_‹ß2ߊ¬ÿu~·é=þèúOïÿú¹ŽŸç=Ø«ŸÇ"ãñÕ¿¥{ ZZ©?ÝÓ¯F5ðcÒüf‡~n;ô·®/é–øj:{ñÐúëÛò—bñ׸i|¿ŒŸ·e+¿V¿óñ÷ø¡ÿÅà§ïÙùõÆÑÏžK#Ž­öåÕ?ëŸ9~i|ʤÿu~7è=þlú#äç7ñ“Ü¡_Še$>I«Õ£Õ ÿ»úïÒÏýÿoM ò‹ +í]=³,¹mÀ‰íÖ&)x‰©ìÀÿÿ‡­«WC ‹‡/’ 41U¨{ïLƒ<‡h‚ì¹ÝÿøÛþþ¯ýó¯Ÿß?ŸÏ?ÿç·ý„Ÿaƒïcø>>·ÿÆþ’Qm=þfÍ`ÿ#mHþ —4;ùè—ªv(ýbòçô«ü‹£ßHþeÐOš?’ÿõÛ/¿[‹ê=Èÿ‡20¼ç?J·ü·ñ§&¦Løo×ïmøo矿6—|¾Þ¨ŸtöÄ/Õ4?æs/Ä÷ŒKãÇaâ°qýâÿß¿ôµç‰ßZçYø[b¬ù[û•ÆÏÛãätØÍŸ;ÏHúI>¥_ þ’~†høoÑo$ÿ¢ë'Íãìú<ÃügéOÃï埉¿”ðß®ü»ò/7ÿŒúX›·sÔ›ô£8®ÀÛÔêmÏ ÛÔü%ÜϘPþ3ø9}`Ûµã<ðÚӑkc¤ÿÿ^ýGý©¸öè߃?Ó’~Ô¹©ô‹Á¿òïýù—U¿‘õy¶ùOн‘øó¬_¼õ_ÁŸ›[J¿úÁ¿+ÿJ¿SøO¬ÏߤŸå<ì…ßZïàöñßæÑú¦í·Hõå~M|Œ~ +«¦mû»§j,¼êK û¨¿46§øSçM?*J¿ü+ÿréÇå^fý4®=×γÍÖ¸³àŸõïåsš?W÷–~9ô«ü+ý"áßùÝö7é×{öÀáê*¿zöVé3Šÿ{I#ü™'~jü%.½õ%ežëƒ‘5öïµSü©¸–ôÃÇŸÆ»~”å_ý¸¹0³~ÞësŽsäùÛ~ïúe•þü©<(ýòèGù—~¥ßIü;¯¿E?‰Ÿ7þïÿ3••••uÙ/¿ý²ÍNs-++++{ŸÕŽ´VC9á?ŸÅypñ¡Å‡‰ÃÏÝ+Ñâ/õc}Ä?-7!~éUúÅáŸÿ-üµÜ‹ŽkÕŒ{NKÏwÛ3Í”ÍÖÎõËvþš~ZMué—é—ÿÈøïZ›ãsUfý(n;ô{>o=øYõØ ¾vÝÂëÏÏg <ñ[ó‹Ãßþ§aËŠú²Å°Ä9׿·6þRlCüø¸(øo×ïmøoâ¯å^tüTmþÀÜzîÛžuþƒmÌà÷®_fù{×/–¸/ýâê·éWúi¶kmŽÏW™õ£xíЯý|“žz÷E­Ï¡FT½$í´ºˆ«oš>žø©xÅ߯¶§>†Çkõ5þœÒWjƒóŸíßꟿvþiþø˜(øo×ïmøoâ¯å^tüاýþËÿô²®Í3θÍÙúû~ñä?[¿Xb¾ô‹«ßiü¥_éwz}þý¸óðnýFî¯G¥Õ/æ‡û‡ß]°˜~K£øág¸/ ~ËTÿðsΟÂOåʪþ9ÿŒü¹\•â?þÛõ{þÛøsy—?ÕÿÈúܪŸÅvΚÞß7*ÿÙúE‹÷Ò/¶~§ñ—~¥ßÉõùô£xÒãëåÚ¾o¯éǾO郑ðyá×î ä¿gü5ªÍ¿ñàü©öqÿ³þYùsùÚ»?UúåŸÿmü¥¹2þfèæ>#ëóìóß*üoá¯Åztü·ëw+þÛùgÀÿÙôÊ®Çé~ý3‰—»~WoüNüRÿ”>=þÖXhïÁX³Ö—˜ãŒFþT|CíÜ67f3ýkø¹õöoÇôß~jRÊÖ¤Zܬð_©ÿjþÜú¿J¿˜ü+ÿÞ¡Ÿ4·FÕod}þ¶ùoÿ +¨¡gÿVþ–Z¯ô‹«_þÒ¯ô;ÿ³ñI?ŒÓãÖÖÝ|½ãÏŸT,Rc@½×ƒŠ}ïü²ößþöƯ­ð1£üÛõ"éüh9ßxû÷ò‰Æ_ZPù é§÷]ù—¿¶>¬ßÈ}áÞ6ÿàçÆÖÃ_›Uü{ê½Ò/ž~½øK¿Òo7þÏæWý8lÚÚ¼gáº3þ,ñÙúƒfÕ,Òþ•?ðwʼñ?µ£´FÀŸ­ª/9Î=ã?âÿüÝÃ)ÿ¦Ÿ5‡£á/ý*ÿÞ¢•s‘õë½v>ƒ?êü7êo©-þ½¶‚¿µÞ+ýbê7ê_ú•~»ð6¿¢ðǸ(ý8üžð—••••••••••••••6¼¿ñ¼g½&@½oÙWÁ{¸éy²šy<ŸPëc¿4® ¿æÓ®{IúqÇâýø^ó×øÃ¶gü³óýªûlñ—~¹ñßÎ_ËÁ¨ø1NËõs©ÍL󟆴þ˜õoúíäO„lé—H? +éWúíÄO}Ï +ÌGÛ_ôãpDüÒg;ó¶ë ªïö·–_š~=ý?ÆÝk—ó‡XñïZÜHù…ù{áGùdâ +c€òoŸsu%´ç; ~ÍfýOó‡ÏBÅoùÒ/¦~'ñ—~®øMsÍiýF¾Û®i’uþ›©?fýOòg¦ŠÒ/‰~•¥ßIüÂ3>޾Në§aåu2ÿÚZ_Úÿ—úhfYŸC¾~G?5–ü÷Šü²hû·hÙúkµ!ìüO´ÚVk£ÕÈ£ëƒoþT,HüŸÜ?Œk-ÖK¿xúyá/ýŽêGæ]4ýz×çoÿfëõËþT=Túåѯò¯ô;©_Ôµyý0  Íð+JþÁϹ˜Ôò«w,4~ ¿Öþ»—?׿?ÆÁíŸpm=?¥ë7íþHÒ9¥Óâ£Goÿ•ü[^HüÛ=<ñsçˆÒ/‡~^øK¿íú±sk$ýF¿Ûþ¶ùOÃ?Ú¿ÕŸÐe .FK¿úUþ•~'õ º6ÿÐï§÷¾õ!ÿÚïøþrøs-ϸûÓj/­Š#~òÇyÔƒßÂß:~šÆTÿwªX_R÷7¶ž)ÿ^ñ_É~wv'~.ÇK¿úyá/ýöë'å^ýfþ÷œÒ'Ëü׋߫Îÿÿžúç¤~Zþܪ_å_éwÔkç§õ[ÁétüÁëZ|öæ×È8pÏ/àøqø9œÞþ©v5iìÚø5^”¶Í`Ý ß×ôŘ$ý,xWøgçÿøqñé—ÿíü¥ù%þÞµ¹´>Ï6ÿYñ[q¯¬_Vð§b3¢~Rþܬ_å_éwZ¿ˆkóçuR¿\¢ä¬U,ù%åÆ7¢/Ç…ÂÄáÇx­f_¿¿æÏÕÈRíl©/%'®ß½?÷™ð—~¹ñßÎ?zþ®Ïq;Ùç? ?u,×ÿÊúÅ›?UóDÓªÍJ¿Ê¿Ò/†~Q׿§ôóä%þš}ÿŸ¾¬¬¬¬¬¬¬¬¬¬¬¬¬¬ì Áµ~»‡œ´Oðø5>?·÷c1ŒÖ?;?Žë¨øK¿ÜøoçoÍ¿–ƒðÏ|·ý ó_~jü8ü+ë—Yþ–Z'Š~Î[õå_ùWúyâxíü¤~£˜³ÄÎ%ê=œ_=ßåGØ/Æ ñ£ð?5Y{þ ®¯zð·ö›?uß#ˆAÂ/µO;¥/‡ÓRZ•ü)n#þœnœ¾ø[ôãÎað—~•7èGå`üŸÞõùÛæ¿ü’þÔ>K¯ÿ.þÜ|I?®+ý*ÿJ¿óúE\›ŸÔos†øãÚáÞë‰OÜWïøQøZÿVüµüúþoÕ0~¬…ƒ?ìûàþÆíô\¿¡Úò¬GÚü¹¸ŒÊ_Ò‹éHøK¿Ê¿7ëGå`üCëó·ÍÞõÇŽúe”?UãDÓÏZ‹Ý¨ß ÿÊ¿ÒoÔûÁÔovªøã>çú´Ö7\{–”°qýKøÛØcØ¿=»¶ÿŸ¾ßÂùYð[ë< KŒ5k¿’þÞþ'§Cþš~TLGÂ_úUþ½]?*OâÇxz׿o›ÿ¬ø-ñ·±~éâÏÕ7‘ô“ê°Ûõóà_ùWúâú,µçuH¿áWÖüƒmjuGïýuq›ÜýA9Ý¡oÛÒƄ¿Óÿè„¿—?Æk>NG® ñïñŸÕßêOÅõªø›ÅoÑ‹éøK¿Ê¿ô£æ–Sø),½÷mËü׋_‹¿ÝõËŒæõ“j°›õóâ_ùWúà—æ…Ïá× ýfðfÏ?k½ŠÛïÅÛŽïÕ¿íWHõ%…ïsxáï5ˆŸÂªiÛþîéŸÒÒ«¾×°úKc…¿E?*ž£à/ý*ÿnÑçá üÜ×óçošÿzð[ûß]¿ŒhU?­öºQ?/þ•¹ùŸÒ/ËÚ|‡~+ñF?î®þ¡øõ`¶®Ïñ¸jü(üÔ±^ø=ô¡Æ_Ò¢·>öÄý-õ±Å¿×¢ð×ôñ éWùwƒ~8Oàß±>Ï8ÿiø{Ö£þ«øc­#ë'Õ]·êçÁ¿ò¯ô»a}¾R?O¬Ùâï[¿”••••••••••••••¶ö}A°_Á®åáž÷þãŸGËù´} iïKíÉÆOíwàýx¬åùÂÚ5,ißúkÏÓãök´=m¿gÔ¿ÿiþ³Ï‡þ¶CÆré—C¿“øK??ý,{ê+õ“æ7Ë}áÞ6ÿyãÈÿ§WTý˜°¼]¿­ü³ã¿ÿ +ü‘¯oàï†ó ñ‡Ÿå†ë‹^Óü1Ÿï=õØñåx5kÏ>8…ÿ +_Œ_‹©>nþ&?w¯A‹¿Ô?æ4â‘?ÅKÒò—Îk¥_|ý*ÿÞ£ÎÅ]úYêËÚ¶Ÿ}þ£lÿéúEÒ;²~T^ܬßÿÊ¿ÒÏK?íÿ>^+õs‚øºü{ÚhÇìä×òƒä¥­Óøáõ•æÿ¼GÝËús¯¨N‰O»V$í®ð§Æ?ª/Š §ŽçÒ/—~§ñ—~~úi5Æ*ý,ÅU‡QcÁõmþ[ÿtý"hV? +ìÍúáø­ü+ývêgy–Ççðk¥~³ØNë·2ÿÚÿ¬·˜î©çp_ÜõŽßó“Z£·ãÛþŠT“µcNá‡ßQÀþ?UsRñ·ÔçR})µÁùÏöoõçò# +­ N?Ï¥_.ý¢à/ýæõ“êŒUø­uQƒý©ý·ÍT›³õÇéú…Ò5²~Þ›õkk„Qþ•¥ß¬~Ñ׿ÏkkßÒyö¦ü¹?ÕæÂÕ8-¿¤±9WìÄõÁýcüìcêÇ +õ9…Ÿ‹µýsþÑùcݬø©X.ýòèé7¯ŸTk¬ÂÿéxÁïµkóGöùoþÓü¹ØŠªÆ{»~cå_é·ÿ[Öæþ½ýJ××oÌ?Œo$??í¾:ð;÷œv+ ßIüT}Gá§t†ZSø%?øyãÁùSíãþgý­úíæ¯õ£é‡c¹ôË¥ßiü¥Ÿ¯~ÚÜî¿§yj0N¿7Ϋñïä¯ÕÑô£ðÞ¬_ÄøÍŽÿvþVü–ï´GXŸ{ñéWºv{Z¿ñ籆9pÜ,úáú[$ü”>~Ék)ñ¦ðk±ÐÞƒ±f©ïq[³þ–øÜÍߪ§ŽãÒ/—~§ñ—~¾úYk/ü^ëó·Ï+ðïâOi?‡ŸÂ{³~Qã7;þÛù[ð[׿§×ç³ügúå>‹ ß®ø{¾ï^VVVVVVVVVVVVVVvÖz÷¬Ï§ÅÃçÓR×(ž÷“öK,÷d´à‡íI{”iø%߆ÿ9n¤ïÖÿ,~ Þ¢ÆÃ?ë‘ÿšþúo³âçb¸ôË¡_ü¥Ÿ~T>®Â?r½ gþÈ>ÿÍâ‡õĉú%£~R]u›~§ã·òï^ý²\7^³úiíCý,x"èw:þ¬ü /+GìMÓŠßQüø;‰ü‰·â·ôß4ÕŽ§ÆÏ?§õž„Ö?:ÿç\Óž‘‰óKÂO‹J¿<úEÁ_úùèÇÕÞø-u5·qzQúYåü=ôãÆy~ +ç¨?w=úF×Oª§.ÔïxüöêÇñ/ýré׳6?½>ŸÑOk›ˆi3žÛóÏÊÂŽs‰ÂmÝ?à4òÔGWJ§žýªížú’;?yà§t’ü5ü³þQù?ÖÖßïw˜ðsç¤Ò/‡~Qð—~~úQó‰7~K­ÁÕ~¬_öùÏ?3ê“vQô뉷Kô ¿•wé×»6?¹>ŸÑOkë§a‰¢_”ü³ò³äu\?NßY}à÷#9M¸Ú±÷û \}‹ïï'ÅŽø5ÝVûGæß®á}ï%iÒO:?•~ñõ‹„¿ôóÑÏR‡Ìâ׫ƒ6dŸÿ<ê+oKý’Q?òµúE‰ßÊ¿»ô{ËÚ\ÓÏÒnó·bˆ _¤üÓLº?0¥›ÕŸËŸ^»ï/ ù´k8#úpýsõ¥Õß?ÔnD¿YÿèüáÿÄöèç¿¥ß9ý¢à/ý|ôë­EFðë\x¿‡þÿÈø=ë—Ñø9Åßkþy‹~#ýŸæ_ù—W¿‘uùÉõù K»#ýŸŽßhùgåÇå·Ö>ëÁÇÕ;;õÚôúS{0Ø¿Ï*ü”n”†ÞþÑùã}¶^ü^ñ[úÑï4þÒÏÿL.Zñk5HËü‘}þůÕñÞõËHìœÖÂ{«~í³(ü{íöüˤß̺üÔú|F¿UýWþÍå×ˆà›©SúXúþîis%~J¯žþGü#ó§ŽÁï·¥ß9ýNá/ýüõÍÅüµ‰÷øïÐo'~.¾{ý­æqß=~æ[õ›©?OéíöüË¢ß›×æX¿“ýß’Ï÷áËÊÊÊÊÊÊÊÊÊÊÊÊÊÊÎ|†]{¾ õš õþã¯íá=´Oýÿ¿÷ïçÀ÷š¿Æ¶=㟿?Ž×(øK¿Üøoçß‹Ÿ›7<ñ÷^?ÀýKσ×,úü‡Ÿg<[ì¨_´ë=õ“bì6ýzã7‚~•ùôó¸v¾óúùˆ~}FÕ/zþÁúˆû|†öÇíPý÷ê?<–ú]2Œ_Š…Ôûœ«+¡Ágjý¯ðŸáïÕË¿=»i5~.fK¿úqøK¿\úá\¡ßHÍ"ñçî5‹5É0ÿIæ…ß“?¥WÏøŸÐOªnÓo$~OëWù—S¿Lëó^ýfúÊ¢_äü³\¿Æú{åÖY‹ëïõö0øñ± =õq‹]Üÿóõ,"ª­ççSƒ¶vFêãYÿþOŠ?Œ…Õü­ø©sWé—G? +é—K?­~ðÐo¦~áú”žóó¨óÆ2[¬®_(­¬üOéçU¿A¿™ø­ü+ý¬ø½Öæ;Öç½úö“I¿Èù‡ñÁ¶GøõøãÏñú| ¶Càç´áúåâ“Óâƒß±Äþíú–íž-¾{ÆËÖ[#ŒòoÇìÀOÇJ¿<úUþå×ouþÖ1TÿÔ˜KŸEŸÿ¨÷gûŸñ—øSZYùÔOŒ¯›ô›‰ßƒú¹à/ýöê—emŽÏa’~3ígÓ/jþi÷—ƒmZxöúãÏ¡ÿhŒGÁ/éÀ}ý¡¦’¾°¾ÄýÃÚ9êýgùCŽ'ø÷â§Îi¥_ý°oå_.ýpîyë×[ÏHó‡4þø=Éÿ~jþóî¥?¥S/ÿÝúI˜oÓÏ#~+ÿJ? ¦kçÖñi;«~‘ó·!µßËOK®}õ9^£ŸÀ¯õ#õÿøj÷E€ÿóß§êK?…‘ã߃Ö?; ~îÜé—ÿJþ-V3ëGå'þ‘º†ê_›OÎåß?š?î_;Žú|¿7.N,üOéGÅÖ­úÍÄï)ý*ÿréç¹6_½>·è7Ònfý¢ç<ÞÊOâhá§ùÃãfãý~êxKl`þ\)ÕžX?¿ž×ïÞÆßŠŸ:×EÀ_úåÆ¿Š?7ßGã¯é$ñðÀ?Sãàù¯½OõÕÞƒ{%æoi¼4ëÅ?ë¯ñçbÅ'ôãâêVýFü+ÿJ? þŒksI¿Þ6³ë—!ÿ¾ÿ/WVVVVVVVVVVVVVVvÐàÚzÞÞx|ž5¾v]3اµ ï}ªÇ¨ï-öâic„?ö§ö˜~ïc³ÜSY³Ç>»oÖŸ{> þ>ð4Oý,{¥_\ýnÊ?.V3ê‡yxãï¹Ñæ$+~ ŸuþŽ0ÿÍà§´_Q¿rMÇß*ý,sÉmúIø£é×Ûéw†ÿŠõȪëçÚø4™^¿Lù‡¹Pïa~=ßEÄm5øx,üÙ~_•Ôÿ©[ñS÷ âðSã×ÃûSºpzQúY•ü)l#þ\Üqñ¿·~–ójéW¿ÝøëGÆj6ý0oü£ës+~ù?»~×üç…ŸÚ'ëõ7èMÆûlü­ÐOÊË[õãøGÔ¯ò/¾~™ÖæÒø÷¶õý²æÅe6¿¨¾ >ðÎu^´ÜèÅ÷N4ü³ü±¿Å¨¶½êc.>fü¹¸„Gáï­w~-ýrè·ÿIý¸¹;“~³ø-u´_,á÷˜¿µúdåüç]¬¬_¨X™?oý¤ùãvý<êÏÊ¿Ò/ÓÚ\ÿîvÞ¢_æü£j5ªOk}ʵ‡¿ÁùQØV¯Ña<®Àïåo*ÆzëKIoŒ“Ó!ÿUúQçÇÒ/~»ðŸÖÏ2G×o~Kýƒç¡ÑøË0¯Ä¿’?ÖÌ“ÿÿî™/í‹ +í]»Ž$» À‰ƒ»À&otƒMxaþÿ[CÆàrHŠzP"%6@ÌLw±tŽ)JªšêŸ~üúùçǯýõ÷ÿÿüÉü]íãƒ|ïË‹;_ñÿñññë?ß¿žýáïTû³øWøkÏç•tü·óÿÇ÷oföað¢ú_ë{£~‘ñÃsr¼ªýPòƒç†çñ¯¿—>Ù•#VøOøÏàŸÕ_ëOŵ‡ø[Ñ~~­±6õó­Ÿ7üVúqu=Š~»ð·æB¸Ä_¤úmßš¿6VNðoaKýüóŽÿvþÑÖæ¿ÖçVýnÀ_?ãÖý¾^¼£ó³º_QüwæŠþ]þ”–«æÇ­<õ§â~æ…¿¥~ÜØ™úÅÐo~úµÆJïúíÀ?»>ׯßhýþïçúþY-ÍÜ`7ÿL¯êç•æŸþ‘ÖæëØWô»%ÿà1ÜÒ§ó*~§Öè‘Öç+ûûköª4þ½æ…¿¥~R ¦~þõÛ߃~­±Ò»~½ØGÚoÍ‘¨4#õ»ÌONÔïUøwÎ_FâÅ’ÿŽø½I?ü3ÿ|ó¶6/¦9öý¢ç_¹>--------------í¬•õ<Üg(ïqky¸'Á½_üÿýÏ¿5}ê¾ µ_€÷ð±pÏa÷ÞÖJü\ÿµ®aIû.µÿ«•÷ ð3|L1ˆ¿µ'Ï=êoÁ¿þ^ö¬ŠµÎÇéw +?èË/¯Ô/Ž~/äŸ4Fz×Âm¡ŸTO¸¤­Ñë÷,þü¥Xß͟‘úÅãÿ­ü#]7×¾^Òïüå÷:‡‚ŸZËóÁÏÁÃø8^Ð,ž§‰óü­¸âúúã÷¥xÅþœ^Zü³þ³ü©øÐĤüðØVü¥~¾õ{!ÿp|FÑÞ—ë'Õ®þôÖ?)"Ôïü»øSãð)þ\Î¥~ñøGÇ#ÿÛÖç¯éwþrŽzÌN~ÄWþ' ˜æ\åg=~÷Ã_¯ôåÊõ >Ÿ ûRñEùpmø[òÇ9 áÇšyÀÞcÇÛÔÏ¿~·çŸf>àU?º‰~\ájÏHýûlGÕORÿµÚ„œgê_õ™ìš¿P1¾rþ¢Å/å[ê7ÏßZ?kü©ßœ~7­Í_Ôï¶ü«ÿ³^ÏÙ3Âmq×?8~å'¼ÆÿÁ<_OšÕcv_G/¯þ:/í™_ÂãµósܾfnI7ÒþŒ¿ wMÿÂOô+9î¦~1ô»=ÿ¤¹gýØ&úqõCª=#õÏ[ý¦ê>çìüc×üe¤þ[èGåYêçcþé ê×§ß-kóWõ»=ÿFžOGµ…¹HóÈz¾ÞH¬íÌ- ?¼w÷•¦ÿq,Pý‡cEÒhuû§ý[ü¥øãrÍþjTÜyèÿÔ/óÔ¦/ñé]?j,·Ð«­Ú3Zÿz̲~ãúg'jl1á¬5OýÖòÏü{G¿[Öæ¯ê÷Bþa|#ú¿Ös nø>Å#áãðïȱ^ü=ýßòÇý×:ŽúœÂ¯m…ÿJþÿ‡œÿIüÔq­±8õóƒÿÅü“âÓ«~¯•~\ÍhÕUõ/zýîÁoÉŸŠï]ü[ãêwÿèø£ñ·Z—ï^›¿ªßKøWìŸa7Ê4ü(®ZüÖ¹¦Åß›½þRlI¦™K¸zý-øks¡¾sÍ~I?*æR¿8úÝžÔœÁ³~Ü<ÇB?ª-MÝ‘ðHüo¬ßü–ü¥±×š?—[©ß]ü£ãÄÿ†µùËúÝŽ¿Üïž––––––––––––––vÖz÷ŠO]ûÃÿÝ×Zñ§®‘ý Þ§ö-z1WŒù~;ë=±r,‡¿ðé»Ú³ý/õ/Þ¢ô/ø©}¡Yÿ^ü#çXÅÿ´~TÌ¥~qô›ÅïY?—Þõ“ðè÷¥Nhluý›ù~÷õ[3ÿØ=¡®_YÏ_p›©_ìùgêwV?ËëæÖ×ÎS¿wóO£Oå]±U«Ã÷ñ1U_|^ÈUm(}ª¯eîÁ{©þ£b‡2«úŸ2*×$üTœöúò§ž»°›ÿiý¨¸KýâèwkþIó úQ9d¨Y'4÷¸ãög럄›ã·³~sþ\þÍúkóWwWò‡úQ9•úÅž¦~gô‹¼6OýÞο}Z¸(zö¨skùÁk,p +ۯ簼†Nͯ`ühøãøXÑÿØ‹9Nܯ³þ½üñµ»ü=èGÅ]êG¿UýïI?*&=ëÇå•~3kt‹úGõ~ò·¬ßœaýfýGó—sWñ‡úiâ3õëÓÏšæŸOý¢®ÍS¿Ì?­>ðþHNnîÒ{}Ÿš_µøáyg½÷¶Ïi³:©ù•–7õ·UÿsíQú[øGç?w©ß[ø½ñ—æñKùc¡Ÿåú|¦þµxì¨ß’µâoÖ_›¿\|¯àO<#èK[©ßœ~–ü3ÿ|êqmžúeþõXïóñ Ž¢éˆ?óR¿wûSú·bfÜFê·N¿“üS¿}úy\›\Òg©_æŸw}V¶O飵yIÝ«Xç—=œ,ûŸâÞÓþˆù;2oúIã}êç_¿›òŠE¯úµòÆJ?®>H63õš—úíq}ŽcfEû\þ¤~óúÄŸúíÑ/ÒÚÜsÿŸÒïõüû|^MZZZZ—}ûþm›æš––––vŸeKKKóhe=÷ù?û ÜçÕ~ŸçS¯Ûàãjûðx|,ÞØ‰åuôúoÔ¿öGtþñSq·Z?Ïü_Âïë:'ü\άÖŸ“ª ÚëçžúïÅø—â{*&S¿{øGÇï•¿·ëæŸÜÈWê—ùÇáÇße Ï?b-̇xŽ.?˜´øW­Ñoè¿^nüŠÊߣ~R¿Àÿ%üÞù·âÐ ~*g,ôÃísµA{»—þ{5þ©ø^Å_;†¿ Ÿ¦"òŽßÿHkóÔï<ïøË9ê1;ùAl_ý^y͹ÊÏzünü£y»j}Îõ_yïsÞ ê¿Yý{ýãØ3ñc­×dzúYóOýlóo·~\ :Õ¯™/³úáöG×çNûï¹øÇ1³rüê‰Ç›õÓöCÖŸúíâïmm.½R¿Ì?Mÿ×ÿY¯ç„íi â£øpüÊOxÿƒy>/u|Ì ü«ÖèVýW÷w¤þ›ÕÄŸ¯^‹ký¸~žÕoÿ×õ³Ê¿úQ1èX¿ß^úáö¥ÚÀ™ãþ{.þ¥1vvüjݯè×ꇬ?¾õÛÁ?ÒÚ<õËüéÿzì7ì¹`^ðÈ·_÷Ezcmþ™<ÖÌÁfûÞ;aÕ£þTÍ}-~vèGÅ^þ©_ŸyãöµCÄŸ4—²èªo4µº÷ÊCÿ½ÿ\|ÏŒ_Úqûý¤~Èúã_?kþÑÖå©_æß~ŒoDßâ¯ûSqÃ÷)~ø ß üVësiî¹ÿ´þTŸ¼?;ðS}ù'~ü©Øóª‡u•~¸ýÑÚàµÿ^Œn|ᯯ_ÑOÛ7ðŽÿÿ(kóÔÏ?ÏøWì¿`7Ê4ü(®ð÷æuïX¥ÿzŽÇ}òrüXãÇ}½B¿Hü_Áï‘?7_ñˆŸÊ“•úQíÖý÷jüSq3Ã_3^¿ •7óŽ7Oksª~¤~±ø{Â_îwOKKKKKKKKKKKKKK;k½û õû᪕=ø}qð3|L±â÷(êÂâ}jßbóNü#{p½ûz§û¯ž¯>—aÖ¿µßmwü`ŽÄ¿úZ„V? sêç?ÿvé7w'ô£rd¥~\û3µ¡§ýèñ±Íú¯äÏÅÍ(*_^ÓèÒ«øGÇš¿‡ëæ©_\þÑðkøULŸ„ ý¡Ác4íkŽåü©v)NÔ1-ü#ù>2†œî¿Þç6HþTŸ@^\üYó¯ßÛp[üKý=£?ì‹Ô/NþíÒ¯7îNêÇá\¡×þL}èÕߪþíˆ*NGýWÇO+¾{øSçzM?"®¿_ѯå?«ßéµyy¥~™»ð÷ð“xp¸{ö(VúHmöâßq ýtÿ\»£ü¹yM÷°»â§ì…UŒè¯ˆª¿gôãð§~1òo£~ª˜;­‡suýiµÛS¼Ô¿†þËúot~i?R ëåOÅàkúé`ªßNþ/è×ãß«Ÿ‡µ9ÎñÔ/óÏ¿–ŸFê¸Þëûø¼«ãSsž}¼­ÑWö_™/×ç¬ô§æ#£ý?Ã?£¡Þ»rKü×þ§bpVÿŠ y©ŸÿüÛ¤_3æ<èÇÍÁ¬×çTÛVësËú'迤ÿVû¯Šnþ>Ÿʓ—ôc¦I¦úíâÿ‚~=þ½úy\›§~™Öø[Æ=š×õø·øúSíÃ>ãæ¡œ>ÚöGÇëkèžïØ3ØËšÂ:~F?ÿRŸ·âjê#ÿvéGå¹7ý8Œ»ú´.x©’þ;úïdüHsøüT ¾¤ÇßZ?kþ¯è×ãߣŸ—µ9ÎíÔ/óÏ¿V‰ ·?PÞëÁGõÝj}´í÷âß±>oÍǬúÏÊŸêúY½Þç!~¨Øˆÿ­~·Ð?õóŸ»ô“òÜ‹~Ü<ìÔú\[¼Ô?Iÿý×Â~2~¨ØáOçý¸1â†ñûýFý5úyY›×˜Lýúô;Í?rþõè3bžæ§TÿSq6Št,X} ݪÿ,ü¹ñod}`‰ÿ†øçú\Š«ë»ÔÏÿjýzæ9'ôãð¼~¸¢&쬖ñ«™_Ši¿òúñÍúµúï†ñûfý´þ½vrm.Åeê—ùg¿ÜŸ––––––––––––––vÖðþ@yï)`ã>«ëýÖ +Þ#Àí×ßË5›b=û3žðÏìÙõîRüáž¼¯ïçÀ÷ª‹?<÷Œ?Ñÿ_^”ætŠ??ðû9/ø¡?7óŽ?2æú„üÔ8´J¿žú×[^­ß³þ+ùs±Óÿ·ê×ê»[ùGÇoÍÿÔusÄý,õ‹Íß#~x~8¿ Ú®òÃþšö‹µžUìÿìØ0rŸ;žrëÜ¿Rÿ·lÖUŸ¥|ñq‚?Õ~+V=áGþdìÝÌ?:þ¨ü™aÏ ~iZÙÿ­ú×[8¾õo®/"ÖïY+þÚØ‘ðSçxA?ÌûæøŽksüyêü`¯žÄNá¢Ì‚ŸÄÑ3þcDï½´ûBŠ‹ò³Ì¡ësd~9ëûŸê.ßàþTõ/ß›\LË¿¿ +¿&%ü§õ£ân'ÿÔïlþíÔHõãø¹ëÖVúµêßHMðPÿvÔo¯õ_ªaZüÿ õûòº9~£ã·æj]㮚&§S¿Xü£á‡Ÿãã´üzü¹ö¥c4þð¯+FÆ#?æSŸYP㣧¿VøC|­ëT¾ {´;oY'´ø×cVâçÚêÅJ¿Öu¹]üS¿3ù·K?i^tk ZÑÿšú7R<Ô?îÿlûøSq݃Ÿ‹¿Ëõ#Ç‚[ã7:~Kþ«Öæ£ësÔç©_lþQð×ßñóåðç-ž½þÚö)Žø=øW+Æ(M|žx¾"ìSîùÎp¬Ä¾p~Û¯×Uwãçb·?¼wv·~Úø±äŸúëç¿F¿Öœçþ\½ý¯­_#5á…úí¹þ·êW‹¿¦þݤ_«æßÈ?:~+þÖæ0¹øLýbó÷Ž^ß¡>çÎ¥á'aáÎßã_~÷Ž嘱j¼¢øµøkm…Õ•+ëç8o4ñ5µÄOåfüõ÷‘=žøGÇ?7ï9Ÿ{,ôkÕ¿‘zà¡þIþUÎ_ƒßsý×Ä„¿å›~Ôp{üFÇoÁßÓÚ¼Æ!Ÿ8FS¿xü#à‡s ?‰£_ËŸãBaŠ€õ¸±bÜâxœ¸~Çõ·F—æÞšõ¤ãjüT›ÞñÿG×ç‘ùGÇ‘¿fî³?ƳJ¿ÞúQ}Fj‡úÇq^U¿½ÖÿV<·øKñw›~­ü¿9~£ã_ÍßÓڼơôY꛿güŸÏƒJKKKKKKKKKKKKKK;hp­_Ÿ!'ퟲÆo]á ¶9rŒ9 +~‹ý½U÷¹÷Xý~áj³þ¥oà÷ÃÏà1˜;Ö¸hŠ÷®¨ø(íðžÅ_¯ñç¿ÆÇÍMü£ã¿‰¿æúÄNüË*ý&ë_w-x¥~{¬ÿ„TjþT.ܨÏ^ôÛ¿ÑñÏúŸ¾nñkŽOýîâï?æB½‡ùõÞËÏUý©ç&A ø=j~ ¿Õý7'ÖçÏQN7"®Éñë¤m;Ž*>¨sSùÉÅÙü½úq±Ó£ÌŸÓü_ÓOò÷¦_+ÏwêGáXõ¯»Ü\¿½×B*5.þnÓóô¤Ÿ5ÿèøWñ?}?»&ÿð+õ‹Ï? +~ŠË,?ª-ÈÃùãß«DüÞÖç#ktØïQ..Aßyiôãò£;ÆÏÅ!—·”ÿIü=ç b§W?oü_ÒOãïE?)Çwêg½>çðR¸aý©·×o¯õŸIÍŸ‹¿›ô“jºývÅotü3þ§×æå¥É?üJýîáï¿4§áøµ¸Qãû 8?×þ(þúý¼;ð[¬ÏËëÄú|v~JõoknýéÿÛK‡8¿¤œÒâ‡çîÉ…žõ%þ)v:ôsÁÿEý$OúI9¾S?f¸Öo¶þÔõOêÿÙù‡×ù ?Úö¨<¸M?.×½ègÍ?º~³þ'×äð¥É?*N_׳(ü#èÏÙšwô>ŸsÄ¿þ^ú„òŸÁÏéƒñ×ãfñG_£[=_šŠkʤ±Ò"þ(üpÍÁå!»óg¥~RìhõóÀÿUý$OúIù½[?Œe·~\ý©êßêú½ÂuüöƇŸÊƒ›ô£â×›~·Í?½äŸ‡59Î- +?wìëúõàÏü›Ç¯ïàó÷âßÔý +i~9‚¿¥>f~‹qgöþ ^ýZy0êOé?£î‰ÓäFý}õúN:–Úëiß +ÿŒ~­¸ÑèwšÿËú­È?kþÒœh·~Ç©ý\ÿFj—ú·²~{Ÿ¿H±ÜÂOùÝ¢Õ/õ³Žß¨úÍø{[›ÃØÃø¹ã_Öo&Ÿ¼ñ¤<†›ÿPúô`¶â7Š¿ô½¤þÌj}eç÷#kìßk=ëó•ñGùSù#ÅbïúÀÿ¨~TÜôêçÿ«ú­È¿ü¹ß­_Äõ¹T <Ô¿•õ;ÂüE[¯0vÊïý(n^õ³Œß¨úú{Z“kâO:þEý2ÿöâÿü¶´´´´.ûöýÛ6;Í5----í>Ë:–––æÑêý‚u _ÞãÖòpO‚{¿øÃï£å|ê¾ µ_€÷ð±x?#*~«½ÃÙëèðZº´'Åí÷h÷´¸þ—´Ç}yÕöµß'x?ׯIüZîztþÑñ߯ŸÊïÝø¹qfF¿õc´Tÿ[êw„úµÑò—â?²~/ÏúÝ:ÿÜ™Î^ÔÊá§ü_ÓïÖøõŽ¿^Çøðü¥ÇZþ˜~ÆïgæÎ ¿‹Î#~¬q=ÖòŸUkt*Fa_àX’æ§”?•­¼}ÍŽ¯8>4šîƯißÿ¨ÿÈúÜ#ÿWõ‹ÀŸ›íÆO33úÍÔ©o45@ÒãÏñ™ÁmvþeþÂÅ5iùDÕâå]¿ÿHóÏYýFüwÞ§®yq±Èá—Îñ‚~Þã÷öü+ŸWŽ;ùAl_½îòyŸÍ‹êSúÀþú? ,Þ×è˜/×P3*Ž¥øÄý¯_3´Ùö†câÏ +ÿ¨?7÷ÆÿUý¢ð×΋,ñ·jPoÿ÷Ô?çÐø¯é¿]õžc¦~{ž¿H1$Í_zã>Š~¯úIü£Î?wäŸ×µ9‹þÖ9n×/óï¼~õàkŸôÌçp[ÜõŽ_ù)íP¹ÏYÿçÞ#þÚ·žÏÊXµF×Ä+œŸRŸkóCë¯?¥sœÆÏµ¿ ÿŒ?£¡ø¿¬_þ£ó£•ø¥öGú¿§~Ô} ì?:îsýƵÏaŸ©øœ³óÏó—ªÖFš¿ôÆ|ý8^ô“øG›îÊ?¯kóŠŽñKçxA?ñ›ù7ÿ|:ª¯0jžBñÃí÷äˆGüð3ÜV±Þµ²‡{ݹø-?1üy+ozý©q”ò§ô£rí~MûVøgýqœDãÿº~ø÷Ô ü\Û«ô“ê¼wÚÌØÏµ³þµlôù¸3þ–üÁuU S÷ßĿR?-úE¿Sù7{MiõK¿æ·êç%~3ÿøÏ{Î ý‹_ë¹@°ßáû”>\¾Qø<âÇÇà6£¬Ñëµt‰_~’¿&>(ÿªãiü\û;ðÏúKóÿü_×/nLÛ…ŸkwT¿õcfÜ÷Rÿ¬ê÷¬¿¬ Ç_çÑô›Íßèü_Âïim.ñÇÇBþÔ¹^ÑïõøõŒÅþ æÀq£ŒãGåK$üø8xÌèZùÄúœšãÁXÕÎO{LJ–?­\¨ïyÀOÅß.ü³þ½ësoü_×/il³ÆÏµ7ªßlý˜÷9î;ë§Ã‰ë?»øS5Šj_Šï“øgôÓrò¬ß®øŒßÓڼşò¡ò¯žëý^_oø?ÿß)--------------í õî/ÔVöà÷ÅÁÏð1ÅŠ?uâñ¾f¿«wë$þúÿÿå8¼¯2s-ûä5tÌï-QýOñ×Zñ‡íÕsP|[þ”>§ðø¯Æ?ãOýD4þ/ë‰?7¾Yá×¶ÓÓÿõãKÝûOÖ¿™ë¸~Gš¿púÙcàéóß^Áõ[¿Ññ¯øßK‹—–¿æ\7ë÷züFïáW1A|.xô‡i´¯Ê# ?Õ.ʼn:f~ö^ë5úêõ9^‡QqÐß2*~¨çFPýQý©øåâó~ˆ¾oéwÏüS¿˜üµ5`~ÍܯÿhýàøŽŒý\ÿP8V×?í±’?[#þœn»æ/½Çx˜¿ôèGÅbpý¦ã7’~œÿÌu"ëWÿÞsÝ¢_æ_LýzøI<8Ü=ûéúIëë$}¤6Wã—æÇ–kt‹õ9¼ŽNñŸYpù]~¶®ßâö±?¥ûIüœÿ.ü³þ­½ïü_×/*iNµ +?uþø[FÔNvîØû©ñÿTý[5¿9‡ƒù ¯JÅ6¼éGЮ߲ø ¶ÙkD;^=ü5ç¹I¿Ì¿Øúiùi´¡Žë½¾Oͯ¤üÂ×Zñ¥é§Q}8üðóúÝw‘×è\­F÷Þçëa.”?Ì-iPýaŸqóHNŸÕøw¯Ï­×è'ô§úŒÒ®ÌÉ)»½ø¹õÆ_áo‰…¿·ZýNñOýtü½ëÇͳVèך¿íêÿÖ\R3öãñÿtýë5+ÿó—VnžRÞëÁGõç_ó‹[;rúhÛ·ÂÏ­¢\CÿK"ÙD ú‹ +í]¹²,9n-CN3íŒ)kŒçÈB2ôÿ6 +>]vãâa'¸e"#÷VU‚<à±dÖò?þþ¯üñ÷ýç?ûSþëß??þßåÇG~¬ w~ÿþ?ÈúQüÿû73<Çkïlü£úø1æsqšýÅŸÏŽÓì‡Ü|ˆ#ƒ?jÌlþ¸1ñÿ–ñâ$7<Š?ê?xý¨µÍЧx̶_ó'éõ¦/a<…?n/>¿¨ïÞÄŸ”ϱ|;,ökºOáÏ»FõkÿÍÅïá'"YþEIÛ_\ ¡ô©õ§ül&þV;R=‚%.ŽÄÌÑñ©õ¥ÖK³¿=ö¬é¬þ<ŠŸã¾nõ_IfáÕ§ø“|ä4û‹¿œýw +ZÍ5«?Ïà/‹¥~åbåŽüÕ·ÔW§Ö/^¹õ;¡~ñúéøËÒ?™¿&Yµæêûÿ¬º·ñgÙ?µÿÎæïóÿþZRRRRRRRRRRRRRR²Qðõöœõžõ<5¦vOÏßÿo÷\šx®Ï4ýÿþû)Ôµ¾þ”¦×ÿ__Z׎¿=žy=ûþy¿ÓýG[?‹ý’N¿ï×Sx¸sñõ,øÜ.üÔþ[–ýœœfñw·ý~*æEñK÷X¢ø£ùC³ë+¯«Þ“+óŸ$#õÇ-õ‹—?¸O¨_4þ$ûžÀŸf?ÅÍMüµ1o¼oÞÉ~ƒú#ø{rü|Ãþ£Æ‡õ5wåë[æ‡ï䄚¿?/õ§à‡‚õoêÑ9û=¢écNúÚrwSýâåÂzRý‚ôÙ=÷þ4}Ê®‹ø»ö}íýàìçÎEÿ_ÏßÓãçÓ÷õZïõ¥ëÿÒ]fØ'ÙÈá‡sQ=5÷üÔú­êÏÛ‘ÙŸ·5XÙÀÚ¸ a»:VûÛjðÞ#ìÄßõûgj­øÛ¹#øGõ=þk±ŸÚËÅßþ"öŸÄó"üQu]ÞüAÙ×ÜRÃR×VOÊßÖúãÆúÅË·÷ð܇ðGîµ'ñgÁOÍu:™u匃Ú;Üy”ýÔyOâï-ñó©ûϲþðuÎ&>7¿¶®š><—»×K­÷jüuýä–{èÝ¿<þb±ŸÚOŸ^cs˜0ÏxÌþ »ñSúý»¯$üýœ(þQ}É~éºÅþâo/£öŸÀ÷¼üqú£ëÉ’=ÖþÇþSówt~«>–öSÜIüI8ðãø#m{üÚ§ðwzo.Å>|P6rç=…¿7ÅÏ'î?mýûÿøûåðëO^}ëü”ø9J¿ ן¯ÆÏqL͉;{tjý,¢Ù/­!®¯©þÜ[NÀO}?õlü³í—öžfñ·Ÿ¿ûOáOªÏ,üi5`4ÿq¶t}KKíÉÓòwÖüœ¾Æß û1XŸãûú.ü”=‘?ÿÂsOåï–Þœ‹ãøÀösç<…¿·Åϧí?IÞßÐìóò#aáÆ÷è·ÿ9üxé:o6~iíúúu»àœ7ôçx]-öZíÇë~i°`N¬þ» +¿¶?Wà϶Ÿº~²ýÅßÝösø¥ºOÃÏÕwYø½ù«cGúóù?7ZÜX¿H½ן[pìæ/‚ûFþ,þ«Ís™5ä¬âè´¿Òë7ó÷Öøù6þ`­eáGâÈ‚OÓçl¡0qøñ|M¸¸ÏY‰_Ó—zœÌ=»?箌ØEê,ý¹ÄcÆýËü–þf6þlû)NN¶¿ø»Û~'û¬ø9½þ¬üAÕÑþ¼çÁSò7u.7ÿmõ æã×|T’]üQþõTþ,þëál5Ù÷wf¿GOŠù·ó÷öøù&þ¾>ïTRRRRRRRRRRRRRR²Q`¯ß¿CNºNÐtZ¯ÝáÎcÖðÿ¼žñû_Òôµ{è³ñGŸ/ë¾öÎûè¿OH]£jÏ5‘xµ|§´&³ñK¾3ÿ*û%^vÚ_üÝm?ÿ$üÜ=î_îñdä?éþQäþùŠü'ùÇHýqKýÂñÅ~:ª_vã×ö´é‰üÖŸ£ñ/gÔ‹³fÝMoûk•?Ÿ…ÿéöãyð˜”}Þ÷òÁ±º>õ½A~ÎÏÙOáokÚÿ®õýØ3ð[ÖŸ;çÆþ®oçÛjÉXŸZ#Sè?Ñø0Ÿ†ß2ÿ(~ÊO£úVþ4^VÚ_üÍÛ·ðg©ñм¿ÔNÜߎÌüg­]µx¿*ÿIþE=ÇñOÕI^}·öS¾uñëTý²¿æOço´þÌŠÿ””Î-½¹´&Ö1¸s©õ«üYõÏ-üqsŽÄGξö_»Ô0a}¬'­Y_Ÿíúóu­GŸ‰Ÿã•ÛpýoîÑ¡ýRàÖC»þ¤q:+¾yøóìI©>Åoþ,½Àjû‹¿üýwZ‡â¾¹–dp;2óŸµvµÄúÓò·Ä¿ö]|§Ö/ÈG¿\ýrBýÅí'ó7ZfÆ?Íþ[zs‰?jOHãHcWþ”ç¨úçLþ$N$~½ãá÷'qz\ìãæ—ð÷k˜M°>W£¬Àoå ë'öÊä±¢?·ì ê<‹ÿá9q~ÎŒþ¼ûrþl}¿H>ÓþâoÞþ»?©Þãú/~¬Ÿÿ¬õ«çOÌßÿ»­~‘ü ¿&Õ/í¹ø9Ÿ{ ü˜¿ÌþJ’›{s¸ŽTüåÆÑƯüùëØž½t +þ7ñc’¦çý~]zæœ)üÔ¹~k­’‰Ÿò‰‹ìþ|W.Ù§ÉHÞ$3?Žð—1ÿˆ¾%>[ô­âífÛ_üÍÝ7ó—YcrcÎδ½;{ú»ë GØWNÀÏa|õ§W8ýzóHþˆÎ¥­_åϪnàïëûJJJJJJJJJJJJJJJJ6J¿ì×µë Üë]þž§Ó¯{âóúüð||.¾‘…ßrq¿å÷õ´k8«îŸ·#ûÞ¹t®óg±_÷ƒëoá“;ã÷³ðS¿§ª ô?iŸr¯èküYÞK‘añ7‡¿UöŸÄŸv?ȺþXweþ‹Æv¼f'æï›ëë½À“ðsøÞÈ߈ÿf诪GYñ—;Þž?ߊÿ‰öãß‚¤^÷ˆ¦ñàï7Áñ‰‹‹]úoWdá÷ôè~wÊ?²{ä=úÈþè:œOaþ5,œ>æJãm~¸?-{ŠÒ—æ§ìôê{í—úó,û‹¿yü­°ÿ4þ¬õ§´þœÎªü‰ëWÑüGÉhþ¾¹~ñöÙø=üqØÞÌ_FýÑ¿±7ïëÊqBÙ˜’åû-ùóMøŸn“ƒzŒX{|ÃøúuËX3ð[ûó¾ö~ê·P0ÔãÙ½x4FgÌc]ÿ¬ýa½^Ðëìsx.Œ…âoÆþ–ö8‡Ÿ›?[ßË_¤?Ø_üÍáo•ý§ñ§ÅGmý©ºuuþ‹Ätn­¢ùo?'·×/šoÍÄoåÂUüÙÕ¿±7ÆßÀ´¿ðüÆüùüO·¿Ç‡>Äg37wý?†ööIé÷ë›Ôøœlü–Ú¥éÁ÷(iøw÷â#q::¾wàõ²ìÏ>UkÀ×½X9ÿs¬Ä/íªÖ˜5R0Ëþâoïþ{Z-Êéc]ùÏÏ%þ Í«ðÏÐß]¿hyw6~‰?/ž7ò·Âþ[úòìø»{þÛóçÓñ?Ý~ Ÿ'.Aý¦§}.~æ>OÅGÊß,ü»{qX+Q¸OîÑ9þ<þ§éSþãá ëkóP¯Sóâ—ô»ŸrúÜ£úþ,×q²ì/þòù[iÿÉüQqQ[|þ®üçåpÞ[ò÷¨>´o•ýRÎÝ…Ÿóóâ/nDÿ–Þ\²?½*¾ ÿ[ì§ðE¤ÇG)FJ±ÏñcYuONñ{[NÕy#ûCÓÇçyÖö™…Ÿƒµ†%>Q1nDßÊŸæã™öùü­´ÿtþpLÔÖŸ:_Ãß×FZ‰? G´??=êkvΰ_Ê·;ðS8Š¿qû=ú™uägòAá¿ •?߇ÿÉö·÷»—””””””””””””””ìî:'Öß§ÅáïÓR×~ÏS×=#˜1~8umD +¿õ>DÇßô#s÷ù%ü+¯³ŽÌ3Ë~N¬˜ðµõŸ\ÿþ—ÌæÏ£O팟òÿ¨þ³ì/þòøÛaÿÉüáx(­?>wcþsÅoÊþÝùÖO©_´û‚3댟ÂPüåÙ¯sÓ}sèÙñ׋¡òç»ñ¿Á~K|ézp 6¬ÅŠÚ7á{ + øÿ¯á7ÆK×{¹¨õÓðßÒ£7™a?Ç_¤m9½ÿÆ)Îϳø³ø·¿¨ç(ÿïøGõ=ök~0Ãþâ/¿öŸÌŸ¥Nzßç‚üçŠÝžü·*Sský"åÖÕõ‹6ñ—ߟßÚ—S>’½óWþ|7þ·Ø¯ Ÿ³EšÃûþ j}Fã#|·&ÜÚyð{úNh¿ÿŽø¾¢G·®ÇŸu\¨Óïá}ý,ùý®ÙüyýOÛw³õ­ãY×=Óþâ/¿öŸÌW«jý—…ƒIùϯ­ü-Ä/ú÷­õ‹”WWÖ/ÔüÅ_®ýXÿ†Þ\óSÎñc«ÿz±UþŒáß?³Öÿ-üi"}?že\ï÷sâX¶úûAáÜýŽW´ßŒØ¿;ίîÕ-Òø‹p?òÃß²ü×âpïEöߨ¾Ç~Ÿöyüí°ÿtþ,õªöú,üKÌÈ;ó÷Mõ‹ÔÌô_ Cñ7Ïþìúæ3éðú(µ~=N[ÖÏ‹¯òg¿5zø[‰ÿmüiÒÇçÆésP¯Sõ•Õ¶þÿ®üÐ{‡ü‘˜;‚ÿ„X¿»'‘Æîñú{ýi–ÿQûŽÚƒÙú^{¼ýù¨ýÅßÝöߟT7R¯ïÊÞØlµ~­þ¸¹~árè +ÿåæ/þæØconõQ,°ÌîÏ%Þ+þ6ÜŸGø[‰ÿmüYñÁñvß·®!Å?÷<ÜS’N¿n'ù/w.¾žŸëúšÿ±Gô#öK÷Ïá=ôöwÛ þo—½÷ƒçŸ™ÿ¼ñ7;ÿáߣ­?žT¿pyr~‡š¿‰ô¾WM~Ì'þŸ“ݽèêþ¼»m´ˆÄÊ¥zû6ޟܾÆûCÚ?šŒê{í—Ö×Dšýý··Vâ;Pðûß¼ö??²Žäž‡sÍΑ؛ÿ$ÑðãùŸV¿p9r~Ê?‹¿œýwC]f¿”.?½ñ׋ç‘ü1ªŸabþ¹ñÇãǺZÿn±/;>v¤õêuýIøñ¹ MÿMý9<žÐ£{ö7Ü›ÐÚsÔoIQcµ¿-ôq"ñiTF÷òlû‹¿¸ý=7bû_ÌYKRÏaL³ó_$Þfç?œ‹Gë'Õ/\^œŸóÙâo|ÿ^‹ñK[_r ÌŸ'D0C.á5ÞhWù3?÷[¨þâÇãŒ/«}V}ü:e“4§¿?—Û4®ºþûsxÜÖ£sþËÕ3пà{\°~¿?)ÕDý;'zLðø{†¾×~knµ¿Ÿ³ +ÿÛùÃöKׯßÈŽe_ãþòÜêü‰³Ùùz~4ÿŽèŸT¿Pü¬ÀOùfñ7¾ÿN¯¿"ùƒg$þzqgçÝùGÊŸ½ò䟷åÿ7ñ‡¿_cÑìöêã×9}*FRku~Ì¿öÔψñ§çëqr.ñ'ù/ô™þ<õýšžX³ãûi#ö[úó~s¶ýÅߘýÐÆöŸÆŽ]íyê9ˆb™‘ÿ¢q5;ÿeçßÝú™üQü¬ÀÏùfñß§×]ÖõÃÂùh4þfá¶â¿-Â÷>߈ÿíõO&Z~õÆG)–qã{ôÛÿðúÄIø=œàù»]pÎêÑÿ:NìÑ5þ°À} Ÿ§â›äÿVÿ㍾Å~i}q¾Úþâïnûwã·Ä°Õù/K¥ù%üÚyÔë£ùû¤üáOò“Yø¹9‹¿øþ;¹Î¿œ¿D⯄³‡×÷mùs‡ý·ã’ýX,ñQ²Ûß4}«-ý9¸V'àçÖÖâ/Ð~ÊGªO?»O×øÓö¾eKþ´ãúcÄ~k¾ÃþâïnûOÀ¯Å®•ùo$Žfç?M¼ù{T_ò?ižüI~2 ?ž¯øÛ'×Tñ9%¬}¼ÊŸëí¿ÿ“ìÿú¼\IIIIIIIIIIIIIIÉFÁ×ðµâúÙÏ_».À œ32ÆÅO½oÑ;dŒ û©k¼?ˆç©õiú}-žr?}÷}ôÕü°¨¹½úÖûçpÌÕöÿää÷¿ä)ñ/ƒ¿ìßÉŸ³Vò??gæ¿ò_Ý_fÖ/œ_1ûO¬—¤ú/"Ôøð÷¢ûïØCÏõfÌðÃ6ª±?«~ϰÿvüO·σǤìó¼—Õõ©ÏÍC ø98?g¿?þí^~ê{¬ø3ìçpZüž›Õ£~^ÜŸ7YÉß)û‡ŠS}i=©}‡ý-&÷ßïÀñõöø7Êß öïäOŠY«ì¡3ò_ù/m?ÅËÌúÏUüÅí?±>²Ô¡æàøã8ˆâÎÀõ)n#úœßrû#»~à—ö‡¿íøßÈ7çH|äìkñµK ÖÇzüZ~“ðãë×^ü£ö[9•ò |>³Wýl8NèÏWñwÊþѾ‹cv¾Âþ&½¿ûúî/Ò~oüx7Ø¿›?.^­²4†ÎÊå¿¿ÚOq2«~±ÌUüÙì?±&âl›ÕŸã5çÖÑ‚[+³? ®«}²aVýÁOÍaàïüoâOâDâ×;~§ÇÅ~nþ›ðϰ_óˆŸóêÑÇ{ôü¸¼úÚZJýùjûû=د{NßÎãjäÛâßMñó&þ¸XµÊþÑøyoñ_Š“ø¥yŠ?Ÿý§ÕB#õŸ&Ô|–q<±h&~È_¶>ÕÛQçͬß=øáØž½t +þ7ñc’¦çý~<ôá“ü—šöŒVþNÂÿFþ¬|áñ½óEñõëÒúFð[>õÿ }j-¬ú·öé;ûs®GßÁߪý3¢éÑWÛï³<-þêŸnÿ üyêÑlûGcçnþÞä¿ÿ­_VûßSù;­îáÖÿŸÝŸKçK×,vdã‡úZÕ§ü¾¶«þƒø%ŒÜü'á+øºŠ5>zæœÙŸFð·üv +þ™úQüÕ£ïëÏoØ?#ú‘þœ{_â û©sŸÿFõO¶ÿ$þ¬5i¦ýq³üwýß©_¢¾Wü}·ÿ¤zÇkÇÌþ÷#Þ84?Ô·ô§}¯œtÿ˜ê¿)þNÄÿþ¾>TRRRRRRRRRRRRRR²Qúû`¿®]_à^ïúð÷ä8~Ý“¸æÿË5|.¾q+~n~í¾Æ‚çý}?nl +ÿ©÷ÔwÝ?ŸÍßiûgTß²¦ÜûÜß?NàïvûWâ§âÔ,û¹y¼qótþnâ_³Ÿã$ ?·øóÙB]Ó©~~O^©þðÀúŒe>2ñ{ê×Lýî£õß,þ¬õÿnüÅß÷ßw‡¿‰íóЦñà÷«âøÌå(7áñ¬Çúøy‹oPöKó[ôߨ£¯äï„ý3ªéÏ»Møó—^ûûooÝ?NäoÄþ·ñGÅ©lþ¥9¼1³üwý'ø©q‹?»ý§Üwlâì×>f­?,Ø"ýy6~Žïþ¾6ªOÕ¿£õß,þ49ñ÷}®ƒ@ŽÇÊŒ;ÆÇý5VûÛÏ?ï!"X2ýŸ‹ÇºPŸ›_šÛ¢¿:¯ÝØŸ[øÓüϳF÷ÿ¨¾u]©Ï¡÷}Ù§Æ¿Ûø±ÿüiõéhþÃãKsk13jÿJþNã?ÊÇG~ÊçŠ?‘à3áÐl’ìçz„®KqŽê:¾^¿zìšß[¿Fõ)ÿ˪ÿ2ù£|Ï}þâï{|íc@|{ðXÜõ ÎGÚ_ô¯oúýþŠäSýœñw^<þÏ·ú'žß²7©ó"óèc™‘ãV÷ç³ùËÞ?£û?#~xÖöçmžÞ›<1~ÜÂ߈ýoã«Q³ìÇcÃñ¼ñrFþ{šÿfÕ/ø9+þdû£5À'ùì¦êéM£W~è’n†>–¬ù³ìׯÀOÃ_üѱÒ#T¬ÆsKþã#õý¤‘X +~øÞ-iÝ9ü8—pûb‘lÌž†þí=úJþNØ?Yû/r½éBŸ?nâ/jÿùãêÛ û©q¥y¥X™ÿžè¿Yû—ãc¿4fñÇÛ?R|Ív©~ì‡Ïea¤â4~~Mÿï]?N_ó߬ù£öã=rþâÇç‰ËP¿éiŸ‹‡q>OåÊßMø=ë¯éãùµó¨×µý­áÕ‡ö[sgž»º?ŸÉŸÕÿàý›Uû'ªéÏO´?3~ÜÄßS쟿ëSµjFþãbd“Œþ<+ÿ½Á=ös|Œàçz¢âO¶´ø$V»)þ0Wœ?da䯷ø¶?~û§·þÕ·ú¯¦Ÿm¿6õºwþ™ø‹¿ß¦]ÿÄ1‹”Xòƒ´V·àñ‹¾”›$±ø·„Ë«Ïá÷ä?Ž?Œ³Ÿ¿»?åïôýÕôçx-N°ÿöø÷vûgã—z§ û¹¸IF~:§óí×øˆâ§Æ*þlöŸÜ›SëNÙÏûL:8?Ã6Xí“ê7nൖHý9ªÏù/ÆoÕϰŸóoMNÁ_üýÃKJJJJJJJJJJJJJJ6 w€“¦Ó{{î½{’4}êÃây꺧3õû=£¿8Š¿Y»¾~£ë/áÃ×–)þ~î¾Ðˆ¾&ÞëÕŒý³îŸÏæoåþi2ûý^Á÷ϛ̴Ÿ‹ÞÁŸÿFõ{lìáóðqfü¼?Ë=ΨýÚ}*é^gä¿,þpnêïÜ¿>"ûQüÙøËÈON=œGâ×ç€CÂ3o­_1þöÿôõßÿ’Ûð¿¿H|ä¾÷¤?†Ïãs:><®´O;·ÿN7?Dz¶Yø!>í|jþŒõç죞ãðSyΫïµ?;'Îê!gó7â»ûëY=zvüö/5ßiñOÒ§°EôwÄÏ'ð‡žûvDí§â‘ÿ\1ñTþ¼ß›gÑ_½­9Ê»ÿ¨1Š?¿Ó{s-~}&Òoÿqö+üúhü½µ~ÍÊ?VûÛ5¹Æ_¯‘nÃÿvþ4|œ}øÚ%gþßsý•Ûšà=jÈœŸZ_<6~œßÚŸS\e­?e§¤¯ù÷¨¾×þ~í*+7ÎèÏgò'ÉîÞyWÞ}"#~p‚ýïÔø§áçöçˆþªøy;&²¾õÚÇ`òŸ+žÊ_äÞ+¥¿sÿZs“·~ÁúÅŸ¿ús‹ýŸ…G[·hŽëøÚhü}Jý:ÛþÎ_ámøßΟ„üþnLnnïû£¨õÑò^÷þÞ%¼>Ò<Üeà·êQg­¿f÷lýQûOëÑgò·»7>½G‡k‰·Ç? ¿´?£ú+ãçíü1¸~©o½ösc ü犷ñwÿý±5/yëΊ?Þþ¬œô8{—xͨÏKxôáãª_×Ûßï¡]gùvwì$üoçoæ÷kÂyú5¯>CÓ¾N­k–ýü3ôµõ‡¶GìÕϲ?ó:öîÞ³d¼G‡Ÿå‰ú_†ÿjûoæþÅ{ü¼…?©ÎµÚOé[æ‘âÞíüÊ¿'y÷_Dÿíüeä¢Ï¥‡V¿}½/Ú|dúÏ›ê×YöÃ:ë[ßÃ[üaÿ¬øÚ¯7xô©kYñ[|½¿–ßû>¯YëOÙM­A¶¾×ËùÙùrwZïÏáû2ãGöþ‹Æ(þÑë³§ÄÏ'ñÇÕÍ}­N–ΓbÝSø;Oþ¡ð ÷‡XýâÖronõ_®~ëzÞùVï¿'Õ¯™öãû¼·á;'ç·Ìù±>\dãoý¹gÌ™ëOÙë™?¢ß»—mõèïk¾3þœÿnŸOâÏRïZûsÏRœ{ +'òoÍ=”>·¿°îíüýVÞD½‹ +í]=“e'}ž-'n´ëòþÿ?l·°‡²F#@ñ!8T©ºû½Ëåˆ#‰{àu÷oÿúüï7b¿|¾ýYkÿý¹ÜÿŸ?¶Ï¦æá¶ÿüûÇoŒ^ë…e%üÉ,ã÷ôO?[|Zé¿tm$üàïϼƒÁ`0³}ùùË2Ûí+ ƒÁî3¬c0ìDKî3¤×J{tO¢ôzêÿû¯?4ûä} ~]Ÿ^ϯåû/ãÝ þ™ûÛ{ï°qKû“-Cþ¡~àñ_ªK%ìÖzþæú¯Yc´øk}ÁŸì¿×úóqn¥3µÕüY1£þÇò?:þÛýOßçgWú~¯µúsò¹?]«¤ùç~Q;¿4¿+ð¿î ÿìµt·6…éô9Uäðèÿw­æé9¹‚ÏTËÀß\ÿ5ë‹{³øûÛwÏõçã׊x%þþøiŒ¿Ô¿6ÿZлò'rü­ào6~ð7Ÿ¿t|ÍJÿèÜò|O¸5÷Ê>&Û‰ŸÎoÖZü£óÔÿÌÇ)ü-ZWÿl»uêËfÕèÈ?ÔÏù+=ûJ÷JP Ÿ©v¿¹ù§YS”¸UýÀßúœãásÎu}¾§?çº=ƒ¿¼ê¿eýгù[üÍç/ÿÎz¾gk¿£6Viÿ¯ä_Þc(å}ÞŸ(Õ§þë'¯!%ÿ¥õ±…ßZ«Àß¼üÓ®!-ü¥>È?Ùÿ뎖CÖá¾Ñ÷%þhŒyÔÿ±E_¿VÇßlþVãëüçøzæ'õ£Ÿ{ŒÖýüÚH]8¿T_éþ3çwþ×ý¯á÷\s­m·vmù·Ï ùü»ýçy)ù/Õ ~k}óü×®-Ìüzä_ÝÿÕúœâãóÇç·ô|ÞË=¿Óò§KÉ?ïüéÁzüîtü7ûï±Á}(ù&™µ6ð:±¿f}“¸òœÿ×ýoáÜ©Ñs;E“Ÿ‚k—>çùü»ý—ò²µNjñ[óüÍñß²V´0—bù÷=îÕëj kž?ú¬¯Ñç3ù³Ä¥äê|ÿ£ã¿Éÿ¯¿ïƒÁ`0 ƒÁ`0l£Y÷òÿ‡Ë–öèÿ‹£ïñk’¥þt‚îòשY÷õJ{—»ðç}—ž9¯áÂß,ÿ{ñÏ>‡¾­Ý~ŽŽü{ÿ©þK9˜ýç¯ñ›òüÍñßR{køùµÈ?ÙÿÙk…¿Úüò³9Éÿü}:ZëlP²Wâ¯'øOïþbñ§å—òªå˜÷§VªG¥ñ?ýMWòIºÆ ¿æZÍüGåoÄþzõÝ˶Ût:òomþíÄ…?m.ñ›rüí~)åŸt-òï{[±Æh9¬ésÉšÿžüIx[>IqÆyÆy.þN\¿éïT€¿8üiù•æGª+ügËþA¡Ž =ËðzÙÂËýœ…ßcþ#ó׃”¿MK£k8Eþ­Í¿Ýø#ð×ÊÁü¦<sòÏRgKø¥ëßb[µ¶hyÌø¥8“æ¿æ¿–XÔÄ›„Ÿê›—âïÔõ›Ÿƒ¿üiýÓø&]g=ßç÷mùg©/Úyêå§ïüߟ?½w/#ç­’NY»#·[t:òomþíĉ¿Zîuà7å/ø›“–úZ_ ¯òw’6'­ÉQm~fð'Å‘5.9nIÛ½Òu'øŸ>‡]zÞgóײÚß—ÔÌ›õïëq_´ý5õ…ß»„½güQü^ó•¿Úø;´›—^ÿ\Úvkn/Ž‘mütÍAý\Ã_-÷,÷³æ.øóá÷·ÔV>~)}]½žX¸”ðSì«ë¿{-.kãçïÓúúBü­äo¶ÿàï,þ´þÕÖ‚RI¯YðIÏ~½þYÖ3iüÝøµó+Évê6o­¾ßz4úËù—û×0–Æ? Tþj9§½§5_ÁŸ¿ÿÖzÊñK±Ðÿþv­##|ÖâNòÑ›?+öš5ËëêÍñW⑾wŠÿà/&ÿzlçþI«Þðù< ¿4ÿ·ð·[«yësœ«ÿÕnÓè·æ_Oéùõsµ<¹G-?ÀŸ¿ÿÖ*á—®y9ÿ¢hóZ®J|Íš)†4¸Wê»Hñqýçó—>ƒÁ`0 ƒÁ`0l¯ñýôšvOOz]ºgkOŸ¿ÏgY–ýþÏ@;k|'»ÏB5ç?5ü3ÏÏqž~öYzé =Rþí®?ÑñGðŸç”O^‚?ÿ-5³à£xÝ«ù·sÝøt6zžF}ÊþÏæÏŠweþôü{úÿ©-ñ3ÚGý˜•àï<þèýi}ÆÎ?÷úÇûkÆOÖúÐü½uUª±;ðÓïWò·[GÍŽ¿•]£×?—µHúœ×Öòï”úy þhþK9¥ÅoÍI𷆿Z“ÆoñÿRþEÔæ©ñù­ÍËzøë‰ÁUù#ÅEéžÒø£ùrýðÎ?ðƒ¿ü¿æÕüÛ¹>|ÿ›QùùܯõÃ+ò‡__ºÿ¹gü‘þ«ë‡wþ¿üåïùß—ãï·ü´ö׎/ùÈ_›‰´ÏÂï…/·ÑuëTþFâo§N÷ÖíŸC›—O3ôyÞû©_¯×ÏSñGôŸçަÿHî??ÿ%îjÜHãók^Í¿ÈÚœóVâ¯e£ñ×·;èuô«×ø»ûïÎ?ðw6üÙ³6¿VÿjXJ÷·ôOßïÂßS½ð&·ÖútVü¥Ï=â×ôßuþ>;Îz㯅m†>áï„øž³ðGô_Šùþ‘|~þó¹ÿzf*¶þÚu/å_dm.qWã¯e½ñ§Åµ:Z×Iïæ„úáàï|þòó'ÇWò¯æ£_«É Ónü#u¹„ÿ³¹½ÄŸ¿¤ƒ=ð·úãÜÝÞ¼õyK£Gˆßèù7 Dÿy¼·ðä +øóóŸÏ} 뺗ò/º6çÜÕü—æÝÊß®•ù#]¯5küö_]?fäø;—¿¯¿o ƒÁ`0 ƒÁ`0l£Q­ß:'Êz>i|~.¯5:fÏ=8æø?‹Ú©þGçZí³Ï£øký=ÎÐg}þÔ³ögè½ü¿Ñóo&þhþóx¯á÷Èð7æ¿4ÿ¥×ó{ »xÍ«ùùÜœ¶ÒYœd½üi±hçÿŸÆó§ç'Åßîú?â?ø‹Á÷Ezûgý,½WîOÏôéµô+ÿž×§HøgÔté³§ú?:¾¤ãzñ[üŸ¥ÑgjöÏe}„¿Sâ7zþyâì?õþžüHý¤×À_¿ÿ|îK<Ò÷K}SÛ»ù‹®Ëskq(ùoáÏ‚Ã2ÿYŸõÄ_ê=þ¢çø‹ÃŸä˨ÒXÔ?zM©?ÿ>÷ˆß£†—ðGð?:´¿t¶4‚_Û•F¿I¯{ktäß}ø#ú_Z#„>æÜHý +ù þœÖÿÚ3ï/½¿;þvówƒ6Ï\j­‡? †žùoé»Züñ³×ˆñ=ÿÀ_þøû¥1©-ߤŸùç JýJØJã÷â/Ũ'þžzmð·é™¶wþ-þïÐè3ôûga›¡Ï‘ûòÏ{þ#ò'­ÒëÖ¼ cJ>ÿ%¾J¼´ž^Ͽ蚼ÄgˬüiÇ?'ÅßmþGdzÿôž%¿,Ÿ àãÐ{öôÏß§9‘úà×î!åë´ø-5ytþÁŸ?üÒ¿’¿ÝºÜS·ktäßžüóšÿ¨üÍÊ >~í}ð§÷ŸÏ}ÃÇôþ¯æß-ºœ·þ´cFÉŸ“âï&ÿ£ãÁÿü^I÷—ðYñZ¯§¾Õú÷â×ü½¦…¿·÷â¾üYñמoWñ·[‡{éõOpŽü[Ÿ£ø£ó7#øØškÀ_Û /?ùw¯6ÏÍ+þ,cͬÿ^ùsJüøsšÿà/Žÿôš’–—ü³`žå_/þŸµåï•Æ×Ö^oüàχ¿üÒú‰üEÑëŸm¶FGþ­Ë¿üÑù›‘£ýuþ¬¼HÚ<µ×óïvmžÛhüõŒÓ[ÿ#¯_Ñë?ø»›¿ôyx ³Ú—Ÿ¿,³Ý¾Â`0ì>Ã:ƒÁN´¤çé>Cz­¤åéžDéõÔÿ÷_höÉûÒ~ßOà×òýŒø5{“+ðƒ¿3ðKûó¯óásïgè·ò÷þèþψÿþV²ÿµêÄø›ÍŸçyy”³s©ñ9¬ñ§¹ê¬úõûMþøÿ²£÷ï±VîÿŒ(ÇWò‹}Fž‰_[K­øGçüíÅŸç¿÷3 7óçùû鳞«<5úmüEÀÿrýœû-üµ>àOö”§Ýøwðmþ}Sð§j7ÕÿQü¯ûÿíþ§ú˜¯Yé_›þœúçg^ͽÒ×43ñ[j^êŸ'L‹tþÁŸ/þþzõùÍüykôÏY£úüfþ"åßkõsFÜkðKgèàOæÏ£>½˜Ðær£|åy³Ô‰¿«ó‡â/åÏìõkçú'ùß“àï^þòßÉsÚÒûµ±øýù½¸ékmÿ5ïOH÷ ü̯©w5üynkøGçüÍÃoå¯ç ýþN×ègè7ó%ÿ^«Ÿ3â^ƒ¿Ôü}Ïß(G/æÎÎëògùŒÆ þFã~ÆwÇúµ{ý«ù¿"ÿÀ_þzþ>4×Ü®||zöoáj¿¥ÖÕðÓ÷fáóð÷ð×£Ñ_ào–F÷zîòÐè7ó%ÿ¬øOö_ßwÌkñK}Áß÷üÖ¥øWñ7KߨÍsËüiÿ¾Á©ùCõÍŽõëdÿWäø‹ÃÇ×3?©=÷—ŒòF_—øå×Ôðyà¯Õ¸ø_çïü½ýÿkøoÒèîÛù»4ÿgÄ»KŸ¿Îßh=Ú6+tùÚ<5kþ£þÇ«X¿Á_éýËþÕ|¬ù®ñOòÕ «¶ŽÿuþNÂߣÑoò¿f¯hô[ù»$ÿgÅ»«Æ½Îß(7»ñÏäÚ|¼ikêÌúõûmþÒçÝa0 ƒÁ`0 ƒí5ëþBþÿpÙ>·ìcÚç þ~³Ç’÷@~^—ö]zæ¼6ÿ£ý³o#}/‚ÿðK{úàï/»å]{†~ÑñG÷Vœ[ñKçïàÏÿÿªV[uf~û¹¹¥ð—ÿvÕ-ñ—úçûqßzû×0 õ`©ÿà/6½þ}ýþÚF}æüdÿ¥k,ñ1:ÿ=÷àýù÷5ãýwù_⦄ãþJŸ!?­ÑSóÔè7ò!ÿJó9ÿfíEõðWûŒûËüypsSþA—¯o½üåÿûtjýë­Ù·ÞúQê/Õ%~ÍJÿÁ_|þzýûúý•­Ä÷¿ežÏÇ#ñ)õç¹(ùp’ÿÒ¥ç“ðKÏàïÇiݳ&xiô[ù‹­ù”ÞqÞÒç-üR]{¿S+á–Ðæë[/é,0ëú;±§Ô?}çÑ¿†EÒy«ü÷ð×ãÁ{Ukñdý|y¯øôî/å¦tÝ)þ·rëTþF5ú­üiõù齄ùvþ¢äß õsFŒ×êQ>çýEþ¼x¹%ÿ Í×·þøß¨ÊŸÝ]?³êGò¥÷o¸¶úg\’¶[å?ø»‹?‹•úJ~yŒÍ}ñüû|Ùh-«ùv +þý#ó'ñt2#úüfþnÑèµsô›ù‹’3ú¯â¯ÿ^q=Ÿ”¯òçYknÉ?hóuïiùë}?Òúµ²?¯Ý³ýwó§õ¯¶”öÒk–ñ¥µÇûùR;þIøkóþÎçoä ýfþ,úÜ¢Ñg<ûôž£ßÌ_”ü«ÍÿhÿÙü•âß+¦Gù«£¿ÂŸw¹%ÿ ÍçµÒÞ˜'«ògVüíìßÚŸ_í?ø‹ÉŸ…ß;‰iý¢ßŸŒ_³>ƒ¿sñ÷jôÛù›¡ÑW< YÏÑoå/JþE¬ŸµØ÷ŠiþjµÍº‘?ïúrKþA›û¶Ú¼ÌàowýóÄAß¿súïâ/}ƒÁ`0 ƒÁ`0Ø^ãû#é5ªß¥=”Ò{Yï·ö`ø?ŸÏ ,û;ÿßo7þÞùñøkí}¿ÈŸõ ]s޾úüBsŽÞ²¨ü펿Ûê§6æ=bÙ+'nçÏ£–Ü”87kÚ¹ásŸÎìèïEðó<úZæ¯?¥×óúÑêÃ1Iñ³ÿëþGÇ»ÿüûZ}Í?÷®o¼?¿4~²Ößê“Æ/ùØâíü–ùñùÓ¬±¯ñç­Ñw?3õèt)&¢ð)ÿN­Ÿ«ô9»‡~­–¸‘?¯rSþA›Û[ÇÜ|3ï%]Àù­ño±V“<¶vàÝÿèøoöŸŽ“¬¶ÿ õÏ{}È>Ôæ‹ã—Æ’|á?Ÿ‚_;ÿàïþ4çK¯ñ×£Ñk:ý”g¨–^ï½ÇiüEÊ¿ë§5Æ=â×›¿VìÞÊŸWí¸)ÿ ÍÛmdn2éÿ&'Óhô5_Ÿ~^©or\ñø“Ö¢þ¤ò}zðö÷öü¿Òx´¾JïkýÓö/_»Æ‚¿uþóiø{Çgà·ŒßÒè¯òç¥ÑO}®ò2>§ð%ÿzúÏο•ú|~­>¿?šq[þA›ËÍ£ö—øKÏý?r]w]¸iý{é¼|ö™9]ÿyŒÿ"¼.ñó<_Ìÿ:[º/ýÑô=~M²Óð¿îtü·ûÏÇá÷”ü³|–€ß+÷çŸßÌ×Ò¯üûܿ俄?Íiú}ú| kþÁßÝüIkt$ÿgò×c§jt öüi°½”­þžþ÷Ʋ‡>_ÍŸVŸFâbè­ \ßF^ÿ^Òå+´yÖçR\—â]Šíµ¥þµø’îM¯9¿ç½ýKu§”'øþâñW³Æok}(ù—¾ò½Û&ÞŸ÷«ÍY^ßÞhøµóþîå¯WŸ¿Àß-]‹}ZþJþiúú_Û“Ù¥ÏgòWË…ˆü±1ºjßÿмþ½¤ÍWèòœ–ó·BlV9ïÕwµ1éÏ'áï¹G­?Ï5ɇ“üqø«qRã×z?þù,áþ¶Rí/_ß÷ ¥ÿŸÿ÷œþ|'~ÍüŸÂß ÿ_ç¯ö þÎÕè3ô¹tŽ=‹¿|7柦ÿhþñyÌ×ï:?ŸÍ_K‡Dã^×Sjùqý»]“ïÐæ–ø¥¼P=à­4÷éÕ73ñ{÷—´tÝ)þƒ¿8üÑšÜêgýûxüžµþ¼öñùÉ{ÈVüô3c¿(×·üµ¹ÁßšÿSø›å?øëÓè/ñ]£{éó™üõàº%ÿFð·ü¯Íá.}¾‚¿–‰Â7kþKû2Q׿4ùJ]Îóaõó›”?TsÐ{—ro4þ¼ñÏèOsÀs|ðþè}Z|ñû[dzèóÔò{ù™¥6¿~þ¼8Ízñ[âk73ü}_Z»O÷%½ý”g¹YÝ“¿QLQóoFü¶æO»¿4ªÏ½ò¯‡¿š9?ɬ¹ÏµyäõÚ|ž.ïáOÊo}§?ÿ|~ ›WÿÚÜœâ?ø‹ÉßWÑ®o–1­ë›v}ðK×ÎÆ_²ü–ç“Søóôü}ÛßC£ßÎ_ä3ô^®ÑéžüàŠœžñ«™¯™úü”úQʃÓù+™5ç%}qýƒ6Ÿ¯ÍGø›Ñ_Òoµ\´ê›™ø5úTÓßj§øþbð—>ƒÁ`0 ƒÁ`0l¯åÏ;P½ÞÚ_(½ŸûÓÿ'Wê“÷}ùu_q}×èµ|?â4ü|Š_ë‰ÿuÿOÇÿ8Ý#D‹ +í]±²-«í`’ <.':rð’ ìþÿóžË3WW ’@T©Î9{·š% ôÙû¯ùÏþØßþüýþûoß÷ûkžïÿBèÿÒ¼þÏÿýŸÿèÖYë­u·Vë‡ÛkëûÅfñwâRÁÿ÷?ñì¿ÿô_?Ù·©ÀzzÆÅŽ™%#l=þVb^ÁoÑ{mÃí¿+ýúî’þñx犟3ÎËu£qîaþäòGÅù]V$ó÷¬Iúok?8ÏôîÕã¿×ϰ÷*þQ^ñ¿tü7Æ_×->ø¾ÄFþÏ?þ€ûcs$v¿âo‰¿æSè_ß§òšfû{äò7çOäïçë¤:çÞæ„ÓüI°qø™±ão¶ÿŽðNŒ³}–Ò–óg7þzó§Öø>‰–¿^lßee·._í¿P_`ãcÖê’}ý=à=þèøo¿X™ƒëq2¿•¿K~ƒøjžÂæJx/küíz³Å_ââÜK¿cþŽÄÿ"ÔØHþ~åO¢ÍoÑçøÛ¡½wèô“ýbì?I¿]é»Çߨÿ­êsùOslŸÄ/åoÛwa٥˵æßÑú¾òÜó…9ƒÒ'œþ§­ovâ=þèøo¿Îõ->Nx/,Þšã0l¾„÷¬{ØVøÛgì ņݣþ½ÚþžùãÄŸüÍùSë‰äïWü}îE£kètüy×é§æOŒOlüYès«ù“Ò-ÑòŸöxö6rbû.,»t¹Öúò‰éx Ç¿í¯}÷ø+ëƒ8¢æ¿Ù1[ï3Û_wϟܸ¾ ‹¶.ßÑ[N+—Øûÿðµž?ü‹äoÿõø£ã¿=þ¾Q,”ñ«{À”µ{ÄíëX~/?±ùÃç?ÅÏü¯Ç¿ÔŸ³ÖˆÿNþ¸Ú<ŠF—hukþ"hôñSïµÕêü9;޾ÊnmŽå«ü‰õóžÿŒ¾Á´†Wü¯Çÿ+ñ¬½?K¯éó=XûÔ¿±9–ƒ¿}¾jªí4ñKÛ¾×þù›ÅŸü­ñ·¸Œ¹Š¿ö ý5>«Ó{üÍÜo‡.ß­Ï{ãÃ0ê¿3í£ÙGNŒ?M}î)ÿQú|µÏõú€tþL]n¯Í±üã%Žú=å_¿Ÿ{?oøµü£ÆŸüÅŠd½ÏÇãÜWúùªp.C>ßî—¢]ý½®M5ñkµTþvÇŸüõýg×37ñ÷ºFŸÕéžuùL|㯧Í{þ»´9·œúÜÛü‰q®¡Ía¿p¦5f¾‡Ê m¾³ÿ®Œß¶ïKû?¥ïàø¯×yïáω?ùKþ4âY½?ujº¾'‰Ûƒ Ö×?M~Ú¶•úsñk¶Dþfð'{ø“®knáïÇsÓºñ3,§u¬†Òå’øj?ëi©ÞøióÞøóªÏ5Ç[ôùr¤µûƈ»ÔåóåV}οX¿ÇÆ€TßÁk¼á_õ—Æã-þä/\|íý$¶c~ÂæÛÓí»›_ªýoàï„ò'çO²¶¹…¿nµÆ=­c#éq­ØFã󑌿]Ú\Ò?v?m}îaþĸÒÖçm]»ÇÆ÷`ÑnÃùoÕŸ3~±þ>ª¿h·žÆƒïyÿê_þ–Ää-þäÏ7õÜ(----MÕNë8ÓÒÒÒÒÒÒÒÒ”¬ýÐúýžÜ= ìõâ?Úƒîí´þ½sdŸá—b…ŸóýªØ53í ­¿5þä¯ÏßèÜáþvýžì'ΜwŸå6ι'ì¿Üsó^ÿ•´ëξ°{üQqFž?±˜¸ý3~í~ÿ=\vÌ##þzÆá¿X=÷ëùS×ÂóÀöµê?êÿÔë­¦èùxÁÿzüÑñ¿û>6?Ô¿góô‡÷Áê¯9¾†ùcó¯~È'wžÖjÿ¨üyÁŸüñø“êhüEÖèÖZ7¢IŸuÇÞ“ö_ɾÇîþ°{üQ1Fž?gôùlþÛ±'ö=\vÍ#½þ§±þ}¢½®ï)]ûp/ÿKlä¿y{ÿª¿uüÉß½üAß‘~çÄ·šß©zíõcm„+üðZ¬-WÛÿ&þêúÖ þäæ»¾‘þߥ7þR£¿g\Žõm }·£¿ú¥Úøëíg´uFž?Wõ9'ÿEžƒ¼–]sÇlÿ•¬Ú¿«6iǼeÕ§hˆªNê +ýŸh.þrí +þUíø“¿ä^ñµùHšß$þð},¦Þ=´œÆÏÑí!.ð'ø53ë©>÷Æ_äõ±µÖlRm.í¿§ÎÎ%ý@küÁ¸zã(òüIñ'ÕçØüÅížçe眡¿0ÿöïò³w~Xûåß~fUÕ’ñÇáèüÆ3Â_?Ÿ¬‡¿^3‹ÕgüÉ_ò×ü|9ˆe·Ô¾Où÷æ)èß››Oã‡ük×#žð¿ÊŸæGr†î‘¿èkdkÙ$Ú\ÚOisn?(´Æß¨ÍÚz£ÎŸ#þFý¥—ÿ${7^çe÷|!é?먰ïõù^ÿçX{ÿÖ[ûIñ·ïíÂï9þä/ùkëê­o¥ù­7Q÷—ø×µ3ôçÌÓ»ñ®ÃÞ_mÿ[øó€ÿUþVÖ9-þ‘Ö‰Æ_dn­q_Õç£þËÑ_§ø¯´ÆW›‹:ÎèsNþKm¾§œ˜/$ýovýSýê½Ú×1}ЫŸÛÿ¹Vÿß¶â£Ì3þ×ãŽÿ¦ø¡qçiûHü¹±Ô×Ú¶âžÿ•² ?Õ¶“¶ÿ­üYâ•?é:gÄßHïDâ/òzÙZãF7®6—ö_/Ú¼QküIôyÔù“;'PýΟ»uù©ùÆc91OpÖ/=þ9þµŸpó¦zã@ãür„Ó;þ×ãŽÿ¦øËóîiiiii¦¶³XÇ–––––––––Æ4¸/÷ ¾/>õ¬Þ¾em3÷€˜%øG‹XiýígœÀ?jÿÛùkñÏ´}òÇ~«ñ÷ÎÕ¼ó·ûlë;\¬Ï¥#uv¾2ÿPÜkô…Ùø´ÆßÌùyù“Œ9ÆÍúð÷`9Õ¶’þ·’?kÿ…×ü†¼ŽÝÿ[<_¬ß]­Ü·ý¾èö=xM1oø_?:þÛã‡õÀ{bñIž%€÷ªþí3=íµíOø{õ§âçâÍéüØçœÂß¶ÿ‹üÕßëúpÿküIÖ4»ãï­Ý±g@=ñ—ýmõÝQ¿®ýw'ç+qiÌŸ£v€õFÍ»çMû,'ÛWÒÿVó'ö:u}¯þѵ”o|`÷n¯ñ€['ÌúS¼Qüzˆ?ù‹ÇUçJ~£â+?áþõô‡~Rü’yžZŸXâ‡íÿ-3ø_àofMs*~ŽžñÊŸöºü3.ÖÚ!¢ItùIÞWãј?¹íŸCˆ–ÿ¢hó]}Ís9Ù¶3ýOcý02llîÒw½:Û¿=áŸÕw”?œ+°<ÅŸüÅá¯ÇI_éýàóe”5wQõÏâçÎ÷^ñ¿Îß-øWýgÖ0â瞥{ãOk}þ9)Öúá%óÈ#5ÞfÆŸ†>÷œÿòìÜw9Ù¶^ò¯Ãý%M}ĹϬ¾Ù‰_ÛÓvØu^âOþâð×®iG~ÒÏǃ÷œñ¯¿—<ˆùkàÍùžñ'±ñÏúÏ®_¼ÅÏ}6ØkôÏY±Ö/˜WþFÏ·KÆGŸÃçd,æOîüã¤Ï¿Ë©¶µÎÿ³ýWâÕßjjœÊÁðïðÇÎ’¿äO+~._ðþÒúfñÕµçû'$øá3ÒÔœïòÿŒÿìº%#î ÿÊ:ýsX¬µÄíæ™;JŸÏÌŸ’³óöüïýK„ü—ÚÜg9Õ®ù5ïðÇô[/©¾Ù‰Ÿ£O9þRóòƒ¿Ÿgž––––vÖv••û[·Éí–mž––––––Öµú¼C«×Gû ÔûÕ¿ý>9ʧî[ÃëjýíõðZ¸± ?\DyÄŸüÅÆ¿ò¼:ì“ãçàçüzý?V«ñ§užöë3¿ÍgpOç'j]ÝÚ.ü0xÅŸüů±&y?®F‡sâ©ñ—ú<ÍŠsm<½ÿ%¡æ®6‡÷‡Ý[þ‹¦ËµúT”r²Mwõ¿ò?^+þP_`ø$þõ÷öu޶hý©÷{úF ?5_Áú±8¥þãOþîá¯ýŸªò÷I}T±C|e¾*ƹWùY¯×ÆsÍá\ü«íŸüéâßÁŸÆZ$ù“ët-þ$ÿ“u]m­)^4¯¼Q㈚?$gÌð}où3¯ÜÞ§"”“mº#ÿµþ+ýw¤ê8íùbk¨EàØ‡uïÒ73ø©úµý±ùÃCüÉß=üÕÿY¯ïKâ÷¢ö/¨>R~¶Ïø|Äç;÷úT½F?–¤ø+/=ü«íŸüíÿÊßIJÃUüžù“èôSãOcíþk]ñ¢yåŒÚë¢æ‰ŽÅô¹Öø[™$óÉ­ý)B9ݦÚùO3ÂñˆéƒžF¡üáµÔ=àßФv㟭ŸëÍ[üÉßüU›ù|:l­ ëîõV`Ÿï<“«µðÃÜ ÅµÁüÉß>üþVÖ^ãŸ֙úêø‹|†n­-^3ïœö¹zãOr_Íñ7;ÿHæÔçvÅ¢M=¯ßÚœXÇ"ö>–?ák˜?ÌÑ£¶ ê‡¿ŸÂ¯U?åï=þäïþ0|’y©õ¯ùŽZ_·ïCœ˜>Âb¡ðiãÇr„wüÉß9ü³ëŒäoþ™3u-ü©ÏÓNò»goÜÀñ·CŸŸÌ©Íý‹6Õλò'–¿{Z ·˜?U7vŸö=Iý;ñsq¯úsù;òw'ûp M­­1ãèƒ^[íÀó„wüÉß^ü³ë‹äï,þ™ót üQ5ºµ¾xÁ"q6ÚÛ‚c2êùù gçßÅŪMwä?üI­Ýaþ„Z€ºO»×Öêƒãè“ø%í¾êOñgòwåy÷´´´´4wvºpñxˆÿ&žf겎9Íμ‡´´´´´E£ö(+>UÛ·Ÿŵâí1ü†¼­ì3H1WŒ-þ™ï„Éð~Nû'²ïw”à—.´“?_üAüÒóôYþ´ÎÚ>§Åãyà‹ç–»ã㜟·ý}õüüäüåÜü{°Xµu±ÝùOÚg{ýw&ÿòcûÚ¿rêÿm5ÿÎÔ ë?k? +ÿª¿Çø“¿ØüÍÌuÞþõïöuxMÅïËÅÓÆÇ™±ù±Å ï´ëOå~iû'}“à—¬%’?üðÏjt škúÏYñªI^ÔN»c䌩–]Ñç«ó§T—§6?[¬ÚºØ©ü·ºþkŸ‰ÉÿT~…¯•=ñúýop‚û,>Ìß'ñSíWñ¯ú{?ù‹Íß<»£bƒ¿Kö±{sç·ÒöcËC[?Ö¾ðÞõo˜Cvãç¶òÇãó'Ú‡U’?ŸüIñKuº”?­µýç¨xÖ&¯j¨ñÆÆŠ6_ÑçÒ¹sF—[js/}ëd±lëSùOcýÏî¤ù˳TüUß•8$úÓ§ñSíñ¯ú{?ù‹Í_fðùêžTÝÒç{°öÍo°Ý볯°}zõ íúSÙ‰¥ý9þ½8nå¯Á?]¼ð÷âøÛŸ«Ñ¥üi­ñ?Gų>yYK펧õ¹tþœÕåÖÚÜK¿:U,ÛødþÛ¹~˜Íÿ½¼[Ï`‹AjŸ¬³Ž>޶ßÏñ'±ùÛùù¨m=uGêßÞcä?û>Ö®€×ŸÊ.üÚí?ŠcKdþ´Ö žø{uü­Ä/Á?Òè+Ÿ}Ã=‚>yYKíŒMCÏržQÑÿ+ºÜ‹6÷ЧNë6¶Î;ú?7ÿ·¹˿ů¾ýGϱ¬®5ðÚoÕß{üÉ_lþ$6;¿Ô<,ñÇö ´æ7ª¨s<˜O¬ñÏ–oãOkÍà‘¿WÇ_}ïþÞš}EŸG×èÖkèÛpî,;ã[Ѳ+Ú\cüFÒåžúÓÎbݾùÏ[þÇònùŽQìÙÏø¹õÏú{?ù»+~+|»ë‡þm{p ækü+þX޼?­õ‚wþfü"ðDZ“ø{kxiÛG×èÖkhnüÖø¬yj‹uhksÎø½M›{éKÚźM«EÉß'ò?'×öžÝ÷†_¢ïfý=ÇŸüÅçïÇÿ#§¥¥¥¥ùµ•²rë¸Ó’¿×-9MKKK{ÌŠFo÷ÊkÔ^D»'A½^üÛï3¦|ê¾rúË~¼îgœÀ¤ü+þ0¦hüq„‰gü«ü½4þ,ñÎÜ8ñ¯œÕ}Šõ9W$ûœëöèŸkÌŸ7ž™{îO3ź 1³Ê=këïÝ'ów®¿’¿ûù+¿·kL8?HmäãϹA|T\­Àó'ü³þD*uÍw=à¿Uÿõü£u~ÏV|Ίµ6±^ÓGã«ë6=ß.?Võx]îµ?IŠuûQæ)ÿA}@å;,ÿa߯.Á_¿{ë…ü½Ë%þä/ùá¯{ÐPÿmÛõ]ؽjŒÅváÇòN‹¼õ{þçâ_mÿY*§záorI°Üÿ¢ðÇí¿VüYáßÍG§sý"®Íµ´ÆlìÖkûH|Y·IµÞs'Üñ§¥Ë£èó/x±n?Ê<å¿Vç´9 ê€v}ßþ]ëµ\¿ìÈß’ö¼þJþ’¿þú?ëõž£ýŽ^]Ôþ_»Ç€ù×ý j~j¯Ù…_š—Zÿº^ïá_mÿÿQ §ø[] ìêÞù{aüyåOªÓ%:á RVµÆl¼Öküµ úzo|pÆ_jsÿźÍ8æ-ÿA<­>ÇÞ‡õ—ŸU#ܘ¿9ø£¯¿’¿ä‹æóé°¶†±`ó Æ/¬¿]•&~ܵ¿FüÞ]üi´'Ĺ«ÿµç<žù»yüyæ£F×ß°6/å¤Ö°^çŠuµÆÙ¿¢Æ_js¿Åº­¸æ%ÿq´¼¾}Ãßb¼-ŸÀoò—üqñC|3íSüÚç0k×ÍíëØú^Ó÷ ¿fNÛÆé͟vûÝÚÿrüÅÃ/Ñé#Íð]PvÇ“ú©_¬õ4¬ÏsÆßkÚþ›â/¬<Ÿ––––vĸå¶x$%Bx¬¹N£y²Æ‘––––Ĥû õû᪕=€öûâÚ÷à5ÅŠ»GÑîÂ×±}‹Ì'ñlœ=_ ~íø¿CÅ+§ûßëñGÇ?º>Ïгœ,Öç•”aý]sìx=/ÿ.(Öm8k^óGïþðló?ŸÛ7ʵ½:¡½²þ¢Ö3âoï—üÅâËoË+—cèß5õú×,~¬^,&ì ~7jÿò“ºv…¿oc‰Âß®þùËñw?©Ñ³œ(Öš¨g'ô¹uŒÐ¾ ÅºÝ4Ìkþëågì5*ÿìÂ?Ó_Ú|ØÞY‡Ìß·­¿°ÿ/Jþöò7;®føÅÚ›Wàß’ý,æ]ú Wç*þÕ<ÓkÿÞµ³ü}‡‹wþvõ¿ÙùeÄ_Ž?¿ü­jôÖþYök]Ô³]úÜ:®ž}ÁŠu{i˜÷ü‡å=¬þQþÜ¥ïPø[}9ß²þ‚gçTýÉŸãI'6ì:éù>µ¡Å/ç>³ü`øWó lÿÞµþ>'Å;šùYÓ?Ç_,þ´õ†õ¸Íâ§Xk#-}¾cœXÙç¼X·¦EÉ=œÔýwãÿœ¯ù;òú«<‡MÍ¿õ¾ÔÞ‘üù›íÿÒøzŸ/Éi7éçëÁ6Óü|>l¯¤›6~ÄÍS=üŸ³…¿Ùþ·Ã?Ç_<þ´u‡õ¸Íâ£Xë#Ž­ž¡[ã¿a|Z·Ç‹ÿ¨üÆÑ-;ñЇüMq­ÿê_i{küÖüîç_o-MÍ3åµ™ïŸh×ÖÜúwãŸÍG_Š?nÿЈµ_zåOÒÿ0lZþ9þbñ·ãlp5'd‰_¬u’æÿ¢ß Í½MëvØeòUg¿zþï’r:sxŒÐÿfú„%~ïü­¶Fû̘§ýlýñdÿÄú  öŸSñKçÜ(üqÇϪŽ¿øüí8#䌫,÷k42é羕1]›[Më¸w[´ü Ã{¢~«þ˜%~¹aý¥µ~ÞÑvõsá{Vž¹OKKKKKS´[‹—vµÆ‘––––––6ap ¼ÆÝÓÃ^Çî9Ú„õÃs%ÉþÆ ø7ïå[Çß-7ð×{ï…þ{+~øµŸåÕ•Y"ëóMÌnø|v¯cÑ:ÞS5Ôó±öµê¿ÿé~˜åîûçûűkê÷‹KÖO«þ+ëOí¶Ãæg;?`1Ô¿gãƒþœúëš;ûÿ®µƒuü£>} ík/ößðïˆ?5z–]ÅZKAKmþßš1`V54UÏþÒÊJÚe‹ +í]»®l· "MŠ\ÃMJW)ܤˆùÿs ëC[&(‰z’”Öˆ3gfs‹Ô¢DQšÇ/?}~ûÏ¿þþ]~ùéóÛçóùþ7—_üýï6€Ç=Ο§Ç5‘â—¿N¥{®Ò§ÿOôï§’ýi '¡×Ký×’Ü?I_ºOk~É瘒î«öÓkÿüñÛ´ðñæÁÿZ\ßÄß«ñÝþ]þÓýHVmàm¬È;„ÇûŠ˜÷"à|­Ü’?蹟?¿ë~­wTy¢Ç~ëøî‡<楱Àÿ]êKóÇé~ë™?ò×K}Úò¯G¿Ô~‹×–þ+öKú“k wþ—bûVþ^ŠßèöïôeÍr2ç>a]Wõƪµ«üðë¾X)Ñóÿ?Õçé/­Ï{òEË~ë¸Þ@)þ[cˆÿ?2~gô­ÇŠvþ Ç4WHs‰ÆÏ^}mûµyîeûkú#yϳÿR|ßÌß ñÝþÝþ£FVÀº¦‰Qk[VùáÖ}²B¢çší’ý-©µ¿#†jk1à]”â?SÍ8¹~´î3ÍüAïÛ¡ëjýÛÛ?µ¹¬tÿýôøuû5ú=ùϳÿ¥8¿¿›ã7ºý»ý—êsÔè@¬kªÑ˜´¶ëÆñeÝ?³rSþl)µßÞþŽØ‘úoG;@Läñ×gÒë³ë'­þÇ ´ó}ö…Ï%ÿj}¤™ßZúÚ¹Œž{Ý~­~Oôê)Ö_àïÖønÿnÿK5úh~6 –°®§fâÑڮǖuÿÌÈMù£d‡æü\cÿê¸iÙ½º= .Jñnm—'hçôK¾>3@ ]òíÇoÇÄÚWÄX$XÛt›äýŠ>~DÇ ÈiÉ÷7èL¦±OöÇ÷MÖöK’·9rn3ìŸÓïÝ»öâ¿´}‘¿›â7ºýþãýîÀ Xœ5[Ÿ×Þ¹íò×ÿþ1ßÿ#÷8á/ìDÏüÁçé9>>{ß‹“ß‹ôó3}þ¾üy~Mm~|ÑþýÁ5Š ÿ¥¸¿â7ºýÖþ¯ú=ªóY +ˆŠ“õ®u]xë‰X›ß”?fÚÿú»­üEõõHÿ'Ý•ý¢?€¿"çÆÚ–˜™?¤±8»¾”ÚÊç§üš’>Lú°¿ý]"-ý™|éÁÿÖX¸¿›â7ºý–þ£F¬°;Ö¬kÃ[ÇHÄÚü¦ü1Óþ®˜èÍ_­ú¼Öÿüìüåüm剿]ñõ +vðÇ_/ÅLÎo+6¥ÿùû“Jz%ÛJíÚ_ŠÑ(öÏè¯ÎþkÆÉ­üÕ$Jü¾<þVó·¢F¿­öcglYׇ7èõyÔü7ÙþrxÉ_¯çoKÿ¥û툵›±‹¿üž%^Wü>ã¨>=N1-éÏØ¯Ý¤ë¼Ù?«¿*–^;Á_kÜÜÌŸÆ~Œ¿wøCXaWLY׈·Žˆõùmù¯§ý1à-Yôÿëþkíß7àôZ©î/ñÛËwïõ¹o5ýQû5Ÿ¡É¯ñfÿJþvæ×ÝüiÇÐÍüiÄ›ÿkù[õ^÷Ûjà vÄ‘ux븸¡>žÿ´²ƒÿSù;Bÿ{Éß§ýåïó¼ð—_Sªå¥øì±y—£ö§ø¬Å(Í›ý«ùÛ•gOòWg·ó×oþcü­ç5:`‰Õñc]#Þ<.n¨Ï#ç¿–ìä~Uþ¾¥ÿ½äï“þ¯âïs!<ðGñU“¯ï¤€@ @ ²IRýﳤçJµ|¾'Sz>éÿ÷ßkêPíϯ£öóëùµ|?ãeûWúo±'¾›?i_ìVþ"Æotû=û¿ú ý†óB .¬ÏroÖýÇ×ü¹óG£ý­@þŽ“¿Oø¿ÓþOxæÿa~ÿiésø÷rûJ~å’ÿ–dDûgû%­zzG¾›¿Ú˜¼?Œ?ð—_·£F¿¥6bÁº~¼q X÷_^‡§y«¶N¸!ÿÕÚßÉóÍù{Öþ×ýßiÿÇ1¢ð—Ö—tÍI~©m¾AkJͽÒßÔžì§ÏÔjíŸíÿ“üíÊÏ»í/Ï×øÃø{‹¿ŸE¿±NbÀºŽ¼-æ­û0ÏÿÒó·å?Þ>éíªe´ùúátþÊý?Ñÿ’X®_$ÿGÖ/ÞùÛÏ·óGßÁD}Úª÷kmñûó{qÿÒßÚùíOH÷Èùñj?õmÍþÙþ?Íßæ5Ï6ûKcþ5þ0þÞâ5:p¬kÉ›bݺ“Ðü9SŸGÉRû_ßñ´ §óßlÿçïñµXX¯_jþßÊߪø~¿‘ï§“Æ +÷…û•_“ϼýüì¿g¬y±?m—ýþïÌ×;í/ù×øÓÆ/Æ_|þNÖè7Õ.€_ 6_ëÚ<Ÿ«FבòŸÔþÊúÜ"ÿÍö^ßX¬?<ûÿ +£ñþܾ‘øNzù¹¿$9oùó¿üšš}°ÿ¼ÿ»rö.ûKcýUþ¼Åotû=úÏkôãöÖð Ôæóð\›këóHù£ÔþJN­óŸçþš¿oæoeÌßÎߊý'îCÉ7I4þI¾Â~[ÿwæîöÏä·ùó¿Ñí÷è¿Å9ú­5 à¨Íï®Ï{×ÞóG©ýÜ"ß“¿oåou¼ßÆ_ú¿%é=ñ@ @öIïþý>IÚÈ/._“$éç{´‡@{¥}Ú·±ùfû£ø¿jŸ}‡ýµ=9ð‡ñwVgè7ŸA@DX›Kó§vpCþÚßÅñ¬ýôÝU^ò׊þ§ûqßFõk6s9íþZ1<3>¢ó7Ÿ¹_Z¹~.ù5Úñ1j¿Ô®ä“tûs[£ð·ë}q«øÓŽñWùÃø‹ÏŸu}>šcX‹Ú¼4ŽêG̽ëYŒÚO¿ûä%­êòm4—ô¥¸æ×œô?š8žÑøOÉvÎ¥dwÏþäÇ®ú Ö¦Wûgæ þvåü•ü­Ìo·ñ·Ú© Œ¿½ü¡>À¢6¯ÍÒµ­{Ýÿ²ç·aÄþtHõAþ™Xëüµ²>_¡_³EªóNù™¿F8—¨üħ†[éºÞó}~ßÕëkÍ}Fãs§ý«õOðw"ÿ¯àOÛàãïþ,jô‘| +ÀXÔæµù¯–Ë5÷î˜?ÿ€uþ;Éwý¥ï¨ò’¿fû?ùBßÛµZŸì’j»SþßÀ_-–yÿÓó-½¨üõHIWòkEÛÜ—•ßÏÇï­ÙGñ`ÿýSüY¬ Fú¿67¼ÌÆ_|þð{èð6,òpmþªéH¯ó¹E3JýÀ_Û‘?>ŽÐ²ôõHë“ú¹í)×îöÿ6þJqÜ«w -!ýÚZº´?žëi_Z»¯®´í{²¿ÖÿÞù;½oÏëô–ý=¹®¶ž¸•?Œ¿øüþúèZ€{jóÚü×Ò˯©ùVš?K×—^ëÉŸ`Ø™ÿ"¬?,ôé¼Ö‹ÿÑø[ËÑùëáwD7ñ‡ñ‹¿gè½çFèá)ïñùOº†ÏŸÇA¿³œÿÞrzÌ%žúç:K«ÍýôýS=ç‘%»¹m^í—òonÛ¬~tÿ£Û?Ã^ýçíð{JýÓó^~/Ò—¾7 ·?—·_ò_²?õiúŒ>åŽhö·úü•Ū>­ÑÁŸ?ûo¨Ï &¬kòÒü÷y äϵ¥¼QÊO4—òD+ŸäóëÚLG´_ÊOÒ½YL·_Ò—rãˆ~þJë—økGïü•ÚœY_–üKùÙOË&®Ïõj}Fõ½W?’ýÚþeû£ÔèIÀŸ/ûo¨Ï <Õæ/B›?$Ý’Ÿë¥ù½çüMÊ £õAÉ–½ÜO+û¥öGîQÓ÷Ì_©ý—ø«gïüÕ8©ñÛ{?þþÎ’^iî+µ_³ŸÎð¤ßŒ§ßžól¿¦ÿÁ_û~§×/3÷~ì¿}üá;â &P—ŸÃèüÏnS¼¾UõäÒ}gê£Z¿hs™¥ýyû«õ#ðÇÛ×Þç2þŠðÊ_¾¦kéõ~¿¿çˆ>=¦3¸^ûóÏ„þ¬¬<Ùßêð×gÿ©µÌŠû‚?{û_¨Ï &P›¯Eþ“îá)péÇÙüµÒþ]úQø“>#-ñt3µ¸õÊŸ–/éûßOô/i~¿(ŽŸ3E³_Û>øë·ÿÄzfÕýÁŸý¯Œ?Ôç«}°ÊµZ¨Tç×êûÒ½øãõM«½Ø_ëÿYýüÕl,µ¥xõÌßWÑ®/{Úܵ¾”ì—®dO}þæíßQ£¯>×çìiüíªÏ_]÷€506ë°ÌR®Ðˆ‡óÇô·§Ÿ=Ú¯©O5úQù#xü–bùVþj±êÁZÖ$½g@ @ È>¡÷;P½þQì•^'ýü÷ôJ:Tûóë¨ýüz~-ß_xÙþ×ýßiÿŠóÂÕçç\ÀÆß +ÿq~Àíð–?nÉ=Üätû_÷_Š]OöóßÒÍï?"-}îÿ~(n_É/úí&+ûùç‹zí_Ñÿào/Þktð‡ñ7ËßÎú5:–@þÛŸÿFøð’ÿÀ_ìõËŒý=ñiÁ_ºG6ÆŽñCý›ÿŸôi]¨¹—µýùwsæöK¿%µË~ðw†¿Ñšdw}ž×èàão”?ÔçÜä?›ü7ÃÖ/öüôß šØ´â>³N}Òª÷kmñûó{qÿh¥¤Oû+Ò=ø5VöçïQ±¶ÿÁßYþ<ÖçT£ƒ?Œ¿þðþvnòŸ¯ü×âÊ:ÿ¿Øë—Yûkq鉿‘ï§“Úâ¾p¿òkr~xûùk=±vÒþœ û­ý•?o5:øÃøõ×{Üw¬½¸iþ¡Ç4ÍÞùÏgþkñ†õ‹oþvøï…?)&½ñÇûw„ߤ—ŸûK’¿ç>^ò_S³öÃÿÓökj”SgèþóZ.{êó™56waÅüÙºÿ ù#ºý-ýVœD÷?ºý/û_ŠG/ö¯Øá>”|“„·OëýÒõ°þ{±ßS}~ÊÿZM¿—Çêsrx?K¶Þ’?¢Û¯¹NQý¿›ýçqhiú¿%_ßù@ @ d“ôî/$ôûp$i ÿ½¸üùü’¤Ÿï±Ðí”öhßbÄfn~¿ÚÞ†$ìÏûüùç/?K'üð§Ðü12÷Òü;;׿'n¿4–ìŸÕ÷èÿ+üµbüùæo…¾ÖþõCi¾µ^jýËýÒö3×Ï¥Äg­Gí§õ(¿Gî NòßÊ~ÉNð矿ӵ9É þ45z>?Eäïæñ‡úb 6?ðçÒž^þû ùúPó^PiþY1kí—æ¯ÜþY}ïþ¿ÆŸ"üCùÿ'ÆŸv­#IOÿñÀËÛ/Ù©iÆ~­÷/üÿžýÉ•ü´úUŠs/öKýþbðgQ£ŸâO{–™¿Òø‰:þ4œ¡>ÇvmÍHõ}VQ»>–ÖÚ«ò¯ÖþÚüÙú.¥ÙúÀƒÿ¯ò×Qü•¿^ýÿOÕµù×jý©õO³¶”®ë=ßßÁOþþŠRL•b׃ýR¿‚¿xüYÔè'üמ¥Gç/úøÓòÔSŸ¯/GH¨ÿÚ¼AgxI>…ïÖÞoWþmÍ{»õ=ûÿ2­ñþ|ó§ÕïñÿdýÐw»×Ÿ-)íyHqÑ£ßòoTEûô˜öÀ"Ù‚¿ZüZû¿“5ú)ÿgjôhüEœ?{jsÔç`‡Öü—ÏÒü‘&ôge}°jþÔÌß-û[ó߬¾wÿ_çO;>¼úÿ:-ýþ¯h¿7ævÚ¯õ¯Äß/à¯õØ'íY­¯©–ðbÿèþËjþjs&øëëÿÓïußíOýwQæÏÞÚõ9Ø@;ÿIóFzÌçV®ß;îÊ¿%ûµíê{÷üýyv¬xòüùðV$Öv¬?µþå|ôˆ×ó«õÁNû5{U'øë]k€¿6žjôYÿ{ëÀøó:ŽÔå=õyoí@½óŸf®ÖÇ=sÊÎü+Íw=íè{öüÉúÚ1cí?øó3þfõGbmEûÔ?5I@ @ ²Oòßà¥ß×Õî‰HÏ'ýÖPmß%×§³›žó%ök~ßXºf¤ÿò× ðW×ß}޾{ü•ÎÉ[g¶·ðw:~9šþÅù9¬Eï˜áó'M:'‘Æ?=Ÿóç\¿ô|¾&¬ép›¤ùÿ„ý¯ûÝþYýÖôîÿëüú_’ë/)¾N®?óþ-½>ã×ç÷‘Ú§u<N«oa?'ml­²ßÚÿkð÷×kvÖè'Æ_­FÔÖ‘‘ù;¿9ošÏh8@}}ù¬_ß–ÖÕ$ôÛMµù»GZú|NâsI¯ý4OÍØoé?ÿ~/ðgÃ_m‚?ÿüõø_ê“ë/)¾N¬?Kür}Mÿ®Z_ò¨Å+­#=Ùϯ•l™íÿ(üÍ®uÀßþßcÛ=þZõ¢æ³é‘ù;¿=µy‹ÔçÐÍ|›Ö÷|üò¹´$¤“Öà´F>YÐ<#Ù/ý–Ô.û-ý~økGðç›?­ÿÖõŸ[;ןRÿäöôú×£Ï_—ø©Ý£¤om¿†麑ö£ñ·b½ó2'êô]ã׊ÿ™¦È‹ +í]½Î$;n­À‰ƒà&9pâÀ†7Ø÷0ÚípxI‰Ô/%Ä÷uw±t¨#‘¢ª»ê¯|ÿ÷ןú?ÿþëÿ’¦ã²þ÷üë?5½þ¾_ï—Ž£ïÓ×Ü^³eϵ¥}ï²}­¿ÿí&ý È'ÍOm¾¦¿û˯ùžçÖô3üœù˜4W“½'Þð8ÆÛ·àÿϯ²ïÁßkßë?ø‹Å_m~‚¿ØüÕü÷¬ÿf­¿¤1%Ùk854{Þ×RÿXüôÚKcMóË:V#áç<Œnÿtþ¼k©.x•?kÝÔ¢3ç_©v¤±ÞR§ŸÌßèùWꫨÏ!1Bç¯;¥ùKë>ÿégÕâ_Iéù[ðÓú`þÝþƒ¿˜üYæ+ø‹Ë_ÍÿÖõ§¿f¯¥ÑëO‰kí3¯¥¾ÔÎï±ÏkKÍ~'þÚqÒç½øoá¯SK5ÂküͬÑgÏ?éº.çÏ[§¿8ÿ,×ËKü¨ÍQŸC^—<ó¼ÒÖ—ôs>7¥õuiþZã‡UoÀÿºÿ§ãé¿gþFñü•ýRÿIchôú“ûnñ¯ä£Å¿š½u,å÷èX€_:Þª^ü/ðÇç€õúï+ü­ºŽ¾sþYëô׿_íš¹•¿žºõ9ò{}^Zc–Öž<~ðõg-ŽŒ¸þu:þ×ý?ÿ ÿ½óüÅâO[{eóÿ+×_¥ñ£õwM9þôº¦?Ó…B¡P( +…B¡P(t’ò}í·ŠY¿Ÿ5{m_FSÚfË98æVüÒ÷>¼í·œc~©ï^äÏòí×ø›y==Êü«]K?™¿šÿ-~kþOÈSò¿ÿõ/ÿœOééuÖ<ÿyŒÈ×BJs7Íï¯óúÔˆü½?íÏ^ûÌø{‹?ï…¿Q1q&‘ê?˸Ñì-ø¹/Ò{Ü?Ïwø¹²=ÿþe>–þåÿóñÝ‹?sÔ‚_ºïÂjüÒ<}™¿Zþ3kôÙߥçœX¾ÛnùŽ÷éó¯öÝ~ïø´<#Ú¼×âKžÚ<¯Å:kÇjö#ò÷NüÎV{ð÷&Sþ:þ¾ 2›¿(õŸ·/Zñkœ÷¬/µþÍã³6®$|Ù~þ?%ü|ÿeþÚ½^åO«Ñ_ãow½íÕž:ÜZ»Fä¯×¿Öñ‹úé-_ò÷¤ù_S)7¬zòßnüZ|í±oñ7rî÷ò÷M¿o¡Ìâ/Rýçì’&üR_ÕæGÍ7é5ÿ~§f§aÓÚÿëþs-Õ¯ñ÷z}NëôHüò©eüÎâpRš‡@BIë|ÞIëai}l‰ßÚyGÔG3òßJü¥øÚjþÞãoVl¨áÿ”Ùó/Rýcí +~:§kóÆ{>~ÎûüêÉþuü¯û¯©¥žx…¿Ýµw„ú|73ö,ü¯äpM¶‡@ö‰”7¤ºhdünµÑ~-ÿEÆoµoò·;–D”þjçž1ÿ¢Ö?Ö>¶à—ö/¤c¥û¿¯˜Ÿy=j¹¾¿å7‘ñƒ¿r»­uÆMüí®»£ÕèšÎäoÖ÷"ò>t±ž<ë(ú™'J±dW}TË«ñ·^­Ùƒ¿÷øÛ["ÈHþ,mžQë?kŸ[ðÓc´>’êæ™ñ¥âçdüàoÍï°OæowÍ}RNëôþFÕÚ­µyþ|'CÈfáã[‹ÕzýqDþ^‰_‹Ï^{ðþ¾ 2’¿ž¶FñWjÆü‹\ÿY¸Ðü­éÏßL@¡P( +…B¡P( +¤©þ¦û Ÿaª´W‘ìéóë4›\ûóãrûôx~,ßÏxÿëþ·â}Í02_£D¼ŽGï÷Ò5þzλ›/\;‡Ü"–X¯ÅßRìæùŸ‡ÚKßç©)Í¿µkJ³ð[žo,“ŸoìÁßkþÀó¿WvãËŸÔY½þŸVÿhƒFßׄçߣ5{îÿ®&ǧÕuT_Çÿºÿ£ñªÕ#ñ7 ïl¯×w눚Ù2N«ËGŒ-$‚xâ»w}m´œ¤ÅïÒïYjö¥ögáçëY©­Òú¸ÿnÿÁßÙüu†íø#ó'uX¯ÿÑê‡ZýÃý¯áOçÈǬôö-Å—~Ôr®ô7^7[ñ÷ö?ø›Ëߌšf5ß`Ù]ž -ü¡.‡@öȈ¹=£¾Ëq¡”ÏxÎÒÚ·äQøù±aíêÂßkþÀŸæk‰‚?*¥~óøJýP:—eýŸóžÏéO¼-mÿDó/ý¥ßQàöô9ðÚ9ó1ñÓï³jçìíð·ž¿™uÏ,ÿ¿E²»n\Y›¶®åµc£×嫯²J,±Ø2§iü¥ùŲ¾Õâwíš½µýYø-µt\Kû=öàüÕøk‰)»ñGç¯Ôw5ûêúÚS¿µÜŸNj‹ûRÔ?éþzž¾Ž†Ÿ~waþÈþ¿À߬Zh–ÿßbÙ]KÏ®M=|Þä7rºÔækޙָÌó_Ëiëfš‹¤ÏKëT‹½ÖþlüàJü–þ÷ñç¹ÞãåϺ i\#‡@æÉ¬9”ï¿Xº¾1"þÒ|Ò’Kù©†?ç¿–ÜÏÛo]?ŒÀ/õ]¯=ø{³€¿6þ,}ûjý`©/²ß¼ÿókú>?&~^ÏR}cáFâ‡âäÿ—t5~oÿƒ¿»øó®/­ü¡ž›/¨Í!92ciyDŠßܶÃ¥ü£Ý7È“µüfÁOók-_iø{×#ðKëd¯}«ÿàïYþ\þÚù+õë«õƒåütl•ڒƉgÿ@:·Õ?ºGEÇm_ßüÜüõ*üÖþçó7c½ÉûõÞA]Œ•Ù±RË/9~kçÐò‡Vôä_)ÏYñçÿkkˆþÞõÃüµ{)õÖàüIþ{bøߥo_¨jÊ¿Ÿ q¢qï½¾/ÏšÚoìùø¬q#·Oÿƒ¿³ø›Y¿å6QîÔæÈX=ŸjyƒçZ®oVþõâ·ä½“ð¿îÿéøOòß«¢á?•?kß\?ÔÔ{<Š#©{zŽš}ëçÒ¸å¿ÿèþ±ù›]Ÿ'ì3Û@Íèô/Ò/³b˜'”êóQùÃ’iî‹–ÿVàÝÿÓñŸè¿'VEÄ"-ý}[ýPÓÖóçý½´4ª>ÒxÐöQògQðƒ¿{ø›]7¯hµ¥_ÐoH›¬Š[¥øm9~Uþ•òž”¹½÷wrÑð÷Ú{ý‰æ?øÛã¿'V¿qüµöû-õîñ1»}‰Ÿ‚üÝËßîZ:’ºîä Ù—´X½3ÿJù®Ö~ª<˜¢áïµ§ß}=Ñð·ÏkœcùóäˆÓë‡Ü?%ýù› ( +…B¡P( +…B¡“4ÕßtŸã3ì/”öJ’=}žœf“k~\nŸÏåû /ãÝÿÓñô÷µî®­Ÿ†¹YvÇ YŠü‰õÏ øoñ¿£NÀüf9¡ÿù³éù[´fÏýá÷!äø4¿¨¾ŽÿuÿOÇ?ÓÿÝëÌjõÓðB /ÉîØ³K‘?áÿ øoñ¿£NÀ +–ö­¹ã„þOç clÙü Ø(¾ü\y+Wùø(øÓ{I­ø{ûü¿Vÿw¯1gé…?ž_!»ãÍNEþÄúü…áOð7ÎÿJÿÓs™%rÿç߬çsÖêýR[üüü\Ü?ºÇ ÙçûJçàÇDÄŸ÷WJø{ûü¿þï^gFªƒ£ãƒ@ ¿Ëî8A‘?cùõÏsü‰þæøï?¥üqBÿ·ÜŸNj‹û"õ«äo?ï‹xÇJüô» ³ðGöüÇßî5æîZ8*.R–Ýñ%Š"ÆðëŸ÷øÓbøïkû?ÑûŸãká'ÙÑëþ’RÜô}É?~L ðÃÿÓñGð÷úrW-±ÉîøQ‘?ßñÿtü7ø¯Å¦SðGæo~‰—èý?bÿ„û ù&©Å?ÉWà‡ÿ·àêÿî5æìz8"&Ò&»çrt-õòç¹þŸŽÿ&ÿù¼: Dþ^š?éuMÓwâ¡P( +…B¡P( +…ÎSïþB~>\Ö´@ŸG?ãÇ$Möt"ï!ä½€Ò^‰åžx¯áÝÿÓñŸèÿîë>/èÔ ‹ȃ²{NGЖ~‹–?óùò}¡zík×訮öŸû!ÿƒ?Òœíüõâ?yþXû—ö«µ¹=UzŒ•ßVüR»’OÒ1ðS¬àüíào÷:óví.F ÈŸd÷¼>1–DÌÿÞûvY쥼ÌYé~nTÄüþ|üñ9þúø{µ~ðøWòCÃíÙ?ü˜ÅO©Í¨ø{æøÛÿdþv¯9_ÐÞu5ù]vÏiÄŽ}Bó¿v§å?þÿªõCº—1ÒߤFÉÿ#ê»ö§ð'GðׯßËõƒÕ?ËØ’Žó^ßçç]YÎÓÊÏLü£íÁøóú¿{ ú‚®_ÅB ÷ÊîùŒ8±]þ^/åû6ik©6Xµ~Ðî-ÿ·®_Jýßk™?i0‚??/×5Õî'õ«Ç¾æ_«½Ô>í3mhüDÀþÀ_$þv¯MoÖõËWälÉqIúl÷|¦*Å[Ĉó¥gýÐúùIë·•ö{ª gû_ú¼4^Àßþn«¬ý[òEÛHïyðI}7škû‘ð—úü¿]üYÖŸ+ù›±†ÉÖÞÈxásŽ~¶»&·ÄH)þ!.œ%»Ö'¬ßvØçëµ;ý¯ð7–¿ëkÿò=«FRÿÓÿ#ã·Œ/ð?ø›ÏߌuóHþp} /µùwJ}®áßÝ¿ŸÌ\?œœÿO­ïZmkãü­åï„ú!ÿ6¢¤é;óP( +…B¡P( +…Bç)ßHïñ=®Úg?÷ˆª{@|€·ŸÿO{&I=ûƒ/ãÝÿˆø½šì¥ïàä½²RÛx¾üŸñç÷­×­Vùï¹Æö,7ø9KJ×?øÜÊsRŠ+´”?ò{¦÷ìñ¨ÏS;ì;꿵‘Öý<Îp|ùŽ77ïki½ÞÊŸ¥}O•ÚïÅŸëŠÒøk?£ìgúß3ÿ +kŒ?q þìþß^?HíS®µþ±øéµ·¶/ù¨Õ—ð¿îtü^õÚk±¶§ý’¿†HøgØSŽ{Û¿½>¿Áȹb™s#ãGoN××¼ý|]®5~}Š7Iý'å~iýÐË_¯?3ñÓï.÷äÏ™ö»ùóâçÜ‚¿6ÿ_¨èþJ©¾ÐÆGÉ¿íüûôÿëø_÷ÿüVõØs,^{­}k_k¹b7~ Û(ûRßXýG}Ì)¾´Ôç-1$ÇÏ”<ó[Ë<¿H1³„ÿ;HFõÿ(þ¤µuVZ÷Ð÷{ø³öQTü¯ógÅ_âôü»ù{­~ \[ü+ùhÁW³·Ž¥üÞëø_÷ÿüVdÏ}.õg->®Æo‰Å{¯¢>×ëóÓü€œ)–973þð5´§F·¬¯KyL¿“‹øWçÎ×Rí0‚?kßFÅÿ:5Œ%OÀ¿›¿–õwÍo i½kÁ/aå˜jøÓëšþ¼Ï +…ºôÇ?–én_¡P(zŸ"A¡ÐÕÊ÷eøž…°÷ó÷š½¶/£)m³å3ðÃÿHø9fúÛ Œ¿Öfiïã¯}JÂ_ÚW¤íKï—üŽ?‚ÿ­¿Qý‘[ü€œ+|þñ1˜ž¯›Õ{}'ÍjŸæ4}^/ýŒ“Ôó]w)¿ðø%éŽy–¯å”⢿§ÿWó—×<ÞÏôßÊATü¯óÇñkÜ‚77×µïõ×Öš”_Ëwø¹²½TËP ü=Ú>ðÿÂÿºÿÑðKJÛj‰~~þV{©ÿ¥Ï¨}¿Høwøß{¿¨“ëÚ›|œ)<~Hõ¯«jšç?+ZLÐâGmŽÔÚ×°æ=×P±ôg ¿·ÿwñWÊQ³üoåú°ÿëüe{7 øó­¿ø{¼ýÈõƒ†_ã¼Ç?­³µq%áã×þGÇŸ÷ër|-a.ùÁýŸñ|ŚΨÏgâŸáÿŒúû†ºö&_n’×øàsV«}[×—š½¶®¢¯©½õ:ºK>r^¥ö3¾YýïÁ?¢ÿWóWÓ™þ{øˆˆüÙøâ~FÁ¿›¿—ê­¯jý[óMzÍ¿_ ÙiØ´ö[ñçgžŠüÅÃÏç^Ïó!µøP:ÆbOýôÖ§ûÝø[ìwÕß§×P7ùrºÜ<Îjb©Ï{×§–µ¥t>xüòÄ+ ¿”§fð ÅßõAþj:Ëÿ|n/Qðƒ¿2šQðGãï¦úA³·ðæ½?ŸV«xìóÿ©O$ûü?>.~ð‹¿Úùzú?ýåö4®ñþãï•ì[û¿fß‹ßSWxÚß]kßX7ÝæÏiòÚx“DªIk5«GK÷¶äÍÞ·÷Ôå´ýR¼ÁIÏú¡7®âoÖúÉÊŸ‡ÝøÁß/î,õ®¿oçï¦úAïÅëš^¼­üæý +Ëýó=øküðc¢áçòg©çùù-Ï8íù»ëÞ™ªùcÍt›?'ÉŒ±û(R}*ÍIOì•âŸgE?+åŸÑ1GÃ_‹Õ3xÉmZßGäO:žÿ?º¾ëån~ðWß[‘|Œ‚?"/Ô|_ÎZßy0Ïò¯êûGü³høÁß=üÑó”úß‹">rw½¼Z5þn¬™nô)ºÌ»ß"Í?é=Ë^d)þI±Þ¢µø?2Öxâ·ÏGsÓ“µþÆŸ§ÿ{íküy8\üýÎç#:þˆüÝX?äú¬¤?ï9…B¡P( +…B¡P(t’æë9d§º¿QÚ«HöôyvšM®ýùq¹}zQ½üiöÒ1µk ?ãú9ézíÉ׈“ÌÃßÁb½Î¬ÅOë5-ÿÔæ{éºIO¼™…G¥üÕŠ?<—žg¼¿‡›Õø_çÏ:O¢âßÁß­õ=6]çøzë‹ÒçÜ~<ŽOókäó¥wãïíð‹¿Úñü'<_~wIùøÅŸ”ùý·AN© o¨CWŒçï`©ù&ÍG-ÿHñSË%Öø«å¤l?"þŒÆ?ƒ'Íþˆüñϵ{=ð¿¿•£™øÁ_9¿GÇ¿Ûêéóžç3·úG±Q|üYÅ¥s¥¿ùz_üù7 Vü½ýþbñW›ü'<_~wM¼K¥±Äû7ßb9¡>¼¡]5Æ¿ƒÅ:é<ã9K[Zâ÷ˆú …³ÙøgpÕÛÿQùãZzÓnüV®fàà0þÄùÿNþn­´ßÀ·<Ÿ™·¥íŸhþ¥¿¥ýºÎÕΙ눈øsß–ð÷ö?ø;›?ªüû嚟Rœ’ðKÇH¯5{íÞ'ÖÒ-þׯ›4þ"ðçY#{—$j­xSºrÞ|‡‹·>çñŸÎSïúÒc/µßëVàÍUOÿGä¯vLDü¾Fââ þŠó#þü½\?´ÜŸNê+î‹Æ÷·/}O´¤ÑðÓÏfáì?ø›ËßêçË·ÔÆ;ñ°¯áׯßnÿ=kãñÖZ4Z?Gklâk->ÿøçÞøQ³—Úoål5þ‘|µöDþ¤ÏKuFü-|õâŸíÿÿc×ñ í‹ +í];Óõ8 NA³04”T4Ë@Áÿÿa0ÙùÌj…î¾ÉŽ<£9ï9‰âGz䋜¼ñÏýé??ÿõ§ÿüã/Ï/Ÿíï&ð·÷óoÏC‡BÓô¹ú±¼ú*™ñϰ¤¾Eà5¡>å;Êþÿþ×kàúá1‹hø1>¯­¯þ«÷¯?ñöÁãØß{K¾Â_ögÁ‘¨~ÃÉéGñ¿ýKûûÏúƒ*Ùð÷ê{íÉÈßCŠã'X,q‘YžJùÄW4ûp»ãú©ýií_š s×oúüø·]øGðõVþ,úm’ ¿—·^üÙìÏÀöqfü;ùÓæ?Z]\ý0?È–ÿŒÈ/° œm”X쓸.üeÿéøgäwœ ZýoîöŠe®›¯þûÝcSVþ¸kÂcѹõîüúö\´|â/aÛkmÉ2¿”æ}–ù¥¦ßÎÑðÃsvãÁYVþ°>…)+þ\1ü”/3ãßÁßÌùw¦ü¡Í?%yJJJJJJJJJJJJJJJ¦Šw}áÕùçß÷?y×Úgû üýÕ§ÖxÚZ·ÎÐÖ-"˜oÆÿuû³á—ô_ÁúÒ:…êsçRëÐN|œ»w#édÁ?Â~ø{‹¿Sìçð?ƒÊî{ß_¸_\>‰ËýsÜ¿ã{#Ôøó¶Ií¾ˆÔÿÃú<×î£gÂ?‚»þ,ö[õ±dÅÿl._äûàü«â÷æü¡W¿Ð·V?c}(Ÿ\ý–s9}ª^Ê&êœ ø!Öâ/?Øü¸Æö·ã\^Ç=äí¤çB%[Gâ‡ï؈ôo½úRü­°¿‡¿Ùs§Ýyõí¹hù$^4û¨y5æqíßò,%5~â6 Ï…Ÿøo®?n9z&ü£8ÔðŸÆŸ”†ÿ¹ dåÚ-þvį6_º-ˆÚ'ÙÁáöÌ/);fñ#Õ™äÅßZüxmQºÿIÕÛrKØ?ákIu¿Ÿm½²õ/sv“½þö?ÑVüï¹Qü#ô¥ø‹Ø?ƒ¿gSÙWßž‹–OúŠ–ŸSc„ô›g~Iõïp~Í1Týío³LøGò¨á?…?<þ߈ÿ9¬dåãÌ+ã÷KùCÔ>KnGçÏäÇz(?3ñÖ/þæàçÆÇöò;üþ~J÷a?Íù¥õƒ-'´Îï˜9;ig¯†¿½ŸLÂßÎiø½ñÓ«ñ¶?ÂЧmewNý…\´üÒW¢¹,×?XÇîzøùNN›;[8óàçÞ9 +ÿJ]x³ñ7ÿlþzñ?”¬üQ8³Åß(}Oü~)ðŠô~>‰M_³/ªOÕ}ÆÅ1ÇOüÅ_^þ´\ ëããÞý©çœ8é«ãú1ö‡œ¡Ïñ?Â~PÿIPv玷硻}’Õ/£ós©ÿÝ=þAÝ·¯xõ­}µ¿´·Äß΋àÍ)ç£Sø‰3ñkú£cG‹¥lü5œpŸÔ“ø³è[â7ªZþÐ+íú’-OT~b-n~Û˵þLø%ÿ{ùÃ:‘ý!›î÷zöW‘›Ÿ°?¤5þ{ôwÚÿ$*»sLj4þNÈEwû*£O¼ÅšÃFúŸÈx6jÿÅHßÉð9ü3xÅuœÆß(ü+ø›‰¿ø³ñ§ÅñwGþÐ+0¿‹H¦ûÇ”ÿ©xˈß_Åß^ü wÈ‘û+Ž˜£cû¿¸¿ü.ûŸÄewî‰álùù‹‰;¶Ûg7äèÖ~kƒZÿñ~÷ô)3òO ò)GÀÇ¢øgp{ =øWñ7 ñgãÏÿÅß]ùô$ï3ó%%%%%%%%%%%%%%%ó„¸_c^¡~§®©­©àúá}(í9R +ïþv»ñGý_üåà;æÙŸÓÖʤºßk{î…¿Âwêþ8~zõWÛŸñžåîû·Q¡ø;é^ñnÿeõ‹§H6½ñÐÚ$lÿÒý“v.÷{ë?4®?€ýw.¾¿Ò~ëáwþßÂßñÝ~/~.þ¿ÆßÍùw}è_ªîö:õ5^<õ¿Â½«ÓÇ|Z¹Í‚ßãÿâ/'~©~©­Cû¹:^‰ÌÁ(ìÚy~­Òðsý§+és\{õ£ñçµ?k.´;/Œ +Ç—›´cO¢²Û‡XžC‹ÖJû+DúËXÑ-x~ËÍ«ñøÔŽj;³ñæøþNÄßÛ~nj+ðSñÿ%þ8NGÎߤù»V?–˜¤ô#û3kþmŸd#‡Ÿª‹²Ï‚ßêÿâ/7œ-ÜoRÿ4c¾¯KÕ¯ùÛá韩kÈÏ%ÿöè[ãÏkÆhw.8"ÇÀüQçü¥)»}ˆå9´hýâ;¿lsì•ùA«?ÔXÈ]ëý|çàÿ¬ödÅßþ§6škt–ãùÛßÃ߈ös[û[_ŠÿÛùûRþ€ë‡Ç9›,þµêsõk~Õô-ÜPçeí¿øÛ‹Ÿ:OúŽñCéSy„z>JÓÁý›§>ÊžxÕâw”¾7þ¬’1ÿÙŽÌ ×>þÒ”Ý>¤ä9°hýc{S›Eú®ÿçæƒp|’î?Á÷Gr×lï‚øµqaf|@üÍ·~êýÔ=åþ²à·ò׃ÿÆö·?ÿ·ó÷…ü×ßþÆï—ÃÇ5¿{õ­õS6RmMz?6ÅGvü£ê/þöáø¿gŽ$]_ê²°œ}”ÿ5Áudx?ûÈø“$cÞ³;ÿ[%Ðÿ“'QÙí#.ÿ:­xúÉHÿÁõ_ÔØA?0? öwÐú¿ÕæÙ1ÂáoÇg´¿øË€›…?³ýÙùÓÚÀÍü}!ˆìÏlµOÂÂ]ߣÿþÍá×ꡎ{량ߊ»ø;—?ŒÅ;¢®5¢µÆ +ÕWyꟅ_ŠŸ^}Oüi’-ç17—Ö—¢q¾BO²²Û/ZîuB‘8çÚ´iý§ö^ 8kó3iü ð[l¦ú¤[âätþ¾ˆÿëö{ñKñ#_˼û3K~·àÓô­±Ô~£ðK±-IüÿùùãlŠä«Ö?±Í’?¥þ%Z¾Æ³U¿'þ$É6Æç?íZ;sLªÝAþžDew>ž5ïZ‘ŸGûŸKÜSš{ZòiÃúÞ6Má¿)^Nãïôø‹Ž_¶?Š_Šû›økç~!x¿kò>_RRRRRRRRRRRRRR2O¢û3këJœÀ:#×À˜5ü¿¬güñW9 ¿ÇÿÅß~üØçm=-rïZ»Ãøµç nßRª´~k?Qû“Ü[šÊw¿šóÿˆ{áRýܹO²²ûžy‚˜í*œ-o潿3¢ÿ¤î±´{!R»´¼SšÎþÙø³ÇÍ)üþ¯Û? ¿ó§ówsþ =×Oý†ýëy–_«éS¹ Ä€ƒõ{𿜶÷ÿãöu~ÍÿÅ_.ü¯ôÌ%0ÚÞ œ>öµµ±ò7¿Ä/Å]þHûwç9+ø£âYÒïm+¿”ÃcûOÉA­ë•ŸÓEŠmüÀ2ªÿ”Ú˜¥þvKû¡® Ï™w|œÂŸuüZÍ_OûùRû[ÍŸ%îOåOš¿œœ?P¿q¾¦~óØÇù·Ù§µ +_Ó·â¥ñÓžÕ? ¿ÕÿÅßzü£æ¼’ ã¨ý)Ÿsýü>#¿‹àçê­OµŸˆý;sœUüI¹±äÿH›‘ø“Ú¶ÿ„Ôê Ì_åçsòóÞþÓZÕ/ÌÏqìpu®À¿3>Náª? #ÚO¯~ñG_Ûÿ'ñGwZþ`Á/ùÊ_’mÔwü|§Çaãê—ð·5”ûl’{÷eÆoññ7ÿèy®µoãú鋾¥o¤ÎÃúRÝ+ðGë·êsíÇSÿŽü†‹³YüI9ÅÿÑöCá—ÖÀ¨úoÊÏ{Úß—òóÈÜrdÿiŠ?O…%âËø=ÿÎ9…?œßdâσÿ«ío'Z8™¿ìùC~<×ù~>|͈~û»­H>¡ðÃgúÿfä'~ÍÿÅß8ü3î9Á¡Çÿ”ý°_öâß(}ŠOüàësýî,ü£ê¶IunÃ夳ù³ææšÿ=íHÃÏépõgÎA­¹ùˆö÷•üÜÓKí§·ÿœ=þb‘|ÁaïÿG⟹¿Â üQÿ#}3ôOi»ù³´ÓøË”?ÌÊÿ¬ñB½ÿ}?š´õ +‰_ +?^ç8 ¿µþâÏv.®ù_ë‹(ÿXö ü‡õ=ý<æ©&~+î^}+Xwn¾‚?-Žò'å¢Vþ,ù9eÆTòÇŒö÷…üÜÓ÷RíDÿ© 5–˜[×*° Y𿟳båþ¬cUfþ¾Üþ2ð§µƒÓøÛ‘?¬Îÿà9œ(û<˜gÙGá§Î= ¿ÅÿÅŸÿè<|ð:~K[þÊþ–ú{õ9þ¬ùͬ¹¤vOuÖ6Ñ×OEõ½ü=çç£ÚßíùydŽ9²ÿŒÈŒüœZOÎŒâ›/ÙùãÚì‰ü}±ýeâOj§ñg9÷¤ü§Ù ÉûÌ|IIIIIIIIIIIIIIÉŸÝþn¼Îù÷ßÔ9Ü1Üs"Ý7ÁüIûárø-û S>Ñö^…?êÿÑí63‘ý¡áïí/#Öö‰¿ÛóüüáˆüB:ŽíÁÿŸñqv5iïÎß…ÿƒÿÿ6üÔœdÚùüµ¿¼ ¿Ä?õ,¯WßjÿÌÜÜóÿ3øÓrÄüqõxø“ÖÞ4ûŸ$ꆏ¢ý˜£k¾ƒ>ÄñCùûŽò¿ÿ\ Rõ7.-mÖ—ø„~É€ßãNTüdæ/küàï í/+~­Mdâï ù_»ßðž³Ò¾æ_Ì•+p×Ú®OAüÔ»ügá/þìøñ|Z{´à¯ýåmø%þ¥ÿõòêsø™yKnÞÃÎïR~8‹?Ë:€•?)?—â÷IR4ÿ¯n7åçÐN‡êsçRëÐNî8ŒM' þö¯¸oþϽl ~ëóâø³Þ¿ÁŸ5~Gó;*²·¿'ai1Ôújìhï Æ~Åã§o‘ãwŒÂÿ üU$ü–~b5~ÿ=ú#b*ão§Øÿþ¸ö1‹¿›ó‡^iöA»¬6b}(\¶ +¿ÕÿQýQA•‰¿Lñ7›¿ìö?Øfñ÷¥ü!j¾>•gPçyçW3øÏWpœp±›?å×â/'\ÿ +qR}%<^ûË÷á÷è¯ÊÉßâÉ«1~®tÿ9ö^þ&ʧðZ«xŒüIò$,RÿÆ}ö¸úKªÿœ1~IøÛ=CAñÏÕ­Åß*üšÿGñ73¶vð—%þVñ—Õþâo#ê×ü·¿Õ>ŽnžÐŽyðQk»òÛ¶Þ’tý¥ø›‹ëàçh¤õ(ðÿcàï\ÿNñFq¨=Sfñ?ÄÇIfüP_¸O9¼DîyGòñ“øëÉϽü{}9#zâ$#ÿ?É +×ÿZí§¾{úŸ‘ã‡ß'òâïÍÏ{ñ[ý7Š¿±µ“¿Ýñ·š¿lö9ìŸí?Î'øï•ùyD²Þ?žÁÏLü¸-ùøküÀ¹²¥“æÞX_{å ÿk8³ã?Wçe‘{ß#óò¬üyíêáß»6òÊŒXˆÆIFþ¼ò$+\lµÿýîñÉÌñË2V{ñ÷ô5½ø½ñ7Š¿±µ‹¿ñ·‹¿,öyø[á¿õ7ÿHò>3_RRRRRRRRRRRRRR2OàØmkëšõû«Ï­Åsk*ðÔ§öãÓ$~ËþâÔ9ÿùø±¿$>§­•ÍÞ_óÇq ñ·?äfçóË;Æß¨ç8þ¹öKÕÕÚ/¶svœXc&#šÿ•sÓˆ_k3Ò¸çT’Çô?w.ôaû}6~ê9÷ øgÙ?2¶2ð—5þ¾nÿéøwÙsþÀ]ú—;ÞcÖÇסê…{מE~OÖØ…·ý_çO«_jë°~£$°~í\N¿q†¯Áq ÿ««å}Ïä²ãÙõùÓòÑ(ÿZûåüÌÙ?;^´¸ÉÊŸæÃùi +l?QÑôqâ÷Cáù-7¯nÒön’Æßø¹ö‰Çv/þWzñϲfœ­æ‹¿›ù»©ý¿ÚÅù„Ò—æÿÑù»V¿eþÁ]ŸÃÏñ+åœ{íãb`ÔþÒ«ðãs),½þ/þróÇ]‹ûÍÓ¿Q~™ŸsuPø#ýó,ü»ró‘9ùWø›‘Ÿsí«á’Ö@8ûgÅŒ5†²òçñÿN¿:JÈn-~°Ï›oÚûó!x,”®õ~F÷§÷â§â>ñS{IÍÂ?Óþ·Š?*þnçï¦öWüñcú­ù5>ÃkGìóèãã?Ò58ýÝø-ÜPçEê/þòñ§ñÄáñöo~¿¨ú[+Ùû˜]ø½yoæœü¾âoÀú×~µüwg~ny†"Vÿ[ù_ágƒˆýÜøÇÍÇ p»ÈþôíœÈþô^üTlÂg\#øÛ;“¢ø{õ-ö¯ˆ½üQñ÷þniÅßOŸÈ¸úðûåp,hvzõ©Xãì²Æj&ü˜‡ÑõïÖ/þäú±nD_®¯J¤þûCîÌËGçä0ÿú +£íïõÿÈø‰ÄUVþzãoÕ:š—‡h‚öSc5þÀü`Çþô^üÒzÚü+í_³ùú0¿»¿Ú_ñ÷ÿÇ¡/nË0×Ü1¯}’/¹ë{ô£ûK¯À¯GïÅŸÉþâO×£®áéߨkíè_Wï¹#7‘[î‹~? —ž9e?Ô·ò#µß1±ÌüYümË+|.ñ‰Á“÷§÷à§Úkü³í_‡_¿ñ›ÙþÓñ϶ÿKù¶ÝbŸd£Å>MßKÑý¥gã§Î·ŠñwÜ5%ü9)¿‹Ô¿27ïÍÉqneÉ»nçÏÂçû»e,•êoúRþs ©ýŽ›uûã-3šÿ#üïÎѽ¾ÇöŸ¼?½?צ2à_aÿÊxüZü­à/³ý§ãŸm;÷ ùÃû]“÷™ø’’’’’’’’’’’’’’’yÝŸ9²·î+#öçåŽyðSÏ}xë\c~ÊwÅß~þ0fø¿A ¿V§´ö÷ÕýåWÝ7ï½_^üùö÷”îÃk[öm"݇ŽÚ?öŽ˜/ö2ó§Å_„ÿÝ÷Ñ¥˜´úóg¿°¿Ú½ûÓÃëEÆ¿†SŠÕ™ø¡?{õ{ø{’+“ÞêøËÂßéíï«üÝœ?hÏõS¿aû<Ï2àkÚŸw~¼÷¡?õÞ…Õø©vZüíåoÆþ~|ý¨>åêÔ×øÓêÇ\Su5Y•—¿eD^n±ÿKüqíÏšŸkúÖX鵿'®zã/3‘øÓøß£[Öwzü§q$ äß;ŽŒ¿9þVà—bÝ«?‚¿çð²:þ²ñwrûÛ?Òø‡£üŸ5àðsœ÷äwÒøÜ»?ïü?~¼v²¿ö.†â/íy…÷ûŒüòÁéž¶?d$GŽÌMzòñ^ûoæÒ¥Ú”Ÿ[ô-ñ2Âþñ³b{,fæO‹¿ÿYóó†øÏ"”_Gæ\”}\ÿåi»#ñs±Þ£ßÃßsAYÙø;µýí¿›?ê<É'眯4ÿj¶QßgíÏûuü_·?~Üözö‡äúé‹>´ÓƒÇ«¯ÕÏ[‘“·\bÿ­üiíëk÷ß4}-nFÙ?nìÇÌüYê÷ðBŽ>ÂV¡øó´w*þGŽ–ö;?å×^ýü=—•¯ñwbûÛ?#šž×™ò<ÖŽ|?¾fD_Ûßõëø¿n&üÚõzð[ö_ÀíÚªõ¿¦¯ÕÏ[1O÷æ³í¿‰?K€ú”¿#ø-¼õÚ?væë‹Ï¬üˆ¿àÙ,ëHÙÆ¯õKãŸæ›Ýø­ú#ù{>Rnå/SüZ柙ñ¯àï¦üÃÏÍ5û¼x£üjûÇDñ[þ!3þâï\ü–|_ß²ÿÉûCΜŸGr€Ùö߯Ÿå:¿7?§ì÷p×cÿœ®«™ùóÆŸ•¿òs.΢þã®…ÿÞ5¿–Æ?Î/3ñ{ÆNþLþžKËWø¿^‰ìŸù¥ö÷…üžÃùˆÊï<˜gÆgÿËÏÉø‹¿³ñsבð[û¢ö‡œ=7÷^…ý7ñçK~.áòê²ÎÌV×ÌüYâOÓäç™rôQþ³JÆü º>Öƒ_‹óÕññÿsYùYÚßüù£Î?=hù™$ï3ó%%%%%%%%%%%%%%%ó¤ÝÏi9ücXßÖ*^}¸§Ór|^«žÏÅë_Æÿuû³âÊ“lùèý­‘b]¿·\ËjÄ÷ØÿøËº¿§À5ëÿ¦/=k<‹¿¹wžø8ÎÊ_¤ýPú«ú†^,÷Ñqÿ͉tßÇŸ´.ÇŸvO†;ÅÏùDÚߘÚ¹íoìÁß«?ÂþQü͌寖/´?\¿eñ[Úß­ù<·wf<>KDZ=ø=xg”¯ãÿºýÙðkç[ðïÞ_~wN>*7Úïù_Ü¿gà/óþžW”ÿ±¾”›Ïäoî,’åŒüyÚ¦K~ãWóÇ!ö_î]Á}©~ +_¿eÝ‚»&¿=øWÛ?š¿™1ýÕrsû£ôñï7·¿Ûò|¼­w¿ç¬´bƒøÞ¹Å+–k½Ÿíü,øñ^Åþ^ÿ¹øÓÚ£ÿÌýåwçÜ#çÞ„ÎoÚe¿ô›'¿“Ƨ™ü¾¿§”cKüi¹ùLþæÏ é¸ÎÈ_¤ýpú«ú‰^XÜóKi~ÛDÚϧÍá˜ÅÕ¯I¿´fAÅ+e;þ^ýQöÏàof\±ÜÜþ(üøÜÛÚß­ù>¯gf\·~ÂÙ÷~Â{üXÎ3¸k¶s2â‡ó<îš½þ/þÎæ +~>”³“ê§(üðœÝùöÌÜÜb¿ô]Ó·^o&·à·æçZü®´ÿÙPnŠ?Ne),ØÏ–ù-7þh×àô­õsüEðkþ ®ƒ¿GêïÑiÿlþfÅø×Ê­íÒ×l8±ý}9ˆ¼ŸŽª Û"Å´z¿žÇ×ÙðSÏ¹ŽÆŸÙþâo.–ýwçÚ3æÙ\®FÙûúÑþçâo·á—òsN_ÒYaÿ³¡Ü’þù9ŒM<—ãæÍíoì?iüâæŠÒõ½üyñsþ€çŒ¬·þNþ¬1 õgµ“ÓJþVÄÕgj?³õ-Ÿ÷»óí™4Ëõ_=í½ +7ü²j ¾Â_ögÁ‘‘û7ìεWçæ’ÿ¢üyùÉßû{jy¶u}iÏÂ’•¿hÿ'égÎÏßÅ$Íå9ÿpãç?<>yü¯ÅO~©Ír×éÅŸÉþÌüÍl+'•Sù³ÄŸvÞ íïöüaV~màl£ÄbŸÄuá/ûOÇß;¿ÞgÏœWsó_‹ÿ"ü½ß=œŒÎþ Ø¿"ì +à‹ +í]»®íºnu‘&Epš”©R¤I‘‹¤ÈÿXã,ÝËÍͧDI”EÄšÓÓ”9¨e/ëoÿöüßß~ä¿þýŸ“ö[“ÿx~ýþ¿ÿòû9I<×BùŸ?uýï¿þùÇoÂÕO]ûŠÇþ÷{”ýÏÂ#+Þø³ès<{e½x 4¿AÿQ×Q:íÜË]ûÌùßS?U§WŸjëÿX¼øGõgØ +Ï%‡dë—Û_œÒþzÆ‹@þ¯X¸ó”ým\íÅßæ/’<%%%%òÇŸ,“ݶ–””””|Oj+))Y-Þõ…W§åþïÚ¾w­æÕ§Ö¨ÚZ€¤û®Ex17Œÿÿç?ý]ÞrÛßö <¿¿ÅÿÅ_þ,õKëŠpŽÂõÛ¹¨ûO«¤wÞo•x‚¿7Âøñèãó-þ4øZj=÷ ø¥ûŒŽØÙfÿ³ðøJüYõw÷-Ú1‚ û¿}Öî­Põ±¼åá{;ÔøÿrÒ3öãúµ2¸öŸòݨ¾×þ¯óÇé?=náïôö÷åüaTZù¯ÝØÿí;<¯iñËåø¤ê·^ûb¤ø8ñgIVã÷ú¿øÛÏŸ¥~îzJ¿õc˜¿÷·ÝyöŽÜ¼§ƒÏŸE¬I¿{ø{…Ë‹¾ˆ4ÇIbÿô#+½þ·êïîc´#2~¡O wð/þÜô¥ñ…:ÇÅe}Ÿ¿¬óm½b?5Oöê÷Ú þçƒÇMüÚþ´ñêäüaT`|h¸¨8ñŒïTÙVûàŒ|ÿ@Š +Ã*üVÿ¹ø³Öϵ¬×#›¾6'݃GÏ—ß2šzòƒ¶^Û«Oµ-f$þÚ¸a)«µÕ6gÀßÖÉ­ø›ÿ{b'!Ó¬ü­hYúœù9äKò?üŒÇêZéœ'?àæ§Pׂ_ÊÑGðsÿ«Ú£ïµÿ&þ4üÏÇŽÛø;­ý}9ü|Ç Ç½w|ïáGzGŒOêºøGü_üíåÏZ?ô³Ô'¼Û:eÏ|ôÔœú£qßr +oûÕ‡|qÏ?pñù£ôá8˕ٮɈÎS¹2_}oNž˜¿éGFþV¶¿,}>Fñ̵qGÓ·–׋_kç£ø³Û_ø×ÙÕÞ‹¿=üiö9ïûñ Ž7¦zô©¹B/>éý‚R\ØïÁíÿâo-Þúñ\êï¾_4ó€1Õ3×_Ù~8þaß+õï0?Âõ{ÿO%~+=yy6ûW·Lüøß«Ÿi£xfŒ¿Üø‘aþÒt¥ö>ŠÿûOço&þöG¶ùâo=·æ£2sÿ)¶¸ùE/~ŽnžÓ~Ë‚¿øËÉ_oýPo÷tæAåœß(jÏTyâ¿W_ÛcþŽmË`ÿjüyyûW´ŒüíhYsô<^ŸAž,㇕¿žÿ“™?HþèÅ?j¿×žYó§ø›6Qí¾øÛÃ_”ý'äTÜõÚ;øé‘,øWë6ü½õ¿¿e˜Î:<ùÔGfˆ?œq¹‘…ÿö¯Ä¯ì´E;ÉÆß®öWù9Í“ä¿þÞüÀÃéèüÁš£÷Ä_þû}¥ý§óQm¿ø;·ýa}n¼Ó$¢~OÌ5ÿHò>3_RRRRRRRRRRRRRR2OÚzzž›ÇO#þSí?¿(ü;ìꊿ=üÔ~"bì+ûëÞŠÿvû³á·ô +眖ý!Gû­n͇ÐÿÖk%þ½ï]³èCñ9ŒŸ‹»Hû3ïïÙû¬ofþž5G +þ2µ¿¯æç¯Ü>~ZúMN¶¿ðï±ÿ <Š¿µöï®ßâÿpú­ÎdûË^»?p/þâ/¸O„ŸWÝòìù–y5nDæúŠ_OüŽØù£âŸÊO©¸„ß#ñæçÙø{&Ùø‹ð_ÏÏo?GsôšÿìåïÄùë3ï(þ&ÛŸ­ýô‰ÇÿÉö—½ràüÅ_.þ$|+rsÍÜ;:ž Ã3ÇÂ|Dä­¿›¡ãŸ£âg†ýÒ;VàúT…}~Onž¿gò‘‘¿hÿ÷ê9G¯ñów~kþ“ÿ—ç¯Ï‚£ø›kÿîöÓ #þÇs?mXÚ"Í/`|ݺ?ðþÌö¿æ3ç™ÿI¿GŒGÞ{ \_µ2þGô!ö7Vzô=ö÷þc0Ú~¿çñ÷,82ñ·ÂÿVý/çç0½uü´ö§Ù #øwÚOõ¿Ï¤£ø‹·WýÞ#ýñõðsúþ¬§ã¿Ýþ,ø¡¼×FÎçp¿ÏõÏ^¼s,Ê—YóƒûδŸk;Ò8GÅÿ~onž¿gÁ‘‰¿•þ×ôoÈÏo?#rô“í/üëí§Úv+ ~ê7pÅŸßþíÇËq´ÿ#ÆWC\lQb‰/iŽRøËþ¬ø£ç˜3øïo¼yØÌø=%?Ÿ‰_Û%‰Äs~Þ£ó™øË¤?km3SŽþÊíãçèrºý…½ý\ßMÙÕwpõºý«Ú‡ÃYþ¿kò>_RRRRRRRRRRRRRR2O¼ë _ØŸõKøo·?~¼&ö–õìãÏšÞ/uµ5;ˆZ„þ“ÖózÖˆ­ØWáÇeèãó-þ4.žVÛ¿ ?wìdþ¤5sŽ¿§ãÈÀ_ÆöwÃýs®ßì?©ý3ŸTßûV^Ï”¾„™j?+ç?'òçõþpÛ¶Øoé#F÷¯-þøñ«?×~¼Üìð¿Õ¿Ð¯Vc}(ð+¿½ø©z)›¨k2à‡X‹¿¼üEÌÑð{Œñü–›WCÿ«dí¬}TVü‘úRüqqûäÝö¯ÆÏÅÂéüQã³ÆßÓqìæ/Úÿ‘üeÊÏgçè£ãOÛwˆÒ‡1qüçüÑâÇûÞ5ÿ”>5¯Â׬œ?œÌ_ÿwògí‡)û]ÆhÿSüMÈ<ìô¿Ç>Ê¿¸n"–ÍuQvÌâGª3+þ‘öQüÍÅ‘›gØ_Uê§,óK +ÿ{Îó,Âèþš£úRüq1“…¿ø5þp|…?j®¤•õt;ùÃñ—‰¿›òó‘ñçõyËíàÿ4ž4þkùùHûÇ÷î¤ø‡ŸWÙÿþ,þÏÄÕ¾=ö{ûö‘ñ—u‘ùƒÅ¿™ÚÕ>Kß@]çŸq¹Ñù­¥œ^~fâÖ/þâðGÎËð3¢»öWíÍÏoߟ3 ³ðSüQùùø£Æn¿¨y×Jþ²·¿[òs8xÆîC§ÿ w_ïñà€ø%}Øn(¬°ÿ+üõø7¸}{í·ö£ýÑ üâ×xâ0eh?špïÇ£üêÑ×ìëÕ§ê‡>ãâ€ã'þâ/'Qs2\?œ_ïÚ_÷aV;nߟ3 ³ðSüIñ|2Ô8®ñ1ÏZÍ_´ÿgðw[~nõ_ïïYÇm|œûÛVfÛÿ5þFë_ÍÕÆ{ùëéãQ.8|ÜÆŸ—[‰ +Ãîöcõ¯” qëm®Ðà 7¿èÁ/aäêÏ„_òñ·‡¿ÈÜ<Ûþ–¸³Ø‘ ´>䇓ÌöÏÆoÍÏOãÏ5þzçU_Ž¿þ²äç+rô•ó‡Œãd޾rÿÌó¿ŒüEø%T±ßÓÇKüöS#þ{.8¤øÏÒ~¬íCšH’©}Sþ§ÚIFü\.þÖó5k}D¦ý-©~Ìsßg7þú8âr£¬öÏįͥOç·¿¨¹Â—â/‚¿ÛòóhÿŸ6þGåè+óóYñ"»õ½üqýqÔýÛþFú¬ˆ2¾r4_Àñ.Kûy¯×äçƒ%%%%%%%%%%%%%%%“„Xïÿ%—ÖÔ©óT™Úš<®ÞОã+üeÿü‘÷ÌáÞ[?õ [+[¹¿<^g´Ú”ÿ+£ú'î/»ÿè=®ìüá6¡ñ×»¦ÿ•ø›É_–ûç+î¡Cî ¿Úyè?<¦Qãw¾ù_Óáâ Æwí~Î/·Øÿ5ü™í§ÚùIüÍèç¾pàøÆþ—¸ÃüÏÎ`ù0¾¨ºÛ÷^û°¾¥þW´wÞŒÿvûwàŸ•›CüFI ýÚµœþÏßߣMÛñK\{õñg­ßÎ`¿Ö~pÙx|èÅñ jvþ¸±žã/r1›¿Ûßêüœãtv~.ù2ryMû8?áòº^ü”on²ÿ‹ø3Û/õͧâéû2ðÇù„Ò§ÆOΗM_šxëoþ±p*áÇ{¢rø,þ¶O²ñvü·Û¿TNÎõwžþòK†ü<~Žë}*ñ÷LöSuPeGáÍÍOà· #s¡•üEÇß +þVççÜ1;?çøk{´}Væïwx¨éã±\*ëýû怭 ~)GÏ`ãÃjÿmüaÕŸÍ×?ŸÂ_d?—¿“óN׊þNŃտV}®~é‹þ-øo·%þˆœ\êç¸ú%¡ð{üEÕß;ÿÌ‚ò¥ÏÅþžÅ~X¶Ã(~kNq:¸]Xøë­äïäö·:?ç8™ŸC»±ÞÜ ryÊïï_øŒï#¼+³½3ɃŸêk2Ú߸)þxÕ_ÁלÎ_oÿ·“?êw¬ýó…ürÍùÇb§WßZ?e#«7á¿ÝþUø#çüš`›Fß/Éa¶æç»ñÏÒ‡1’™?êÒ° œm#ø#róøÃíÂÊŸw´š¿ÙþŸÉßêü\:fåç3ýÏñOÝÔø ój­ÍõàfÛßî«gÚù£Úû—ø³öqYø;)èÅ÷W‘ÆG¯}®|þûùvü·Û¿ÔœOÂMá×ÛçÕ§¤wÞÙ0ìÆßô=s +¾GYì·¶n¬÷âºw~\»Öø{œÇJþ¢ão«ósŽÓ™÷Ï©ñ“ó_/­ÿÐÞkçýð¼6¿ŒÄOùé&û¿Š?³ý\_ð%þ,}ßNþNË$ÿ[ðC®-öI6ZðiúÖXjçnÇ»ý3ñGÍó¸ú$ü=2¢Ïa÷̳ܳôÅ}¯d±Ç¿ÖFðGåæ§ðgŸI:–þb3âo5î·cv~.c‘ë{ÜYš;[òƒHü‘kƒ'ÚÿEüÙíçúë¯ñ'Ù¹“¿ví ùU–ÿû]“ŸÿI-)))qÉþ±LvÛZRRRRò=©q¬¤¤dµàu¼fsþç'g×Öe8uö”1þ²þˆ{1p= â×pKk¿öe¿Pv×½ ,øqýÑú? cVûgà·Þçû¸ys_Œ¿ü­¾.q}ÿÜòNmM<ûËãk^iã/æ¥ÝË‘¸™ÿ=ÇùìûODzýTŸ}þSù;!°è[ðc[¨sØ>ϳ ¸¬¦O½·bÀç`ý…ÿøo·þÑü– ëêé)ü¸ü^}ÐotÍ1)þvà—boDŸŠ-~3Ù?¿uNü5þ´öNéë™Þïå}!þvð·òÙö‘¾Ó#Í'Ð~‰3N,þÇeÃkZýRŒhõâ§bÅš£c}üY¬¿Ëþ/ò׫¿“?®ß.þæó'õÿøÜòŽóû8ÿ6û´¸¢ðáû…¿ìÆo3qó2Œ¿­×µþUÂ,ÙíÚ_qd~Iõ/«ñk18¢OÅŸÖ¿f²&~Onþ5þp[‘ø³ez¶yÞiñ·ƒ¿•ù¹vœ’ŸsßqLyÆ/ª¬HüžqÛ¢OÅ"þžÉþ¯ñ7ª¿ƒ?ªÍóù£®£ìÿJþ#Å„_’mÔwü|§ÇaãêïÅßö.<ñ$?oeÀú[?Ðæ§žþ‘ë¤k,ú§Þ¹¥V÷*ü=õ[õ¹ø­•ý3ñSk5·ð‡Û +WFo^÷•øÛÅß×òsè?¿8ÿAßi:–ñ[ÒÅüGàçôµñŠÓçâÏbÿWùëÕßÉÕî‹¿µüiz'çx¬‹|?.³G¿}~}BéàçøÁøÛuÙð±üyæL¸O¶ôY#þÿb}دaÿás”~ïÜ’ÃÇõ»³ðGÕßÙíŸ_{–âëüQm…ã¯7¯ûJüíâïkù9g¿W¨ÿQ…¾¤tàùÕóJ$Jïw–|Éþ¯ó×£¿›?ªíkø»!ÿ³Æ õþ÷ü¶õ +Ëûó=ø5~ð5Ùð~þ¨yÏ+Þ9ì‹{ðk} åËþžý{ç•–úWà×ê¿aÌ•øµÜüþ¨öBéäu_‰¿üeÈÏß#òþyt~']‹—øÓô#ñSذhù¹ÖN¨ß³Ø½ú»øãÚ~ñ·†?nüâê?1ÿƒ×p>¢ò;æYöõâ}/q„ˆ¿øóñÇÛ=s&ÜòË‘üoí‹´ý{ç“TšÝ3ðK±ƒcoDŸãïû#ñkùÃ-üá6CéŒät_Š¿Õüi±ú,>²Ý?ç8—â©I–ûoZœpüc}¯d±ÿþ,ú™øãÚñ·†?êúÓó¿–ŸIò>3_RRRRRRRRRRRRRR2OÚz:XR×7¤µŠWîgÇé´Ü_×ê‡×ãkñzÆÍøo·ß‚?âþ…ô¼…¿W^ýUû+öÜëɶ?$å¿—ªî/'&ná·Jäžëão°<ÏsP3ˆçÛ{ì§®á~Ãã'Ò}Ò~¾Ñø½üÍþÓñÉ~ª8 ÿ)ü}=ÿi÷ð!>Ì¿G4}l~ÆÇÙ¹¿ônü£þ/þhü³òò6§ãü¯ÙkÁ¿bEïüQ‹‡Õø)Cþ©gy½ú_ÙíÁoÍnäšQö÷æs_‰¿]üÁß=}úÌct-Xóg?ö?õ5~qü{êo±8 ¿¦ïY÷8ÑþÓñÙ~ª8 ÿ)ü}=ÿ{ÙŸ¹×>ˆ âÃ{¥Je½Ûz{üí¬øGý_üýŠf^çKZ{´øöþŠ=óF)vïIůô¿^^}­-d·ß‹ß››ßÈž{Qö÷ær_‹¿ÕüÁóÞu×YÇÈx3kzÊÿÞù1å,³ð[ô=cÛiößÀßÉöSýúIø3ówKþ×þ¾ù×ãO\·~ÂÙ÷þ•Öà<ƒ+³ãñ7ßJøGý_üý¥³"/§r“ÿ7ÁÏwrµÆÓÖ¸u†¶nуùËøo±ß{ßCÂß{ïÜúNzI°¾´GùêS׎ܧў€ñC­FàÇkŠí<Œ_ÍϸìýÓí×ðsœSø¹Ø¸?îÞ÷O}]ÇWâo”-M?Ó=ô÷ð<³õâçüÖÞ¡¬Ùÿr¢Ý×áÖßSÆLü=úžgå²Û#_²ÿtü«ì—æß_Í<ö5LŸÅ·X +Ç'W¿åZNŸª—²‰º&~ˆõþzòI‰¿žgÏÏ߃Zÿ¶àñC²ut~LO0? ph\ÌÂ?ª¯õ…Ùí¿¿Óí?ÿJû=óo©~θìLùŸÕ>ÊÍ6¯}T¹Ñù­¥œ^~fâÖÏÊ_oÉÙГ§Žàçú×öò;üþþåî?Yçy¹9U?Õ†°=þûCR±?ý,ûá8Ë•ÙÆ±(üžûE?¥SüÑm\ßuTûë·Ûãy~$SŽŽm¢ì§®±Ú¹±–‡ŸOåô(NfàÒׯÀ¬ögÛ_üùíï?¨ú­åXü'éÂzfççÒûù$^4};^}ª~è3.Ž9~2à¿…?OÞláo47·à׿ÊXÿŽm™ßEçæØ~ÜŽ(ü8?˜½?ä ý™öSÏ©ÍÄ/Ÿ†ŸËÏ‹?þÐ{ó´Uø¿ÎŸVöüÚóÆå?iüÐì×öïke¶ëzÆÿ™ø#ô¥X¿ëø“ì/þîäïkùŸÅ>ÍŽ'*?±Æ7¿åÇZ&ü’ÿ¿ÀŸ5göò7’«Zñc›½ûCFÍí"òò÷‡´Æÿˆþ©ö[rs ?/Åß_q[lz½mù‹ñ·Š?+~®MdÉÑ)ž´ñÃk¿–àkzç/³ðêkñ`­—ýÅŸÏŽlökøƒúVΦlùŸÕ?ÒÜ@’L÷)ÿSñ–¿%¾NäOËGø‹ÈW{Ú§eȨ9ݪü<Ëþ;Úßiös|{ñ[óóùÃí±]ßÛž¿«ùóàïé'Ÿ‡7?ç8Ôìoï"àÊÄ¿ÍÊzñê¿ßá¹]ùyñß&Ùì/þÖðGéc|ð»uü©ßz½&?ï¡*))))))))))))))™$x}à=g]¡ÎSejk*¸~¸>nY#Çú£ûÛíÆßëÿ“ø³Þ«ˆâ¯ç>I/Üo?ïG +½Ç}ß<¢ýPϵµ¾ÙûCbü£ú§Ú/ñÝ‹Ÿj›Åß/m?ì8=þvòÇ{Ðí3×îŸcŒ;è¯vúÏc?>ßü¯épñãgþöSý\Vû‹¿³í?ÿ.ûoÉÿ`ùпTÝí;õÔ×xñÔÿ +÷®BNóiå6 ~ÿOäÏš3Fò7’·öÄÑîžì¹¹5~p Pý“ä#I ÿ´k%}.V½ú½ñ·Ë~ËzW/ZìqëoÕþúùóÖù>Cš-Go6qój(ðÿ§"ÖW¤ß±Ïñ؈ççüÒþVþ"í—ÆÉögÛ_ü­µŸóIäøÏýn©ŸŠ §”~ÏþÌš£í“läðSuQ¶àïYð[ý"Öœ1Š¿ˆ¼µ—¿L¡ÇŒ¼úã–úŽyòôÏTYù?£úÖøÛe¿µMõògÉõ‹¿˜ƒ«£Ú_™ós˳ Íîw¾ryèó67‡ãûŸZ+þ÷Úü£ú”ý–üœ³Ÿš‹kù±¿øËÍßÍùü³Éâ_«>W¿æWMß u]6ü½õgçO˜÷„ó7š¿öð÷ó9ü˜•—cÿAÛ4Ü¿YâLòŸ'^µøÒ÷ÆßjûG8·òG•[üýfÈËŽâofüeâÏ‹¿½ƒ)S~N½¿û¿shÕþòðÜûWºÖ|+áo×ôâÕ§ì·æçšýÅßþ¢ì/þòñGýŽõGÇè_É®~KÝü˜kü~9ü»æw¯¾µ~ÊF*V¹÷ãÁkNÂUÿÍüEåæVü³ælѹ8ç?É^‰Êÿšà:2¼:2þVØÏñÍŸ”Ÿ}jëÕþÖð%Ó=têÙÙYþçø§Æ>jü‡ùõ~êÙøgØoéO-ö{ø‹²¿øËËߪüagþãÝŸÙcŸ„…+ߣÿ~æðkõP¿{량ߊ»øÓùëÍk{ðÏœ³ÍÎÍÿÖX¡ú*OÿŒ}‰ã¯¿?£úžø[a¿57ણøûõsT[¯ö;~[%c~ÎÙMÙ7jëÿµ÷Á¼ž×æ—+ðGÙÏõ©Ùí/þζÿtü³í¿-ÿ³ìÏÌùÈÊGßKí…_ŠmI²à÷ø¿øãùóææxöàŸ9_³b\ÿÄ6Kñ õ/½õèkqjÕ‰¿Ùö{Ö—"ø³¬19ú þ¢ãï‹üŸKãp­lnŽ,Í-ùÁlü‘öK¹yVû‹¿³í?ÿlûÛµ7äïwMÞgâKJJJJJJJJJJJJΖÿ¦˜ûÖ Œ‹ +í]»’,· À‰K¥Ä¡#JÈeþÿ³«¥K ‹‹7ÁW[…ÚÝ™Fó>€îžáçóùß§l[ûåŸýÃ~ýéó›Á×þýÏ{|~þü~Üó?<Öb°ÍÈ90f ÿƒõ—ÿ´Óð{â_ú}µ¿ÿôƒÛ"ø?ƒ ./ þÿüë/ØóZûÝþÆ_—ôãúœÔ"ø¹sãö³ýÛøYÉ_ë·#õÃm–~4ÿŒ1_ã/O?¼þÁØRÇX׊ÏÀŠ×£ŽŸ×2æÿßÖd×gà¿ÿéøoç:þüoªÿ°ÎÔk8¾í¦>Wóo8ð±ð7þ»ù{ð?šþ÷o¿·‡ûç øµø—~¼ykó'/òà™Ÿ5,0&X¿fmžÐ4„øñ떹ŪŸÖ~/~©RÚõøïÂ_ê·³ô£Ú-ý¾çŸ1öküå釴1»º>×ðk<%-þøÜð?®Xâ߃ߪµÅÿm?Wò/ýJ¿Ûõ“æÿ7ÖœæRÿÒøqñmü´~EákþVü5}¼§á·Æ¿ôûj‘{çü#s3œŸQñ·æØÍ—šŸ¤u€jÛ:¿p2ñsígûSãg6kŸ­ŸÔvé÷];)ã¿Æ_¿~ØbÛ¹>§â2ª>àþÇqòÜ?rŽŒõoþ¥_éw«~Ôqo®ÿ¤>!õ/‰õ?~¾€óã°qíKøÛ5”ǰÿóÚîø-ñ/ýrês þ‘yYËÍ`ÛÔü cñ·ÌÔqØ_j{þhûVnüÌä­Í³õãÚ/ý¾?GÖPã¯O?Í_²Õõ9?_Ž?<·æƒ×?O{£ðgû{çÏÕüK¿Ò¯ôã{Sý‡×:)¾–g¨¸÷ø·¿Û5)&~øLÿÏF}v¯ſôË¿wNá™Q¹Ž ÅÎk8~ø5ÊŸÒÀÓðù¹ywþ¬ö£ãgK_¡Ÿõ¹úÒ¯o®Øÿ[ôÓüO©Ï#ø9þ’Þ”OOû#ððΟ+ø—~¥_éGû¾µþ³ö|~/Þ¨¾íz…¤/…_ç8 ¿µýÒ/^›Kõùc#ó0)7£âÃ}¦A‹ö÷Ìð=Oû#ñ[q÷úKýí9™úa¥Ÿìÿ5þòõÃþÚqÍV?ߎ¹f×Ò±ø}I?Í?¿G?¯¿gþ\Å¿ô+ýJ?Ý®_¸}î+þõ<†‹Åσy? +?uìIø-ñ/ýþ|-Z›KõùÈÌ’—Qü-c¾¿ËγäÇ3ðk}÷½®ÿÍàûéJý´ú¼ôëŸ;jüõëÇùB˱TŸŸ}ÿ\â1.~Z¢ú_oû=þVý4ÿžùs%ÿÒ¯ô+ý¾šåØ“êŸÆA³oŸ¹-++++++++++++++dízz«á?†ëÜûÍîgÇù´Ú×Ú‡ÇãcñõŒ›ñßοçž9¼ˆñº'bxÿ˜ýåµögàÇ× %ü½þ³ùã~ºZ?iÜ”~4ÿÀ4±þõÓîIHïQþ+îŸsñ²ðµ¿0§™Ôÿ"ø³õ³úãõwÿÒ¯ô+ýlüß^ÿàçÏp|½¦ùc>øóùÇ«YûîüUø‰}u\ø3â«~µ9~¶}D}έwÒþòø|+ðKý—z–×뿊¿ô¹óUúY>_úõ×ç;á?U?î}Š»ÅåóíÞýé)^œ¦Tü4ýµöñû^ü#ôãüwä_ú•~¥Ÿÿ õ_»^ý3“_‹/Ö‡Ê5¹s­Æ¯OAüÔwù£~Â=ðýóoø‡äX–s¯Ø_ñ-ûCRýWú¬—×6é³Þ«ô³|þ¼ôûê˜6¶Âª~\~ÝŸ}ö=tŒSÚχÂOÅ—ŠþD}ÁŸ­çOõ¿ø—~¥_é'ó¿¥þkë`‹¯'ž¸-îú ÇïùÝj<ʿݟ•út;f~øŒBoüoÓ«±[ûÞú¼é—™_qøµ| ?ßÉéDÍSTü©cÞ¶?$ŠïÿÙüµú|…~Üs'¥Ï?0u Ó/‚ÿDý0OK~iñŸù]qF~íøÿ¬øeáÏÔÏÒ¯vã_ú•~¥Ÿ|Mã¦ú/òýtT[˜‹Ô?a}‡Û‡ïYl~¨Ï +ü·è'ÝÿÖŽ‘òªìú\ã(ïÕro÷P¹c¸q¯Rúiísýg~-~½þ³ùk϶¯ÒO{¾½ôûÞß;wÔøËÕçRÔú…s-î}ËZ’ùÛ—òT ?¥'þYñ‹âÏÔ/ÒÿVó/ýJ¿ÒoÜúqZý§=“f9ÿã§}/|æ¾Îå'\ÿ*üwð·|v\:NÊ©žv²ò)ËüÀùZý)k÷ˤõŠ?¾Ï†ý½xfã·¶õ_Á_ªÍWé§½Òö÷Î!»á‹~\~…? ù[×”Œ)—n¯qø¹µŸ‹C{[%?.~=øGé§åD»ð/ýJ¿ÒOÇoõ?½þ¡ÞXã'q”¸ãö±þØ +ÿûùªÍÛ½÷Þ<Êé<£òkJêX*?ö`š‰ß;~"þ+øKÏ‘¯ÒO{¥íïKvÃÿý¤va®•QŸgÖè°} +‡_Ê-%³äÇê8/þQúYðïÀ¿ô+ýJ?ž?wž·Õ?mý“ìy&¾¬¬¬¬¬¬¬¬¬¬¬¬¬¬lœy¯/X÷÷ÃÿÃýý¨k<íZ€tmÉòàüð|Þk];à‡ñ|«~Â} V¿È³í÷6¤ë„Tÿ¡ÎÕîåÃëpTì?šÏ.øOãûè.ø¥gîK?ž¿wNÙ ÿ©úQ\šÿƒ‰ZûÛwkþ3טÖ' ~\Ü(ü¿ÅÿÇ?Mâo±ŒüɃ„~'ñ/ýJ¿Òï+~*ï¾¥þ³òƒ¼¬±?4NO)¾Qüø™ ˆþÆÂù&ý¤çÙ%ýv¨Ï)Ãñ£ÎŸ·ßeyiüh\ñŵŽà_ÉߣÕGwÑú\Hé§óÏžSjüùøKþTžeñ_¹ÎHù5…¿ííÐrgÌ_‹7µþcMá±ð7þ;‚„~'ñ/ýJ¿Òïûúƒ:÷ õŸ•…ÒÿïYŸ)™úhq¥tÚ?ÿ7è§}Ö\ÒofÎd}Ãçgê|Ô}É•ûË[úÄ·µ ¯§ŽÚR³•ü­úqß°ÿÓ.wÝ ôÓÏÕS‹eéwÛø£þ¦ü¹Ï:jþÞú phZxñÐï$þ¥_éWú©Ï{âg1êܳês|~GN#ïúoÖÏÂ?:Ïì‚ÿDý¢ø­þ«êóçǃŸ:–Ê=šŒÌŸféw +ÿÒ¯ô+ýrøÏˆßˆö[|$ûö™Ù²²²²²²²²²²²²²²²A÷Ànû[[¯‰P¯?þÞkÚè~×ëã–käØ5~ËþâÔ1‘øŸ¦w_¡G¿‘÷0"úqqkñP°}¹GÔø¶ke’.–ï”Ö ëÇi ¿Õø¡6½þœþ\°ò§´ßQ?íþþ­úYùn‘ÖøëÔO‹|¿Å¶¯ù÷Ü?ϸ‡þü4¼üÜû0þšן`ÿᎅz÷â¿ÿéøoç:þUü9{sýã˽ßÃûãóPí?Æ}מÅ~ÜŸ¬}+ ÿ®úiµyÿ¨ü(ªŸ?­>×b,l_;–óošáspPí¯Ä/õU¯T‰¿ôÌønúy>{r‹~þÒ+U¿^ü'êçmÆÚâ¿S}Þönêáã/½cŽs3œŸsuAOü³ý{øãï÷òò/ýJ¿ÒÏÇŸ‹ å×¼vrë?·¾XÚÏ\¿°vÒõk|{ùq}@ê¯xOÚðãc),½ñ?E?­6ê7"?ÊÔ:—VŸ[t¢ÚÀúYσýáxÓúþ{ü\_íñ÷èÏ™T›ï¨Ÿ„õFý¼ü¥Wª~½øß¬_3ïþì;ÔçÏOãíÅo¿ÔgZÛðù¸æÿ¼Fí%Åõß^ü+ù·ý0˳(¥_éWúùùßVÿQñx¼ü<þø}Jéœÿjüm¨ã"íﬗ£dé7 ?JÑOÒ)«>çâçћҿͷ<Çhügâ§téõïÕŸÓ~wý´ûç·éçå(»jüuêçÅß¾³§åwšo}žY£?xÚ=@+~©_i÷o°ø×°?wNoü{õËæ÷(Œð/ýJ¿ÒÏΟzûÃøœ\ÿq±¦âcáéõ§úÇËÚWwÂuÈnµ¿Äß[›{õ‘eë‡}“°y¿ß‘›k£i§ý!Gù÷èo©ÏwÕÏZŸß¢Ÿ—¿·Þªñ7W¿ˆÿNõùóÓ˟ӟʽ¨õÖ¸}Xû¬ì?#ùCŽ+ø—~¥ßúÝPÿQZsïyùI±äÎïñçö—Þ¿võ~/þ]øKyI¦~ÙyÑ,ý²êsK¬_ÄNßRÓ¯×?ª?×_w×OªÏoÓ:^ãï­µjüåéÁ`ñ?¥>òoë2—Ã÷±&T}ÀéFᛡßÛùŸŽÿvþ§ãÍÿ¦ús·ð“8ZøiþÖ¾Äí/½?u¼Õ¼øwÓOÊI²õË΋Fê7êþ¹¤ß ûCjã¯×?Sm<쨟ó-úEâï­µjüí¥ß õ9—ü[,¹YÊqûÚ£úßÍüOÇ;ÿÓñæß޽¡þ{þ×ìy&¾¬¬¬¬¬¬¬¬¬¬¬¬¬¬lœáë2øš¾>ðùV³Göf},cWî=~ê¹oû‘sdá§b·R?éyöü³ïYPX#úaÌíz Äÿü¶<ÿO]»Ãñמƒ¢ðK×aûÔëN³YûCRø{ý³øSZŸ 1†®Ô/:þ¼÷Bküåó±?ûn÷Ï­Ï·dä_Ô3Ží^ŽäkùNlkü{õÓú?7và_ú•~7ëwSý‡¹P¯a~žgð¹š?UË@ ø5ª÷âÇ{zðSß»0?5NWè'=Ë>ŠfN„kãý¬ûCZ?c‚õƒç·hHùSñ§Þƒþš~ZûXkª-îüøWð—tÞU?f ]©_tüyk­ùü‘æc%ÿ“ëóÖg1N.~\³Ä/ûLýzúÿjþ¥_éw»~Òü_£âZýÇiÞSßqñmýSëW¾æŸ_ÓG¯¬À¯}Ã(ý`.`­Í³ù¨ÏGéמWxþQŸÃñÄù¾yHm öøgð·è¼£~æõëÞZ«Æ_>ìÏñ·¶Ïês­FÏÊ¿,F;«¾ÉЯ§ÿ¯æ_ú•~7ëG'ÅïôúŠ•_õÿ¨ý]oÇ?ƒ¿%ï˜Å?3‚yM~<ö¨ý!­õ97?HÇXü!Oo~ìñ×Ú×8Pë‹·ýÿ^þwÑOªÏoѯgüEj­¹ü5¯AÿSëóù gTÿóè5R¿žþ¿’éWú•~tܸÿ½ñÛ©þÃk]æ÷óásFüµý]oÇ?’¿'ç˜ÅDmž…_‹gó÷ÖçÖýð¸¶úGû毵ïálü=þ”¾§èÇ]{»I?Kÿ•ô‹ÔZ5þæú{MÛß`vmŽ×0­F‘¿ŒÌŸFë×Ûÿwç_ú•~o×oäüß?oýÀáçòCŸï¨ýc¢ø-ŸAØÿý¸5ß[›â?³>¥Ÿ7ŽíÜ–ýnÚÒƒX¿B­¾ÝY?­>“~‘þkñ÷ÖY5þÆñÇþÚqVÿ]ësn-•¿pšâ¿³òû,ý²úÿlþ¥_éWúÉ~o«ÿà1\Œ¨ú΃ydÿŒàô9†~Öõ~d}îÁ¿c}î¿Giî{ü­sÑ ûCjí÷úkü©–z½i{Š~þ7éñ·êç­³jüåðç|)þÒ±ÿësj]›Yhúõøgé—Õÿgó/ýJ¿Òï«QÇŸ^ÿµúZ²ç™ù²²²²²²²²²²²²²²²qÖî´þc¸¾!]«xüáþuœO«ýñq­}x<>_Ϙÿ³à‡ÃBÝÿîùñÞ ˜©_ö½ +ŠG~Ëþ–^“?gÐÿ†ý!9üTìzý-:>þÚ9A¿(‡Óô“ð÷Ž?ïÜ[ã/G?ë=•ŒýÙWß;o?žõšã†×/Τû>Öý©c"ñïõÁ_êïÙý·ô+ýnÖïíõ+·?sÔ4ÌÆÇñ‚6ÿçå?ø™8m­Ÿ©ß¨ú|~mK©>·øã× ~ϼô–ý!)üÔ³È^¿¥>?Q?ŠÃõãø÷Ž¿ÈÜ[ã/O?î}̽×?{MŠþxÚ×økús@ü:wÎÕúàßç¾ëÙâ¿éWú¤ßÛë×v½ú9f&?ˆ â{r‹Ç,çz~·ãgàÿ¼ø¯á–ëð³ô‹äA–úœÂ÷šÖðSãGÛßÒRŸKþ°}ø7uý +½æ©vÚ’ÂÏ}V5âÏá÷Þ³:E?.§›~ÿÞñ™3õ»eüqü¹üŽ;nßê]—FÔêÞ¶)>™õ >–Šeoü{ýGò‡&íÇôÎ9vÀ_ú•~;ë·¢þÃxFÕШý™­ñÄmq×O8~ÏoxûÃ<ƒ;g;fþÏ¡? ~÷?µvsµÆlýFå>ü0OçðãñŸÏäú™TŸ[ü©yJš_¨¹:2?içÛÿ(þÞøý¤{noÒoTÿ혛·À²~˜§–_Rí[ý{ëóÌ=Ò6Oüp~ÊéC§7þ½þ£ø[¸[â· +éWúíªßêú¾6¢~ðG¾ŸŽj s‘úäG}¿ž'ֻ᧞“ôâ÷äwþÞµ}…~£òž–›ÌÐ2³·ÿŽØ_ÞÛ>7~vÁ?’äÕ úYyœ®ß¨þë­­vÃÿýp.åm_óϨϳêôh»=ü©\UêgÙñ_í¯ñ—òG.×ß éWúí¬Ÿæo1ný ´§â?³~ОI³œÿñÓ¾W↯Sü¨±Àá+ü6ﺾŠÿˆ|r‰_³Œúã”æç·ï9Â_ãÓ[ŸïªŸ—Ç©úè¿‘Ú*[¿üoÔ˯ð1^ÿÌú¼·Fïi—ŠÖJŠ^?µã¨÷#ñÏôÏäoñoyç¿éWúí®Ÿ¶~hmqí7]a›»ÔÑõó“8JÜ-ü$­ ¿ü~dM_ÅTžÃñš­ßÌúœãpúþžö#þÏÿÒ93jóõË®ÏwÕoDÿÔVÙúõà£~\»Úü¯ùg×ç=5zo»8~Rœ´øsë¥f³õ“úO”?‡“ÂÔÆ^û{ü¥_é·»~·Ômý“ìy&¾¬¬¬Ìk?üôÃ4[͵¬¬¬¬ì}VëXYYÙló^_x|z÷W¥®Qµk’¯å;ñ°áç3öœ‰ßáXÓ}Ë=óú¸AqÌį£QçƒþRÜ-þܱÔõ@Ø´1˽Çæ³ þÑüߪÇëmúè¿Þûž»áƒ~—柹?ûˆûçÑûèYíJÚdäÜ{‘øgú{ñGΑÅ?ûÒ¯ô{ƒ~øœ7Õšeí¯ŠÏËéIµo=¶}ï>×><¥oÌÆï$/l¾ð·]ô‘×àçù²ñSc’Òïy{ÆÐêÿ—Wß´?¤f#ùk¹í©úQýòúe÷ßOàg'üoÓOò§ò,¯ÿÈúÜ[£g¶KÅ33ÿãò«ÙúiýãO}ïÓlþ–ï¦(ýJ¿·é§­Wo®ÿ,ç‡}Kj‹ê'žõ™:·•¼Fû¾ õ +Ã,üÖøGóÁô‘ÏPµy&~ëþˆOüµú|æþòÞþ§ÅlæþšõúGëó“õ£x½Q¿Hÿ•ô‹ÎÇ3ñ¿]?êoÊŸû¬£Ç?ZûžPŸsùiFþ@åY‘øgùkc ãÇ÷ÿVð×ê»Ò¯ô{£~7ךáç8M8í½ësDé;f`ÿÔ´¡Ž›ßÿhx’~Ùõ9u ?>?ã©Õwð³ö—·ÆjŸ›ÏVí)õ§ü©>øý¤úüMúõö_¬_dN®ñ—ËóÆ­_ÚºÏùGÖ¨¶þf×è™õ9^#aüGäÑøgù[Ï·+ÿÓñßÎÿtü3ùß\ÿify&ã÷ô©ˆ?•+Dñqïkëz~ɼ¹•ÿ¤ß¨Ú€¯™RæÁO=g–4-¯=Q?®>£~=ýë×;?ÏÆÿvý,íõßëß[÷fÖè#êóÞüÅ’?ôÄ?Ã_ÿ;ÿÓñßÎÿtü;ñsýg±‘û·H}‹Ë/¢ø9¤u¾å:³ñgæ{'é·º>à÷ìHqðøC]¨~Kõaí™$Kÿø8Û6JÃÓõãúåøwí¿žyÚ:_×øóó·â‡õï­Ï­ç±ö§5º%~½ùÃ*ý¼|vãoù óÎøK¿³ñŸ¢öçÖŠ|ouýºª¬Ð'b3ñÈñNÑ/³6§ò–QøµÜÑRŸ[ý¡.Z®š9~p ÀÕ»âÏæ5|ƒ~=õùiúeõ_ë|»küÙøGñGü©u%RŸk~o¯Ï£ñïõþ÷pÚÿSߌ¿ô;ÿ)úamݰ®ŸÑö=Çkö<3_VVVVVVVVVVVVVV6ÎÚõèV¯ פk%§íϺ~ËõqŒåTþÜuúÈ5þÈ=…‘ýŸ^ƒ¯3\Ìþû+¾mÈÇ¿Ïûìç/aæt<]?ëxyƒ~xüGûïÇùSãoŒ~šOæúIÍßÚzÕÚ¥ôØí:Åy§üíÔü'‹ÿéøoç:þüoŠÿiûËRv"þH.÷þÙÏßEó•‘ý:–:WŸ[ý9ýnÞ²éçýÞ5‹?Œ|ÍòlèiúIyúÛôãâçÕÏ;§×ø£Ÿ·Ížõ3ZŸKëÏNõù ùÛIùOá/þoÃ?›ÿmñ?iÙ“÷wþ~,˜OÑo·ÚÜ«×ÿ¢ñçês«?5î­ùõ[÷‡„ù}†¿„¥½îÉoOÑÏÂã-úÁ¿{ú¯wn¯ñ·V¿Œõ“›¿-õ9·þŒXóFÔç«×Ï ý¸þ§™ó×Ò¯ôÛA¿ÛâßòƒvÎÈúÌ­\>Ñ^{~£g¼Ø˜ÂOÕÔß0¹<øOÑovmÎå*üðû“¸˜àøÏªÏ)=,úKßѯÿIíà~Ól~Éÿ6ßð‡ýFÒÑ[£ï¦Ÿ•ÃôƒGûodŽ©Ÿÿ›ôóâïY?{ësnýÙ¥Fï]ÿ#ëçLýpº9-ýJ¿Óô»-þ8÷ópÃþ‹”_@~§ìŒñs¹—7g‹àß]¿ÌºÜS›syŠ?|ö$;þ6¯~ÜXâãÞ‡óQfÿóâÑÿ{ñgÔç»éç­ÏOÖŽõhÿý~FêçÅ«~½ísó·u>ÖŸצ£õytý¹~fùWþZú•~gêw[ü1¾ˆ>–½O nø:Å#á[…?’ŸÂ¿“~+ks.G™ÕÿF×ç–¬ù•ë;Ò¥¿ÄW³]ðÏô·Ô²'éGõË㿪>ìü©ß‰ñ_¥_oû‘ú<²þ¬¬ÑOËßzýoË_wÃ;ÿÓñæSüŸÿ5{ž‰/++++++++++++++gÞë oØŸ5 ¿õöHü;ë·ê¾¹vï`dÿkç㮕µøsñ×á(<°}îXêz Ô_ºžçÁ/ùì‚JÓõ“úåõ‹ößè¼ׄùüµõ/svnœHëYÏú“ý,™ÇvÉß2õÓú"5~fò§ö_<=ÿ.ýJ¿ýzñŸk|a\­1ÆþÐà1V}£ø©v)NÔ1­}i-bÝU¿¬Ú•[väŸì¼¨•,üþêsX°:a×üõé3ãóÿÛæßÍ_óçå¯BýwÊÿZû4±…gÍÏðºÙõ­æ:Úú|'þlýLþN׿Ò<äDüÁü ­Ïç5.Ìÿó8GÅõ8gÌÉ3ðSmYñõ=ÿÈo^üQ}É~®>¿‘?©>žøý·ÓøßÌwGÜ/°´OéSùeGþY‘WÕè™óŸLþ¨8£bjÇüu®çÆç±ï óïæ¯ù‹ðÅ}£ñaÿKcó«E_²Ï«µ?ûL“ÛaûXÎÛ‰¿:§ksi²;þ0}®>‡ºóü¶o}Î( ÿìª?iðÏϾžŒÿˆý\|ÝÈ—oäÏ¿‘±‰Ë»ð ;ðï¨Ï±öWåÇÌý–ù&öž¾²zþê=~Óü»ùkþvñ·¢þ;é­9[¨<9æ +n¨ùE”mûã³e®µ +?çÿÓüeÕæ‘ú<óÞÿªø£j !ó¼yÞͯ)Þ0áüÖ‹~n“Êø³íÇx¼™?.6+௿‘ÚhäŒîkì×¶¿ª>ß™*×è+ç?»õG?©0…×¾mþÝü5;ø£Ú׿ +x¼‚ÿ-ñå‘Jñùþlžu¿&¾NðW½>¯ÚÚ\ãl~Í?™ã…³:þlû!—oà/RŸßÆŸ'~#u‘'otÿÓÛ¿º}lÿŠú\Ó~4WÖç;ýS}¡¿jþVÕÿÍ_ó—Ý>Ìóç*þΗäyf¾¥¥¥¥¥¥¥¥¥¥¥¥¥¥eÀûÏ>xOº?íÇ®)Ý߆íÏ÷Ç¥çøváçÖAªà?Í_æÚ¹wý\ºæŽøûÛÿÛòìÇÿ¦qþ£=ƒ3î•qmk~“Y ~(•ñï°{Fãvþ¨gOÞÈŸ7~#ë–ð¿•?8¦cùkü?|2·oÑ÷ä¾Ñ.ÆÇìÿã|î쯟õ“”Í›§£ø#þÏâoìñ'édò÷Íø¿ÝþÛñŸ²Ÿ’·Õ¯óõgÿbmÏ^û ¾¦ýG¤ß +\_šcÄ_‰¿Ûëó,þ0^f?Ró¨OµÁÉÌŸt.¥/ż66>ÄÏŪUãŠ5ÆnàOÛwÞÀŸ·ÿEj¡ÕüŒ¿Óüx?»·žÍz?}$-ù“’(þÓüQýêGÙü}3þo·ÿvü»í§|¢ÍŸ”/‡>—_¬íÿh8åðÃw¢Rø4þͶ³q~i~u%þª×ç;ãk‹òÓ|že|Ãx]UßqmVÅ﹆†¿y?7W½™?]oà~¶Äo¤ZÍ_…ø«Îߌ÷³{êsêýôÏ;ÑÎUÎMݬ¹zÆåBÔÿüiãÆ`ã=ð7Í_eþªÖ?;ê¿ù8Zÿjõ©ö¹s4úYø¥¹Õiü•ø;]›KóŠñÏ“pYÇ7¬} ßÿóµ5ªáÏÖ§b‰Û×ðçí?7ñ?WªÏ»ÿùø³âÏx?»·>‡ÏˆBþžy?´âç|lžúœúýA +ÔÿüQøáµ`fòWó×üUã;õgÿ¼¡~¹¦ü£±Óª¯m³‘ŠÕ,üX¾ª†¿§ës˼hp\‘jëï;Rc­W°ï4A(Ûªà_¡?s<öa1ö&þ,õùüEÛÖ>«ù;·ð—¥ÿ`²ä6¨;ϯaûc]nG‡øçg_OÆÄ¦å~lþÅ_EüÍ_óW•¿ŒúIŸUyñÃ÷«pùÑj‡…º¾Eÿù%~˜§*â¯Äßõù*þ¨v4s5Žx>ü?»¾Ó¶_ ?çÿ¨þì,¾ÞÄŸ¦¶¸™?ìXµú<Âß©ø«ÂŸƒWߺ~¾êýôŸÅ›”[£øOñ7ëÏüP²Š¿Æßöߎµýóõ+Õ?\þ‰àŸ¹ÖØÇÙ¨Á'ékciì[ËMUñWáï–ú|ÔØÂaâÆ­dêC›¹x¨†_3kôµ×¿4úRüIöcürœhëó]ø£üEñCýh½ãµŸ:GêÚs5ý—ÿ¨s*àç|mÕŸÿ׿¶ÕöoØxðþ´ãÇéøíþ×ü};ÔqlßêWŠóˆ}”‡}R\aøàü< ?7oºþv׿Ø|«ŸNñ—Q›Cþ$Άßô~O)wÁõw®mŒg©>çÚÆâ‡Ë%”ÿ¤ñ]k¿öýœÜ|ü$~/üýHÍåOƒú?£ÿJþ†6UÂï¹§¯Ìm[ìÿ,Þ4yì6þ,ãG…øÅÚøæþ×ü}Øy˜ýo©_¹˜à⋳ û Ÿ/ ô(lTû^ü?u +9_ªŽ¿"UÖΫð§]CÑð¡ßg;ægÔ±øÇì½ùýžØõ±ñ‘;âÕSŸcýo¶ÏâO«>e¿Ævª?WÀáÏÚ¾Eß[ïDø“úÔ÷ô_hÿ|m Lÿ$þl}mÞÛeÿgæ¹Ï|–ñãtüÎ×Ö`¨†¿ùkþ2ù“ô(ý1·Õ^ïDý癿ϯéÑÿ?>Áô#ø±¼ƒá[0¯²Ïƒ_“o •ðgè¯æïäÚùiþ2ÖO0ÿßþ~Ìø¥ø¥®/ oTû~ê_?ŸÕÿVýhÍcñŸ·ÿeéCœœß$ÿíÆ/ùÙÙëç^û?¶7òç?vÛ?l˜uÿkþ¾™?ì|ÉþñÛJÔ5O×£>ãäyf¾¥¥¥¥¥¥¥¥¥¥¥¥¥¥eŒõ”QÃ÷7¸{7¼Ÿ™Z·¸?¼v5þv|ïüÙ°ïWâúž2'Ÿ©ù·Û´2÷é/eoôý˜ðþb…÷{FýÇ]_ZKø±uý[ßωű„ßã{Øþ +þ"þ—ô±õEϺ¤Ä_fþ€û+ŸüíçrÜ.þ>¶·ò·3~oÇÿíöߎÿÛí¯ŽþF”u~EÒ¯ð~f,ÏœÄõ%þvÕæÏFÕGøÓ|/žó?ö»mó8÷ÍúVɨ¯9{6hn_©ñ1Š?Øh8ã»Ï€ÙÌéKöbþË~?§µ>ŸãËÿ[ôáøôó왫îáø‹æ?MÿÑðÕù·ŸËs»øóÄ'NßÈŸ5~»ÿÝmów·ýoçï9>lÜiߌMû~cx­çïXïÐàçòL~Ïû¥#þ¯ÂŸ·6÷Ôç+ã/ƒ?Om>ã‡k‡\ûóÿþ‰COFŸÃ~ÓÞ?ä|aÈÀŸá? §æyª¾ÆÎµèK±¼òýœÜwî9üÚßFÅð¯à/âI£†¾§ö±ðgÉ’T?oÌC{ÎË+ùûlØÞÌߪùçüÝÿš¿æï=ü~¿1wÿ{¿1¼æ˜Iø±³ÿŽ÷KWà/R›[ëóñçå/RŸÏÏ×RvRµ‡u|‚þÐĬÇó;sûP¶ƒaÏ¿ÂZN9}î³Õ~êz«ì×~W£*þ¨ÿ9}iŒòÔ>œýÞü§á£Êøy[þƒú\}¾ƒ¿Ï†íÍü­˜vÿkþš¿æ/Ÿç÷é0_A[°yfl{Î?•_Vâßñ~éÓüU©Í+ñç­Ï­üiÞ¯(éSþó࣎ÏãY¶ýüÿQ1®Å?ÛþûoÃñ¿¤¯£"õEªåïoȘýÖgܳñ{â-#>ßÂߊùç üßÚÿš¿æïüIÏôi®_ñýÌ–üR¿‡ßÕüEërk}~KüYçd–þyÌ–¬ñŠ=jœÇNá—ü§}¾›»?aíÿ{ªÙ¯ùúü^ÿKúÒ8©—$›WåÓãgû5õùJþ>¶7ów2~oÇÿíöߎÿÛí¯Œ?c~m lÃDcf+‡ß2÷©ˆßÛ¿Vò—U›këó›âÏ[›ï®ÏWÅç/INá·Ö§žþëéÿÏg‹M»ì§žqÇêó +ø½þ—ôá8Åñç©$Yþ«4~FñW°_Êy«ùûlØÞÌßÉø½ÿ·Û;þo·¿þ1àäy&¾¥¥¥¥¥¥¥¥¥¥¥¥¥¥eXï/Tx¿±+¶]ƒ_ãÿÝüe®›S8™ÿçêÏ2Ÿ£iŸ;—Ë#Ð?víùœø-þßÉ_V]®±ŸšTçOš‡eŒ/ÜqlLÀôÇqª®™eþ®MuüÙögÌ­oò‡?£Æ¸1~)}O­­2òåïù3uÎ7ç?¨ÏÙ¯É+ùûØÞÄßÊøíþ×ü5ÍŸ¿Å>Î +·e~„Ù!Ù'åŠ®Íø#þ_Å_òwÍUößÈŸ¦–ÛYŸ=ŸçïÊDÞÏ8~‡²þgu/2ª/ñé±ÿ©!Ž›ùß]ŸGù:QÿSúÞúÄSûÀùMöü„ú<ûQÃwí[óŸÇþÝõ9üü9´½…¿ñËñÏ©ˆ¿ùkþš¿½øµöi¸ÁγÎàu9û49Æ—ÆO^~¬ø#þ_Á_f]>æó™õy5þ4õ‹—ÿ¹} …>£{âýš+ñÃ÷cFõÇÿÑûKØo~TôŸ…ÿH}¾‹ìšQÿSú–ÚdÆï©{²óæ' ;æÿ7ç?ì<ýT=ny~,Êßçàv;;âWⲡ +þæ¯ùkþöã—„ú}¼y>åÑ—ì“ôµ¹ûŽKØþUø£þÏæoEmnÁOñX•?ísÐþ¨ö¡¨ñq®oN¼_s%~ø~̨>Çç#'úoþ½õùNþWøŸÒ×Ö%˜ýÞº'ó÷i+Ÿ'ø[1ÉÊü}n·ò·#~»ÿ5Í_ó·BÆõ9[¨ûc®e± þé[ó‡‘j%þLÿgð·¢6·ØÏñY•?míë•ßÏX†ýšúÜkuÿQø2žÑ}CüZsf¿§æ±Ž_\ûÕÆÏJù/2‘žgßÉßçàv+;â·û_ó×ü5+dæÇ#Ù÷o,¹êcþÇâl%þ¨ÿ³ù[±fnµŸã³"ZÛ³ø‡5 UÛ|ëû%3ì§8­ÐÿOñy¾½þLþ,9‡²ßS÷dÆ_•ñ³Rþ“Dƒõú¹–¿ÏáíVþvį†¿Êø›¿æ¯ù[ÿ9_’Ÿï̵´´´´´´´´´´´´´´,xàÙï)PkØ~ìšÒšlü?~§—ºqÛ6ü~»]ø ›Üþèg®›G퇄VæOZ;—Ú†’¿Ø3<ã^Û7¼_2Ã~ïZñ?ãwÕ¬þƒúÖþ³Š,Ö¡oˆ_‰?n­ÐÊŸg]Râ¿óßùù‹”wð÷)²ÝÈ_$~»ÿ5Í_ó—Áß|ýá_ªíñÙËÔ×´ÿ|.7GíÃëj|³–ÿ³øËªÍìGy­ÈŸÆ~®_c’¿œšöµx1})þ൱ñ-Š?Ã~ÏsÜÃ~ëïîiô¹1`…ýš˜Çêó7Ä/Ç6>yùóÔ;œo:ÿÙôWÙoùÎ×*þ>…¶Ûø‹Äo÷¿æ¯ùkþ2ùƒï”¥ðI²Â>h#6þcïÄ…ma¶ÀÏ;ðgú?ƒ¿Ìï›'ØÿËV™?hVÿ‰Æ¯¦LúO{ +?Övílüì÷¬cúR߇ÿ¯¶Ü‹ú—ßKürüqc”‡?O½}Ðù¯ÖüEû»,+ùûÛnâ/¿Ýÿš¿æ¯ùËæo>NÙ$ñcѧڧÎÁÆ}?Ç vÞjüZýhûþ²žgÚÏåôjüI÷'²ú×~­`ö[ðRøçkk0dâ?mÿS¯J÷L½úXžÈöŸ§>Ÿ~7íúøåü/Õþ"µŽ4þ{ýÿMùo…ýÖú|£VÛnà/+~»ÿ5Í_óåoü_—x²êkÛÇzIòpÿ¬÷yüÕ®—gÚ/åñJüQ¾Úç°cø£öK}’ýþ +È7gÛ ü+ìß©?cjÂÕöϵ9ì£o‰_î87FEøóÔ9šüõÿÛóß*û5õùþª×èUùËŠßîÍ_ó×üyñÃ÷ÓpöYùá°P×çô±qžÂ/µƒ—ÚâÇø‰ú?ª©Í3íçrxEþ¨g$ÿs}gî?ñ+ ´ö_`¿í¥iÿþUöŸÐýhµýp¾ÿÆøåŽKc”·}OÃåÎz»)þ"ökëóÕüQ>¶ÊüEã·û_ó×ü5üߘƒþ¥ìâ8Òà“ô±ó°ñ}ÇðÃö´² +?þè{Ÿg϶ã¶*œO2ëó¨ýÉÔ‡ör|TÄÿöúÜÓ>6Ç~küJ¶sö{ø³Ö7ÿ>)úûµÏžíàOÂò9¸Uå/¿Ýÿš¿æ¯ù‹ò÷|–äy&¾¥¥¥¥¥¥¥¥¥¥¥¥¥¥e̵>ö¾6Xó~jv¸.¯•¹MÍ5°{®Ô¹þÿ¿Ÿñÿ”Ýø9} ~‹ÿ­úžµóösüVäz¶]ëî¾ä¬ƒíçâ‡j³Êû5wâ÷9üÔ¹ØýPÈŸ„ÿ—ø ècþ›ßçIé,´_‹‹ãwó§ÍC^û=ëó5:ÿÕ™¿hžAÓØŸÅŸ1Çoߪñ—¿Ýÿš¿æ¯ùóâ‡\`û¨úBó,¼ÖП×ôçsç¿ÄœÅ„ÿ™ =ïºÁ~~xŽ¿äÿˆ¾·>Ï´ŸÊÕUùãæZVÿcø`Û~)~(`í_h|x~lÌÃü?ŽSu¼>×¾$Q}.~¸x_dÿ/Û…øÝüEm—Ú÷Ö5ÿêÍ_<õùjþ¹~ëV‰¿¬øíþ×ü5Í_”?Œ‹(?X[³}ó9˜>1Œ£zþG?ãYý]ø1|VüZÿ[ô=u9VŸgØåèÊüaß#ôðGõOIVÔ·³?(]8¾Uů7ßúØXÍñ?î·þÄ«ÊÎY¢úXühbž²ÿéOhíçKýuþüQõD¶ý‘º†òe¥ñ³Bþ[m¿ö7\NÌ_yËV¿Ìøíþ×ü5Í_”?xœjS;¿¡®Ÿ/ ô¨±›jŸÃ?î¡`sÒgß +ü”o=ø5þ×êGjóQŸgÙÏåçŠüaþðò7·Ãõñ¨>5¾pçhô«â‡ç#Ï(ÿ¢;³ðzp5¡ÅÞ }¿˜í”¿$ûGÿáìçüà'çÓ'ðïâÚ½Š?oMÓù¯ÆüÅ’KµøWðW½F?=ÿÌŒßîÍ_ó×üyñù2çwÍ3°l®Ä 5f{ œO0üóÌ_”üDðS~öâ—üoÑÔæÙöCŽ+ó§©Í=üÁZ$[«u°ã°.‚Ç$ýŠøg±êcÏ)Yð[Å£OÅ/f»Õþ±.®Å‚Ë'ñïâÏc·×~k=Óù¯Îü…ËÞü±’¿ªuú)þVÄo÷¿æ¯ùkþ"üQós‰+^é|j¬÷+(} +?¼Ï±?%^üÚö5úѵóLû1ž«ò'­}¬âOÂÛÒôo‹þìj|«ˆà†ã†Ÿz.^ßd«Å~‹þl%«ì×Σ«â÷øŸÊI«øóÔ2ÿjÌ_¨ÜùØ/­ŸŸæ¯Z~‚¿ìøíþw·ýÍßÝö¿‰?l® áÇ‚™;—š{hìÃðcç®ÄáÇë‹~´6Ï´_šcVâOªÍ3ø“ô0}Ø—µúÚ±xì›k¥êø¥ÚGSßyûߪø£ì§ì\i?5>ß‚ßãÿ¨ÍVû=µLåñ³JþÛa¿·>¯Àß ëè7Åo÷¿ýý¯ùkþÞÄßÀÇÉóÌ|KKKKKKKKKKKKKKË:÷óG ÿì£jùùž +µßó~[i=`>ÞÓ©€¬}üËý•ø9ýèó쬰Ÿ»O^‰?Êþàš¼‡6ú¤´.HÉ£?·e½Æ¬a¿?¶ÆNñ í›ù÷Ȉ¿!Qý×Ïó1xÎ#;ìçÖ¸nÀoåOZÓ[a¿w±Òøy:ÿ°ŸÊ£Ï¹ÔþJøýŠëèoßÛñ»ý·ãÿvû«ã‡Ï¯fÌo¸ãˆ=è\Æ´kÈøíüSøá÷ %üþúlõ¹d?ü}ýïªüiŸk·àÇú=…_ó, 6¾@Ló¹ó_øÿзŒkUñSíhâG{.§aóèsù„Ê/«íÇÆkŒŒ_ìÚ0¿Uã³wžúó¿ÇþËóßVûaþãîscÇ«Î_*Öè;ø³ÆoUþ¾µÿ5ÍßÛøë]c~´Ë>bþcNs­“øgßÎþ}öYÞ/Å/­·dÕæ˜ýã÷Ÿ¡ý¾ªüiîUDø‹Ö·Ôü~Ø5Ÿ#µõ¡vÊøµþ‡×Ψï8ÿDô¡¯0vØÏÍ©úœks7~«ÿ-uBÇöÍùïTþ€ùOÊ¥Øþªùϲ–þÙ´­æ¯çŸw÷¿æ¯ù{c=|â™ßPócj>B½ ïçÝ‚ì{þÎÏ(xðGü¯ÍkÞº\cÿüŽ&Ê~.ßVåòKÔqíøBÕ8ðùrJúDjŸjOÂ_åý’œáøê‰?Ø~¶>ÄIùq—ýÔ¼Ö§?TçÏR#dñ÷qlÕÆÏù/C?j?Ì–õóÙGUù»¡FÏäÏ¿Õùû¶þ×ü5oåOóL*eÔŸm™sÇ5¢ïçÝêÎüìÂÉoÚú\kÿl#f¿%×VáOû<¿ Vû©¾îñÝ3>`úóXdů}¿ä8oþ•þ‹ò§ÕŸ9¨?T?ƾ“…qEqX‘?M}°‚?ÏØ^eüÜ™¿£úQû±ü‡Õæš¼R•¿Ê5ú +þvÆo÷¿æ¯ùkþ4ø!>¿ÖwÇÌÇ©ù½v¾·ÿù;;ð¯Ês0¿®°Ÿj»2ØúGFüYô5ýÕÚ¿W¾ŸÑSŸÃsVá§l‚ÿgå7Oìjô©<1Ží²öå?‡‘j7~ÿ©qkžñ¼Êøy2W·_[ŸWÄ_¥>¶·Æïíø¿ÝþÛñ»ý•ñgÌo  C°1Ú Û—~Ãy'~iÿ +üŸÍÛ +û©¶*óÇÕç‘ø³ê?Ÿ->YYßzìÆ'®F‡ÇvÖç™þƒú”¬úVÙiÿèÇ”>´æ¦Óø9}jÌÚÍŸg Sþ;Áÿjû³×ÏOã¯T£¿!~oÇÿíöߎÿÛí¯„Ìÿ9yž‰oiiiiiiiiiiiiiiY'Öû Ú÷»ÎŸ±ûžð¸@Ýg÷-<˜!þùzܽ L}ìÎ,üŸ›Äß,^û±v+ó‡­ dÅŸ„™:>÷?I‡âcÆO‹ÝO¼?¼.Œé9&®}ÎNêXDÆ?çÿŠö߆Ÿ.·ÛïÓOŸ˜¬z?}DÿÁµ#ÿÍö{~פ"•ÖÑwòß*ü}kÿkþš¿[ùÓÚ7ÛÅÙH¥ðºóµ´þõâþÎߘ1ÌáÿÐþlü;óٜӴ1µ¶_?l•‘þÇÇÆLçêÚ!³¯«ã—¸ÅÚ§~+^£û{}ªÿQý³šý7ã'†Ííö{ÆöóŸgþÕß™ÿ†~´>¯Ä_•úüÙvñßJü}cÿkþš¿[ùÓÚ‡aG¸À6u[˜™üH~ÅxZ…gÓò‡Ù±ŸÂQ•¿Ûëó7¼_Ã?¾ÓŽ]K;©ö¹÷¹=}FåŸl}Ì\þ«fÿ­ø™áóˆý‘qþ†ü—1ÿˆê¯ÎÙõyþ*Öè+ùˈßJüeõŸ[ú_ó×üiùû?Ûôu î‹ +í]=³ì¸­œÀÉ ¼®M:ràÄ]Ïÿÿ[—®/½88~7D¨ +uæÌb7›iFúç_>¿ýó/Ÿßþñ×ÿûñ÷óùïÿ{|Š_±Ç_z–|üø¥MÂãÛÖÊO9î¿ÇÿoŸÏoÿúUoó£¯gãÿìß\úIÜGùKãY¿?ÿúË›5þzüµøÀÅu|þþûºéGéåÿ§¿Ë¾høŸÏ¤qjÍ¿Ú>ŠÏêQiüÌhÿˆø[âç.þ=>Bþk5-úïÈÅ_Ê+-øõ㜨}6o«õ¿ˆúΟHó/õKý¢êW³²V·xY1óoüzý½ø­öËëGÓ™øOä,~³ûŒMª~Ò:j÷øã¨?ûV|¤õ-oÿé“–X†Ÿ~ÆÛâãïùËý­öù{–?ÝÚ¾æ_ëÿYí¯â¿7–îæ?÷ó_­òß‘ÿŠÿH}ެJ}.û™úí¿9ÿR¿Ô/õkå§é`ÅJi}äím}¾ZªM«¿…ÿt~ÒôÓê¤úy1¢è·º>o©‹©ÿãWêjÍhÝMß—êsMw _$üÒ¸Öðküùñ­ü$µ?êïíTþñ÷ÄÖügä”ü×kµü5ê¿2ÿ¨Ïwë‡RŸKc?ן9ÿR¿Ô/²~-úp“b$ßõüÏ +}$Û“ZôóØÿV¬§õC¹~Îýy Ëͪ}=õ­c£à÷´/ÅOjå=z®ÀSßñcú·Öwhü£á»øæ„Óùoæú²gy2ÿE«Ï{ÛGªÑsý¹äù—ú¥~Qô{ö¯Ùóù´´´´´´´´´´´´´´´uöÿÿÃóÏßÇž÷hýn]S³®9XçPø9vœÿ½~ÎYԾ˭yŸ¶ß‹¿ôeéÛ•ç‡gé7“¿¦ŸgŒ à/}ɯÐ~æ{û¿v¾L?寷}éc9×fõK¹ÿÛÈùAüôm YñÃ:>Gÿ§Ôö¨+~4þAð‹QVÜ:Á¿'OH˜wå¿Öùßÿ#å¿bR^¡þ§ñÏÒáú¹5þoYæüKýR¿øú|Öç?)Zþü8Rûi÷Úóø·à¯éãÅO÷]‘gjøOó×ôã\Ðõ³ÖQÚñkøkÆÇíi¿ÆÑÓ¾¯ä_ӛǷQüeÌIíHcHã¯KSÊ_:ÏÐê_ã«?þñ‹·-kýüGòÆÎøÙ¿jñ£†Ô”mý¢åü3õCªÑgé×â]¿7οÔ/õ‹¦_ù¿|®ù×l…>–Fü\ þç½ÙùÅj]¿ÂƒþîY?«>_ÙÿôØV¬±Ú÷˜„kU}nµ9oÚ>R»\ ·å/á¯ÝK¯Åßâ/_4þ‘ð—8Uðkqø$ÿÖÜq*ÿi|%ßžø)ÿYy1ÿÍÒ©F¶Qý$ß7ë÷¶ù—ú¥~‘ôãøè±{øµøóÏ%}¬chþ§ñ?ÿÏÌ)VûQô{xðûâ ëg]çØÕÿµ9 µï5‰ ^ ?=¶ÃLüôûÅZ[÷¶íùZü±Æß ÿžçq ñ¯Õç|4üiqù¤~½uÈÎøéÕ~6ÿ‘ò‡åoåü«ôC­ÑŸ­à·êrnÈë—œ±ë‡Ô/õ£û{ùY=üjþš&Äçó–ýGr…$ý´ë¨úµÞÎÓÿZ»Rû=6£¾žåÏùZzœÆïy¾¥„·¥ýÿçÿNhüŸÚÛªÑùghø“ÖñúõÔ;ãçÌøõ†üW^K5bþ[¥rÞR›Kk™ô‹>ÿø{·Í¿Ô/Ž~eý`ÙÏ{椥¥¥¥¥¥¥¥¥¥¥¥¥¥-² Ÿoû¹n3‚ßs ïyÛý®_íz4š~ÞãÏ:¯G}¤÷­öµ6g?_rôùŽ;ð—s‹~~\¾¯t>—ëWÃO=â/éOû[óAáÿÏóÓb¼>ÅŸ¼îÙ¶æ?ËŸÛÛó_ñ×ò Zþ[­ê5ô²õ\G¿I¿¨óoÿÔ/õÛ¡ç"½§Õžïâñc!=Ÿ×óÛH ÿãëÅ_Ë#ýI¿Z}ަŸô;Á™ãOÂÇûNÂ_k_ë©ý¢¥§iûü}OlÚ_ŠyRÿ—ϵºŽ+Rû5õ·Æ5Þgñ§s="þúñ˜}’ù¬³ìøÂkGþÓðÆÏhù¯ø[÷oGÊ;ôCþ®û³õ~×ýý"οYüS¿Ôo~‰Ë¨>R[TºæÏ_óõÙ~ï½…5}¼øµØ?³ÿ#è§ýf U?­>Ÿ1þ´ùY³õ-ÕÓû|I©--®ÐÿWãçÇ+q”ú—ßD{j¥rŒ’Ozë»müׯ¼Æ_ÒÒâ_Η£à?¡Ý'ùÓý:JŽ/¼vä¿Uù;Zþ+þÚýáZñ¿E?ôýÙZêóÛô‹6ÿfñOýR¿]øùçZ›Þõv<þýÍO浌ŸÇúø‘ù?¯­<†ŠßªÏGûŸ¶cÍñQ-¾Xûxü%¾Ò1øÿ«ñóýŸ¿ÖõSgùñø>¥¦mÑk†?¿w­¿jüižÔŽYò0"þ]úñŽÂ¿£ÔhÂ%#æ¿§>GÆ¿¢ÿ¥õÁlë¹_Ü-úÝ>~£ã¿?2~¾V¶p·Þ_W[ëµø¯~¾íjü<ÎÏÆÎÿùë©ÍÑðK¿-›Ýÿ|->ÛŸ®ù󺀦ùK}€‚_ªo¸¿ô=¥™ão†¿6~%î­ü¥ï™E¿K¿Z ?Å¿§Îx[þFÍ­–‹‚•~oªÑoÔïÖñÿíü#à×Öç5~­x#>Ÿw?ñ3ñGѯ–¿õ“0ÏîË¿†Ÿ·å™ß-þÖó%[âýlþ‚›Ç=îo}/Þ£_M«ýZü)?ÍùGÄ/Åpþ=5ÆîüGuÚ?‘òå¯]?GË'ôÓêÝÐ6r ýíúE˜3ñ§~±ùGÒOZ'xôiÁ¼Š_/þGŸÕøy|Ÿ‰?Š~žóËhúµÔç£úÕü$>—½þÞXVÞ£µ­Ï{l5þZíã©ïzçßÊù#ñ×x¢óˆßÃwó—°Õ¶Ýùê´*~FZ¿X¿WFʧôC¯Ñg×çoÓ}þÍÄŸúÅæ®_é_Ëžï̧¥¥¥¥¥¥¥¥¥¥¥¥¥¥­³r>¿ÔðÏ{Z-OÏIhïG{¾íjüÒù×™øÑùkçÃ#èÇÏÝÏo{¾äþúÝðKר5½9?ª•ñWlÔ¿çùòHü£ãgŸ©q|'z¯¾!#çm_ë:kü»ôC¾ŽÞr ýVýn¿ÑñßÎÿžo‹ŒŸÇõø‘ù[ßçCÇÏ×3ú_š÷~Ïwi¤øÂ1Ñ}é_þºø·Äµ'–•çWñúè$~­ÏøñîkùKØzü­|¢å—Óü-}¥cóü†ªŸ´NGЯ·Æðè!£æ¿tßÑHøwê‡Z£{ësë^q7èwÃøŽÿvþèøËõ®²>ÚÅb}¾m¹Ç-~R«|Û$ü£ý¬Ÿ•¯Ðõãëmüõö¿4g[ê[m}_xÑ}jísîgÕ ¥>/¿…AÀïí~ì™õiÏ1,ÞW$þÚ8’x!âWæ§ÏOè§=ÿÍ»ÕôÌ.üoÎÒ1x>DÍ(úE¯Ño×mþqþ9ÿR?dýÊ:º³g}£­µõHyïùK¯ñŸx¾í*ü<žkÇídý¤\E?­>Ÿ¡Ÿö¹7¾h5ÿ~¹æÇû¤Ö¾ÖÞcåºSµûcîÆoõ#¯=ã·?ÛŸãÔú…?=¶~c~Š1}§~Rüì­1VÇzžíÆü'­_¤ú?Š~‘ësOþvýæ_”õgê—úiZõpãþ”‹µ>¡üN<ßv~)ž¯ÂÈ¿XkžB¿B¿ÚXnå¯Íõž¾+×Àµ}´¸AÏ!Jó÷4þ•íêçõ§ ©}m¾iØGõß©_-&ìÖÏÂæÝVÆéw*«øGY¿X9 ?š~H5ú¬úü&ýæ_$ü©_ê§}Þr\ê_{F ýœ÷ƒÄïcáCÁÏcùNüüÓî—A?KÃü-þÒÿ-ú·X™gV}!ñç×¹QñkœøëYù­gìzüµCàoaÔÚGÂoõ? (úIؼÛÛò÷¨ÿjþÞúÿiý"Öè©ß=ü£ã¿?2þ™ë3£ÅÝÃO⊄_Šã;ñŸæ_Žå½—)*~†­ø[ýŸÿ[úde}[›«èøW¶Ïý5}[ý[ …áÀÇ6–Ððkúñ˜pB?+~ôÖoÊߣþ«ùϾ~¾?‚~(õù³­¨Ï߮ߛùGÇ;$üeýlÙóø´´´´Vûå×_¶Ùi®iiiiiï³Ìciii»­õüÂãSjúÛ}¯=þÒw ˹Ë×sO‡7ïõóÔïüükÁ›ó/õCÒÏ£Oá]°+ÿÓ÷ù>E_~\ÊÕ;><ÚHúPœüµeüRìîÅßÚÿHúYù Y?ÖÖ7gé×k5ÎYê?ºŸU× èomvãç¿o¯á¯i+µ¯Ý+ÞãÏÇ—4wFüµñ«ïügÌ¿“øõû²ÐÏzjŒÙñS›ÿ7ä?«}o}~:ÿEÔïspóÖç©_Ö©_ê×£_‹>5\’N-ë{éØ^~Ϻ½`d¿)VÇ×BÂPÃÏcv/~oÿ£ê7ZŸŸÒÏÒr¦~;êÛ¢3/庣çX¥ÿK¾?½>JñkÏǬÅN­}ëynñ>Óâ÷l©ÿ¬ü±‹ÿÈüCÀ? ß·ø¾[?oüì©1fÆÏ‘ümõ_„ügñ÷Ôçù/²~Ð=õ;?ÿ¼ñ3ç_ꇦŸGŸ²^·4‘´iå'õ™‡Ÿu*º>«i#í×SŸ÷¬¯zûE?í¾íèúYZÎÒ¯Ç_‹oZ<¡:Òso{¾¤„ßZM¯qÒü)¾ZŽñ—ÆÏŒögñï(ø;Ú7ãûý¼ñs¤Î¨éçµ[óŸÅ¿VŸ£ä¿7è÷«ÑS¿óóÏ?éÿ9ÿR?ýjÖz<ŠãÑ´ÇŸ£æßû¹4®Z/ÅêVü³û§~VŽŠ _MÏSúiã‡Î}+¾ÐúümÏ—äøµ¸K%}.µÏß³üùëÖö5ÿZÿÏj¿—?ï÷hø[Û·âû ýjÇ©3<ǯÙMùÏËäþí;óß›ôûlÞZïåžúÙúÝP?¤~©ß¨½ýùÄZP>k©ÏWâGÓ¯–Ÿ"èWã4»ÿk±@óŸù|Fé¾Hø¥q¡á×øóçcXñ]jÔßÛÿ»ùϘ'ñ÷ê'Å„Súyl´Î°ô«ÙMù¯…ï³·vç¿7ê÷©ÑS¿>ýPø§~©ß üHúÌl_Ò§ÇZêó•øÑô³rSý7­>Oýîåÿíüwâ§çëéïç5Ó>¿ùùÌ<&ïš¿”"ê'?ÎkþÚù2ïóùÿ(Ïg¤÷¿¨]›—lþÑö­ãókûÿ§Ôö¨+þühò§ß-þVý´X·S¿–øÓQN¨¿ÓBÌßÈùCÛ×ú®süoÑï³qó\COýâñŽÿvþèøŸ×‘žo,ÙiüR<Þ‰ÿ$z8ý´ñljíÂÏã„ÛŠ/R_×4àí{öµúŸö Å@ÿò׳ðÏhß×­ñ'ghõ¯ñ•ôßÉÿÉeÏ=¤ç¯EÀߪ_-&ìàß:J ×9W¤üš?4þ¼F‹†ÿ-ú}lµß6¤~ñøGÇ;tüå|ÿϘµÅFñ•çÊ{Žõü-ûŸÂÏcðîçKŸÒOIAáôããO{Öñ*ý4üÒúœÏuþKûRܘYŸkmHüz⫆FûR?[þµúlÔ¿6–9þ]ü+õyùÞW$ü­úÕb þZüì,!T_ŽÙ?«ü#ç?-ÿñ 8ÿ½^¿Xžú­ŸœοÔY¿²Žàßmᥭ¯µz¢¼÷ü¥×ø£=ŸYŠ¿ÔŸ®³´cŽöÿ)ý$ÞÑô³ÆŸ¦ëlý¨ÑúBâ!½/ù·ô/£øé÷{5¸&3ñ¯h¿Öï«ý½Ç;Á¿\C—rj™ÛÈø[ô³bý.ý¼ñ³³| \¾qmÍßoÎþRþ“êsTüo×ïsxã¿qHýÖÏ?oüDÀŸú¥~’V=ܸ?å"­+$~ÑžÏÌã-o_úžâlü§øsîõ³ÆŸÄï”~4Ìl_‹»Æm»\ƒÝ‰ßÓ>íûžþõGçOÏ!KóÿMúÕbÒük­<þ­ùûÍùÏÃ_Ê#Ï?ßÿý> [êw_ýú¥~-økßÉôÿñã÷ááFqÓ÷%~| ßNüRŒEÀ¿ƒ¿Ä=š~µñ'ñÛ¥Ÿæ«Å‰òYK|’¸œˆïtœœÂ_k¿güÎðoå³›?¿Î «~ÒšúÿþÞú€ÆGm_äü¾~ñÖç¨øß¨ßdKýâóŽÿvþÈøg¬Ï9›d~×øylEÁ¿ƒ¿Ä…ÿ¬ñ§qÜ¡Ÿ,C?»êóÝíêßãÿüßÂi'ißHø{ôã1á/þÖÚ ø×òœâ?úúeöõóÝøßªßd+ßwOýbòŽÿvþHøËú!­Í¤¸z3ÿÓx’cÓîvKòþ]1aÿÖº çX§õˆhÏ?O›3gVm96ÒÒÒZÏ/xŸÏ,íƒò|æQüR<=…ÿvþ+Çç8 ?ýß:§&½Oïá='Ç8}Ñ£ö=nø-ýéyLi‡7:FR?LþÑñßÎ?~?¾ž ¯-ãþÔè>žö=ûjþR»'i©>ÝŸb=¡ßiþ£úyÇŸÄs~é3>4}jܤø Ý+ÚãËøåÜx}¦Õu¼¬þ«Ù¨¿5~´¾*ÆïÏÖÊ¿<;í~@ý¾Å„ÝúyâOO=@Û×0!ÄÿÓùÏ›?´öGësM¯~£øoбFOýÞQ?œÆŸúÅÕ¯…ŸÅCÃݲ>’x¬ÒÇj“áÿ¶Âß;¿õƒáß©_Óøãgá×â—ÇߊµØ¡ñ×jt~­ ¿5~ËgôûÅÿy¯åùšO H~‹Û¬ù¨¿5þµ¾*ØËýO9ϹÜYüGðêçŠ}+õ«Í·ÞZ€¶/õciß›^šÿÜmiüWÔçV›¨ë¯úQ>‡6†!õá/µ‘ó/õ[‰ßËÏ£´_ëúˆwöøô‡´ým;…¶ƒ~ü{ôCÅ_ë÷YþþÚ>ÿÓø­ñK÷çßQîy¾fùP©i[õõ§ø¼ù…ò§Ï(yÛóEè×ÿVèWÃß[Ô°Sü-¾/ËÍãžóŸUŸ¿!ÿEÐëu¢^ï/©_®?S¿÷èW3í7ët=Ñã_ã×ë/µ/­ã-ìÏûRÌ<…ÿ”~=}€¢ÒøÓŽï™·­þR­#}®õ§×ÿþÚø->åýÏ×õׯŸ¤ÄŸr<Á?’~½9`•~Œžã¬á÷öÛò_Oûÿ‘úümù/Š~Z¾³V©Ïo×o&þœ©ß)ü^},.Ú:ÝZ_×ú¥e}Ò¢·}ïzd~«ÿWê×ÚHú!¿Ö~×ü­ZZ;~‹ÿóš?m?ïó)éõWO¼Öð÷èßëOùi†Ì?2þž<°’ ŸwÓæÿ¿¥>[þ›•?fÖçÞögâ¿U¿Z¾£^o3©_®?S¿wé×¢O!ÿ‘ú_gÞõÌNüžñ5S¿Y}pB?ÔñDZ{↧¾­ù{k™ò­ðׯ/úó5Gýk<ÑùGÆ?gó¯áónµùÈÛïÍQóßÌü1ZŸS¢æ¿ˆúµÔç+kõÖ1“úÍç_8ÐÏrþ¥~³ñ?û§ÙÆããíüo샴´´4ô8Ø»æc_ Z>ÿ<®õÖè³kõ7iiï7~~Àºÿ³Qñ¯Ò/ +ÿèãïvþÑñßÎ?:~?…€ü»¶üÊ¡ õC¿¼f‹†ÿfýFëóY5:½†žúaðŽÿvþˆøéñ >­íò/?îïiÿäó™­u +þúñ>@â}üÝÎ?:þÛùGÇßê/å0þ][/~éXÈú!Œ_­>‚?õû¢N/5zê—ù/õ{7~Äç{8®Â_[Ç àß¡_mý…¨_”ñw;ÿèøoç«-ðïÞzñ×úI?„ñ+Õç‘ðß®ZžúeþKýîÀO?çûyùµøkí[ûxüGð×Ö0HøWëWëƒÓü£¿ÛùGÇ;ÿèø[ýkùïZ¿kޏ}þy®Ÿ#ã¿]?¤Ž¡Ô/ó_ê÷Nüåõó›tÉŸ¿Ö¬Õß۾đ¿7 ¿Ñð¯Öôñw;ÿèøoç¿Tƒ"ñï]ëà׎‡¨ßéñ+Õç‘ðß®ý ­FOýöòŽÿvþèøùóiøçÚ±<ü,,Úñ[üŸ×³ñ×b!þÕú¡ó>þnçÿíü£ã+ÿžuþ(~혩ßW^›Eû~œ?Ržúíåÿíü#à/÷˜ãø4~G¾š¿ÆEÂ4-"â_©_þÑÇßíü£ã¿tüoæ¯Åo)·ÍÀ¯7õûý5¯Ë¢á¿]?‰ÿé]ú½Dê—ù/õ‹ÿù?í«•˜G_Ó÷n1)œÆ”––––†Û3gØÆk2éýÓÓÆu=UŸŸî‡´´´9Fkýr9ë<Áç§¿.ï5z¼žcX÷×[_…°øgóçÄ#êiüÝÎ?:þÛùGÇi? ¿uìÔO¾?œT«¡â¿]¿„=õÛÏ?:þÛù#âç\¤÷8¿òúáÉ?çÆUüé5}º/ýË_ÿø¥ú ÿJþœxDýÐÇßíü£ã¿tü·ò—Ö÷3ñkÇOýüõyùm:þÛõóð?]£§~{øGÇ;ÿ(ø%.£ü¤¶(?ºæÏ_ÓûÏïÀoÕçHøgó·ÖWˆü£¿ÛùGÇ;ÿèøoãï©ÏGñ+%DêG~ƒN?÷Ôè(øo×ÏÃÿD®}ÿ"õËü—úÅÅÏ?7r®É©v<þýÍOæµß‹ÿß´'­/ð¯Ò“Žªúø[¥_þ©_lþ©_Lþµú|~­>Oýôö¼õùc9ÿðùŸªÑS¿õüsþÅæA?zLWËwx;ô˜=þåõÓ'’ÿ~MÒŸ_64ü«ôÓÖnÑô+Ç,ûÝ¢çŸú¥~©ß}úýºÍG‹ +í»’ä¸EÛ³ÆH±ŽLY2äÈІ֘ÿÿ0)83ˆÁdgâE€È$NGdTu‘IÜ‹S ™|ÕÿøøßYüëãûë‡ò—Ï—â?ÿüí[|ýòk~k´´s-?o«´<­ý»ù¥ËÉOïÿü½Mÿßÿë§°ÚO\júGùè?Ÿ¶ik| ü¥ï üÖúgüÁï ýiZ>]›W.¿Woïü¹·Rþ¨þ¹Þó¦¿Ò>U4~ržø•›øÁ~Ïûo­Ïgðk­Ñá÷Sÿ¬ú|¿ß¿·ó“úwÕçð[ëŸñ¿§ôçóXµ¼Æ§Gó*£ú¯¾/1zª>Õ¿‚_i_*?9í~¥ðæ~ðƒßÿ-õù,~-mÁï·ê9tÆ_ ~šþ'kôÞú~lÿàç_êß§ã#‹]u~ªÏ#éŸé9"¿‚ÇÐúO÷]ÿéþ£ëƒÿ–õü,ýZ ±›w~²F‹¦ßsìòÿd¾»ßÈýøZ~œájϪåócÖçWþÿý—jNÞv©ý|~9¯<ž±R¿\çyÓ¿Àÿ§¿Èü¼ÿN÷]ÿéþ£ë?Ù¿\ϯ֯µ?[¿V£EÒ:?+žªÏá·Þtý§û÷®?ÃÏõåù½QË—~ÒyKŸå+k«ô[ë¼™úïöÿd~Ÿö¡"ó{B¿3~û‡_lÿð;_a·~™~kÛ?[¿uº'ýðëÓÿÔ9tø±ýƒŸýµþ¿¦'Oú˵åú.-W´,ëz½ú`•þR}néO÷4´ê¿Ûÿ³øiëøèüFôGå7Ë?üà¿wó+íׯâgµ?[ÿÊú¼—Ÿ¥~ýúªÑá·ˆßJýŒ?øI>×kꓼ½ÖÈõi~,×kéøA:>¡-#ýñY¥¿VŸ×ô§¾-é¿Ûÿ³øiûNÑùÝÕ‰ß +ÿðƒüÞǯµ>ŸÍϪÏá§ëo­Ï>ùí¬ÑáÇö~ïâ—¼Žx“ù¹é+Ÿ'÷'Ûϯ]h‰™úµu^¯þ|Ú*ý3ü[^#ó›¡? +¿Uþá?ø½_K}¾‚_éXü>ç·ÔçŒ?¿üv×èðcû¿÷ð“úFø^y©_­Èû=ÿ\ã#ç)雩¿T¯zÖ?’/½¾_Tý§û®ÿtÿÑõŸàßÚŸ_­¿t<~Ÿõ÷^ßîMÿéüZ4?q~lÿà_ÿŒã/ÒƒåM‹š×Ùúµõ\ý½9–×Èü"ë?Ýtý§û®ÿÿÖþüjý¥~¿þ¯Õd‘ôŸÎ¯5V×èðcû¿xú¯ÿ‰Ï!×o»õà• ‚˜Ö¾ü®¶w÷‡×Ðj²Ýšˆg8ϪÑw{#¢?z/¤ß‡KqÈ/.Ÿ&ç¹âãG»òBÒcgHÇ-f<Ÿ¯¦_[¿yÕ?ÿå5*¿HúO÷]ÿéþ£ë?Ùi;÷„~Ù6üìõX4ý§óëÑ¿ªF‡Û?øÅÖßâ/iÊõ•tåóåùyäó´´ß2¯•¯µ›ûëµ|ús­wóµõxt~rÙoæ÷Æñ?øÁo=?k?þ)~ZÛðÓúÎñƒ_žo±‘:f×çðcû¿Øüzü•|Xº{Žh>VñÉÿ/í¯xÒ?:¾j^£óÓ¾—oå§é…üà¿™õù*ý½5úÉüJõy©M/úOç§µßÂoò½èðcû¿ üZýµ°Ñæë=¿/—;ûû©è+î¯xÑ?#¿wß,?Kƒ7ý³óß2þà?ø=ï´ÿ$¿‘úüD~²cüÅâ'Ûïá7±F‡Û?øåW ëžõÔ^­ÝÞ{Þ¥—‘{æeûyŸå˾Þkû +wÚ_¡V~ÍkD~–OúWä¿eüÁ~ð{†ßH}¾BO}~2¿Z}ÎøóÍïîúsæuîð{žŸýð‹Ë¯•OÉ‹u|àú¬GŸÖw³ùÈéµýúKýß“oÕç‘ùYí¿‘Ÿ¥~ðƒüZø•öãŸâ×SCœÌO«Ï[Û÷ ÿt~3ÖŸ³îI‡ß~ôÃ/.¿>#áéøìkÅ£þ–ïW-¿æ5?9<ëŸÁïmã~ðƒß³üJõù“Û¿Öâd~µúœñ盟Ìå7ëùîðÛÃσ~øÅàwÍO|¹þ:ÉëÛýA¿F­>ß­ewÿx +YoíÖCøù.ŒÖè»}a‡<>Pzþ¼<æ¢}žßÿn…¢_Ó?»F÷¦Ÿñ÷ÜúsV?¶ðó¡ßj?ŸnyªñéÉ·Ú¯õk-¿…Mú¼v¼~§þÑöKù¥}Ÿˆü<ÿVð{Ûøó¬~ð{;¿žúüIý-5ú‰ü¬:Ì£~Æß3ëÏÚ¹ñŽkÞáÇö~NôçÓ®×ëžt-_¾·¢7¿µ}Í£üLË—4ý¥}€ÝúgµŸ¿/ùÈϳþü"ù‡üàçŸ_­>ߥ¿V£ŸÊϪϽégü=·þœU£Ão?Æüd~:ïžæ+ùëåSÒb-¿'ÿzo鯵“¦—¶ÿ;õ·öÿH~k}ŸœæEÿJ~oðƒüöó³êsüJÛ«SùY5˜ýŒ¿çןwŸ§Õçð{Žã~Zÿ§gÌÉþµ|•µè«å[^4M–~ÙžrÛïEOÿ÷ä×ÎGDã'ãíüÞ6þà?øíç×SŸ?ͯ¶Í:•ŸV[yÑÏøÛ³þ\U£Ãíüžçwýÿöø!¦}ªÏßý–øþ~±~ïçgÕ绵[úvëñÂO«Ï‰³×Ÿ³jôÝýæ%ØþÅŽÈüòZ?=C®tœ ù“çå[#>ÞÈ2JÏ×Óôóø·Ÿ‘ë×öG¼éïéÿÆü.¿žùEøþ-àÊ?üà?ÿü¬ú|·~k»¿ïmk׸{ÒÏøÛ³þ\u~±ôÃ/6?ÉBûLòÉϽËéÚ9ü|Y)??§ŸÏ›¿Ê÷)¿Gÿõ›ó_¿|oïGMnnó=ê¯õO¾¶ÿ™_„ïßL~oôÃ~'ðk©ÏwòÓ¶[ðÓÏ•zÒÏøÛ³þœUŸËïübégü½ƒŸÆâ.­­Ü_>•/ß§üVýW$>éZ‡ÌK±Võ ¿µÿ[ò¥ßèü"èŸÉ¯”ïÕ?üà?ÿü¬ú<¯ÑwòÓtÁïû«UOyÐÏøÛ·þ\Q£Ã/–~Æß;øÉéV›¹¿š7íy}•gi³Ú/éOÇP®h­Ï=éoéÿZ¾¶ß×gÞõÏàWË÷ì~ðƒŸo~¥ú|·þ;Ûëøiõ”'ý-ý2¿•úg×èð{–ß ý-ý?¿úóeZ\z® íäËÉOïÓ1RŸhúókúKç ¼ê¯õK~Om…_i|½ßý»ýÃ~ðóͯTŸçÛ‹ü,Mð«ŸC÷ÀÏj~kõϬÑá÷<¿»úký?ßúóiùtm^¹ü^½½óçÞJù–~yœ#å÷žOÞ¥¿µýZþ¬ý-/ü¢èŸÅ/ªøÅö¿3ø­ªÏgò+é:_˳½vó[‘ÿ~+õϬϭïü|êom~>õ[óXµ¼æ¯Gó*š~m^kÄ£þžñUʯíoEäAÿ,~QýÃ~ð‹Áow}ÞÚÿ¥íöÉü®÷;ëóÑþ‡ß3úŸ®Ñá·_?ã/>¿¤ïéøÈbCÛŸþ"éÚkdÿoÕºÿèúO÷]ÿÛükÛˆÒöb—þÛ²7ð»Âº9ŠþÓù­Ö?û:÷hþ=Etý§ûR~œD>_Î:¦R8Wûí~üZNÞvùýóÖ¼òxF¯~¹¦_.»”o ‰ÌïMúO÷]ÿéþ£ë?Ým›èM¿VŸÃïççÚsâ<ë‡ß³úgÖèð‹¯ÿtÿÞõËßrk}>Ÿµ|éGÞŸ/õY¾R¤gç÷è×êÕQýòþ†^ý3ú¿”_ò•ßLýÞù­ö?øÁ~­Û‰Ýü´ãÍðûµk‘wó[‘ÿ&~O¬?­Z{ô:wø=ËoöøŸo~×2ÒÏûVêמå?K¿•õù.~3õ{ç·Ú?üà?øÔç»øiçÐOç—ëo­Ïwñ“¿qý£üfÕè»ýŸÊo¦~øùæwMOm]ÓóöZ#×§ù±ü]¯‰‘–ŸŽ¯hËó´ê×öEîèϯQÑ·ÿkù-µy$~³õ{ç÷¶ñ?øÁÏ?«>÷ÈO«ÏOç—·¯Õ]žø1þæêå'¿'IÿȽèðcû¿õüÒ¼#Þd~îEúÊçÉùÈöói=ßµZhµù¨þœÏSúgæGä7S?üà?øÌÏ:fí‘ßìçË¿_žoõÂoµÿèüzõò+ÕÚÖôÒytø±ýƒßZýRßß+/?ï¯E~Í}þ¹æOÎSÒ‡~üG׺ÿèúO÷]ÿ‰þe½ë]K}~?©¿TŸ{׿çô—jmkzíZ÷Hþ£ócü¥ÆñéÁò¦…l?ÝoÍ~ü¿Mÿéþ£ë?Ýtý'ú—õ®wýÖ9ôSùõÔçÞõÃïYýµg +Ž\ëÉt~Œ¿÷ê¿þ'‚ âÌÐîéö5?ZÝD£ß—Þ ˆûÑ{|!ý>\Šë@þ{qùçùÿ)>~´+!$=Öq†tÜbÆóùò啎mháAÞŸðƒüà?øÝá§?÷ÎϺÆýD~2¬óçô3þü­?kçÐGïG‡Ÿßõ'ã/¿V¹¯V2?|žÖþÕ½æ÷äòWùÞ‹~M'üà?øÁ~#ü¬Z×3?ë÷ù嬮W«fò Ÿñçsý9ó:w«F‡ß~ýŒ¿¸üZýiÚ% MwÏñÍÇL>µ~Õ8yѯõ?üà?øÁ~½ü´:7¿‘úüü´y­ú܃~­ÿïæ¿ßŽñ·ºF‡ŸýZÿß͇ßzý­þZØhóõžß—ËÁçº!ñ±˜hl¼è×ú~ðƒüà¿~ÚõíøÖçoã'õ^¯wëó'øÍÊ#?ÍÃúKuö¬ú~ûôkýz7~Ï诅uϺæ«'¿æo4FûéýÅ4š~øÁ~ðƒüJù-×·{ä×{û[ùi1ãùÚŒ¿3ןV­}åß©ÏáK?ü|ñkõgq°Ž£¤i=ú´c»¾Ÿéx‹ý£Ç_àçC?üà?øyáW«q½ò­ÏßÆÏŠ;õ9ão?¿ã¯t|g´F‡ŸýŒ¿˜üzøŒ„×ã?+ø¬ÔoøÁ~ðƒüv×çOðÓêóRþV~VÜ=¾šßÝü·óÛ=þfÔçy?ú1ø]óAqfÈú6²öˆV…u” Zª·­iµ‚ Ú#ÿ »ôûtyý®±¦Éûß­ÇòiyþuÌ"=¿5<èoù}@mž‘þ‡üà?øÁï?YÛFãgC?…_Iíž`üN3õÏä×{ž<}¿´Ïá÷üÊíËe”–ßë¯Ô—Öò{ò¯÷éº-§þÚ|Úô»ú=ù‡üà?øÅàgÝ» ¿üZô—~^ÇßÌóèðcüÁOŸ¿Õ_Éc‹¿Z¾ÅBÓt½¦güÉöwé׿o^ýðƒüà?øÝá×SŸÃÏ¿Výµg¹ÃÏ7?¯ãoV?Æü~]AAg†¬Ïwë!Ö¿KM¬ŠZ}¾[AD‹¼v×~oNøø‘'¯+hüùx#Ë(=_¯Gÿ×/÷õ,c–~­ïà?øÁ~ðëå×òüvøùå×Ó~í9ÛðóÍÏóø«ýîü|ócüùâ'½hŸIéýåSN—!—•òókòyóWù>åÏÒŸúwDÿ•»[¿<¾?øÁ~ðƒ_/¿Úóáàç›_þÒ=èðóÏ/Âø³¾cð‹Áñ狟æå.­­œO>•/ßçÏŸ¿«¿Æ§¤_;Ù¡?ïøÁ~ðƒüFøY÷ŸÃ/¿ý¥çÄÁÏ?¿<—ñ?ø½ŸŸœnµ™û«yÓþO×”~o¾¤Íjÿtý§û®ÿtÿÑõŸî?ºþÓý[¿EÿéüzõžC‡úñÿ>ý§û÷¬?_¦å«çšÙN¾Ì‘üôþê-ÿtý§û®ÿtÿÑõŸî?ºþÓý§×¶GÑ¿~ý-çÏáç—Ÿ'ý§û®ÿtÿô§iùtm^¹ü^½½óçÞJù£ú[îAð¬~±õÃ/¶~øÅÖ¿Øúá7¦¿õwøùäçE?übë‡_ýùvn[:¿mïÛúýŒÊüÕóg篞?;õüÙù«çÏÎ_=ÿ^þ¥ñƒ¿<þžÍ_=vþêù£óë½wËgûÏÖZŸGïû÷øz¹lU篞?;õüÙù«çÏÎ_=vþêù·ò·®ÍõúñýEᯞ?;õüÑùe msf>Ëfù䙩‘±äUÛGá—ϤFù÷®?þð‡?üáøñ—Ã_çòIüõøñ‡?ü]ǟ׹ä¸o´,_+O/Ÿ¼Ú{ü¾¿¬»¿5¦¶‰È¯û+÷ø÷®?þð‡?üáÑøñÛŸ¿oŽ¿\þøûÃþêøÓ¶[²ùþ6‹ÏeÛØ|~~Ý™=×¢ðÛï.<Š?r~üáøÃþð—øÃþðßçÛâWúÙûþ­²ÜöóV>ßæüäÏÎ_=vþêù³óWÏŸ¿zþìüÕóg篞?;õü‘ùØñzÙZ5’¯•~ò_…¿zþìüÕóg篞?;õüÙù«çÏÎ_=vþêù#ñË{Š¢(Š¢(Š¢(Š¢ž[³û öùuûìþh-ÿçõ{Ês¯¯>??댖_þ¿–Œkÿß=æÛHÍ?²þøÃþð‡?üáøÃþð‡¿ëùñ£¹•MKßÛÏ}õëǵYGÏ7-?–Óÿ~¯ÎæŸ]üáøÃþð‡?üáøÃßuüÍøYãjyšÙ?h=šOö2”Ñ~OÀÎß:¿üØþýYü£ë?üáøÃþð‡?üáø»¦¿?’WŸ{ï9i¹™Í×Z³‘|þ{ûö»ü:ÿˆ›V»3ø÷¬?þð‡?üáøÃþð‡?üáïþÖjö™uË!N·ô·c¬õßz¼u^•†ÿèõÇþð‡?üáøÃþð‡?üåô÷(¿ºß2Ó¿µsÔùÕóÐÛGÑcQøñ‡?üáøÃþð‡?üá×öÉÏ‘ó·ül©(üøÃþò¬?þð‰øË´þøÃ_$~üáïvÿ?å×`³  \ No newline at end of file diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/VampireMatCaveSky.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/VampireMatCaveSky.cs new file mode 100644 index 000000000..d7d9aab19 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/VampireMatCaveSky.cs @@ -0,0 +1,44 @@ +using Everglow.Commons.Mechanics.EliminateLight; +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain.NPCs.VampireMat; +using Everglow.Yggdrasil.WorldGeneration; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class VampireMatCaveSky : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.VampireMatCaveSky.Value; + Distance = 2.8f; + UseColorStyle = 2; + LayerPriority = 2; + Shader = Effects.XWrap_YClamp_Shader; + } + + public override void Draw() + { + Main.spriteBatch.Draw(Texture, WorldAnchor - Main.screenPosition, null, Color.White, 0, Texture.Size() * 0.5f, new Vector2(2f, 2f), SpriteEffects.None, 0); + EliminateLightManager.AddCircle(WorldAnchor, 65 * 16); + foreach (var npc in Main.npc) + { + if (npc is not null && npc.active && npc.type == ModContent.NPCType()) + { + VampireMat mat = npc.ModNPC as VampireMat; + if (mat is not null) + { + if (mat.DiveAtBackground) + { + VampireMat.DrawSelf(npc, mat, Main.spriteBatch, Lighting.GetColor(npc.Center.ToTileCoordinates())); + } + } + } + } + } + + public override bool CanActive() + { + return (Main.LocalPlayer.Center - KelpCurtainGeneration.VampireMatCaveCenter).Length() < new Vector2(Main.screenWidth, Main.screenHeight).Length() / 2f + 60 * 16; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/VampireMatCaveSky.png b/Sources/Modules/Yggdrasil/KelpCurtain/Background/VampireMatCaveSky.png new file mode 100644 index 000000000..98ae60453 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Background/VampireMatCaveSky.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/VampireMatCaveWall.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Background/VampireMatCaveWall.cs new file mode 100644 index 000000000..14921219f --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Background/VampireMatCaveWall.cs @@ -0,0 +1,38 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain.Biomes; +using Everglow.Yggdrasil.WorldGeneration; + +namespace Everglow.Yggdrasil.KelpCurtain.Background; + +public class VampireMatCaveWall : BackgroundSlideBase +{ + + public List BgTiles = new List(); + + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.VampireMatCaveWall.Value; + Distance = 1f; + UseColorStyle = 1; + LayerPriority = 2; + Shader = Effects.XWrap_YClamp_Shader; + } + + public override void Update() + { + base.Update(); + } + + public override void Draw() + { + var bars = new List(); + BackgroundHigherPerformanceHelper.Add_TileBgVertice(this, BgTiles, bars); + DrawVertexBackground(this, PrimitiveType.TriangleStrip, bars); + } + + public override bool CanActive() + { + return (Main.LocalPlayer.Center - KelpCurtainGeneration.VampireMatCaveCenter).Length() < new Vector2(Main.screenWidth, Main.screenHeight).Length() / 2f + 60 * 16; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Background/VampireMatCaveWall.png b/Sources/Modules/Yggdrasil/KelpCurtain/Background/VampireMatCaveWall.png new file mode 100644 index 000000000..4863ff666 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Background/VampireMatCaveWall.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Biomes/DeathJadeLakeBiome.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Biomes/DeathJadeLakeBiome.cs index 71d84a13e..f951022f4 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Biomes/DeathJadeLakeBiome.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Biomes/DeathJadeLakeBiome.cs @@ -1,5 +1,6 @@ +using Everglow.Commons.Utilities.BackgroundHelper; using Everglow.Yggdrasil.Common; -using Everglow.Yggdrasil.KelpCurtain.Items.Placeables; +using Everglow.Yggdrasil.KelpCurtain.Background; using Everglow.Yggdrasil.KelpCurtain.Water; using Everglow.Yggdrasil.WorldGeneration; @@ -7,11 +8,11 @@ namespace Everglow.Yggdrasil.KelpCurtain.Biomes; public class DeathJadeLakeBiome : ModBiome { - public float LiquidSurfaceY = 0; + public static float LiquidSurfaceY = 0; - public Dictionary RightBoundOfACertainY = []; + public static Dictionary RightBoundOfACertainY = []; - public void GetLiquidSurfaceY() + public static void GetLiquidSurfaceY() { int checkY = (int)(Main.maxTilesY * 0.88f); int checkX = Main.maxTilesX / 2; @@ -50,7 +51,7 @@ public void GetLiquidSurfaceY() /// /// TODO: BGM /// - public override int Music => YggdrasilContent.QuickMusic(ModAsset.JellyBallHotbed_BGM_Path); + public override int Music => YggdrasilContent.QuickMusic(ModAsset.KelpCurtainBGM_Path); public override SceneEffectPriority Priority => SceneEffectPriority.Environment; @@ -64,7 +65,7 @@ public void GetLiquidSurfaceY() /// /// TODO:MapBackground /// - public override string MapBackground => ModAsset.YggdrasilTown_MapBackground_Mod; + public override string MapBackground => ModAsset.KelpCurtain_MapBackground_Mod; /// /// TODO:WaterStyle @@ -73,11 +74,6 @@ public void GetLiquidSurfaceY() public override Color? BackgroundColor => base.BackgroundColor; - public override void Load() - { - base.Load(); - } - public override bool IsBiomeActive(Player player) { bool flag1 = player.Center.X / 16 > Main.maxTilesX * 0.05f && player.Center.X / 16 < Main.maxTilesX * 0.75f; @@ -88,6 +84,79 @@ public override bool IsBiomeActive(Player player) public override void OnInBiome(Player player) { + // Vampire Mat + if ((Main.LocalPlayer.Center - KelpCurtainGeneration.VampireMatCaveCenter).Length() < new Vector2(Main.screenWidth, Main.screenHeight).Length() / 2f + 60 * 16) + { + BackgroundSystem bgSystem = ModContent.GetInstance(); + if (!bgSystem.HasBgSlide("Everglow.Yggdrasil.KelpCurtain.Background.VampireMatCaveWall")) + { + List polygon = new List(); + for (int k = 0; k < 40; k++) + { + polygon.Add(KelpCurtainGeneration.VampireMatCaveCenter + new Vector2(60 * 16, 0).RotatedBy(k / 40f * MathHelper.TwoPi)); + } + List bgArea = TileUtils.GetPolygonAreaOfTilePos(polygon); + + VampireMatCaveWall vmcw = new VampireMatCaveWall(); + vmcw.WorldAnchor = KelpCurtainGeneration.VampireMatCaveCenter; + vmcw.BgTiles = bgArea; + bgSystem.AddBackgroundSlide(vmcw); + + VampireMatCaveSky vmcs = new VampireMatCaveSky(); + vmcs.WorldAnchor = KelpCurtainGeneration.VampireMatCaveCenter; + bgSystem.AddBackgroundSlide(vmcs); + } + } + + // Add water light + float lightTop = LiquidSurfaceY; + if (lightTop - Main.screenPosition.Y < -Main.offScreenRange) + { + lightTop = -Main.offScreenRange + Main.screenPosition.Y; + } + float lightBottom = Main.screenPosition.Y + Main.screenHeight + Main.offScreenRange; + lightBottom = Math.Min(lightBottom, LiquidSurfaceY + 45 * 16f); + if (lightTop > lightBottom) + { + return; + } + int yLayers = (int)((lightBottom - lightTop) / 16f); + for (int offsetY = 0; offsetY < yLayers; offsetY++) + { + float rightClamp = Main.screenWidth + Main.offScreenRange + Main.screenPosition.X; + float rightBound = Main.maxTilesX * 16; + int tileY = (int)(lightTop / 16) + offsetY; + if (RightBoundOfACertainY.ContainsKey(tileY)) + { + int rightX; + RightBoundOfACertainY.TryGetValue(tileY, out rightX); + rightBound = rightX; + } + if (rightClamp > rightBound) + { + rightClamp = rightBound; + } + int y = tileY; + for (int x = (int)((Main.screenPosition.X - Main.offScreenRange) / 16f); x < rightClamp; x++) + { + var tile = Main.tile[x, y]; + if (tile.LiquidAmount > 0 && tile.WallType == WallID.None) + { + Lighting.AddLight(x, y, 0.1f, 0.4f, 0.3f); + } + } + if (y == LiquidSurfaceY) + { + for (int x = (int)((Main.screenPosition.X - Main.offScreenRange) / 16f); x < rightClamp; x++) + { + var tile = Main.tile[x, y]; + if (tile.LiquidAmount > 0) + { + tile.LiquidAmount = 255; + } + } + } + } base.OnInBiome(player); } } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Biomes/DeathJadeLakeIcon.png b/Sources/Modules/Yggdrasil/KelpCurtain/Biomes/DeathJadeLakeIcon.png index af16d5736..3647d4e68 100644 Binary files a/Sources/Modules/Yggdrasil/KelpCurtain/Biomes/DeathJadeLakeIcon.png and b/Sources/Modules/Yggdrasil/KelpCurtain/Biomes/DeathJadeLakeIcon.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Biomes/IsleOfBloom.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Biomes/IsleOfBloom.cs new file mode 100644 index 000000000..97586be87 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Biomes/IsleOfBloom.cs @@ -0,0 +1,89 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.Common; +using Everglow.Yggdrasil.KelpCurtain.Background; +using Everglow.Yggdrasil.KelpCurtain.Water; + +namespace Everglow.Yggdrasil.KelpCurtain.Biomes; + +public class IsleOfBloomBiome : ModBiome +{ + public List Polygon_Bound = new List(); + + /// + /// TODO: BGM + /// + public override int Music => YggdrasilContent.QuickMusic(ModAsset.KelpCurtainBGM_Path); + + public override SceneEffectPriority Priority => SceneEffectPriority.Environment; + + public override string BestiaryIcon => ModAsset.IsleOfBloomIcon_Mod; + + public override string MapBackground => ModAsset.KelpCurtain_MapBackground_Mod; + + /// + /// TODO:WaterStyle + /// + public override ModWaterStyle WaterStyle => ModContent.GetInstance(); + + public override Color? BackgroundColor => base.BackgroundColor; + + public override bool IsBiomeActive(Player player) + { + bool flag1 = player.InModBiome(); + if (flag1 && Polygon_Bound.Count <= 0) + { + Polygon_Bound.Add(new Vector2(865, 18715)); + Polygon_Bound.Add(new Vector2(865, 18655)); + Polygon_Bound.Add(new Vector2(900, 18620)); + Polygon_Bound.Add(new Vector2(940, 18480)); + Polygon_Bound.Add(new Vector2(900, 18450)); + Polygon_Bound.Add(new Vector2(470, 18460)); + Polygon_Bound.Add(new Vector2(495, 18630)); + Polygon_Bound.Add(new Vector2(475, 18715)); + } + bool flag2 = MathUtils.IntersectsPolygonAABB(Polygon_Bound, Main.screenPosition / 16f, (Main.screenPosition + new Vector2(Main.screenWidth, Main.screenHeight)) / 16f); + return flag1 && flag2; + } + + public override void OnInBiome(Player player) + { + BackgroundSystem bgSystem = ModContent.GetInstance(); + if (!bgSystem.HasBgSlide("Everglow.Yggdrasil.KelpCurtain.Background.IsleOfBloom_Underground_sky")) + { + AddBackground(bgSystem); + } + base.OnInBiome(player); + } + + public void AddBackground(BackgroundSystem bgSystem) + { + List polygon = new List(); + Vector2 centerPosWorld = YggdrasilWorld.KelpCurtain_IsleOfBloom_CaveCenter.ToWorldCoordinates(); + polygon.Add(centerPosWorld + new Vector2(0, -12) * 16); + polygon.Add(centerPosWorld + new Vector2(130, -4) * 16); + polygon.Add(centerPosWorld + new Vector2(130, 4) * 16); + polygon.Add(centerPosWorld + new Vector2(0, 12) * 16); + polygon.Add(centerPosWorld + new Vector2(-130, -4) * 16); + polygon.Add(centerPosWorld + new Vector2(-130, 4) * 16); + List bgArea = TileUtils.GetPolygonAreaOfTilePos(polygon); + + IsleOfBloom_Underground_close iob_bg_close = new IsleOfBloom_Underground_close(); + iob_bg_close.WorldAnchor = centerPosWorld; + iob_bg_close.BgTiles = bgArea; + bgSystem.AddBackgroundSlide(iob_bg_close); + + IsleOfBloom_Underground_middle iob_bg_middle = new IsleOfBloom_Underground_middle(); + iob_bg_middle.WorldAnchor = centerPosWorld; + iob_bg_middle.BgTiles = bgArea; + bgSystem.AddBackgroundSlide(iob_bg_middle); + + IsleOfBloom_Underground_far iob_bg_far = new IsleOfBloom_Underground_far(); + iob_bg_far.WorldAnchor = centerPosWorld; + iob_bg_far.BgTiles = bgArea; + bgSystem.AddBackgroundSlide(iob_bg_far); + + IsleOfBloom_Underground_sky iob_bg_sky = new IsleOfBloom_Underground_sky(); + iob_bg_sky.WorldAnchor = centerPosWorld; + bgSystem.AddBackgroundSlide(iob_bg_sky); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Biomes/IsleOfBloomIcon.png b/Sources/Modules/Yggdrasil/KelpCurtain/Biomes/IsleOfBloomIcon.png new file mode 100644 index 000000000..8d7b7585c Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Biomes/IsleOfBloomIcon.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/CrimsonMoonAlgaeSummonStaff_Buff.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/CrimsonMoonAlgaeSummonStaff_Buff.cs new file mode 100644 index 000000000..26dcebcb2 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/CrimsonMoonAlgaeSummonStaff_Buff.cs @@ -0,0 +1,14 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Buffs; + +public class CrimsonMoonAlgaeSummonStaff_Buff : ModBuff +{ + public override void SetStaticDefaults() + { + Main.buffNoSave[Type] = true; + Main.buffNoTimeDisplay[Type] = true; + } + + public override void Update(Player player, ref int buffIndex) + { + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/CrimsonMoonAlgaeSummonStaff_Buff.png b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/CrimsonMoonAlgaeSummonStaff_Buff.png new file mode 100644 index 000000000..0ee56b863 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/CrimsonMoonAlgaeSummonStaff_Buff.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/Photophore_lightPetBuff.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/Photophore_lightPetBuff.cs new file mode 100644 index 000000000..cfba70e22 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/Photophore_lightPetBuff.cs @@ -0,0 +1,19 @@ +using Everglow.Yggdrasil.KelpCurtain.Projectiles.Pets; + +namespace Everglow.Yggdrasil.KelpCurtain.Buffs +{ + public class Photophore_lightPetBuff : ModBuff + { + public override void SetStaticDefaults() + { + Main.buffNoTimeDisplay[Type] = true; + Main.lightPet[Type] = true; + } + + public override void Update(Player player, ref int buffIndex) + { + bool unused = false; + player.BuffHandle_SpawnPetIfNeededAndSetTime(buffIndex, ref unused, ModContent.ProjectileType()); + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/Photophore_lightPetBuff.png b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/Photophore_lightPetBuff.png new file mode 100644 index 000000000..fafa24260 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/Photophore_lightPetBuff.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/RedAlgaeMinionGyroscopeBuff.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/RedAlgaeMinionGyroscopeBuff.cs new file mode 100644 index 000000000..65be7a338 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/RedAlgaeMinionGyroscopeBuff.cs @@ -0,0 +1,14 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Buffs; + +public class RedAlgaeMinionGyroscopeBuff : ModBuff +{ + public override void SetStaticDefaults() + { + Main.buffNoSave[Type] = true; + Main.buffNoTimeDisplay[Type] = true; + } + + public override void Update(Player player, ref int buffIndex) + { + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/RedAlgaeMinionGyroscopeBuff.png b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/RedAlgaeMinionGyroscopeBuff.png new file mode 100644 index 000000000..bf8f0869e Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/RedAlgaeMinionGyroscopeBuff.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/RedAlgae_FriendlyDebuff.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/RedAlgae_FriendlyDebuff.cs new file mode 100644 index 000000000..853322da8 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/RedAlgae_FriendlyDebuff.cs @@ -0,0 +1,32 @@ +using Everglow.Yggdrasil.KelpCurtain.VFXs; + +namespace Everglow.Yggdrasil.KelpCurtain.Buffs; + +public class RedAlgae_FriendlyDebuff : ModBuff +{ + public override void SetStaticDefaults() + { + Main.debuff[Type] = true; + } + + public override void Update(NPC npc, ref int buffIndex) + { + npc.color = Color.Lerp(npc.color, new Color(0.7f, 0.1f, 0.6f), 0.1f); + if (Main.rand.NextBool(12)) + { + Vector2 vel = new Vector2(0, Main.rand.NextFloat(2)).RotatedByRandom(MathHelper.TwoPi); + var redAlgaeDust = new RedAlgae_Small_Dust(); + redAlgaeDust.Position = npc.position + new Vector2(Main.rand.NextFloat(npc.width), Main.rand.NextFloat(npc.height)); + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = vel; + redAlgaeDust.ai = new float[] { 0.99f }; + redAlgaeDust.MaxTime = 30; + redAlgaeDust.Scale = 1f; + redAlgaeDust.Frame = Main.rand.Next(10); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + base.Update(npc, ref buffIndex); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/RedAlgae_FriendlyDebuff.png b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/RedAlgae_FriendlyDebuff.png new file mode 100644 index 000000000..01f386300 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/RedAlgae_FriendlyDebuff.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/RedAlgae_FriendlyDebuff_glocalNPC.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/RedAlgae_FriendlyDebuff_glocalNPC.cs new file mode 100644 index 000000000..814d7a7f5 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/RedAlgae_FriendlyDebuff_glocalNPC.cs @@ -0,0 +1,42 @@ + +using Terraria; + +namespace Everglow.Yggdrasil.KelpCurtain.Buffs; + +public class RedAlgae_FriendlyDebuff_glocalNPC : GlobalNPC +{ + public override void OnHitByProjectile(NPC npc, Projectile projectile, NPC.HitInfo hit, int damageDone) + { + DoDamageRedAlgaeBuff(npc); + base.OnHitByProjectile(npc, projectile, hit, damageDone); + } + + public override void OnHitByItem(NPC npc, Player player, Item item, NPC.HitInfo hit, int damageDone) + { + DoDamageRedAlgaeBuff(npc); + base.OnHitByItem(npc, player, item, hit, damageDone); + } + + private void DoDamageRedAlgaeBuff(NPC npc) + { + int buffType = ModContent.BuffType(); + if (npc.HasBuff(buffType)) + { + int index = npc.FindBuffIndex(buffType); + int buffTime = npc.buffTime[index]; + int damage = 900 - buffTime; + if (damage > 10) + { + NPC.HitInfo hit2 = new NPC.HitInfo() + { + Damage = damage, + Knockback = 0, + HitDirection = 1, + Crit = false, + }; + npc.StrikeNPCWithCustomCombatText(hit2, new Color(0.7f, 0.1f, 0.4f), true); + npc.DelBuff(index); + } + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/Wither_Activated_Dog_Buff.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/Wither_Activated_Dog_Buff.cs new file mode 100644 index 000000000..a8825e407 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/Wither_Activated_Dog_Buff.cs @@ -0,0 +1,16 @@ +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Buffs; + +public class Wither_Activated_Dog_Buff : ModBuff +{ + public override void SetStaticDefaults() + { + Main.buffNoSave[Type] = true; + Main.buffNoTimeDisplay[Type] = true; + } + + public override void Update(Player player, ref int buffIndex) + { + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/Wither_Activated_Dog_Buff.png b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/Wither_Activated_Dog_Buff.png new file mode 100644 index 000000000..dfac1d105 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Buffs/Wither_Activated_Dog_Buff.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/CustomTiles/BlackAwningBoat.cs b/Sources/Modules/Yggdrasil/KelpCurtain/CustomTiles/BlackAwningBoat.cs new file mode 100644 index 000000000..4bfb43756 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/CustomTiles/BlackAwningBoat.cs @@ -0,0 +1,148 @@ +using Everglow.Commons.CustomTiles; +using Everglow.Commons.CustomTiles.Abstracts; +using Everglow.Commons.CustomTiles.Core; +using Everglow.Commons.Templates.Furniture.Elevator; +using Everglow.Yggdrasil.KelpCurtain.Projectiles.Miscs; + +namespace Everglow.Yggdrasil.KelpCurtain.CustomTiles; + +public class BlackAwningBoat : BoxEntity +{ + public bool OnSelect = false; + + public bool LightOn = false; + + public BlackAwningBoat_ControlUI LocalUIHelper; + + public override void SetDefaults() + { + Size = new Vector2(92, 20); + LocalUIHelper = null; + } + + public override Color MapColor => new Color(51, 40, 38); + + public override void AI() + { + var bottomTile = TileUtils.SafeGetTile(new Vector2(Box.Center.X, Box.Bottom).ToTileCoordinates()); + if (bottomTile.LiquidAmount > 0) + { + Velocity = new Vector2(Velocity.X, 0); + } + else + { + Velocity = new Vector2(Velocity.X, 2); + } + List collideTile = TileUtils.GetAABBAreaOfTile(Position + Velocity, Size); + foreach (var pos in collideTile) + { + var tile = TileUtils.SafeGetTile(pos); + if (tile.HasTile && Main.tileSolid[tile.type]) + { + Velocity *= 0; + break; + } + } + Position += Velocity; + OnSelect = Box.Contain(Main.MouseWorld); + if (OnSelect && Main.mouseRightRelease && Main.mouseRight) + { + RightClick(); + } + if (!CanClick()) + { + if (LocalUIHelper is not null) + { + LocalUIHelper.Closing = true; + } + } + if (Velocity.Length() > 0.001f) + { + bool shouldReleaseProj = true; + foreach (var proj in Main.projectile) + { + if (proj is not null && proj.active && proj.type == ModContent.ProjectileType()) + { + BlackAwningBoat_WaterDistort bABWD0 = proj.ModProjectile as BlackAwningBoat_WaterDistort; + if (bABWD0 is not null && bABWD0.ParentBoat == this) + { + shouldReleaseProj = false; + break; + } + } + } + if (shouldReleaseProj) + { + Projectile p0 = Projectile.NewProjectileDirect(Main.LocalPlayer.GetSource_FromAI(), Box.Center, Velocity, ModContent.ProjectileType(), 0, 0, Main.myPlayer); + BlackAwningBoat_WaterDistort bABWD = p0.ModProjectile as BlackAwningBoat_WaterDistort; + if (bABWD is not null) + { + bABWD.ParentBoat = this; + } + } + } + if (LightOn) + { + Lighting.AddLight(Box.Center, new Vector3(1.2f, 0.7f, 0.3f) * 1.25f); + } + } + + public override void Draw() + { + Texture2D boatTex = ModAsset.BlackAwningBoat.Value; + var frame = new Rectangle(0, 50, 100, 50); + if (!LightOn) + { + frame.Y = 0; + } + Main.spriteBatch.Draw(boatTex, new Vector2(Box.Center.X, Box.Bottom) - Main.screenPosition, frame, Lighting.GetColor(new Vector2(Box.Center.X, Box.Bottom).ToTileCoordinates()), 0, new Vector2(frame.Width / 2f, frame.Height), 1, SpriteEffects.None, 0); + if (LightOn) + { + frame.X += 100; + Main.spriteBatch.Draw(boatTex, new Vector2(Box.Center.X, Box.Bottom) - Main.screenPosition, frame, new Color(1f, 1f, 1f, 0), 0, new Vector2(frame.Width / 2f, frame.Height), 1, SpriteEffects.None, 0); + } + if (OnSelect) + { + Texture2D boatTex_highlight = ModAsset.BlackAwningBoat_Single_Highlight.Value; + Main.spriteBatch.Draw(boatTex_highlight, new Vector2(Box.Center.X, Box.Bottom) - Main.screenPosition, null, Lighting.GetColor(new Vector2(Box.Center.X, Box.Bottom).ToTileCoordinates()), 0, new Vector2(boatTex_highlight.Width / 2f, boatTex_highlight.Height), 1, SpriteEffects.None, 0); + } + } + + public void RightClick() + { + if (LocalUIHelper is null || !LocalUIHelper.Active) + { + LocalUIHelper = new BlackAwningBoat_ControlUI + { + AnimationTimer = 0, + ParentBoat = this, + Owner = Main.LocalPlayer, + RelativePos = new Vector2(0, -120), + Visible = true, + Active = true, + }; + Ins.VFXManager.Add(LocalUIHelper); + foreach (var customTile in ColliderManager.Instance.OfType()) + { + if (customTile.LocalUIHelper is not null && customTile.LocalUIHelper.Active && customTile.LocalUIHelper.Owner == Main.LocalPlayer && !customTile.LocalUIHelper.Closing && customTile.LocalUIHelper != LocalUIHelper) + { + customTile.LocalUIHelper.Closing = true; + } + } + } + else + { + LocalUIHelper.Closing = !LocalUIHelper.Closing; + } + } + + public override Vector2 StandAccelerate(IBox obj) + { + return base.StandAccelerate(obj) * 2; + } + + public virtual bool CanClick() + { + return (Main.LocalPlayer.MountedCenter - Box.Center).Length() <= 200; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/CustomTiles/BlackAwningBoat.png b/Sources/Modules/Yggdrasil/KelpCurtain/CustomTiles/BlackAwningBoat.png new file mode 100644 index 000000000..78ead3897 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/CustomTiles/BlackAwningBoat.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/CustomTiles/BlackAwningBoat_ControlUI.cs b/Sources/Modules/Yggdrasil/KelpCurtain/CustomTiles/BlackAwningBoat_ControlUI.cs new file mode 100644 index 000000000..5c10ccdd9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/CustomTiles/BlackAwningBoat_ControlUI.cs @@ -0,0 +1,206 @@ +using Terraria.Audio; + +namespace Everglow.Yggdrasil.KelpCurtain.CustomTiles; + +[Pipeline(typeof(WCSPipeline))] +public class BlackAwningBoat_ControlUI : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawDusts; + + public BlackAwningBoat ParentBoat; + + public Vector2 RelativePos; + + public Vector2 Position; + + public Vector2 MouseWorldCurrent; + + public Player Owner; + + public float AnimationTimer; + + public bool Closing = false; + + public UICircle LeftButtom = new(0f, Vector2.Zero, 0); + public UICircle PauseButtom = new(0f, Vector2.Zero, 1); + public UICircle RightButtom = new(0f, Vector2.Zero, 2); + public UICircle LampButtom = new(0f, Vector2.Zero, 3); + public UICircle KillButtom = new(0f, Vector2.Zero, 4); + + public class UICircle + { + public float Scale; + public Vector2 RelativeCenter; + public int UIType; + + public UICircle(float size, Vector2 relativeCenter, int uiType) + { + Scale = size; + RelativeCenter = relativeCenter; + UIType = uiType; + } + } + + public override void Update() + { + // Data validation + if (Owner?.HeldItem is null) + { + throw new InvalidOperationException("Owner must be initialized correctly before updating."); + } + if (Owner == null || ParentBoat is null || !ParentBoat.Active || !Owner.active || Owner.dead) + { + Closing = true; + } + if (!Closing) + { + if (AnimationTimer < 30) + { + AnimationTimer += 3; + } + else + { + AnimationTimer = 30; + } + Position = ParentBoat.Box.Center + RelativePos; + UpdateUI(LeftButtom); + UpdateUI(PauseButtom); + UpdateUI(RightButtom); + UpdateUI(LampButtom); + UpdateUI(KillButtom); + } + else + { + if (ParentBoat is not null && ParentBoat.Active) + { + Position = ParentBoat.Box.Center + RelativePos; + } + UpdateUI(LeftButtom); + UpdateUI(PauseButtom); + UpdateUI(RightButtom); + UpdateUI(LampButtom); + UpdateUI(KillButtom); + if (AnimationTimer > 0) + { + AnimationTimer -= 3; + } + else + { + Active = false; + Visible = false; + return; + } + } + } + + public void UpdateUI(UICircle ui) + { + MouseWorldCurrent = Main.MouseWorld; + ui.RelativeCenter = new Vector2((ui.UIType - 2) * 30, 60); + if (AnimationTimer < 30) + { + ui.Scale = AnimationTimer / 30f; + } + if (AnimationTimer >= 30) + { + CheckMouseOver(ui); + } + CheckMouseClick(ui); + } + + public void CheckMouseOver(UICircle ui) + { + if (ParentBoat is null || !ParentBoat.Active) + { + return; + } + if ((MouseWorldCurrent - Position - ui.RelativeCenter).Length() < 14 && ui.Scale < 1.1f) + { + SoundEngine.PlaySound(SoundID.MenuClose); + ui.Scale = 1.2f; + } + if ((MouseWorldCurrent - Position - ui.RelativeCenter).Length() >= 14 && ui.Scale > 1.1f) + { + ui.Scale = 1f; + } + } + + public void CheckMouseClick(UICircle ui) + { + if (ParentBoat is null || !ParentBoat.Active) + { + return; + } + if ((MouseWorldCurrent - Position - ui.RelativeCenter).Length() < 20) + { + if (Main.mouseLeft && Main.mouseLeftRelease) + { + if (ui.UIType == 0) + { + ParentBoat.Velocity += new Vector2(-1, 0); + Owner.velocity += new Vector2(-1, 0); + } + if (ui.UIType == 1) + { + ParentBoat.Velocity *= 0; + Owner.velocity *= 0; + } + if (ui.UIType == 2) + { + ParentBoat.Velocity += new Vector2(1, 0); + Owner.velocity += new Vector2(1, 0); + } + if (ui.UIType == 3) + { + ParentBoat.LightOn = !ParentBoat.LightOn; + } + if (ui.UIType == 4) + { + for (int l = 0; l < 16; l++) + { + int type; + switch (Main.rand.Next(3)) + { + case 0: + type = GoreID.ChimneySmoke1; + break; + case 1: + type = GoreID.ChimneySmoke2; + break; + case 2: + type = GoreID.ChimneySmoke3; + break; + default: + type = GoreID.ChimneySmoke1; + break; + } + + var gore = Gore.NewGorePerfect(ParentBoat.Position + new Vector2(Main.rand.NextFloat(92), Main.rand.NextFloat(20)) - new Vector2(17, 18), new Vector2(0, Main.rand.NextFloat(1f)).RotatedByRandom(MathHelper.TwoPi), type); + gore.timeLeft = Main.rand.Next(60, 120); + } + ParentBoat.Active = false; + } + } + } + } + + public override void Draw() + { + DrawUICircle(LeftButtom); + DrawUICircle(PauseButtom); + DrawUICircle(RightButtom); + DrawUICircle(LampButtom); + DrawUICircle(KillButtom); + } + + public void DrawUICircle(UICircle ui) + { + Texture2D tex = ModAsset.BlackAwningBoat_ControlUI.Value; + Rectangle frame = new Rectangle(ui.UIType * 32, 0, 32, 32); + if (ui.Scale > 1.1f) + { + frame.Y += 32; + } + Ins.Batch.Draw(tex, Position + ui.RelativeCenter, frame, Color.White, 0, frame.Size() / 2f, ui.Scale, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/CustomTiles/BlackAwningBoat_ControlUI.png b/Sources/Modules/Yggdrasil/KelpCurtain/CustomTiles/BlackAwningBoat_ControlUI.png new file mode 100644 index 000000000..8e0273057 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/CustomTiles/BlackAwningBoat_ControlUI.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/CustomTiles/BlackAwningBoat_Single_Highlight.png b/Sources/Modules/Yggdrasil/KelpCurtain/CustomTiles/BlackAwningBoat_Single_Highlight.png new file mode 100644 index 000000000..d02261052 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/CustomTiles/BlackAwningBoat_Single_Highlight.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/AbandonedLakeWreckDust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/AbandonedLakeWreckDust.cs new file mode 100644 index 000000000..ac77adddf --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/AbandonedLakeWreckDust.cs @@ -0,0 +1,5 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class AbandonedLakeWreckDust : ModDust +{ +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/AbandonedLakeWreckDust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/AbandonedLakeWreckDust.png new file mode 100644 index 000000000..894bd3f41 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/AbandonedLakeWreckDust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/AbandonedOxygenTankDust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/AbandonedOxygenTankDust.cs new file mode 100644 index 000000000..e2c962260 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/AbandonedOxygenTankDust.cs @@ -0,0 +1,5 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class AbandonedOxygenTankDust : ModDust +{ +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/AbandonedOxygenTankDust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/AbandonedOxygenTankDust.png new file mode 100644 index 000000000..31257129a Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/AbandonedOxygenTankDust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/BlackAwningBoatDust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/BlackAwningBoatDust.cs new file mode 100644 index 000000000..ceba161f5 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/BlackAwningBoatDust.cs @@ -0,0 +1,5 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class BlackAwningBoatDust : ModDust +{ +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/BlackAwningBoatDust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/BlackAwningBoatDust.png new file mode 100644 index 000000000..c4f9bef86 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/BlackAwningBoatDust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/CrimsonMoonAlgea_fruitDust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/CrimsonMoonAlgea_fruitDust.cs new file mode 100644 index 000000000..2c67b379a --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/CrimsonMoonAlgea_fruitDust.cs @@ -0,0 +1,16 @@ + +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class CrimsonMoonAlgea_fruitDust : ModDust +{ + public override bool Update(Dust dust) + { + Lighting.AddLight(dust.position, new Vector3(1f, 0.8f, 0.7f) * dust.scale); + return base.Update(dust); + } + + public override Color? GetAlpha(Dust dust, Color lightColor) + { + return new Color(1f, 1f, 1f, 1f); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/CrimsonMoonAlgea_fruitDust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/CrimsonMoonAlgea_fruitDust.png new file mode 100644 index 000000000..8f11b2084 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/CrimsonMoonAlgea_fruitDust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/FluorescentHydraWoodDust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/FluorescentHydraWoodDust.cs new file mode 100644 index 000000000..6d655ddd9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/FluorescentHydraWoodDust.cs @@ -0,0 +1,10 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class FluorescentHydraWoodDust : ModDust +{ + public override bool Update(Dust dust) + { + dust.alpha = 150; + return base.Update(dust); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/FluorescentHydraWoodDust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/FluorescentHydraWoodDust.png new file mode 100644 index 000000000..b0b492fae Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/FluorescentHydraWoodDust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/HydraMud_Dust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/HydraMud_Dust.cs new file mode 100644 index 000000000..af1ea9ac7 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/HydraMud_Dust.cs @@ -0,0 +1,5 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class HydraMud_Dust : ModDust +{ +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/HydraMud_Dust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/HydraMud_Dust.png new file mode 100644 index 000000000..317995f91 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/HydraMud_Dust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IsleBamboo_DryDust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IsleBamboo_DryDust.cs new file mode 100644 index 000000000..d8754f0b7 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IsleBamboo_DryDust.cs @@ -0,0 +1,5 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class IsleBamboo_DryDust : ModDust +{ +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IsleBamboo_DryDust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IsleBamboo_DryDust.png new file mode 100644 index 000000000..b2b48b574 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IsleBamboo_DryDust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IsleBamboo_Sawdust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IsleBamboo_Sawdust.cs new file mode 100644 index 000000000..4b6197534 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IsleBamboo_Sawdust.cs @@ -0,0 +1,5 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class IsleBamboo_Sawdust : ModDust +{ +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IsleBamboo_Sawdust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IsleBamboo_Sawdust.png new file mode 100644 index 000000000..297baa818 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IsleBamboo_Sawdust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IslePeachTree_Sawdust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IslePeachTree_Sawdust.cs new file mode 100644 index 000000000..62ee05c4a --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IslePeachTree_Sawdust.cs @@ -0,0 +1,5 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class IslePeachTree_Sawdust : ModDust +{ +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IslePeachTree_Sawdust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IslePeachTree_Sawdust.png new file mode 100644 index 000000000..fa8157802 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/IslePeachTree_Sawdust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/JadeLakeSpongeDust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/JadeLakeSpongeDust.cs new file mode 100644 index 000000000..5b8985d84 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/JadeLakeSpongeDust.cs @@ -0,0 +1,5 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class JadeLakeSpongeDust : ModDust +{ +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/JadeLakeSpongeDust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/JadeLakeSpongeDust.png new file mode 100644 index 000000000..5458ae987 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/JadeLakeSpongeDust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/KelpMoss_dust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/KelpMoss_dust.png index 31b58f765..6f9d9cf31 100644 Binary files a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/KelpMoss_dust.png and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/KelpMoss_dust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/KelpWaterDrop.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/KelpWaterDrop.cs new file mode 100644 index 000000000..ee2ad7aca --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/KelpWaterDrop.cs @@ -0,0 +1,13 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class KelpWaterDrop : ModDust +{ + public override bool Update(Dust dust) + { + if (Collision.IsWorldPointSolid(dust.position + new Vector2(4))) + { + dust.active = false; + } + return base.Update(dust); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/KelpWaterDrop.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/KelpWaterDrop.png new file mode 100644 index 000000000..ec885a137 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/KelpWaterDrop.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/MossyDockWoodDust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/MossyDockWoodDust.cs new file mode 100644 index 000000000..600df844d --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/MossyDockWoodDust.cs @@ -0,0 +1,5 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class MossyDockWoodDust : ModDust +{ +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/MossyDockWoodDust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/MossyDockWoodDust.png new file mode 100644 index 000000000..44f835499 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/MossyDockWoodDust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_BoardSign_Dust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_BoardSign_Dust.cs new file mode 100644 index 000000000..5e823bcb8 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_BoardSign_Dust.cs @@ -0,0 +1,5 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class VampireMatCave_BoardSign_Dust : ModDust +{ +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_BoardSign_Dust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_BoardSign_Dust.png new file mode 100644 index 000000000..aeffd3321 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_BoardSign_Dust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_HangingSign_Dust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_HangingSign_Dust.cs new file mode 100644 index 000000000..642f4a329 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_HangingSign_Dust.cs @@ -0,0 +1,5 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class VampireMatCave_HangingSign_Dust : ModDust +{ +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_HangingSign_Dust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_HangingSign_Dust.png new file mode 100644 index 000000000..f21cc1dfb Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_HangingSign_Dust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_WoodenBoarding_Dust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_WoodenBoarding_Dust.cs new file mode 100644 index 000000000..d173e700b --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_WoodenBoarding_Dust.cs @@ -0,0 +1,5 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class VampireMatCave_WoodenBoarding_Dust : ModDust +{ +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_WoodenBoarding_Dust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_WoodenBoarding_Dust.png new file mode 100644 index 000000000..820241549 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/VampireMatCave_WoodenBoarding_Dust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/WaterDeliveryHoleDust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/WaterDeliveryHoleDust.cs new file mode 100644 index 000000000..5a795516a --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/WaterDeliveryHoleDust.cs @@ -0,0 +1,5 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Dusts; + +public class WaterDeliveryHoleDust : ModDust +{ +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/WaterDeliveryHoleDust.png b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/WaterDeliveryHoleDust.png new file mode 100644 index 000000000..96a43529b Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Dusts/WaterDeliveryHoleDust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Attack_Proj_Tusk_Gore.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Attack_Proj_Tusk_Gore.cs new file mode 100644 index 000000000..1e311f34b --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Attack_Proj_Tusk_Gore.cs @@ -0,0 +1,82 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Gores; + +[Pipeline(typeof(WCSPipeline))] +public class VampireMat_Attack_Proj_Tusk_Gore : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawProjectiles; + + public Vector2 Position; + + public Vector2 Velocity; + + public float Rotation; + + public float RotateSpeed; + + public float Timer = 0; + + public float MaxTime = 120; + + public float Fade = 1; + + public bool Stop = false; + + public Rectangle Frame; + + public override void Update() + { + Timer++; + if (MaxTime - Timer < 30) + { + Fade = (MaxTime - Timer) / 30f; + } + else + { + Fade = 1; + } + if (Timer >= MaxTime) + { + Active = false; + return; + } + if (!Stop) + { + Position += Velocity; + Rotation += RotateSpeed; + float size = Frame.Width * Frame.Height / 300f; + Velocity.Y += 0.25f * size; + Velocity *= 0.98f; + RotateSpeed *= 0.98f; + if (Collision.IsWorldPointSolid(Position + new Vector2(Velocity.X, 0))) + { + Velocity.X *= -Main.rand.NextFloat(0.25f, 0.96f); + RotateSpeed *= Main.rand.NextFloat(0.25f, 0.96f); + } + if (Collision.IsWorldPointSolid(Position + new Vector2(0, Velocity.Y))) + { + Velocity.Y *= -Main.rand.NextFloat(0.25f, 0.96f); + RotateSpeed *= Main.rand.NextFloat(0.25f, 0.96f); + } + if (Velocity.Length() < 1f) + { + Stop = true; + } + } + } + + public override void Draw() + { + if (Timer < 20) + { + Rectangle whiteFrame = Frame; + whiteFrame.X += 36; + Color drawColor = Color.White; + if (Timer >= 10) + { + drawColor *= (20 - Timer) / 10f; + } + Ins.Batch.Draw(ModAsset.VampireMat_Attack_Proj_Tusk_Gore.Value, Position, whiteFrame, drawColor, Rotation, whiteFrame.Size() * 0.5f, 1, SpriteEffects.None); + } + Ins.Batch.Draw(ModAsset.VampireMat_Attack_Proj_Tusk_Gore.Value, Position, Frame, Lighting.GetColor(Position.ToTileCoordinates()) * Fade, Rotation, Frame.Size() * 0.5f, 1, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Attack_Proj_Tusk_Gore.png b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Attack_Proj_Tusk_Gore.png new file mode 100644 index 000000000..20e4d813d Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Attack_Proj_Tusk_Gore.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_0.png b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_0.png new file mode 100644 index 000000000..93d4ae880 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_0.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_1.png b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_1.png new file mode 100644 index 000000000..81eb699bb Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_1.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_2.png b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_2.png new file mode 100644 index 000000000..5ccdccd1c Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_2.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_3.png b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_3.png new file mode 100644 index 000000000..02782f42b Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_3.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_4.png b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_4.png new file mode 100644 index 000000000..332d96450 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_4.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_5.png b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_5.png new file mode 100644 index 000000000..efd4361aa Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_5.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_6.png b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_6.png new file mode 100644 index 000000000..57a07c8e6 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_6.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_7.png b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_7.png new file mode 100644 index 000000000..0d56549a7 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Gores/VampireMat_Gore_7.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/BossSummon/MossyRuby.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/BossSummon/MossyRuby.cs new file mode 100644 index 000000000..71c87fc52 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/BossSummon/MossyRuby.cs @@ -0,0 +1,53 @@ +using Everglow.Yggdrasil.KelpCurtain.NPCs.VampireMat; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.BossSummon; + +public class MossyRuby : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.SummonItems; + + public override void SetDefaults() + { + Item.consumable = true; + Item.width = 22; + Item.height = 34; + Item.value = 13000; + Item.useTime = 12; + Item.useAnimation = 12; + Item.noMelee = true; + Item.maxStack = Item.CommonMaxStack; + Item.useTurn = true; + Item.UseSound = SoundID.Roar; + Item.useStyle = ItemUseStyleID.Swing; + } + + public override bool ConsumeItem(Player player) + { + return true; + } + + public override bool? UseItem(Player player) + { + return base.UseItem(player); + } + + public override bool CanUseItem(Player player) + { + int type = ModContent.NPCType(); + if (NPC.CountNPCS(type) <= 0) + { + var npc = NPC.NewNPCDirect(Item.GetNPCSource_FromThis(), player.Center + new Vector2(player.direction * 1800, 0), type); + npc.velocity.X = -player.direction * 12; + Item.stack--; + if (Item.stack <= 0) + { + Item.active = false; + } + return true; + } + else + { + return false; + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/BossSummon/MossyRuby.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/BossSummon/MossyRuby.png new file mode 100644 index 000000000..48f60d5e2 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/BossSummon/MossyRuby.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Consumables/VampireMatTreasureBag.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Consumables/VampireMatTreasureBag.cs new file mode 100644 index 000000000..4a5d77a44 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Consumables/VampireMatTreasureBag.cs @@ -0,0 +1,54 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Items.Consumables; + +public class VampireMatTreasureBag : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.TreasureBags; + + public override void SetDefaults() + { + Item.maxStack = 999; + Item.consumable = true; + Item.width = 32; + Item.height = 32; + Item.rare = ItemRarityID.Cyan; + Item.expert = true; + } + + public override bool CanRightClick() + { + return true; + } + + public override void RightClick(Player player) + { + player.QuickSpawnItem(null, ItemID.GoldCoin, 15); + base.RightClick(player); + } + + private int myLightTimer = 0; + + public override bool PreDrawInWorld(SpriteBatch spriteBatch, Color lightColor, Color alphaColor, ref float rotation, ref float scale, int whoAmI) + { + Texture2D t = ModAsset.SquamousShellTreasureBag.Value; + for (int i = 0; i < 4; i++) + { + Vector2 v = new Vector2(0, 8 * ((float)Math.Sin((double)(Main.GlobalTimeWrappedHourly * 6.28318548f / 4f)) * 0.3f + 0.7f)).RotatedBy((double)(Main.GlobalTimeWrappedHourly * 6.28318548f / 4f) + MathHelper.Pi * i / 2d); + Main.EntitySpriteDraw(t, Item.Center - Main.screenPosition + v, null, new Color(100, 100, 100, 0), 0, new Vector2(16, 16), 1f, SpriteEffects.None, 0); + } + if (!Main.gamePaused && myLightTimer % 20 == 19) + { + myLightTimer = 0; + int num37 = Dust.NewDust(Item.Center + new Vector2(Main.rand.Next(-16, 6), 0), 0, 0, DustID.SilverCoin, 0f, 0f, 254, Color.White, 1f); + Main.dust[num37].velocity = new Vector2(0, -Main.rand.NextFloat(0.3f, 0.9f)); + Main.dust[num37].rotation = 0; + Main.dust[num37].noLight = true; + Main.dust[num37].alpha = 240; + } + if (!Main.gamePaused) + { + myLightTimer++; + Lighting.AddLight((int)(Item.Center.X / 16f), (int)(Item.Center.Y / 16f), 0.5f, 0.15f, 0.0f); + } + return true; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Consumables/VampireMatTreasureBag.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Consumables/VampireMatTreasureBag.png new file mode 100644 index 000000000..f7fde868d Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Consumables/VampireMatTreasureBag.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Materials/CrimsonMoonSap.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Materials/CrimsonMoonSap.cs new file mode 100644 index 000000000..7b97d7b65 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Materials/CrimsonMoonSap.cs @@ -0,0 +1,15 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Items.Materials; + +public class CrimsonMoonSap : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Materials; + + public override void SetDefaults() + { + Item.width = 20; + Item.height = 28; + Item.value = 5000; + Item.maxStack = Item.CommonMaxStack; + Item.rare = ItemRarityID.Orange; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Materials/CrimsonMoonSap.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Materials/CrimsonMoonSap.png new file mode 100644 index 000000000..733418daa Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Materials/CrimsonMoonSap.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Materials/CrimsonMoonSap_glow.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Materials/CrimsonMoonSap_glow.png new file mode 100644 index 000000000..733418daa Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Materials/CrimsonMoonSap_glow.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Materials/ElftigernPowder.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Materials/ElftigernPowder.png index 3591182bc..53d9c16f9 100644 Binary files a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Materials/ElftigernPowder.png and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Materials/ElftigernPowder.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Misc/FleshOfVampireMat.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Misc/FleshOfVampireMat.cs new file mode 100644 index 000000000..70e5013b9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Misc/FleshOfVampireMat.cs @@ -0,0 +1,13 @@ +namespace Everglow.Yggdrasil.KelpCurtain.Items.Misc; + +public class FleshOfVampireMat : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Materials; + + public override void SetDefaults() + { + Item.width = 44; + Item.height = 34; + Item.value = 0; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Misc/FleshOfVampireMat.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Misc/FleshOfVampireMat.png new file mode 100644 index 000000000..af31d0b2d Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Misc/FleshOfVampireMat.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Pets/Photophore.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Pets/Photophore.cs new file mode 100644 index 000000000..05cfb9efc --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Pets/Photophore.cs @@ -0,0 +1,35 @@ +using Everglow.Yggdrasil.Common; +using Terraria.Localization; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Pets; + +/// +/// "绿ç‰ç’ƒæžœ" Permanently increase life max by 5, at most use for 10 times. +/// +public class Photophore : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.PermanentBoosters; + + public static readonly int MaxJadeFruits = 10; + public static readonly int LifePerJadeFruit = 5; + + public override LocalizedText Tooltip => base.Tooltip.WithFormatArgs(MaxJadeFruits, LifePerJadeFruit); + + public override void SetStaticDefaults() + { + Item.ResearchUnlockCount = 12; + } + + public override void SetDefaults() + { + Item.CloneDefaults(ItemID.LifeCrystal); + Item.width = 30; + Item.height = 34; + Item.rare = ItemRarityID.Blue; + Item.value = 15000; + Item.maxStack = Item.CommonMaxStack; + Item.useStyle = ItemUseStyleID.EatFood; + } + + public override bool? UseItem(Player player) => player.GetModPlayer().UseJadeGlazeFruit(); +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Pets/Photophore.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Pets/Photophore.png new file mode 100644 index 000000000..5cf307755 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Pets/Photophore.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Pets/Photophore_glow.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Pets/Photophore_glow.png new file mode 100644 index 000000000..ee2b92103 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Pets/Photophore_glow.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/BlackAwningBoatSign_Item.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/BlackAwningBoatSign_Item.cs new file mode 100644 index 000000000..bf5cc5909 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/BlackAwningBoatSign_Item.cs @@ -0,0 +1,13 @@ +using Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Placeables; + +public class BlackAwningBoatSign_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/BlackAwningBoatSign_Item.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/BlackAwningBoatSign_Item.png new file mode 100644 index 000000000..2d0a85153 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/BlackAwningBoatSign_Item.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/DryIsleBamboo_Item.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/DryIsleBamboo_Item.cs new file mode 100644 index 000000000..54792ca40 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/DryIsleBamboo_Item.cs @@ -0,0 +1,34 @@ + +using Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Placeables; + +public class DryIsleBamboo_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public int PlaceStyle = 0; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } + + public override void HoldItem(Player player) + { + if (Main.mouseRight && Main.mouseRightRelease) + { + PlaceStyle++; + PlaceStyle %= 2; + if (PlaceStyle == 1) + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } + else + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } + } + base.HoldItem(player); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/DryIsleBamboo_Item.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/DryIsleBamboo_Item.png new file mode 100644 index 000000000..a16e0a1c5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/DryIsleBamboo_Item.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/ForestRainVineTile_Thick_Item.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/ForestRainVineTile_Thick_Item.cs new file mode 100644 index 000000000..8ea5c2a19 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/ForestRainVineTile_Thick_Item.cs @@ -0,0 +1,19 @@ +using Everglow.Yggdrasil.KelpCurtain.Tiles.ForestRainVines; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Placeables; + +public class ForestRainVineTile_Thick_Item : ModItem +{ + public override void SetDefaults() + { + Item.width = 24; + Item.height = 24; + Item.value = 40; + Item.DefaultToPlaceableTile(ModContent.TileType()); + } + + public override void HoldItem(Player player) + { + Main.placementPreview = true; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/ForestRainVineTile_Thick_Item.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/ForestRainVineTile_Thick_Item.png new file mode 100644 index 000000000..8ef14e21e Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/ForestRainVineTile_Thick_Item.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/ForestRainVineTile_Thin_Item.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/ForestRainVineTile_Thin_Item.cs new file mode 100644 index 000000000..d0cf695fc --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/ForestRainVineTile_Thin_Item.cs @@ -0,0 +1,19 @@ +using Everglow.Yggdrasil.KelpCurtain.Tiles.ForestRainVines; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Placeables; + +public class ForestRainVineTile_Thin_Item : ModItem +{ + public override void SetDefaults() + { + Item.width = 24; + Item.height = 24; + Item.value = 40; + Item.DefaultToPlaceableTile(ModContent.TileType()); + } + + public override void HoldItem(Player player) + { + Main.placementPreview = true; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/ForestRainVineTile_Thin_Item.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/ForestRainVineTile_Thin_Item.png new file mode 100644 index 000000000..8ef14e21e Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/ForestRainVineTile_Thin_Item.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/HydraMud_Item.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/HydraMud_Item.cs new file mode 100644 index 000000000..1406c313d --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/HydraMud_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Placeables; + +public class HydraMud_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 16; + Item.height = 16; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/HydraMud_Item.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/HydraMud_Item.png new file mode 100644 index 000000000..4c67b460a Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/HydraMud_Item.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/HydraMud_Item_glow.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/HydraMud_Item_glow.png new file mode 100644 index 000000000..4b088c80e Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/HydraMud_Item_glow.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/JadeLakeRedAlgae_Item.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/JadeLakeRedAlgae_Item.cs new file mode 100644 index 000000000..afc1f5bf0 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/JadeLakeRedAlgae_Item.cs @@ -0,0 +1,14 @@ +using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Placeables; + +public class JadeLakeRedAlgae_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.value = 50; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/JadeLakeRedAlgae_Item.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/JadeLakeRedAlgae_Item.png new file mode 100644 index 000000000..64b9afb47 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/JadeLakeRedAlgae_Item.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossProneSandSoil.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossProneSandSoil_Item.cs similarity index 57% rename from Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossProneSandSoil.cs rename to Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossProneSandSoil_Item.cs index 35004e439..d6a3c97ef 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossProneSandSoil.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossProneSandSoil_Item.cs @@ -1,14 +1,13 @@ +using Everglow.Yggdrasil.KelpCurtain.Tiles; + namespace Everglow.Yggdrasil.KelpCurtain.Items.Placeables; -public class MossProneSandSoil : ModItem +public class MossProneSandSoil_Item : ModItem { public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; - public override void SetStaticDefaults() - { - } public override void SetDefaults() { - Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.DefaultToPlaceableTile(ModContent.TileType()); } } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossProneSandSoil.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossProneSandSoil_Item.png similarity index 100% rename from Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossProneSandSoil.png rename to Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossProneSandSoil_Item.png diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossyDockWood_Item.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossyDockWood_Item.cs new file mode 100644 index 000000000..c93afb5f2 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossyDockWood_Item.cs @@ -0,0 +1,13 @@ +using Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Placeables; + +public class MossyDockWood_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossyDockWood_Item.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossyDockWood_Item.png new file mode 100644 index 000000000..5a6c85bfc Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/MossyDockWood_Item.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/OldMoss.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/OldMoss_Item.cs similarity index 90% rename from Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/OldMoss.cs rename to Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/OldMoss_Item.cs index 171d78ba5..7cfb02466 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/OldMoss.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/OldMoss_Item.cs @@ -1,6 +1,6 @@ namespace Everglow.Yggdrasil.KelpCurtain.Items.Placeables; -public class OldMoss : ModItem +public class OldMoss_Item : ModItem { public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/OldMoss.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/OldMoss_Item.png similarity index 100% rename from Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/OldMoss.png rename to Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/OldMoss_Item.png diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/UnderwaterLightningMechanism_Item.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/UnderwaterLightningMechanism_Item.cs index 92daf1518..ab182774d 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/UnderwaterLightningMechanism_Item.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/UnderwaterLightningMechanism_Item.cs @@ -22,22 +22,6 @@ public override void HoldItem(Player player) { if (Main.mouseRight && Main.mouseRightRelease) { - // if (OldPos == default(Vector2)) - // { - // OldPos = Main.MouseWorld; - // } - // else - // { - // Projectile proj = Projectile.NewProjectileDirect(player.GetSource_FromAI(), Main.MouseWorld, Vector2.zeroVector, ModContent.ProjectileType(), 250, 5f, player.whoAmI, 0, 2); - // UnderwaterLightningMechanism_Lightning uLLML = proj.ModProjectile as UnderwaterLightningMechanism_Lightning; - // if (uLLML is not null) - // { - // uLLML.StartPos = OldPos; - // uLLML.EndPos = Main.MouseWorld; - // OldPos = Main.MouseWorld; - // } - // } - State++; if (State >= 2) { diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/VampireMatCave_BoardSign_Item.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/VampireMatCave_BoardSign_Item.cs new file mode 100644 index 000000000..8b131d99f --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/VampireMatCave_BoardSign_Item.cs @@ -0,0 +1,34 @@ +using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Placeables; + +public class VampireMatCave_BoardSign_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 18; + Item.height = 34; + Item.value = 10; + } + public override void HoldItem(Player player) + { + Main.placementPreview = true; + } + + public override bool CanUseItem(Player player) + { + var vS = TileLoader.GetTile(ModContent.TileType()) as VampireMatCave_BoardSign; + if (vS != null) + { + int x = (int)(Main.MouseWorld.X / 16); + int y = (int)(Main.MouseWorld.Y / 16); + vS.PlaceAtTileObjectDataOrigin(x, y); + Item.stack--; + return false; + } + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/VampireMatCave_BoardSign_Item.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/VampireMatCave_BoardSign_Item.png new file mode 100644 index 000000000..2acb2b721 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/VampireMatCave_BoardSign_Item.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/VampireMatCave_HangingSign_Item.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/VampireMatCave_HangingSign_Item.cs new file mode 100644 index 000000000..4da769097 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/VampireMatCave_HangingSign_Item.cs @@ -0,0 +1,36 @@ +using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; +using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.UnderwaterGuillotine; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Placeables; + +public class VampireMatCave_HangingSign_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 18; + Item.height = 46; + Item.value = 10; + } + + public override void HoldItem(Player player) + { + Main.placementPreview = true; + } + + public override bool CanUseItem(Player player) + { + var vS = TileLoader.GetTile(ModContent.TileType()) as VampireMatCave_HangingSign; + if (vS != null) + { + int x = (int)(Main.MouseWorld.X / 16); + int y = (int)(Main.MouseWorld.Y / 16); + vS.PlaceAtTileObjectDataOrigin(x, y); + Item.stack--; + return false; + } + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/VampireMatCave_HangingSign_Item.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/VampireMatCave_HangingSign_Item.png new file mode 100644 index 000000000..f8bf3b6d0 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/VampireMatCave_HangingSign_Item.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/Walls/IsleBamboo_Wall_Item.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/Walls/IsleBamboo_Wall_Item.cs new file mode 100644 index 000000000..bc85d9715 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/Walls/IsleBamboo_Wall_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.KelpCurtain.Walls; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Placeables.Walls; + +public class IsleBamboo_Wall_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableWall(ModContent.WallType()); + Item.width = 24; + Item.height = 24; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/Walls/IsleBamboo_Wall_Item.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/Walls/IsleBamboo_Wall_Item.png new file mode 100644 index 000000000..e1c711cab Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/Walls/IsleBamboo_Wall_Item.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/Walls/MossProneSandSoilWall_Item.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/Walls/MossProneSandSoilWall_Item.cs index 41d4b0f32..b5a72c798 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/Walls/MossProneSandSoilWall_Item.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/Walls/MossProneSandSoilWall_Item.cs @@ -16,7 +16,7 @@ public override void SetDefaults() public override void AddRecipes() { CreateRecipe(4) - .AddIngredient(ModContent.ItemType(), 1) + .AddIngredient(ModContent.ItemType(), 1) .AddTile(TileID.WorkBenches) .Register(); } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/Walls/OldMossWall_Item.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/Walls/OldMossWall_Item.cs index cf548eccb..315f13018 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/Walls/OldMossWall_Item.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/Walls/OldMossWall_Item.cs @@ -16,7 +16,7 @@ public override void SetDefaults() public override void AddRecipes() { CreateRecipe(4) - .AddIngredient(ModContent.ItemType(), 1) + .AddIngredient(ModContent.ItemType(), 1) .AddTile(TileID.WorkBenches) .Register(); } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/WaterDeliveryHole_Item.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/WaterDeliveryHole_Item.cs new file mode 100644 index 000000000..4f3b3e662 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/WaterDeliveryHole_Item.cs @@ -0,0 +1,128 @@ +using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.WaterDeliveryHoles; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Placeables; + +public class WaterDeliveryHole_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public int State = 0; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 38; + Item.height = 14; + Item.value = 5000; + } + + public override void HoldItem(Player player) + { + if (Main.mouseRight && Main.mouseRightRelease) + { + State++; + if (State >= 6) + { + State = 0; + } + if (State == 0) + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } + else if (State == 1) + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } + else if (State == 2) + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.placeStyle = 0; + } + else if (State == 3) + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.placeStyle = 0; + } + else if (State == 4) + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.placeStyle = 0; + } + else if (State == 5) + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.placeStyle = 0; + } + } + if (State == 2) + { + Main.placementPreview = true; + } + base.HoldItem(player); + } + + public override bool CanUseItem(Player player) + { + if (State == 2) + { + var waterHole_TopLeft = TileLoader.GetTile(ModContent.TileType()) as WaterDeliveryHole_TopRight; + if (waterHole_TopLeft != null) + { + int x = (int)(Main.MouseWorld.X / 16); + int y = (int)(Main.MouseWorld.Y / 16); + if (waterHole_TopLeft.NoCollideInSolidGrid(x, y)) + { + waterHole_TopLeft.PlaceAtTileObjectDataOrigin(x, y); + Item.stack--; + return false; + } + } + } + if (State == 3) + { + var waterHole_TopLeft = TileLoader.GetTile(ModContent.TileType()) as WaterDeliveryHole_BottomRight; + if (waterHole_TopLeft != null) + { + int x = (int)(Main.MouseWorld.X / 16); + int y = (int)(Main.MouseWorld.Y / 16); + if (waterHole_TopLeft.NoCollideInSolidGrid(x, y)) + { + waterHole_TopLeft.PlaceAtTileObjectDataOrigin(x, y); + Item.stack--; + return false; + } + } + } + if (State == 4) + { + var waterHole_TopLeft = TileLoader.GetTile(ModContent.TileType()) as WaterDeliveryHole_BottomLeft; + if (waterHole_TopLeft != null) + { + int x = (int)(Main.MouseWorld.X / 16); + int y = (int)(Main.MouseWorld.Y / 16); + if (waterHole_TopLeft.NoCollideInSolidGrid(x, y)) + { + waterHole_TopLeft.PlaceAtTileObjectDataOrigin(x, y); + Item.stack--; + return false; + } + } + } + if (State == 5) + { + var waterHole_TopLeft = TileLoader.GetTile(ModContent.TileType()) as WaterDeliveryHole_TopLeft; + if (waterHole_TopLeft != null) + { + int x = (int)(Main.MouseWorld.X / 16); + int y = (int)(Main.MouseWorld.Y / 16); + if (waterHole_TopLeft.NoCollideInSolidGrid(x, y)) + { + waterHole_TopLeft.PlaceAtTileObjectDataOrigin(x, y); + Item.stack--; + return false; + } + } + } + return base.CanUseItem(player); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/WaterDeliveryHole_Item.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/WaterDeliveryHole_Item.png new file mode 100644 index 000000000..102e4431a Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Placeables/WaterDeliveryHole_Item.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/GenerateMazeRoom.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/GenerateMazeRoom.cs new file mode 100644 index 000000000..adca433f9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/GenerateMazeRoom.cs @@ -0,0 +1,142 @@ +using Everglow.Commons.Physics.DataStructures; +using Everglow.Yggdrasil.Common.Tiles; +using Everglow.Yggdrasil.Common.Walls; +using Everglow.Yggdrasil.KelpCurtain.Tiles; +using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; +using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.WaterDeliveryHoles; +using Everglow.Yggdrasil.KelpCurtain.Walls; +using Everglow.Yggdrasil.WorldGeneration; +using Spine; +using static Everglow.Commons.Utilities.TileUtils; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Tools.Developer; + +public class GenerateMazeRoom : ModItem +{ + public override void SetDefaults() + { + Item.width = 30; + Item.height = 30; + Item.useTurn = true; + Item.useAnimation = 4; + Item.useTime = 4; + Item.autoReuse = false; + Item.useStyle = ItemUseStyleID.Swing; + } + + public List SeedMap = new List(); + + public override void HoldItem(Player player) => base.HoldItem(player); + + public override bool CanUseItem(Player player) + { + BuildMazeRoom(Main.MouseWorld); + //ClearMazeRooms(Main.MouseWorld); + //BuildEntireMaze(Main.MouseWorld); + + // ConnectDeliveryHole(player.MountedCenter, Main.MouseWorld); + //List polygon = new List(); + //for(int h = 0;h < 5;h++) + //{ + // polygon.Add(Main.MouseWorld + new Vector2(0, 720).RotatedBy(h / 5f * MathHelper.TwoPi)); + //} + //PlacePolygonBoundOfBlock(polygon, TileID.Dirt, 16); + return false; + } + + public void BuildMazeRoom(Vector2 worldPos) + { + Point tilePos = worldPos.ToTileCoordinates(); + Point buildPos = tilePos; + int dir = 1; + if (GenRand.NextBool()) + { + dir = -1; + } + int space = CheckSpaceLeft(tilePos.X, tilePos.Y); + if (dir == -1) + { + space = CheckSpaceRight(tilePos.X, tilePos.Y); + } + buildPos.X -= space * dir; + int randomAddPosX = GenRand.Next(0, 4); + buildPos.X += randomAddPosX * dir; + if (dir == 1) + { + if (GetUniformTile(buildPos.X, buildPos.Y - 9, 10, 10) == -1) + { + YggdrasilWorldGeneration.QuickBuild(buildPos.X, buildPos.Y - 9, ModAsset.MazeUnderLake_ChestRoom_withLamps10x10_Path, false); + PlaceLineBlock(buildPos, buildPos + new Point(-randomAddPosX, 0), 1, ModContent.TileType()); + } + } + else + { + if (GetUniformTile(buildPos.X - 10, buildPos.Y - 9, 10, 10) == -1) + { + YggdrasilWorldGeneration.QuickBuild(buildPos.X - 10, buildPos.Y - 9, ModAsset.MazeUnderLake_ChestRoom_withLamps10x10_Path, false); + PlaceLineBlock(buildPos, buildPos + new Point(randomAddPosX, 0), 1, ModContent.TileType()); + } + } + } + + public void BuildEntireMaze(Vector2 worldPos) + { + Point tilePos = worldPos.ToTileCoordinates(); + int xBoundLeft = tilePos.X - 200; + int xBoundRight = tilePos.X + 200; + int yBoundTop = tilePos.Y - 100; + int yBoundBottom = tilePos.Y + 100; + + // Random seed Points + List seeds = GenerateRandomSeeds(xBoundLeft - 30, xBoundRight + 30, yBoundTop - 30, yBoundBottom + 30, 180, 25); + + for (int x = xBoundLeft; x < xBoundRight; x++) + { + for (int y = yBoundTop; y < yBoundBottom; y++) + { + // Exist a projection. SeedMap is not TileMap. + var tile = SafeGetTile(x, y); + tile.ClearEverything(); + if (KelpCurtainGeneration.MazeUnderLake_IsEdgePoint(x, y, seeds)) + { + if (!tile.HasTile) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.WallType = (ushort)ModContent.WallType(); + tile.HasTile = true; + } + } + } + } + Dictionary> holes = new Dictionary>(); + Point mediumSeedPos = default; + float minDisToCenter = new Vector2(xBoundRight - xBoundLeft, yBoundBottom - yBoundTop).Length(); + foreach (var pos in seeds) + { + float boundRange = 8; + Vector2 center = new Vector2(xBoundLeft + xBoundRight, yBoundTop + yBoundBottom) * 0.5f; + float toCenterDis = new Vector2(pos.X - center.X, pos.Y - center.Y).Length(); + if (toCenterDis < minDisToCenter) + { + minDisToCenter = toCenterDis; + mediumSeedPos = pos; + } + if (pos.X >= xBoundLeft + boundRange && pos.X <= xBoundRight - boundRange && pos.Y <= yBoundBottom - boundRange && pos.Y >= yBoundTop + boundRange) + { + KelpCurtainGeneration.MazeUnderLake_AddNewConnection(pos, holes, seeds); + } + } + if (mediumSeedPos != default) + { + int maxStep = 6; + for (int t = 0; t < maxStep; t++) + { + List connectedWithMediumSeeds = KelpCurtainGeneration.MazeUnderLake_GetAllConnectedPoints(holes, seeds, new List(), mediumSeedPos, 0); + foreach (var pos in connectedWithMediumSeeds) + { + KelpCurtainGeneration.MazeUnderLake_AddNewConnectionWithMediumNet(pos, holes, seeds, connectedWithMediumSeeds); + } + } + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/GenerateMazeRoom.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/GenerateMazeRoom.png new file mode 100644 index 000000000..5287abc03 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/GenerateMazeRoom.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/KelpMoss_largeCreate.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/KelpMoss_largeCreate.cs index 0760597b4..9319f0d6e 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/KelpMoss_largeCreate.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/KelpMoss_largeCreate.cs @@ -1,4 +1,7 @@ -using Everglow.Yggdrasil.KelpCurtain.Tiles; +using Everglow.Yggdrasil.KelpCurtain.Projectiles.Enemies; +using Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; +using Everglow.Yggdrasil.KelpCurtain.VFXs.VampireMat; + namespace Everglow.Yggdrasil.KelpCurtain.Items.Tools.Developer; public class KelpMoss_largeCreate : ModItem @@ -7,8 +10,26 @@ public class KelpMoss_largeCreate : ModItem public override void SetDefaults() { - Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 16; Item.height = 16; } + + public override bool CanUseItem(Player player) + { + //if(player.itemTime == 0) + //{ + // var screenEffectVFX = new ScreenScaringEffect() + // { + // Active = true, + // Visible = true, + // Timer = 0, + // MaxTime = 120, + // }; + // Ins.VFXManager.Add(screenEffectVFX); + //} + //player.itemTime = 30; + Projectile.NewProjectileDirect(player.GetSource_FromAI(), Main.MouseWorld, Vector2.zeroVector, ModContent.ProjectileType(), 100, 1, player.whoAmI); + return false; + } } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/ResetIsleOfBloom.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/ResetIsleOfBloom.cs new file mode 100644 index 000000000..c8d9fb4b6 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/ResetIsleOfBloom.cs @@ -0,0 +1,178 @@ +using Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; +using Everglow.Yggdrasil.KelpCurtain.Walls; +using static Everglow.Commons.Utilities.TileUtils; +using static Everglow.Yggdrasil.WorldGeneration.KelpCurtainGeneration; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Tools.Developer; + +public class ResetIsleOfBloom : ModItem +{ + public override void SetDefaults() + { + Item.width = 30; + Item.height = 30; + Item.useTurn = true; + Item.useAnimation = 4; + Item.useTime = 4; + Item.autoReuse = false; + Item.useStyle = ItemUseStyleID.Swing; + } + + public Point OldMousePos = default; + + public override void HoldItem(Player player) => base.HoldItem(player); + + public override bool CanUseItem(Player player) + { + IsleOfBloom(Main.MouseWorld); + return false; + } + + public static void IsleOfBloom(Vector2 worldPos) + { + Point tilePos = worldPos.ToTileCoordinates(); + TileUtils.PlaceRectangleAreaOfBlock(tilePos.X - 150, tilePos.Y - 60, tilePos.X + 150, tilePos.Y + 150, -2); + + List area = new List(); + area.Add(tilePos + new Point(-130, 0)); + area.Add(tilePos + new Point(130, 0)); + area.Add(tilePos + new Point(150, 120)); + area.Add(tilePos + new Point(-150, 120)); + area = GetPolygonAreaOfTilePos(area); + foreach (var pos in area) + { + var checkPoint = pos; + var tile = SafeGetTile(checkPoint); + float value0 = GetPerlinPixelG(pos.X, pos.Y) * 12; + if (pos.Y - tilePos.Y < 12 + value0) + { + tile.TileType = (ushort)ModContent.TileType(); + } + else + { + tile.TileType = (ushort)ModContent.TileType(); + } + float value1 = GetPerlinPixelR(pos.X, pos.Y); + float value2 = GetPerlinPixelR(pos.Y, pos.X); + if (pos.Y - tilePos.Y > value1 * 3 + value0) + { + tile.HasTile = true; + } + else + { + tile.HasTile = false; + } + if (pos.Y - tilePos.Y > value2 * 3 + value0 + 2) + { + if (pos.Y - tilePos.Y > value2 * 4 + value0 * 1.2f + 3) + { + tile.WallType = (ushort)ModContent.WallType(); + } + else + { + tile.WallType = (ushort)ModContent.WallType(); + } + } + } + + // Middle Cave Shaft + for (int y = -10; y <= 70; y += 2) + { + float radius = (60 - y) / 3f; + radius = MathF.Max(radius, 10) * 1.4f; + PlaceCircleAreaOfBlockWithRandomNoise(tilePos + new Point(0, y), radius, ModContent.TileType(), 3, (int)TileChangeState.HasTile); + PlaceCircleAreaOfBlockWithRandomNoise(tilePos + new Point(0, y), radius - 3, -1, 3, (int)TileChangeState.Forceful); + PlaceCircleAreaOfWallWithRandomNoise(tilePos + new Point(0, y), radius - 1, ModContent.WallType(), 3, (int)TileChangeState.HasWall); + } + + // SubFloor Cave + List Cave0_Bound = new List(); + List Cave0 = new List(); + int cave0Y = 75; + int caveHeight = 128; + for (int x = -130; x <= 130; x++) + { + float height = 130 - MathF.Abs(x); + height = Math.Clamp(height, 0, caveHeight + 64); + float value2 = GetPerlinPixelR(x * 2, cave0Y) * 64; + height += value2; + Cave0_Bound.Add(new Vector2(x * 16, cave0Y * 16 - height)); + height -= 64; + height = Math.Clamp(height, 0, caveHeight); + value2 = GetPerlinPixelB(x * 2, cave0Y + 40) * 64; + height += value2; + Cave0.Add(new Vector2(x * 16, cave0Y * 16 - height)); + } + for (int x = 130; x >= -130; x--) + { + float height = 130 - MathF.Abs(x); + height = Math.Clamp(height, 0, caveHeight + 64); + float value2 = GetPerlinPixelB(x * 2, cave0Y + 30) * 64; + height += value2; + Cave0_Bound.Add(new Vector2(x * 16, cave0Y * 16 + height)); + height -= 64; + height = Math.Clamp(height, 0, caveHeight); + value2 = GetPerlinPixelB(x * 2, cave0Y + 70) * 64; + height += value2; + Cave0.Add(new Vector2(x * 16, cave0Y * 16 + height)); + } + PlacePolygonAreaOfBlockWithOffset(Cave0_Bound, tilePos.ToWorldCoordinates(), ModContent.TileType(), (int)TileChangeState.HasTile); + PlacePolygonAreaOfBlockWithOffset(Cave0, tilePos.ToWorldCoordinates(), -1, (int)TileChangeState.Forceful); + SmoothTile_XXYY(tilePos.X - 150, tilePos.Y - 60, tilePos.X + 150, tilePos.Y + 150); + + // Bamboo + IsleOfBloom_PlantBamboo(tilePos); + + // Side peach + for (int y = -3; y <= 40; y += 2) + { + if (GenRand.NextBool(4)) + { + int checkX = 0; + int direction = -1; + if (GenRand.NextBool()) + { + direction = 1; + } + for (int x = 0; x < 23; x++) + { + var tile = SafeGetTile(tilePos.X + x * direction, tilePos.Y + y); + checkX = (x - 1) * direction; + if (tile.HasTile) + { + break; + } + } + if (MathF.Abs(checkX) < 21) + { + if (direction == -1) + { + if (CheckSpaceRight(tilePos.X + checkX, tilePos.Y + y) > 11) + { + PlaceFrameImportantTiles(tilePos.X + checkX, tilePos.Y + y, 10, 1, ModContent.TileType(), 180); + IsleOfBloom_FillBlockHorizontally(tilePos + new Point(checkX - 1, y), true); + } + } + else + { + if (CheckSpaceLeft(tilePos.X + checkX, tilePos.Y + y) > 11) + { + PlaceFrameImportantTiles(tilePos.X + checkX - 10, tilePos.Y + y, 10, 1, ModContent.TileType(), 0); + IsleOfBloom_FillBlockHorizontally(tilePos + new Point(checkX, y), false); + } + } + break; + } + } + } + + // Peach + IsleOfBloom_PlantPeachTree_Surface(tilePos); + + // Small Peach + IsleOfBloom_PlantSmallPeachTree_Surface(tilePos); + + // Wall Peach + IsleOfBloom_PlantPeachTree_ShaftWall(tilePos); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/ResetIsleOfBloom.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/ResetIsleOfBloom.png new file mode 100644 index 000000000..9a2358fe2 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/ResetIsleOfBloom.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/UnderWaterDungeon.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/UnderWaterDungeon.cs index 7377d4d5b..b17c71301 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/UnderWaterDungeon.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/Developer/UnderWaterDungeon.cs @@ -1,11 +1,9 @@ -using System; using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.IRProbe; using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.LightningMechanism; using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.UnderwaterGuillotine; using Everglow.Yggdrasil.KelpCurtain.Walls; -using Everglow.Yggdrasil.WorldGeneration; -using static System.Runtime.InteropServices.JavaScript.JSType; +using static Everglow.Commons.Utilities.TileUtils; using static Everglow.Yggdrasil.WorldGeneration.YggdrasilWorldGeneration; namespace Everglow.Yggdrasil.KelpCurtain.Items.Tools.Developer; @@ -34,7 +32,7 @@ public override bool CanUseItem(Player player) return false; } - public void GenerateUnderWaterDungeon(int i, int j) + public static void GenerateUnderWaterDungeon(int i, int j) { KillRectangleAreaOfTile(i - 800, j - 170, i + 80, j + 70); KillRectangleAreaOfWall(i - 800, j - 170, i + 80, j + 70); @@ -52,7 +50,7 @@ public void GenerateUnderWaterDungeon(int i, int j) // Trigger of the trap #0 Point irPos = new Point(i - xRoom * cellDistance - cellWidth + 9, j); - Tile irProbeTile = TileUtils.SafeGetTile(irPos); + Tile irProbeTile = SafeGetTile(irPos); irProbeTile.TileType = (ushort)ModContent.TileType(); irProbeTile.TileFrameX = 36; irProbeTile.HasTile = true; @@ -70,7 +68,7 @@ public void GenerateUnderWaterDungeon(int i, int j) // trigger #1 irPos = new Point(i - xRoom * cellDistance - 12, j - cellHeight + 9); - irProbeTile = TileUtils.SafeGetTile(irPos); + irProbeTile = SafeGetTile(irPos); irProbeTile.TileType = (ushort)ModContent.TileType(); irProbeTile.TileFrameX = 18; irProbeTile.HasTile = true; @@ -87,7 +85,7 @@ public void GenerateUnderWaterDungeon(int i, int j) // trigger #2 irPos = new Point(i - xRoom * cellDistance + 12, j - cellHeight + 9); - irProbeTile = TileUtils.SafeGetTile(irPos); + irProbeTile = SafeGetTile(irPos); irProbeTile.TileType = (ushort)ModContent.TileType(); irProbeTile.TileFrameX = 18; irProbeTile.HasTile = true; @@ -130,8 +128,8 @@ public void GenerateUnderWaterDungeon(int i, int j) int lampY = centerY - cellHeight + thick + moveY; int lampX0 = centerX - cellWidth + thick + moveX; int lampX1 = centerX + cellWidth - thick - moveX; - Tile lamp0 = TileUtils.SafeGetTile(lampX0, lampY); - Tile lamp1 = TileUtils.SafeGetTile(lampX1, lampY); + Tile lamp0 = SafeGetTile(lampX0, lampY); + Tile lamp1 = SafeGetTile(lampX1, lampY); lamp0.TileType = (ushort)ModContent.TileType(); lamp0.HasTile = true; @@ -145,7 +143,7 @@ public void GenerateUnderWaterDungeon(int i, int j) { int y = j + (cellHeight - tunnelHeight / 2) - 3; ConnectWaterErodedBrickTunnel(i - xRoom * cellDistance - (cellWidth - 7), y, i - xRoom * cellDistance - cellDistance + (cellWidth - 7), y, tunnelHeight); - Tile lamp0 = TileUtils.SafeGetTile(i - xRoom * cellDistance - (cellWidth - 7) - 0, y); + Tile lamp0 = SafeGetTile(i - xRoom * cellDistance - (cellWidth - 7) - 0, y); lamp0.TileType = (ushort)ModContent.TileType(); lamp0.HasTile = true; } @@ -157,7 +155,7 @@ public void GenerateUnderWaterDungeon(int i, int j) { int checkX = checkXRoom2 + k * 15; int checkY = checkYRoom2 + (k % 2 == 0 ? 3 : 0); - Tile lamp = TileUtils.SafeGetTile(checkX, checkY); + Tile lamp = SafeGetTile(checkX, checkY); if ((!lamp.HasTile || lamp.TileType != ModContent.TileType()) && lamp.wall == ModContent.WallType()) { lamp.TileType = (ushort)ModContent.TileType(); @@ -172,7 +170,7 @@ public void GenerateUnderWaterDungeon(int i, int j) ConnectWaterErodedBrickTunnel_Serrated(new Point(i - 1 * cellDistance - 40, j - 64), new Point(i - 38, j + 9), 12, 8); } - public void ConnectWire(Point point0, Point point1, bool red = true, bool green = false, bool blue = false, bool yellow = false) + public static void ConnectWire(Point point0, Point point1, bool red = true, bool green = false, bool blue = false, bool yellow = false) { int distanceX = Math.Abs((point1 - point0).X); int distanceY = Math.Abs((point1 - point0).Y); @@ -189,7 +187,7 @@ public void ConnectWire(Point point0, Point point1, bool red = true, bool green } for (int y = 0; y < distanceY; y++) { - Tile tile = TileUtils.SafeGetTile(check); + Tile tile = SafeGetTile(check); tile.RedWire = red; tile.GreenWire = green; tile.BlueWire = blue; @@ -198,7 +196,7 @@ public void ConnectWire(Point point0, Point point1, bool red = true, bool green } for (int x = 0; x <= distanceX; x++) { - Tile tile = TileUtils.SafeGetTile(check); + Tile tile = SafeGetTile(check); tile.RedWire = red; tile.GreenWire = green; tile.BlueWire = blue; @@ -207,7 +205,7 @@ public void ConnectWire(Point point0, Point point1, bool red = true, bool green } } - public void BrickRoom(int centerX, int centerY, int halfWidth, int halfHeight) + public static void BrickRoom(int centerX, int centerY, int halfWidth, int halfHeight) { int thick = 8; @@ -216,7 +214,7 @@ public void BrickRoom(int centerX, int centerY, int halfWidth, int halfHeight) { for (int y = centerY - halfHeight; y <= centerY + halfHeight; y++) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); int boundValue = halfWidth - Math.Abs(x - centerX); int boundValue2 = halfHeight - Math.Abs(y - centerY); boundValue = Math.Min(boundValue, boundValue2); @@ -230,7 +228,7 @@ public void BrickRoom(int centerX, int centerY, int halfWidth, int halfHeight) tile.HasTile = false; if (boundValue > 1) { - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); tile.liquid = (byte)LiquidID.Water; tile.LiquidAmount = 255; } @@ -244,12 +242,12 @@ public void BrickRoom(int centerX, int centerY, int halfWidth, int halfHeight) int height = WorldGen.genRand.Next(-12, 18); if (height > 0) { - Tile algaBottom = TileUtils.SafeGetTile(centerX - halfWidth + algaX, centerY + halfHeight - thick); + Tile algaBottom = SafeGetTile(centerX - halfWidth + algaX, centerY + halfHeight - thick); if (algaBottom.HasTile) { for (int algaY = 0; algaY < height; algaY++) { - Tile algaTile = TileUtils.SafeGetTile(centerX - halfWidth + algaX, centerY + halfHeight - thick - algaY - 1); + Tile algaTile = SafeGetTile(centerX - halfWidth + algaX, centerY + halfHeight - thick - algaY - 1); if (algaTile.HasTile) { break; @@ -266,7 +264,7 @@ public void BrickRoom(int centerX, int centerY, int halfWidth, int halfHeight) // Drain(bubbles for breathe) Point outlet = new Point(centerX - 2, centerY); - TileUtils.PlaceFrameImportantTiles(outlet.X, outlet.Y, 4, 4, ModContent.TileType()); + PlaceFrameImportantTiles(outlet.X, outlet.Y, 4, 4, ModContent.TileType()); } /// @@ -318,12 +316,12 @@ public static void ConnectWaterErodedBrickTunnel(int x0, int y0, int x1, int y1, } if (shouldKill) { - Tile tile = TileUtils.SafeGetTile((int)(x + checkPoint.X), (int)(y + checkPoint.Y)); + Tile tile = SafeGetTile((int)(x + checkPoint.X), (int)(y + checkPoint.Y)); float distance = checkDir.Length(); if (distance < halfWidth - (sideThick - 1)) { tile.HasTile = false; - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); tile.liquid = (byte)LiquidID.Water; tile.LiquidAmount = 255; } @@ -333,7 +331,7 @@ public static void ConnectWaterErodedBrickTunnel(int x0, int y0, int x1, int y1, tile.TileType = (ushort)ModContent.TileType(); if (distance < halfWidth) { - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } } } @@ -350,7 +348,7 @@ public static void ConnectWaterErodedBrickTunnel(int x0, int y0, int x1, int y1, /// /// /// - public void ConnectWaterErodedBrickTunnel_Serrated(int x0, int y0, int x1, int y1, float width, float sideThick) + public static void ConnectWaterErodedBrickTunnel_Serrated(int x0, int y0, int x1, int y1, float width, float sideThick) { ConnectWaterErodedBrickTunnel_Serrated(new Point(x0, y0), new Point(x1, y1), width, sideThick); } @@ -363,7 +361,7 @@ public void ConnectWaterErodedBrickTunnel_Serrated(int x0, int y0, int x1, int y /// /// /// - public void ConnectWaterErodedBrickTunnel_Serrated(Point point0, Point point1, float width, float sideThick) + public static void ConnectWaterErodedBrickTunnel_Serrated(Point point0, Point point1, float width, float sideThick) { // Calculate the shape float centerThick = width - sideThick; @@ -439,23 +437,23 @@ public void ConnectWaterErodedBrickTunnel_Serrated(Point point0, Point point1, f if (inflectionPoint.Contains(s)) { Point point = trailPos[s]; - Tile checkLeft = TileUtils.SafeGetTile(point + new Point(-8, 3)); - Tile checkRight = TileUtils.SafeGetTile(point + new Point(8, 3)); + Tile checkLeft = SafeGetTile(point + new Point(-8, 3)); + Tile checkRight = SafeGetTile(point + new Point(8, 3)); Point probePos = point + new Point(0, -7); if (checkLeft.HasTile) { - TileUtils.PlaceFrameImportantTiles(point.X - 7, point.Y + 3, 5, 3, ModContent.TileType(), 90); + PlaceFrameImportantTiles(point.X - 7, point.Y + 3, 5, 3, ModContent.TileType(), 90); probePos += new Point(7, 0); ConnectWire(probePos, new Point(point.X - 3, point.Y + 4)); } if (checkRight.HasTile) { - TileUtils.PlaceFrameImportantTiles(point.X + 3, point.Y + 3, 5, 3, ModContent.TileType()); + PlaceFrameImportantTiles(point.X + 3, point.Y + 3, 5, 3, ModContent.TileType()); probePos += new Point(-7, 0); ConnectWire(probePos, new Point(point.X + 3, point.Y + 4)); } - Tile irProbe = TileUtils.SafeGetTile(probePos); - Tile irProbeTop = TileUtils.SafeGetTile(probePos + new Point(0, -1)); + Tile irProbe = SafeGetTile(probePos); + Tile irProbeTop = SafeGetTile(probePos + new Point(0, -1)); if (!irProbe.HasTile && irProbeTop.HasTile) { irProbe.TileType = (ushort)ModContent.TileType(); @@ -468,7 +466,7 @@ public void ConnectWaterErodedBrickTunnel_Serrated(Point point0, Point point1, f if (lumpLampPoint.Contains(s)) { Point point = trailPos[s] + new Point(0, -1); - Tile tile = TileUtils.SafeGetTile(point); + Tile tile = SafeGetTile(point); if (!tile.HasTile) { tile.TileType = (ushort)ModContent.TileType(); @@ -480,15 +478,15 @@ public void ConnectWaterErodedBrickTunnel_Serrated(Point point0, Point point1, f if (breathePoint.Contains(s)) { Point point = trailPos[s] + new Point(-2, 1); - TileUtils.PlaceFrameImportantTiles(point.X, point.Y, 4, 4, ModContent.TileType()); + PlaceFrameImportantTiles(point.X, point.Y, 4, 4, ModContent.TileType()); } // Platforms if (platformPoint.Contains(s)) { Point point = trailPos[s] + new Point(0, 1); - Tile checkLeft = TileUtils.SafeGetTile(point + new Point(-8, 2)); - Tile checkRight = TileUtils.SafeGetTile(point + new Point(8, 2)); + Tile checkLeft = SafeGetTile(point + new Point(-8, 2)); + Tile checkRight = SafeGetTile(point + new Point(8, 2)); if (checkLeft.HasTile) { int length = CheckSpaceLeft(point.X, point.Y); @@ -508,7 +506,7 @@ public void ConnectWaterErodedBrickTunnel_Serrated(Point point0, Point point1, f for (int x = 1; x <= 2; x++) { Point pointCheck = point + new Point(length, 0) + new Point(-x, 0); - if (TileUtils.SafeGetTile(pointCheck).HasTile) + if (SafeGetTile(pointCheck).HasTile) { j = 20; break; @@ -536,7 +534,7 @@ public void ConnectWaterErodedBrickTunnel_Serrated(Point point0, Point point1, f for (int x = 1; x <= 2; x++) { Point pointCheck = point + new Point(-length, 0) + new Point(x, 0); - if (TileUtils.SafeGetTile(pointCheck).HasTile) + if (SafeGetTile(pointCheck).HasTile) { j = 20; break; @@ -571,7 +569,7 @@ public static void ClearRectangleAreaExclude(int x0, int y0, int x1, int y1, int { for (int y = y0; y <= y1; y += 1) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); if (tile.TileType != excludeType) { tile.ClearEverything(); diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/VineRepairWand.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/VineRepairWand.cs new file mode 100644 index 000000000..f6ab8dcf4 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/VineRepairWand.cs @@ -0,0 +1,342 @@ +using Everglow.Yggdrasil.KelpCurtain.Projectiles.Miscs.VineWand; +using Everglow.Yggdrasil.KelpCurtain.Tiles.ForestRainVines; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Tools; + +/// +/// æŽ§åˆ¶æ£®é›¨è—¤æ›¼é•¿åº¦çš„é­”æ– - 藤曼修ç†é­”æ– +/// +public class VineRepairWand : ModItem +{ + // 存储当å‰è°ƒæ•´çŠ¶æ€ + private AdjustmentData currentAdjustment; + + // 存储激活的能é‡çº¿å¼¹å¹• + private int staticBeamIndex = -1; + private List movingOrbIndices = new List(); + + private class AdjustmentData + { + public Point FixPoint; + public bool IsAdjusting; + public int LastManaChange; + public int PendingOrbs; // 待生æˆçš„能é‡çƒæ•°é‡ + } + + public override void SetDefaults() + { + Item.width = 34; + Item.height = 34; + Item.damage = 1; + Item.useTime = 12; + Item.useAnimation = 12; + Item.useStyle = ItemUseStyleID.Shoot; + Item.autoReuse = false; + Item.mana = 6; + Item.value = 13320; + Item.rare = ItemRarityID.Green; + Item.noMelee = true; + Item.tileBoost = 60; + } + + public override void HoldItem(Player player) + { + // 如果正在调整,让法æ–å‘å…‰å¹¶ä¿æŒä½¿ç”¨çŠ¶æ€ + if (currentAdjustment != null && currentAdjustment.IsAdjusting) + { + Lighting.AddLight(player.Center, new Vector3(0.2f, 0.8f, 0.2f)); + Item.useTime = 0; + Item.useAnimation = 0; + + float rot = (player.Center - currentAdjustment.FixPoint.ToWorldCoordinates()).ToRotation(); + player.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, rot + MathHelper.PiOver2); + + // æ›´æ–°é™æ€èƒ½é‡çº¿ä½ç½® + UpdateStaticBeam(player); + + // 生æˆå¾…定的能é‡çƒ + GeneratePendingOrbs(player); + + // 清ç†å·²å®Œæˆçš„能é‡çƒ + CleanupFinishedOrbs(); + } + else + { + Item.useTime = 12; + Item.useAnimation = 12; + } + } + + public override void UpdateInventory(Player player) + { + // 如果ä¸å†æŒæœ‰æ³•æ–,结æŸè°ƒæ•´çŠ¶æ€ + if (player.HeldItem?.type != ModContent.ItemType()) + { + EndAdjustment(); + } + } + + /// + /// 开始调整藤曼 + /// + public bool StartAdjustment(Player player, Point fixPoint) + { + // 消耗åˆå§‹10ç‚¹è“ + if (player.CheckMana(10, true)) + { + currentAdjustment = new AdjustmentData + { + FixPoint = fixPoint, + IsAdjusting = true, + LastManaChange = 10, + PendingOrbs = 0, + }; + + // åˆ›å»ºé™æ€èƒ½é‡çº¿ + CreateStaticBeam(player, fixPoint); + + return true; + } + return false; + } + + /// + /// 更新藤曼调整(长度å˜åŒ–) + /// + public void UpdateAdjustment(Player player, Point fixPoint, int deltaLength) + { + if (deltaLength == 0) + { + return; + } + + if (currentAdjustment == null || !currentAdjustment.IsAdjusting || currentAdjustment.FixPoint != fixPoint) + { + return; + } + + // 检查是å¦ä»ç„¶æ‰‹æŒæ³•æ– + if (player.HeldItem?.type != ModContent.ItemType()) + { + EndAdjustment(); + return; + } + + if (deltaLength > 0) // è°ƒé•¿ï¼Œæ¶ˆè€—è“ + { + if (player.statMana >= deltaLength) + { + player.statMana -= deltaLength; + currentAdjustment.LastManaChange = deltaLength; + + // æ¯1å•ä½é•¿åº¦å‘é€ä¸€ä¸ªèƒ½é‡ç‚¹ + currentAdjustment.PendingOrbs += deltaLength; + } + else + { + // è“é‡ä¸è¶³ï¼Œå¼ºåˆ¶ç»“æŸè°ƒæ•´ + EndAdjustment(); + } + } + else if (deltaLength < 0) // 调短,æ¢å¤è“ + { + player.statMana = Math.Min(player.statManaMax2, player.statMana - deltaLength); + currentAdjustment.LastManaChange = deltaLength; + + // æ¯1å•ä½é•¿åº¦å‘é€ä¸€ä¸ªèƒ½é‡ç‚¹ + currentAdjustment.PendingOrbs += Math.Abs(deltaLength); + } + + // é™åˆ¶å¾…生æˆèƒ½é‡çƒæ•°é‡ä¸è¶…过4个 + currentAdjustment.PendingOrbs = Math.Min(currentAdjustment.PendingOrbs, 4); + } + + /// + /// 结æŸè—¤æ›¼è°ƒæ•´ + /// + public void EndAdjustment() + { + if (currentAdjustment != null && currentAdjustment.IsAdjusting) + { + // 清除所有能é‡çº¿å¼¹å¹• + ClearAllBeams(); + + currentAdjustment.IsAdjusting = false; + currentAdjustment = null; + } + } + + /// + /// æ£€æŸ¥æ˜¯å¦æ­£åœ¨è°ƒæ•´è—¤æ›¼ + /// + public bool IsAdjusting(Point fixPoint) + { + return currentAdjustment != null && currentAdjustment.IsAdjusting && currentAdjustment.FixPoint == fixPoint; + } + + /// + /// 生æˆå¾…定的能é‡çƒ + /// + private void GeneratePendingOrbs(Player player) + { + if (currentAdjustment == null || currentAdjustment.PendingOrbs <= 0) + { + return; + } + + // 计算当å‰å¯ä»¥ç”Ÿæˆçš„能é‡çƒæ•°é‡ï¼ˆä¸è¶…过4ä¸ªåŒæ—¶å­˜åœ¨ï¼‰ + int availableSlots = 4 - movingOrbIndices.Count; + int orbsToGenerate = Math.Min(currentAdjustment.PendingOrbs, availableSlots); + + for (int i = 0; i < orbsToGenerate; i++) + { + CreateEnergyOrb(player, currentAdjustment.FixPoint); + currentAdjustment.PendingOrbs--; + } + } + + /// + /// 清ç†å·²å®Œæˆæˆ–无效的能é‡çƒ + /// + private void CleanupFinishedOrbs() + { + // ç§»é™¤å·²å®Œæˆæˆ–无效的能é‡çƒ + for (int i = movingOrbIndices.Count - 1; i >= 0; i--) + { + int index = movingOrbIndices[i]; + if (index < 0 || index >= Main.maxProjectiles || !Main.projectile[index].active || + Main.projectile[index].type != ModContent.ProjectileType()) + { + movingOrbIndices.RemoveAt(i); + } + } + } + + private void CreateStaticBeam(Player player, Point targetPoint) + { + if (Main.myPlayer == player.whoAmI) + { + Vector2 startPos = player.Center; + Vector2 endPos = targetPoint.ToWorldCoordinates(); + + // åˆ›å»ºé™æ€èƒ½é‡çº¿ + int projectileIndex = Projectile.NewProjectile( + player.GetSource_FromThis(), + startPos, + Vector2.Zero, + ModContent.ProjectileType(), + 0, 0, player.whoAmI, + TileUtils.SafeGetTile(targetPoint).TileType == ModContent.TileType() ? 0.5f : 1); + + // 设置弹幕属性 + Projectile projectile = Main.projectile[projectileIndex]; + if (projectile.ModProjectile is VineEnergyBeam beam) + { + beam.StartPosition = startPos; + beam.EndPosition = endPos; + } + + staticBeamIndex = projectileIndex; + } + } + + private void UpdateStaticBeam(Player player) + { + if (player.ownedProjectileCounts[ModContent.ProjectileType()] <= 0) + { + CreateStaticBeam(player, currentAdjustment.FixPoint); + } + } + + private void CreateEnergyOrb(Player player, Point targetPoint) + { + if (Main.myPlayer == player.whoAmI && movingOrbIndices.Count < 4) + { + Vector2 startPos, endPos; + + // æ ¹æ®è°ƒæ•´æ–¹å‘决定能é‡çƒæµå‘ + if (currentAdjustment.LastManaChange >= 0) // 调长,从法æ–到tile + { + startPos = player.Center; + endPos = targetPoint.ToWorldCoordinates(); + } + else // 调短,从tileåˆ°æ³•æ– + { + startPos = targetPoint.ToWorldCoordinates(); + endPos = player.Center; + } + + int projectileIndex = Projectile.NewProjectile( + player.GetSource_FromThis(), + startPos, + Vector2.Zero, + ModContent.ProjectileType(), + 0, 0, player.whoAmI, + TileUtils.SafeGetTile(targetPoint).TileType == ModContent.TileType() ? 0.5f : 1); + + Projectile projectile = Main.projectile[projectileIndex]; + if (projectile.ModProjectile is VineEnergyOrb orb) + { + orb.StartPosition = startPos; + orb.EndPosition = endPos; + orb.Speed = 0.02f + Main.rand.NextFloat(0.01f); // ç¨å¾®éšæœºåŒ–é€Ÿåº¦ + orb.Progress = 0f; + if (endPos != player.Center) + { + orb.TileDestination = endPos; + } + } + + movingOrbIndices.Add(projectileIndex); + } + } + + private void ClearAllBeams() + { + // æ¸…é™¤é™æ€èƒ½é‡çº¿ + if (staticBeamIndex != -1 && Main.projectile[staticBeamIndex].active) + { + Main.projectile[staticBeamIndex].Kill(); + staticBeamIndex = -1; + } + + // 清除所有移动能é‡çƒ + foreach (int index in movingOrbIndices) + { + if (index >= 0 && index < Main.maxProjectiles && Main.projectile[index].active) + { + Main.projectile[index].Kill(); + } + } + movingOrbIndices.Clear(); + } + + public override bool CanUseItem(Player player) + { + return false; + } + + public override void PostDrawInWorld(SpriteBatch spriteBatch, Color lightColor, Color alphaColor, float rotation, float scale, int whoAmI) + { + if (currentAdjustment != null && currentAdjustment.IsAdjusting) + { + Texture2D texture = ModContent.Request(Texture).Value; + Vector2 position = Item.position - Main.screenPosition + new Vector2(Item.width / 2, Item.height - texture.Height * 0.5f + 2f); + + Color glowColor = currentAdjustment.LastManaChange >= 0 ? + Color.Lerp(Color.White, Color.LightGreen, (float)System.Math.Sin(Main.GlobalTimeWrappedHourly * 6f) * 0.3f + 0.7f) : + Color.Lerp(Color.White, Color.YellowGreen, (float)System.Math.Sin(Main.GlobalTimeWrappedHourly * 6f) * 0.3f + 0.7f); + + spriteBatch.Draw( + texture, + position, + null, + glowColor, + rotation, + texture.Size() * 0.5f, + scale, + SpriteEffects.None, + 0f); + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/VineRepairWand.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/VineRepairWand.png new file mode 100644 index 000000000..b6a2efc57 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/VineRepairWand.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/VineRepairWand_bloom.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/VineRepairWand_bloom.png new file mode 100644 index 000000000..0539d7e55 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/VineRepairWand_bloom.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/VineRepairWand_glow.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/VineRepairWand_glow.png new file mode 100644 index 000000000..14e560530 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Tools/VineRepairWand_glow.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/ActivatedDogStaff.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/ActivatedDogStaff.cs new file mode 100644 index 000000000..9729072fe --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/ActivatedDogStaff.cs @@ -0,0 +1,59 @@ +using Everglow.Yggdrasil.KelpCurtain.Projectiles.Summon; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Weapons; + +public class ActivatedDogStaff : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.SummonWeapons; + + public const int LeftManaCost = 10; + public const int RightManaCost = 20; + public const float SpecialProjectileSpeed = 15f; + + public override void SetStaticDefaults() + { + Item.staff[Type] = true; + } + + public override void SetDefaults() + { + Item.DamageType = DamageClass.Summon; + Item.damage = 8; + Item.knockBack = 1.1f; + Item.mana = LeftManaCost; + + Item.useStyle = ItemUseStyleID.Swing; + Item.useTime = Item.useAnimation = 20; + Item.noMelee = true; + + Item.rare = ItemRarityID.Green; + Item.value = Item.buyPrice(gold: 1); + + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 12f; + } + + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) + { + Projectile proj = Projectile.NewProjectileDirect(source, Main.MouseWorld, Vector2.zeroVector, type, damage, knockback, player.whoAmI); + Projectile proj2 = Projectile.NewProjectileDirect(source, Main.MouseWorld, Vector2.zeroVector, ModContent.ProjectileType(), damage, knockback, player.whoAmI); + proj.spriteDirection = -1; + proj2.spriteDirection = -1; + if (Main.MouseWorld.X < player.Center.X) + { + proj.spriteDirection = 1; + proj2.spriteDirection = 1; + } + return false; + } + + public override bool CanUseItem(Player player) + { + if (player.maxMinions - player.GetSlotsMinions() < 1) + { + return false; + } + return base.CanUseItem(player); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/ActivatedDogStaff.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/ActivatedDogStaff.png new file mode 100644 index 000000000..fab08b199 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/ActivatedDogStaff.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicSpellBook.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicSpellBook.cs new file mode 100644 index 000000000..c4c3509b8 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicSpellBook.cs @@ -0,0 +1,71 @@ +using Everglow.SpellAndSkull.Items; +using Everglow.Yggdrasil.KelpCurtain.Items.Materials; +using Everglow.Yggdrasil.KelpCurtain.Items.Placeables; +using Everglow.Yggdrasil.KelpCurtain.Projectiles.Magic; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Weapons; + +public class RedAlgaeMagicSpellBook : SpellTomeItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.MagicWeapons; + + public override void SetDefaults() + { + Item.damage = 70; + Item.DamageType = DamageClass.Magic; + Item.mana = 4; + Item.width = 38; + Item.height = 36; + Item.useTime = 4; + Item.useAnimation = 4; + Item.useStyle = ItemUseStyleID.Shoot; + Item.noMelee = true; + Item.knockBack = 0.5f; + Item.value = 35000; + Item.rare = ItemRarityID.Orange; + Item.UseSound = SoundID.Item42; + Item.autoReuse = true; + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 0.5f; + + // DecorativeProjectileTypes.Add(ModContent.ProjectileType()); + // DecorativeProjectileTypes.Add(ModContent.ProjectileType()); + } + + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) + { + if (player.GetModPlayer().MagicBookLevel > 0) + { + return false; // TODO: Adapt to the crystal skull + } + if (player.ownedProjectileCounts[type] > 0) + { + foreach (var proj in Main.projectile) + { + if (proj is not null && proj.active && proj.type == type && proj.owner == player.whoAmI) + { + RedAlgaeMagicSpellBook_proj rAMSBp = proj.ModProjectile as RedAlgaeMagicSpellBook_proj; + if (rAMSBp is not null) + { + if (!rAMSBp.Released) + { + return false; + } + } + } + } + } + Projectile.NewProjectileDirect(source, position, Vector2.zeroVector, type, damage, knockback, player.whoAmI); + return false; + } + + public override void AddRecipes() + { + CreateRecipe() + .AddIngredient(ModContent.ItemType(), 18) + .AddIngredient(ModContent.ItemType(), 1) + .AddTile(TileID.WorkBenches) + .Register(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicSpellBook.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicSpellBook.png new file mode 100644 index 000000000..c8df48bb3 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicSpellBook.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicSpellBook_glow.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicSpellBook_glow.png new file mode 100644 index 000000000..36b9daccf Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicSpellBook_glow.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicStaff.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicStaff.cs new file mode 100644 index 000000000..6c4fe1700 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicStaff.cs @@ -0,0 +1,49 @@ +using Everglow.SpellAndSkull.Items; +using Everglow.Yggdrasil.KelpCurtain.Items.Materials; +using Everglow.Yggdrasil.KelpCurtain.Items.Placeables; +using Everglow.Yggdrasil.KelpCurtain.Projectiles.Magic; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Weapons; + +public class RedAlgaeMagicStaff : SpellTomeItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.MagicWeapons; + + public override void SetDefaults() + { + Item.damage = 54; + Item.DamageType = DamageClass.Magic; + Item.mana = 12; + Item.width = 46; + Item.height = 46; + Item.useTime = 30; + Item.useAnimation = 30; + Item.useStyle = ItemUseStyleID.Shoot; + Item.noMelee = true; + Item.knockBack = 2.7f; + Item.value = 35000; + Item.rare = ItemRarityID.Orange; + Item.UseSound = SoundID.Item42; + Item.autoReuse = true; + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 12f; + Item.staff[Type] = true; + } + + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) + { + Projectile.NewProjectileDirect(source, position, velocity, type, damage, knockback, player.whoAmI, -MathHelper.PiOver2); + Projectile.NewProjectileDirect(source, position, velocity * 0.8f, type, damage, knockback, player.whoAmI, MathHelper.PiOver2); + return false; + } + + public override void AddRecipes() + { + CreateRecipe() + .AddIngredient(ModContent.ItemType(), 12) + .AddIngredient(ModContent.ItemType(), 1) + .AddTile(TileID.WorkBenches) + .Register(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicStaff.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicStaff.png new file mode 100644 index 000000000..203b6c51b Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicStaff.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicStaff_glow.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicStaff_glow.png new file mode 100644 index 000000000..48854a670 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicStaff_glow.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicWhip.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicWhip.cs new file mode 100644 index 000000000..91828e665 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicWhip.cs @@ -0,0 +1,33 @@ +using Everglow.Commons.Templates.Weapons.Whips; +using Everglow.Yggdrasil.KelpCurtain.Items.Materials; +using Everglow.Yggdrasil.KelpCurtain.Items.Placeables; +using Everglow.Yggdrasil.KelpCurtain.Projectiles.Summon; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Weapons; + +public class RedAlgaeMagicWhip : WhipItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.SummonWeapons; + + public override void SetDef() + { + Item.width = 40; + Item.height = 32; + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 5.04f; + Item.value = 35000; + Item.rare = ItemRarityID.Orange; + Item.damage = 59; + Item.useAnimation = 30; + Item.useTime = 30; + } + + public override void AddRecipes() + { + CreateRecipe() + .AddIngredient(ModContent.ItemType(), 15) + .AddIngredient(ModContent.ItemType(), 1) + .AddTile(TileID.WorkBenches) + .Register(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicWhip.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicWhip.png new file mode 100644 index 000000000..81ee86867 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicWhip.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicWhip_glow.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicWhip_glow.png new file mode 100644 index 000000000..75e16a73e Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMagicWhip_glow.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMinionGyroscope.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMinionGyroscope.cs new file mode 100644 index 000000000..72a72cca1 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMinionGyroscope.cs @@ -0,0 +1,74 @@ +using Everglow.Commons.Templates.Weapons.Gyroscopes; +using Everglow.Yggdrasil.KelpCurtain.Buffs; +using Everglow.Yggdrasil.KelpCurtain.Items.Materials; +using Everglow.Yggdrasil.KelpCurtain.Items.Placeables; +using Everglow.Yggdrasil.KelpCurtain.Projectiles.Summon; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Weapons; + +public class RedAlgaeMinionGyroscope : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.SummonWeapons; + + public override void SetDefaults() + { + Item.width = 32; + Item.height = 32; + + Item.DamageType = DamageClass.Summon; + Item.damage = 44; + Item.knockBack = 0.2f; + + Item.useTime = Item.useAnimation = 16; + Item.useStyle = ItemUseStyleID.Shoot; + Item.UseSound = SoundID.Item117; + Item.autoReuse = true; + Item.noMelee = true; + Item.noUseGraphic = true; + Item.channel = true; + + Item.value = 35000; + Item.rare = ItemRarityID.Orange; + + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 0; + } + + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) + { + if (player.altFunctionUse == 2) + { + var gyroscopePlayer = player.GetModPlayer(); + if (gyroscopePlayer != null) + { + gyroscopePlayer.EnablePowerBarUI ^= true; + if (gyroscopePlayer.EnablePowerBarUI) + { + CombatText.NewText(player.Hitbox, Color.White, "Enable Gyroscope Power Bar"); + } + else + { + CombatText.NewText(player.Hitbox, Color.White, "Disable Gyroscope Power Bar"); + } + } + return false; + } + player.AddBuff(ModContent.BuffType(), 1800000); + return base.Shoot(player, source, position, velocity, type, damage, knockback); + } + + public override bool AltFunctionUse(Player player) + { + return true; + } + + public override void AddRecipes() + { + CreateRecipe() + .AddIngredient(ModContent.ItemType(), 9) + .AddIngredient(ModContent.ItemType(), 1) + .AddTile(TileID.WorkBenches) + .Register(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMinionGyroscope.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMinionGyroscope.png new file mode 100644 index 000000000..a26b9c6de Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMinionGyroscope.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMinionGyroscope_glow.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMinionGyroscope_glow.png new file mode 100644 index 000000000..94c6b7460 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMinionGyroscope_glow.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMinionStaff.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMinionStaff.cs new file mode 100644 index 000000000..878ae0169 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMinionStaff.cs @@ -0,0 +1,65 @@ +using Everglow.Yggdrasil.KelpCurtain.Buffs; +using Everglow.Yggdrasil.KelpCurtain.Items.Materials; +using Everglow.Yggdrasil.KelpCurtain.Items.Placeables; +using Everglow.Yggdrasil.KelpCurtain.Projectiles.Summon; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Weapons; + +public class RedAlgaeMinionStaff : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.SummonWeapons; + + public override void SetStaticDefaults() + { + Item.staff[Type] = true; + } + + public override void SetDefaults() + { + Item.DamageType = DamageClass.Summon; + Item.damage = 42; + Item.knockBack = 2; + Item.mana = 27; + + Item.useStyle = ItemUseStyleID.Swing; + Item.useTime = Item.useAnimation = 27; + Item.noMelee = true; + + Item.rare = ItemRarityID.Orange; + Item.value = 35000; + + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 12f; + } + + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) + { + player.AddBuff(ModContent.BuffType(), 360000000); + Projectile proj = Projectile.NewProjectileDirect(source, Main.MouseWorld, Vector2.zeroVector, type, damage, knockback, player.whoAmI); + proj.spriteDirection = -1; + if (Main.MouseWorld.X < player.Center.X) + { + proj.spriteDirection = 1; + } + return false; + } + + public override bool CanUseItem(Player player) + { + if (player.maxMinions - player.GetSlotsMinions() < 1) + { + return false; + } + return base.CanUseItem(player); + } + + public override void AddRecipes() + { + CreateRecipe() + .AddIngredient(ModContent.ItemType(), 15) + .AddIngredient(ModContent.ItemType(), 1) + .AddTile(TileID.WorkBenches) + .Register(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMinionStaff.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMinionStaff.png new file mode 100644 index 000000000..e62eda33b Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/RedAlgaeMinionStaff.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/ArcI.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/ArcI.cs new file mode 100644 index 000000000..1e38459c0 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/ArcI.cs @@ -0,0 +1,53 @@ +using Everglow.Yggdrasil.KelpCurtain.Projectiles.Ranged; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Weapons.UnderwaterTreasury; + +public class ArcI : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.RangedWeapons; + + public int ShootType = 0; + + public int Power = 0; + + public int CurrencyCount = 0; + + public override void SetDefaults() + { + Item.width = 90; + Item.height = 20; + + Item.DamageType = DamageClass.Ranged; + Item.damage = 39; + Item.knockBack = 6f; + Item.crit = 8; + + Item.noUseGraphic = true; + Item.useStyle = ItemUseStyleID.Shoot; + Item.UseSound = SoundID.Item40; + Item.useTime = Item.useAnimation = 17; + Item.noMelee = true; + + Item.rare = ItemRarityID.Orange; + Item.value = 35000; + + Item.useAmmo = AmmoID.Bullet; + Item.shoot = ProjectileID.Bullet; + Item.shootSpeed = 16; + } + + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) + { + ShootType = type; + if (player.ownedProjectileCounts[ModContent.ProjectileType()] <= 0) + { + Projectile.NewProjectile(source, position, velocity, ModContent.ProjectileType(), damage, knockback, player.whoAmI); + } + return false; + } + + public override void HoldItem(Player player) + { + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/ArcI.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/ArcI.png new file mode 100644 index 000000000..d30af3f4f Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/ArcI.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/ArcI_glow.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/ArcI_glow.png new file mode 100644 index 000000000..528b78e79 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/ArcI_glow.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/ArmOfGiantTree.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/ArmOfGiantTree.png new file mode 100644 index 000000000..fea9586f1 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/ArmOfGiantTree.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/EmptyWaterStaff.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/EmptyWaterStaff.cs new file mode 100644 index 000000000..8c9f84153 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/EmptyWaterStaff.cs @@ -0,0 +1,44 @@ +using Everglow.Yggdrasil.KelpCurtain.Projectiles.Magic; +using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Weapons.UnderwaterTreasury; + +public class EmptyWaterStaff : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.MagicWeapons; + + public override void SetStaticDefaults() + { + Item.staff[Type] = true; + } + + public override void SetDefaults() + { + Item.width = 22; + Item.height = 22; + + Item.DamageType = DamageClass.Magic; + Item.damage = 33; + Item.knockBack = 0.3f; + Item.mana = 6; + + Item.useStyle = ItemUseStyleID.Shoot; + Item.UseSound = SoundID.Item20; + Item.useTime = Item.useAnimation = 20; + Item.noMelee = true; + Item.autoReuse = false; + + Item.rare = ItemRarityID.Orange; + Item.value = 35000; + + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 8; + } + + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) + { + Projectile.NewProjectileDirect(source, position + velocity * 4, velocity, type, damage, knockback, player.whoAmI); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/EmptyWaterStaff.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/EmptyWaterStaff.png new file mode 100644 index 000000000..d83a27e1f Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/EmptyWaterStaff.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/EvilHalbertBarnacle.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/EvilHalbertBarnacle.cs new file mode 100644 index 000000000..59f974cc8 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/EvilHalbertBarnacle.cs @@ -0,0 +1,57 @@ +using Everglow.Yggdrasil.KelpCurtain.Projectiles.Melee; +using Everglow.Yggdrasil.KelpCurtain.Projectiles.Melee.EvilHalbertBarnacle; + +namespace Everglow.Yggdrasil.KelpCurtain.Items.Weapons.UnderwaterTreasury; + +public class EvilHalbertBarnacle : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.MeleeWeapons; + + public int State = 0; + + public override void SetDefaults() + { + Item.useStyle = ItemUseStyleID.Swing; + Item.width = 64; + Item.height = 62; + Item.useAnimation = 30; + Item.useTime = 30; + Item.shootSpeed = 10f; + Item.knockBack = 5f; + Item.damage = 46; + Item.rare = ItemRarityID.Orange; + + Item.DamageType = DamageClass.Melee; + Item.noMelee = true; + Item.noUseGraphic = true; + + Item.value = 35000; + } + + public override bool CanUseItem(Player player) + { + if (base.CanUseItem(player)) + { + if (Main.myPlayer == player.whoAmI) + { + if (player.altFunctionUse != 2) + { + Projectile.NewProjectile(player.GetSource_ItemUse(Item), player.Center, Vector2.Zero, ModContent.ProjectileType(), player.GetWeaponDamage(Item), Item.knockBack, player.whoAmI); + } + else + { + // Right Click + if (player.ownedProjectileCounts[ModContent.ProjectileType()] <= 0) + { + State = 1; + Projectile.NewProjectile(player.GetSource_ItemUse(Item), player.Center, Vector2.Zero, ModContent.ProjectileType(), player.GetWeaponDamage(Item), Item.knockBack, player.whoAmI); + } + } + } + return false; + } + return base.CanUseItem(player); + } + + public override bool AltFunctionUse(Player player) => true; +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/EvilHalbertBarnacle.png b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/EvilHalbertBarnacle.png new file mode 100644 index 000000000..5cb705a06 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/UnderwaterTreasury/EvilHalbertBarnacle.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/KelpCurtainBiome.cs b/Sources/Modules/Yggdrasil/KelpCurtain/KelpCurtainBiome.cs index 1834b129a..4d07d6d5c 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/KelpCurtainBiome.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/KelpCurtainBiome.cs @@ -1,4 +1,7 @@ +using Everglow.Commons.Utilities.BackgroundHelper; using Everglow.Yggdrasil.Common; +using Everglow.Yggdrasil.KelpCurtain.Background; +using MonoMod.Core.Platforms; using SubworldLibrary; namespace Everglow.Yggdrasil.KelpCurtain; @@ -18,7 +21,7 @@ public class KelpCurtainBiome : ModBiome public override string BackgroundPath => base.BackgroundPath; - public override string MapBackground => "Everglow/Yggdrasil/KelpCurtain/Backgrounds/KelpCurtain_MapBackground"; + public override string MapBackground => ModAsset.KelpCurtain_MapBackground_Mod; public override ModWaterStyle WaterStyle => ModContent.GetInstance(); @@ -93,6 +96,29 @@ public static float FindClosestStratumBoundPointX(float checkTileY) public override void OnInBiome(Player player) { YggdrasilEnvironmentLightManager.LightingScene = YggdrasilScene.KelpCurtain; + Vector2 biomeCenter = new Vector2(9000, 157000); + BackgroundSystem bgSystem = ModContent.GetInstance(); + + KelpCurtainSky kelpCurtainSky = new KelpCurtainSky(); + kelpCurtainSky.WorldAnchor = biomeCenter; + bgSystem.AddBackgroundSlide(kelpCurtainSky); + + KelpCurtainFar kelpCurtainFar = new KelpCurtainFar(); + kelpCurtainFar.WorldAnchor = biomeCenter; + bgSystem.AddBackgroundSlide(kelpCurtainFar); + + KelpCurtainMiddle kelpCurtainMiddle = new KelpCurtainMiddle(); + kelpCurtainMiddle.WorldAnchor = biomeCenter; + bgSystem.AddBackgroundSlide(kelpCurtainMiddle); + + KelpCurtainMiddleClose kelpCurtainMiddleClose = new KelpCurtainMiddleClose(); + kelpCurtainMiddleClose.WorldAnchor = biomeCenter; + bgSystem.AddBackgroundSlide(kelpCurtainMiddleClose); + + KelpCurtainClose kelpCurtainClose = new KelpCurtainClose(); + kelpCurtainClose.WorldAnchor = biomeCenter; + bgSystem.AddBackgroundSlide(kelpCurtainClose); + base.OnInBiome(player); } } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/MapIOs/MazeUnderLake_ChestRoom_withLamps10x10.mapio b/Sources/Modules/Yggdrasil/KelpCurtain/MapIOs/MazeUnderLake_ChestRoom_withLamps10x10.mapio new file mode 100644 index 000000000..1f23cca2f Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/MapIOs/MazeUnderLake_ChestRoom_withLamps10x10.mapio differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat.cs b/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat.cs new file mode 100644 index 000000000..5696ec03b --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat.cs @@ -0,0 +1,1166 @@ +using Everglow.Commons.Coroutines; +using Everglow.Commons.DataStructures; +using Everglow.Commons.Mechanics.Miscs; +using Everglow.Commons.Physics.MassSpringSystem; +using Everglow.Yggdrasil.Common; +using Everglow.Yggdrasil.KelpCurtain.Items.Consumables; +using Everglow.Yggdrasil.KelpCurtain.Items.Misc; +using Everglow.Yggdrasil.KelpCurtain.Projectiles.Enemies; +using Everglow.Yggdrasil.KelpCurtain.VFXs.VampireMat; +using Everglow.Yggdrasil.Netcode; +using Everglow.Yggdrasil.WorldGeneration; +using Microsoft.Xna.Framework.Graphics; +using Terraria; +using Terraria.DataStructures; +using Terraria.GameContent.ItemDropRules; +using Terraria.ModLoader.IO; + +namespace Everglow.Yggdrasil.KelpCurtain.NPCs.VampireMat; + +[AutoloadBossHead] +[NoGameModeScale] +public class VampireMat : ModNPC +{ + public CoroutineManager AICoroutine = new CoroutineManager(); + + public Rope BodyRope; + + public MassSpringContainer EularSys = new MassSpringContainer(); + + public Vector2 RealCenter; + + public bool DiveAtBackground = false; + + public enum TextureState + { + Flat, + TowardScreen, + ProjRelease, + } + + public int NPCTextureState = 0; + + public int Phase = 1; + + public int HitTimer = 0; + + public int CurrentSkillInPhase2 = 0; + + public int VortexStyle = 0; + + public int StickPlayerTimer = 0; + + public int FailToEscapeStickTimer = 0; + + public int TotalDamageIntakeWhenStickPlayer = 0; + + public bool TowardScreenAndAttacking = false; + + public bool HitStuckPlayerAtTheLastMoment = false; + + public bool StickPlayer = false; + + public static List BackgroundWallHoles = [new Vector2(0, 0), new Vector2(-616, -397), new Vector2(-535, 396), new Vector2(371, 610), new Vector2(611, -466),]; + + public static List TentacleInBackgroundPoints = [new Vector2(1000, 1000), new Vector2(385, 600), new Vector2(655, 765), new Vector2(767, 890), new Vector2(766, 1131), new Vector2(460, 1394), new Vector2(951, 1282), new Vector2(947, 1590), new Vector2(1109, 1219), new Vector2(1375, 1599), new Vector2(1190, 1393), new Vector2(1088, 1192), new Vector2(1297, 1147), new Vector2(1186, 1014), new Vector2(1497, 962), new Vector2(1316, 848), new Vector2(1451, 722), new Vector2(1675, 471), new Vector2(1874, 945),]; + + public override void SetStaticDefaults() + { + Main.npcFrameCount[NPC.type] = 11; + NPCSpawnManager.RegisterNPC(Type); + } + + public override void SetDefaults() + { + NPC.width = 100; + NPC.height = 100; + NPC.boss = true; + NPC.noGravity = true; + NPC.HitSound = SoundID.NPCHit1; + NPC.DeathSound = SoundID.NPCDeath1; + NPC.value = 32000; + + NPC.lifeMax = 26000; + NPC.damage = 70; + NPC.defense = 45; + NPC.knockBackResist = 0f; + + NPC.noTileCollide = true; + NPC.aiStyle = -1; + } + + private void SpawnAttackProjectile(Vector2 position, Vector2 velocity, int type, int damage, float knockback, float initialRotation = 0) + { + if (NetUtils.IsClient) + { + return; + } + Projectile.NewProjectile(NPC.GetSource_FromAI(), position, velocity, type, damage, knockback, + Owner: Main.myPlayer, ai0: NPC.target, ai1: NPC.whoAmI, ai2: initialRotation); + } + + public override void OnSpawn(IEntitySource source) + { + NPC.localAI[0] = 0; + NPC.TargetClosest(); + AICoroutine.StartCoroutine(new Coroutine(ChasePlayer())); + RealCenter = NPC.Center; + VortexStyle = Main.rand.Next(2); + } + + public override bool CheckActive() + { + return false; + } + + public override void AI() + { + AICoroutine.Update(); + RealCenter += NPC.velocity; + if (BodyRope is null) + { + BodyRope = Rope.Create_Vine(NPC.Center, 20, 1, 1, 17.3f); + EularSys.AddMassSpringMesh(BodyRope); + GlobalRopeSystem.EulerContainers.Add(EularSys); + } + BodyRope.Masses[0].Position = RealCenter; + BodyRope.ApplyForce_VelocityDecay(0.2f); + if (NPCTextureState == (int)TextureState.Flat) + { + Rectangle hitBox = GetAABBBound(BodyRope); + NPC.position = hitBox.TopLeft(); + NPC.width = hitBox.Width; + NPC.height = hitBox.Height; + } + if (Phase == 1 && NPC.life < NPC.lifeMax * 0.3f) + { + Phase = 2; + } + if (HitTimer > 0) + { + HitTimer--; + } + if (StickPlayerTimer > 0) + { + StickPlayerTimer--; + } + if (FailToEscapeStickTimer > 0) + { + FailToEscapeStickTimer--; + } + NPC.dontTakeDamage = DiveAtBackground; + } + + public Rectangle GetAABBBound(Rope rope) + { + int min_x = int.MaxValue; + int max_x = 0; + int min_y = int.MaxValue; + int max_y = 0; + foreach (var mass in rope.Masses) + { + int mass_x = (int)mass.Position.X; + int mass_y = (int)mass.Position.Y; + if (mass_x < min_x) + { + min_x = mass_x; + } + if (mass_x > max_x) + { + max_x = mass_x; + } + if (mass_y < min_y) + { + min_y = mass_y; + } + if (mass_y > max_y) + { + max_y = mass_y; + } + } + int width = max_x - min_x; + int height = max_y - min_y; + return new Rectangle(min_x, min_y, width, height); + } + + #region skills + + public IEnumerator ChasePlayer() + { + yield return new WaitUntil(() => NPC.target >= 0); + bool reachTarget = false; + float rot = NPC.rotation; + int reachTimer = 0; + Player player = Main.player[NPC.target]; + for (int k = 0; k < 90; k++) + { + Vector2 headPos = RealCenter; + int direction = RealCenter.X > player.Center.X ? 1 : -1; + + NPC.spriteDirection = direction; + Vector2 toTarget = player.Center - headPos; + if (!reachTarget && toTarget.Length() < 30) + { + reachTarget = true; + reachTimer = 0; + } + if (!reachTarget) + { + toTarget = toTarget.SafeNormalize(Vector2.Zero) * 11f; + rot = toTarget.ToRotation(); + NPC.velocity = toTarget; + } + else + { + reachTimer++; + } + if (reachTimer >= 45) + { + reachTarget = false; + } + NPC.rotation = rot * 0.05f + NPC.rotation * 0.95f; + if (!TowardScreenAndAttacking && StickPlayerTimer <= 0) + { + if (IntersectWhenFlat(player)) + { + StickPlayer = true; + StickPlayerTimer += 120; + VampireMatStickScreen vMSS = new VampireMatStickScreen(); + vMSS.Owner = player; + vMSS.Active = true; + vMSS.Visible = true; + vMSS.MaxTime = 200; + vMSS.ParentNPC = NPC; + Ins.VFXManager.Add(vMSS); + break; + } + } + yield return new SkipThisFrame(); + } + for (int k = 0; k < 120; k++) + { + NPC.velocity *= 0.96f; + if (StickPlayer) + { + player.Center = NPC.Center; + if (k == 119) + { + HitStuckPlayerAtTheLastMoment = true; + FailToEscapeStickTimer = 45; + ReleasePlayer(); + } + } + yield return new SkipThisFrame(); + } + StickPlayer = false; + TotalDamageIntakeWhenStickPlayer = 0; + AICoroutine.StartCoroutine(new Coroutine(NextAttack())); + } + + public IEnumerator ShortDash() + { + yield return new WaitUntil(() => NPC.target >= 0); + Player player = Main.player[NPC.target]; + for (int k = 0; k <= 180; k++) + { + if (k % 30 == 0 && !StickPlayer) + { + Vector2 headPos = RealCenter; + int direction = RealCenter.X > player.Center.X ? 1 : -1; + NPC.spriteDirection = direction; + Vector2 toTarget = player.Center - headPos; + toTarget = toTarget.SafeNormalize(Vector2.Zero) * 31f; + NPC.velocity = toTarget; + } + else + { + NPC.velocity *= 0.96f; + } + if (!TowardScreenAndAttacking && StickPlayerTimer <= 0) + { + if (IntersectWhenFlat(player)) + { + StickPlayer = true; + StickPlayerTimer += 120; + VampireMatStickScreen vMSS = new VampireMatStickScreen(); + vMSS.Owner = player; + vMSS.Active = true; + vMSS.Visible = true; + vMSS.MaxTime = 200; + vMSS.ParentNPC = NPC; + Ins.VFXManager.Add(vMSS); + break; + } + } + yield return new SkipThisFrame(); + } + for (int k = 0; k < 120; k++) + { + NPC.velocity *= 0.96f; + if (StickPlayer) + { + player.Center = NPC.Center; + if (k == 119) + { + HitStuckPlayerAtTheLastMoment = true; + FailToEscapeStickTimer = 45; + ReleasePlayer(); + } + } + yield return new SkipThisFrame(); + } + StickPlayer = false; + TotalDamageIntakeWhenStickPlayer = 0; + AICoroutine.StartCoroutine(new Coroutine(NextAttack())); + } + + public IEnumerator Escape() + { + int playerDeadTimer = 0; + for (int k = 0; k < 9999; k++) + { + if (NPC.target >= 0) + { + Player player = Main.player[NPC.target]; + if (player.active && !player.dead) + { + if ((player.Center - KelpCurtainGeneration.VampireMatCaveCenter).Length() < 60 * 16) + { + AICoroutine.StartCoroutine(new Coroutine(NextAttack())); + yield break; + } + if ((player.Center - NPC.Center).Length() > 240 * 16) + { + NPC.active = false; + yield break; + } + } + else + { + playerDeadTimer++; + if (playerDeadTimer > 120) + { + NPC.active = false; + yield break; + } + } + } + else + { + NPC.active = false; + yield break; + } + NPC.velocity *= 0.95f; + NPC.velocity.Y += 1; + yield return new SkipThisFrame(); + } + } + + public IEnumerator GoBehiveBackground() + { + float speed = 0f; + for (int k = 0; k < 99999; k++) + { + speed += 0.2f; + if (speed >= 30) + { + speed = 30; + } + Vector2 toCenter = KelpCurtainGeneration.VampireMatCaveCenter - RealCenter; + NPC.velocity = toCenter.SafeNormalize(Vector2.Zero) * speed * 0.25f + NPC.velocity * 0.75f; + if (toCenter.Length() < speed * 1.5f) + { + DiveAtBackground = true; + AICoroutine.StartCoroutine(new Coroutine(NextAttack())); + yield break; + } + yield return new SkipThisFrame(); + } + } + + public IEnumerator TentacleRelease() + { + for (int k = 0; k < 120; k++) + { + NPC.velocity *= 0.96f; + NPC.rotation *= 0.96f; + if (NPCTextureState == (int)TextureState.Flat) + { + if (NPC.frame.Y == 1060) + { + NPC.width = 220; + NPC.height = 220; + NPCTextureState = (int)TextureState.TowardScreen; + NPC.frame = new Rectangle(0, 0, 400, 400); + break; + } + } + yield return new SkipThisFrame(); + } + NPC.velocity *= 0f; + NPC.rotation *= 0f; + for (int k = 0; k < 19; k++) + { + if (k % 4 == 3) + { + NPC.frame.Y += 400; + } + yield return new SkipThisFrame(); + } + TowardScreenAndAttacking = true; + yield return new WaitForFrames(20); + List projRots = [0, 1, 2, 3, 4, 5, 6]; + for (int k = 0; k < 48; k++) + { + if (k % 7 == 0) + { + float rotation = 0; + int number = projRots[Main.rand.Next(projRots.Count)]; + switch (number) + { + case 0: + rotation = -15.8f / 360f * MathHelper.TwoPi; + break; + case 1: + rotation = 25.54f / 360f * MathHelper.TwoPi; + break; + case 2: + rotation = 84.36f / 360f * MathHelper.TwoPi; + break; + case 3: + rotation = 143.07f / 360f * MathHelper.TwoPi; + break; + case 4: + rotation = -162.52f / 360f * MathHelper.TwoPi; + break; + case 5: + rotation = -114.61f / 360f * MathHelper.TwoPi; + break; + case 6: + rotation = -59.09f / 360f * MathHelper.TwoPi; + break; + } + SpawnAttackProjectile(NPC.Center, Vector2.zeroVector, ModContent.ProjectileType(), 88, 5, rotation); + for (int j = 0; j < 2; j++) + { + SpawnAttackProjectile(NPC.Center, new Vector2(4, 0).RotatedBy((j - 0.5f) * 0.6f + rotation), ModContent.ProjectileType(), 55, 2.5f); + } + projRots.Remove(number); + } + yield return new SkipThisFrame(); + } + yield return new WaitForFrames(180); + TowardScreenAndAttacking = false; + for (int k = 0; k < 8; k++) + { + if (k % 4 == 3) + { + NPC.frame.Y += 400; + } + yield return new SkipThisFrame(); + } + NPCTextureState = (int)TextureState.Flat; + NPC.frame = new Rectangle(0, 0, 346, 106); + AICoroutine.StartCoroutine(new Coroutine(NextAttack())); + } + + public IEnumerator ProjRelease() + { + for (int k = 0; k < 120; k++) + { + NPC.velocity *= 0.96f; + NPC.rotation *= 0.96f; + if (NPCTextureState == (int)TextureState.Flat) + { + if (NPC.frame.Y == 1060) + { + NPCTextureState = (int)TextureState.ProjRelease; + NPC.frame = new Rectangle(0, 0, 400, 400); + break; + } + } + yield return new SkipThisFrame(); + } + Player player = Main.player[NPC.target]; + NPC.velocity *= 0f; + Vector2 toTarget = player.Center - NPC.Center; + NPC.spriteDirection = 1; + NPC.rotation = toTarget.ToRotationSafe() + MathHelper.PiOver2; + for (int k = 0; k < 31; k++) + { + if (k % 4 == 3) + { + NPC.frame.Y += 400; + } + if (k == 25) + { + SpawnAttackProjectile(NPC.Center, toTarget.NormalizeSafe() * 6f, ModContent.ProjectileType(), 48, 2.5f); + NPC.velocity -= toTarget.NormalizeSafe() * 12f; + } + NPC.velocity *= 0.9f; + yield return new SkipThisFrame(); + } + NPCTextureState = (int)TextureState.Flat; + NPC.frame = new Rectangle(0, 0, 346, 106); + AICoroutine.StartCoroutine(new Coroutine(NextAttack())); + } + + public IEnumerator TentacleRelease_Phase2() + { + Vector2 destination = KelpCurtainGeneration.VampireMatCaveCenter + BackgroundWallHoles[Main.rand.Next(BackgroundWallHoles.Count)]; + for (int k = 0; k < 300; k++) + { + Vector2 toDest = destination - NPC.Center; + if (toDest.Length() > 200) + { + NPC.velocity = NPC.velocity * 0.9f + toDest.NormalizeSafe() * 20 * 0.1f; + } + else + { + NPC.velocity = NPC.velocity * 0.9f + toDest * 0.1f * 0.1f; + } + if (toDest.Length() < 10) + { + NPC.width = 220; + NPC.height = 220; + NPC.Center = destination; + NPCTextureState = (int)TextureState.TowardScreen; + NPC.frame = new Rectangle(0, 0, 400, 400); + break; + } + yield return new SkipThisFrame(); + } + NPC.velocity *= 0f; + for (int k = 0; k < 19; k++) + { + if (k == 8) + { + DiveAtBackground = false; + } + if (k % 4 == 3) + { + NPC.frame.Y += 400; + } + yield return new SkipThisFrame(); + } + TowardScreenAndAttacking = true; + yield return new WaitForFrames(6); + List projRots = [0, 1, 2, 3, 4, 5, 6]; + for (int k = 0; k < 34; k++) + { + if (k % 5 == 0) + { + float rotation = 0; + int number = projRots[Main.rand.Next(projRots.Count)]; + switch (number) + { + case 0: + rotation = -15.8f / 360f * MathHelper.TwoPi; + break; + case 1: + rotation = 25.54f / 360f * MathHelper.TwoPi; + break; + case 2: + rotation = 84.36f / 360f * MathHelper.TwoPi; + break; + case 3: + rotation = 143.07f / 360f * MathHelper.TwoPi; + break; + case 4: + rotation = -162.52f / 360f * MathHelper.TwoPi; + break; + case 5: + rotation = -114.61f / 360f * MathHelper.TwoPi; + break; + case 6: + rotation = -59.09f / 360f * MathHelper.TwoPi; + break; + } + SpawnAttackProjectile(NPC.Center, Vector2.zeroVector, ModContent.ProjectileType(), 88, 5, rotation); + for (int j = 0; j < 2; j++) + { + SpawnAttackProjectile(NPC.Center, new Vector2(6, 0).RotatedBy((j - 0.5f) * 0.6f + rotation), ModContent.ProjectileType(), 55, 2.5f); + } + projRots.Remove(number); + } + yield return new SkipThisFrame(); + } + yield return new WaitForFrames(180); + TowardScreenAndAttacking = false; + for (int k = 0; k < 8; k++) + { + if (k == 4) + { + DiveAtBackground = true; + } + if (k % 4 == 3) + { + NPC.frame.Y += 400; + } + yield return new SkipThisFrame(); + } + NPCTextureState = (int)TextureState.Flat; + NPC.frame = new Rectangle(0, 0, 346, 106); + AICoroutine.StartCoroutine(new Coroutine(NextAttack())); + } + + public IEnumerator VortexAbsorb() + { + Vector2 destination = KelpCurtainGeneration.VampireMatCaveCenter + BackgroundWallHoles[0]; + for (int k = 0; k < 300; k++) + { + Vector2 toDest = destination - RealCenter; + if (toDest.Length() > 200) + { + NPC.velocity = NPC.velocity * 0.9f + toDest.NormalizeSafe() * 20 * 0.1f; + } + else + { + NPC.velocity = NPC.velocity * 0.9f + toDest * 0.1f * 0.1f; + } + if (toDest.Length() < 10) + { + NPC.width = 220; + NPC.height = 220; + NPC.Center = destination; + NPCTextureState = (int)TextureState.TowardScreen; + NPC.frame = new Rectangle(0, 0, 400, 400); + break; + } + yield return new SkipThisFrame(); + } + NPC.velocity *= 0f; + for (int k = 0; k < 19; k++) + { + if (k == 8) + { + DiveAtBackground = false; + } + if (k % 4 == 3) + { + NPC.frame.Y += 400; + } + yield return new SkipThisFrame(); + } + TowardScreenAndAttacking = true; + yield return new WaitForFrames(6); + SpawnAttackProjectile(NPC.Center, Vector2.zeroVector, ModContent.ProjectileType(), 1, 0); + switch (VortexStyle) + { + case 0: + SpawnAttackProjectile(NPC.Center, Vector2.zeroVector, ModContent.ProjectileType(), 88, 5); + break; + case 1: + SpawnAttackProjectile(NPC.Center, Vector2.zeroVector, ModContent.ProjectileType(), 88, 5); + break; + } + VortexStyle++; + if (VortexStyle >= 2) + { + VortexStyle = 0; + } + yield return new WaitForFrames(600); + TowardScreenAndAttacking = false; + for (int k = 0; k < 8; k++) + { + if (k == 4) + { + DiveAtBackground = true; + } + if (k % 4 == 3) + { + NPC.frame.Y += 400; + } + yield return new SkipThisFrame(); + } + NPCTextureState = (int)TextureState.Flat; + NPC.frame = new Rectangle(0, 0, 346, 106); + AICoroutine.StartCoroutine(new Coroutine(NextAttack())); + } + + public IEnumerator TentacleHide() + { + Player player = Main.player[NPC.target]; + NPC.width = 220; + NPC.height = 220; + NPCTextureState = (int)TextureState.TowardScreen; + NPC.frame = new Rectangle(0, 0, 400, 400); + NPC.velocity *= 0f; + for (int k = 0; k < 19; k++) + { + if (k % 4 == 3) + { + NPC.frame.Y += 400; + } + yield return new SkipThisFrame(); + } + TowardScreenAndAttacking = true; + for (int k = 0; k <= 26; k++) + { + NPC.alpha += 10; + if (NPC.alpha > 255) + { + NPC.alpha = 255; + } + NPC.scale -= 0.05f; + if (NPC.scale < 0) + { + NPC.scale = 0; + } + yield return new SkipThisFrame(); + } + for (int k = 0; k <= 600; k++) + { + float minDis = float.MaxValue; + Vector2 releasePos = Vector2.zeroVector; + List possiblePos = TentacleInBackgroundPoints; + if (k % 60 == 0 && k <= 480) + { + for (int j = possiblePos.Count - 1; j >= 0; j--) + { + Vector2 offsetPos = possiblePos[j] + KelpCurtainGeneration.VampireMatCaveCenter - new Vector2(1000); + float toPlayer = (offsetPos - player.Center).Length(); + if (toPlayer < minDis) + { + releasePos = possiblePos[j]; + minDis = toPlayer; + } + } + possiblePos.Remove(releasePos); + Vector2 truePos = releasePos + KelpCurtainGeneration.VampireMatCaveCenter - new Vector2(1000); + SpawnAttackProjectile(truePos, Vector2.zeroVector, ModContent.ProjectileType(), 88, 5, (player.Center - truePos).ToRotationSafe()); + } + yield return new SkipThisFrame(); + } + yield return new WaitForFrames(150); + for (int k = 0; k <= 26; k++) + { + NPC.alpha -= 10; + if (NPC.alpha < 0) + { + NPC.alpha = 0; + } + NPC.scale += 0.05f; + if (NPC.scale > 1) + { + NPC.scale = 1; + } + yield return new SkipThisFrame(); + } + TowardScreenAndAttacking = false; + for (int k = 0; k < 8; k++) + { + if (k % 4 == 3) + { + NPC.frame.Y += 400; + } + yield return new SkipThisFrame(); + } + NPCTextureState = (int)TextureState.Flat; + NPC.frame = new Rectangle(0, 0, 346, 106); + + TentacleInBackgroundPoints = [new Vector2(1000, 1000), new Vector2(385, 600), new Vector2(655, 765), new Vector2(767, 890), new Vector2(766, 1131), new Vector2(460, 1394), new Vector2(951, 1282), new Vector2(947, 1590), new Vector2(1109, 1219), new Vector2(1375, 1599), new Vector2(1190, 1393), new Vector2(1088, 1192), new Vector2(1297, 1147), new Vector2(1186, 1014), new Vector2(1497, 962), new Vector2(1316, 848), new Vector2(1451, 722), new Vector2(1675, 471), new Vector2(1874, 945),]; + AICoroutine.StartCoroutine(new Coroutine(NextAttack())); + } + + public IEnumerator NextAttack() + { + if (!PlayerInCave()) + { + AICoroutine.StartCoroutine(new Coroutine(Escape())); + yield break; + } + if (NPC.target < 0) + { + AICoroutine.StartCoroutine(new Coroutine(Escape())); + yield break; + } + Player player = Main.player[NPC.target]; + if (!player.active || player.dead) + { + AICoroutine.StartCoroutine(new Coroutine(Escape())); + yield break; + } + if (NPC.target >= 0 && Phase == 1) + { + if ((player.Center - RealCenter).Length() > 600) + { + AICoroutine.StartCoroutine(new Coroutine(ChasePlayer())); + yield break; + } + } + if (Phase == 2 && !DiveAtBackground) + { + AICoroutine.StartCoroutine(new Coroutine(GoBehiveBackground())); + yield break; + } + + // Main.rand.Next(3) + switch (Phase) + { + case 1: + switch (Main.rand.Next(3)) + { + case 0: + AICoroutine.StartCoroutine(new Coroutine(ShortDash())); + break; + case 1: + AICoroutine.StartCoroutine(new Coroutine(TentacleRelease())); + break; + case 2: + AICoroutine.StartCoroutine(new Coroutine(ProjRelease())); + break; + } + break; + + case 2: + CurrentSkillInPhase2++; + if (CurrentSkillInPhase2 >= 3) + { + CurrentSkillInPhase2 = 0; + } + switch (CurrentSkillInPhase2) + { + case 0: + AICoroutine.StartCoroutine(new Coroutine(VortexAbsorb())); + break; + case 1: + AICoroutine.StartCoroutine(new Coroutine(TentacleHide())); + break; + case 2: + AICoroutine.StartCoroutine(new Coroutine(TentacleRelease_Phase2())); + break; + } + break; + } + + yield return new SkipThisFrame(); + } + + #endregion + + public override void FindFrame(int frameHeight) + { + if (NPCTextureState == (int)TextureState.Flat) + { + float animationSpeed = 0.4f; + NPC.frameCounter += animationSpeed; + NPC.frameCounter %= Main.npcFrameCount[NPC.type]; + NPC.frame.Y = (int)NPC.frameCounter * 106; + } + } + + public override void HitEffect(NPC.HitInfo hit) + { + HitTimer = 20; + if (StickPlayer) + { + TotalDamageIntakeWhenStickPlayer += hit.Damage; + if (TotalDamageIntakeWhenStickPlayer >= 100) + { + ReleasePlayer(); + } + } + } + + public void ReleasePlayer() + { + StickPlayer = false; + Player player = Main.player[NPC.target]; + TotalDamageIntakeWhenStickPlayer = 0; + Vector2 toCenter = KelpCurtainGeneration.VampireMatCaveCenter - player.Center; + player.velocity += toCenter.NormalizeSafe() * 12f; + player.position += toCenter.NormalizeSafe() * 100f; + if (toCenter.Length() > 800) + { + player.Center = KelpCurtainGeneration.VampireMatCaveCenter - toCenter.NormalizeSafe() * 720; + } + } + + public override bool CanHitPlayer(Player target, ref int cooldownSlot) + { + if (!DiveAtBackground) + { + if (!TowardScreenAndAttacking) + { + if (HitStuckPlayerAtTheLastMoment) + { + HitStuckPlayerAtTheLastMoment = false; + return true; + } + return false; + } + else + { + return base.CanHitPlayer(target, ref cooldownSlot); + } + } + return false; + } + + public bool IntersectWhenFlat(Player target) + { + if (!TowardScreenAndAttacking) + { + for (int k = 1; k < BodyRope.Masses.Length; k++) + { + Vector2 old_pos = BodyRope.Masses[k - 1].Position; + Vector2 pos = BodyRope.Masses[k].Position; + if (CollisionUtils.Intersect(old_pos, pos, 10, target.Top, target.Bottom, target.width)) + { + return true; + } + } + } + return false; + } + + public override void OnHitPlayer(Player target, Player.HurtInfo info) + { + OnVampireMatHitPlayer(target, info.Damage); + base.OnHitPlayer(target, info); + } + + public static void OnVampireMatHitPlayer(Player target, int damage) + { + if (NetUtils.IsSingle) + { + VampireHitHealEffect(target, damage); + } + else if (NetUtils.IsClient) + { + ModIns.PacketResolver.Send(new VampireMatHitPacket(damage)); + + if (target.HasBuff(BuffID.Gills)) + { + target.ClearBuff(BuffID.Gills); + } + } + + // Add screen effect + var screenEffectVFX = new ScreenScaringEffect() + { + Active = true, + Visible = true, + Timer = 0, + MaxTime = 120, + }; + Ins.VFXManager.Add(screenEffectVFX); + } + + public static void VampireHitHealEffect(Player target, int damage) + { + // Sync the buff removal on the server side + if (target.HasBuff(BuffID.Gills)) + { + target.ClearBuff(BuffID.Gills); + } + + NPC owner = NPCUtils.FindNearest(target.Center, ModContent.NPCType()); + if (owner is not null) + { + owner.netUpdate = true; + int amount = damage * 2 + 98; + owner.HealEffect(amount, true); + owner.life += amount; + if (owner.life > owner.lifeMax) + { + owner.life = owner.lifeMax; + } + } + } + + public override bool SpecialOnKill() + { + if (!NetUtils.IsServer) + { + for (int i = 0; i < 8; i++) + { + Vector2 v0 = new Vector2(0, Main.rand.NextFloat(0, 6f)).RotatedByRandom(MathHelper.TwoPi); + int type = ModContent.Find("Everglow/VampireMat_Gore_" + i).Type; + Gore.NewGore(NPC.GetSource_Death(), NPC.position + new Vector2(Main.rand.Next(NPC.width), Main.rand.Next(NPC.height)), v0, type, NPC.scale); + } + } + + return base.SpecialOnKill(); + } + + public override void OnKill() + { + VampireMat_Summon.VampireMatSummonCD = 600; + } + + public override void ModifyNPCLoot(NPCLoot npcLoot) + { + npcLoot.Add(ItemDropRule.BossBag(ModContent.ItemType())); + npcLoot.Add(ItemDropRule.Common(ModContent.ItemType(), 1, 1, 1)); + base.ModifyNPCLoot(npcLoot); + } + + public override float SpawnChance(NPCSpawnInfo spawnInfo) + { + return 0; + } + + public override bool PreDraw(SpriteBatch spriteBatch, Vector2 screenPos, Color drawColor) + { + if (!DiveAtBackground) + { + DrawSelf(NPC, this, spriteBatch, drawColor); + } + return false; + } + + public static void DrawSelf(NPC npc, VampireMat vampireMat, SpriteBatch spriteBatch, Color drawColor) + { + float fade = (255 - npc.alpha) / 255f; + Effect effect = ModAsset.VampireMat_HitEffect.Value; + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + var texture = ModContent.Request(npc.ModNPC.Texture).Value; + var drawPos = vampireMat.RealCenter - Main.screenPosition; + if (vampireMat.NPCTextureState == (int)TextureState.TowardScreen) + { + drawPos = npc.Center - Main.screenPosition; + texture = ModAsset.VampireMat_Attack.Value; + if (vampireMat.TowardScreenAndAttacking) + { + List boss_bottom_bars = new List(); + for (int k = 0; k < 20; k++) + { + Vector2 offset0 = new Vector2(200, 0).RotatedBy(k / 20f * MathHelper.TwoPi); + Vector2 offset1 = new Vector2(200, 0).RotatedBy((k + 1) / 20f * MathHelper.TwoPi); + Vector2 pos0 = drawPos + offset0 * (1 + MathF.Sin(k / 4f * MathHelper.TwoPi + (float)Main.time * 0.09f) * 0.1f) * npc.scale; + Vector2 pos1 = drawPos + offset1 * (1 + MathF.Sin((k + 1) / 4f * MathHelper.TwoPi + (float)Main.time * 0.09f) * 0.1f) * npc.scale; + SpriteBatchUtils.AddVertexWithEnv_Light(boss_bottom_bars, pos0, new Vector3((new Vector2(200, 1800) + offset0) / texture.Size(), 0), false, fade); + SpriteBatchUtils.AddVertexWithEnv_Light(boss_bottom_bars, pos1, new Vector3((new Vector2(200, 1800) + offset1) / texture.Size(), 0), false, fade); + SpriteBatchUtils.AddVertexWithEnv_Light(boss_bottom_bars, drawPos, new Vector3(new Vector2(200, 1800) / texture.Size(), 0), false, fade); + } + if (boss_bottom_bars.Count > 2) + { + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + Main.graphics.GraphicsDevice.Textures[0] = texture; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, boss_bottom_bars.ToArray(), 0, boss_bottom_bars.Count / 3); + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + + if (vampireMat.HitTimer > 0) + { + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + effect.Parameters["hitTimer"].SetValue(vampireMat.HitTimer); + effect.CurrentTechnique.Passes[0].Apply(); + + Main.graphics.GraphicsDevice.Textures[0] = texture; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, boss_bottom_bars.ToArray(), 0, boss_bottom_bars.Count / 3); + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + } + } + return; + } + } + if (vampireMat.NPCTextureState == (int)TextureState.ProjRelease) + { + drawPos = npc.Center - Main.screenPosition; + texture = ModAsset.VampireMat_ReleaseProj.Value; + } + + var frame = npc.frame; + if (vampireMat.NPCTextureState == (int)TextureState.Flat) + { + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + if (vampireMat.BodyRope is null) + { + spriteBatch.End(); + spriteBatch.Begin(sBS); + return; + } + List bars = new List(); + for (int k = 1; k < vampireMat.BodyRope.Masses.Length; k++) + { + Vector2 dir = vampireMat.BodyRope.Masses[k].Position - vampireMat.BodyRope.Masses[k - 1].Position; + dir = dir.SafeNormalize(Vector2.Zero); + Vector2 normal = new Vector2(-dir.Y, dir.X) * 16; + Vector2 ropePos = vampireMat.BodyRope.Masses[k - 1].Position - Main.screenPosition; + float value = k / (float)vampireMat.BodyRope.Masses.Length; + if (npc.velocity.X > 0) + { + vampireMat.AddVertex(bars, ropePos + normal, new Vector3(value, (frame.Y + frame.Height * 0.25f) / texture.Height, 0), fade); + vampireMat.AddVertex(bars, ropePos - normal, new Vector3(value, (frame.Y + frame.Height * 0.75f) / texture.Height, 0), fade); + } + else + { + vampireMat.AddVertex(bars, ropePos + normal, new Vector3(value, (frame.Y + frame.Height * 0.75f) / texture.Height, 0), fade); + vampireMat.AddVertex(bars, ropePos - normal, new Vector3(value, (frame.Y + frame.Height * 0.25f) / texture.Height, 0), fade); + } + } + if (bars.Count > 0) + { + Main.graphics.graphicsDevice.Textures[0] = texture; + Main.graphics.graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + + if (vampireMat.HitTimer > 0) + { + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + effect.Parameters["hitTimer"].SetValue(vampireMat.HitTimer); + effect.CurrentTechnique.Passes[0].Apply(); + + Main.graphics.graphicsDevice.Textures[0] = texture; + Main.graphics.graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + } + } + } + else + { + var rotation = npc.rotation; + var spriteEffect = npc.spriteDirection < 0 ? SpriteEffects.None : SpriteEffects.FlipVertically; + spriteBatch.Draw(texture, drawPos, frame, drawColor, rotation, frame.Size() / 2, 0.8f, spriteEffect, 0); + + if (vampireMat.HitTimer > 0) + { + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + effect.Parameters["hitTimer"].SetValue(vampireMat.HitTimer); + effect.CurrentTechnique.Passes[0].Apply(); + + spriteBatch.Draw(texture, drawPos, frame, drawColor, rotation, frame.Size() / 2, 0.8f, spriteEffect, 0); + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + } + } + spriteBatch.End(); + spriteBatch.Begin(sBS); + } + + public void AddVertex(List bars, Vector2 screenPos, Vector3 coord, float fade = 1f) + { + bars.Add(screenPos, Lighting.GetColor((screenPos + Main.screenPosition).ToTileCoordinates()) * fade, coord); + } + + public bool PlayerInCave() + { + if (NPC.target < 0) + { + return false; + } + Player player = Main.player[NPC.target]; + if ((player.Center - KelpCurtainGeneration.VampireMatCaveCenter).Length() <= 60 * 16) + { + return true; + } + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat.png b/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat.png new file mode 100644 index 000000000..d493da9d9 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat_Attack.png b/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat_Attack.png new file mode 100644 index 000000000..aa1ca59a5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat_Attack.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat_Head_Boss.png b/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat_Head_Boss.png new file mode 100644 index 000000000..712f486d8 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat_Head_Boss.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat_HitEffect.fx b/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat_HitEffect.fx new file mode 100644 index 000000000..b403fed71 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat_HitEffect.fx @@ -0,0 +1,27 @@ +sampler2D uImage : register(s0); +float hitTimer; +struct PSInput +{ + float4 Pos : SV_POSITION; + float4 Color : COLOR0; + float3 Texcoord : TEXCOORD0; +}; + +float4 PixelShaderFunction(PSInput input) : COLOR0 +{ + float4 color = tex2D(uImage, input.Texcoord.xy); + if (any(color)) + { + float value = hitTimer / 20.0; + return lerp(float4(1, 0, 0, 1), float4(1, 1, 1, 1), value) * value; + } + return float4(0, 0, 0, 0); +} + +technique Technique1 +{ + pass Test + { + PixelShader = compile ps_3_0 PixelShaderFunction(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat_ReleaseProj.png b/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat_ReleaseProj.png new file mode 100644 index 000000000..5d63ddec6 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat_ReleaseProj.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat_Summon.cs b/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat_Summon.cs new file mode 100644 index 000000000..f8f59134e --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/NPCs/VampireMat/VampireMat_Summon.cs @@ -0,0 +1,46 @@ +using Everglow.Yggdrasil.KelpCurtain.Biomes; +using Everglow.Yggdrasil.KelpCurtain.VFXs.VampireMat; +using Everglow.Yggdrasil.WorldGeneration; + +namespace Everglow.Yggdrasil.KelpCurtain.NPCs.VampireMat; + +public class VampireMat_Summon : ModPlayer +{ + public static int VampireMatSummonCD = 0; + + public override void PostUpdate() + { + if (VampireMatSummonCD > 0) + { + VampireMatSummonCD--; + } + base.PostUpdate(); + } + + public override void OnHurt(Player.HurtInfo info) + { + if (VampireMatSummonCD <= 0 && Player.InModBiome()) + { + if (NPC.CountNPCS(ModContent.NPCType()) <= 0) + { + Vector2 center = KelpCurtainGeneration.VampireMatCaveCenter; + Vector2 toCenter = center - Player.Center; + float dis = toCenter.Length(); + if (dis < 880) + { + NPC.NewNPCDirect(Player.GetSource_FromAI(), center + toCenter.NormalizeSafe() * 800, ModContent.NPCType()); + Main.NewText("Strange stirrings in the pitch-black depths send a chill down your spine.", Color.Purple); + var screenEffectVFX = new ScreenScaringEffect() + { + Active = true, + Visible = true, + Timer = 0, + MaxTime = 120, + }; + Ins.VFXManager.Add(screenEffectVFX); + } + } + } + base.OnHurt(info); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack.pdn b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack.pdn new file mode 100644 index 000000000..b5b0cc598 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack.pdn differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_0.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_0.png new file mode 100644 index 000000000..80f9c4523 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_0.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Absorb.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Absorb.cs new file mode 100644 index 000000000..e9f5747a7 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Absorb.cs @@ -0,0 +1,173 @@ +using Everglow.Commons.DataStructures; +using Everglow.Commons.Graphics; +using Everglow.Yggdrasil.KelpCurtain.NPCs.VampireMat; +using Everglow.Yggdrasil.KelpCurtain.Projectiles.TileEffect; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Enemies; + +public class VampireMat_Attack_Proj_Absorb : ModProjectile +{ + public int TargetPlayerIndex => (int)Projectile.ai[0]; + + public int ParentNPCIndex => (int)Projectile.ai[1]; + + public int Timer = 0; + + public float Fade = 1f; + + public float rotationValue = 0; + + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicProjectiles; + + public override void SetDefaults() + { + Projectile.width = 20; + Projectile.height = 20; + Projectile.aiStyle = -1; + Projectile.timeLeft = 600; + Projectile.penetrate = -1; + Projectile.tileCollide = false; + Projectile.ignoreWater = true; + Projectile.friendly = false; + Projectile.hostile = true; + ProjectileID.Sets.DrawScreenCheckFluff[Type] = 1024; + base.SetDefaults(); + } + + public override void OnSpawn(IEntitySource source) + { + base.OnSpawn(source); + } + + public override void AI() + { + Timer++; + Fade = 1f; + if (Timer < 60f) + { + Fade *= Timer / 60f; + } + if (Projectile.timeLeft < 60f) + { + Fade *= Projectile.timeLeft / 60f; + } + rotationValue += 0.004f * Fade; + Projectile.velocity *= 0; + int maxDistance = 800; + foreach (var player in Main.player) + { + if (player is not null && player.active && !player.dead) + { + Vector2 toCenter = Projectile.Center - player.Center; + if (toCenter.Length() < maxDistance) + { + float force = (maxDistance - toCenter.Length()) * 0.01f * Fade; + Vector2 move = toCenter.NormalizeSafe().RotatedBy(MathHelper.PiOver2) * force; + player.position += move; + } + } + } + foreach (var proj in Main.projectile) + { + if (proj is not null && proj.active) + { + if (proj.type == ModContent.ProjectileType()) + { + Vector2 toCenter = Projectile.Center - proj.Center; + if (toCenter.Length() < maxDistance) + { + float force = (maxDistance - toCenter.Length()) * 0.01f * Fade; + Vector2 move = toCenter.NormalizeSafe().RotatedBy(MathHelper.PiOver2) * force; + proj.position += move; + } + } + } + } + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + return false; + } + + public override void OnHitPlayer(Player target, Player.HurtInfo info) + { + VampireMat.OnVampireMatHitPlayer(target, info.Damage); + base.OnHitPlayer(target, info); + } + + public override bool PreDraw(ref Color lightColor) + { + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, CustomBlendStates.Reverse, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + List bars = []; + List bars_dark = []; + float width = 150f; + SpriteBatchUtils.AddVerticesForCircleRing(bars, Projectile.Center, 960, width, new Color(0.6f, 0.05f, 0.11f, 0), rotationValue, 10 + rotationValue, 1 - Fade); + + if (bars.Count > 2) + { + Effect effect = ModAsset.VampireMat_Attack_Proj_Absorb_Fade.Value; + effect.Parameters["uTransform"].SetValue( + Matrix.CreateTranslation(new Vector3(-Main.screenPosition, 0)) * + Main.GameViewMatrix.TransformationMatrix * + Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1)); + effect.CurrentTechnique.Passes[0].Apply(); + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Trail_16.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + float timeValue = rotationValue; + bars = []; + bars_dark = []; + int count = 200; + for (int k = 0; k <= count; k++) + { + float value = k / (float)count * 3; + Vector2 pos_out = Projectile.Center - Main.screenPosition + new Vector2(0, -960).RotatedBy(MathHelper.TwoPi * value); + Vector2 pos_in = Projectile.Center - Main.screenPosition + new Vector2(0, -480).RotatedBy(MathHelper.TwoPi * value + 1f); + bars.Add(pos_out, Color.Transparent, new Vector3(value + timeValue, 0, 0)); + bars.Add(pos_in, new Color(0.3f, 0, 0.06f, 0) * Fade, new Vector3(value + timeValue, 1, 0)); + bars_dark.Add(pos_out, Color.Transparent, new Vector3(value + timeValue, 0, 0)); + bars_dark.Add(pos_in, Color.White * Fade * 2, new Vector3(value + timeValue, 1, 0)); + } + + if (bars.Count > 2) + { + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Noise_hiveNet_black.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_dark.ToArray(), 0, bars_dark.Count - 2); + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Noise_hiveNet.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + bars = []; + bars_dark = []; + for (int k = 0; k <= count; k++) + { + float value = k / (float)count * 3; + Vector2 pos_out = Projectile.Center - Main.screenPosition + new Vector2(0, -480).RotatedBy(MathHelper.TwoPi * value + 1f); + Vector2 pos_in = Projectile.Center - Main.screenPosition + new Vector2(0, -20).RotatedBy(MathHelper.TwoPi * value + 2f); + bars.Add(pos_out, new Color(0.3f, 0, 0.06f, 0) * Fade, new Vector3(value + timeValue * 2, 0, 0)); + bars.Add(pos_in, Color.Transparent, new Vector3(value + timeValue * 3, 1, 0)); + bars_dark.Add(pos_out, Color.Transparent, new Vector3(value + timeValue * 2, 0, 0)); + bars_dark.Add(pos_in, Color.White * Fade * 2, new Vector3(value + timeValue * 3, 1, 0)); + } + + if (bars.Count > 2) + { + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Noise_hiveNet_black.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_dark.ToArray(), 0, bars_dark.Count - 2); + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Noise_hiveNet.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Absorb.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Absorb.png new file mode 100644 index 000000000..95b725b3b Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Absorb.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Absorb_Fade.fx b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Absorb_Fade.fx new file mode 100644 index 000000000..70021aaad --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Absorb_Fade.fx @@ -0,0 +1,44 @@ +sampler2D uImage : register(s0); + +float4x4 uTransform; + +struct VSInput +{ + float2 Pos : POSITION0; + float4 Color : COLOR0; + float3 Texcoord : TEXCOORD0; +}; + +struct PSInput +{ + float4 Pos : SV_POSITION; + float4 Color : COLOR0; + float3 Texcoord : TEXCOORD0; +}; + +PSInput VertexShaderFunction(VSInput input) +{ + PSInput output; + output.Color = input.Color; + output.Texcoord = input.Texcoord; + output.Pos = mul(float4(input.Pos, 0, 1), uTransform); + return output; +} + +float4 PixelShaderFunction(PSInput input) : COLOR0 +{ + float fade = input.Texcoord.z; + float4 color = tex2D(uImage, input.Texcoord.xy); + color -= float4(fade, fade, fade, fade); + color = clamp(color, float4(0, 0, 0, 0), float4(1, 1, 1, 1)); + return color * input.Color; +} + +technique Technique1 +{ + pass Test + { + VertexShader = compile vs_3_0 VertexShaderFunction(); + PixelShader = compile ps_3_0 PixelShaderFunction(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Absorb_Pipeline.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Absorb_Pipeline.cs new file mode 100644 index 000000000..977ca5e4b --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Absorb_Pipeline.cs @@ -0,0 +1,29 @@ +using Everglow.Yggdrasil.KelpCurtain.NPCs.VampireMat; +using Everglow.Yggdrasil.KelpCurtain.Projectiles.TileEffect; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Enemies; + +public class VampireMat_Attack_Proj_Absorb_Pipeline : Pipeline +{ + public override void BeginRender() + { + Ins.Batch.Begin(); + Ins.Batch.GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap; + effect.Value.Parameters["uTransform"].SetValue( + Matrix.CreateTranslation(new Vector3(-Main.screenPosition, 0)) * + Main.GameViewMatrix.TransformationMatrix * + Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1)); + effect.Value.CurrentTechnique.Passes[0].Apply(); + } + + public override void EndRender() + { + Ins.Batch.End(); + } + + public override void Load() + { + effect = ModAsset.VampireMat_Attack_Proj_Absorb_Fade; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball.cs new file mode 100644 index 000000000..492af18e5 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball.cs @@ -0,0 +1,92 @@ +using Everglow.Commons.DataStructures; +using Everglow.Commons.Graphics; +using Everglow.Yggdrasil.KelpCurtain.NPCs.VampireMat; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Enemies; + +public class VampireMat_Attack_Proj_Ball : ModProjectile +{ + public int TargetPlayerIndex => (int)Projectile.ai[0]; + + public int ParentNPCIndex => (int)Projectile.ai[1]; + + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicProjectiles; + + public override void SetDefaults() + { + Projectile.width = 20; + Projectile.height = 20; + Projectile.aiStyle = -1; + Projectile.timeLeft = 600; + Projectile.penetrate = -1; + Projectile.tileCollide = true; + Projectile.ignoreWater = true; + Projectile.friendly = false; + Projectile.hostile = true; + } + + public override void AI() + { + if (!Main.dedServ) + { + Lighting.AddLight(Projectile.Center, new Vector3(1f, 0.1f, 0.2f) * Projectile.scale * 5f); + } + int playerWhoAmI = TargetPlayerIndex; + if (playerWhoAmI < 0 || playerWhoAmI >= Main.maxPlayers || Main.player[playerWhoAmI] is not { active: true, dead: false }) + { + return; + } + Player player = Main.player[playerWhoAmI]; + Vector2 toPlayer = player.Center - Projectile.Center - Projectile.velocity; + toPlayer = toPlayer.NormalizeSafe() * 6; + Projectile.velocity = toPlayer * 0.05f + Projectile.velocity * 0.95f; + Projectile.velocity = Projectile.velocity.NormalizeSafe() * 6f; + if (Projectile.timeLeft % 6 == 0) + { + Projectile.frame++; + if (Projectile.frame >= 10) + { + Projectile.frame = 0; + } + } + } + + public override void OnKill(int timeLeft) + { + if (NetUtils.IsClient) + { + return; + } + + if (Main.rand.NextBool()) + { + Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center, Vector2.zeroVector, ModContent.ProjectileType(), 36, 2.5f, Main.myPlayer, TargetPlayerIndex, ParentNPCIndex); + } + else + { + Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center, Vector2.zeroVector, ModContent.ProjectileType(), 36, 2.5f, Main.myPlayer, TargetPlayerIndex, ParentNPCIndex); + } + } + + public override void OnHitPlayer(Player target, Player.HurtInfo info) + { + VampireMat.OnVampireMatHitPlayer(target, info.Damage); + base.OnHitPlayer(target, info); + } + + public override bool PreDraw(ref Color lightColor) + { + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, CustomBlendStates.Reverse, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + Texture2D tex = ModContent.Request(Texture).Value; + float drawScale = Projectile.scale * (MathF.Sin((float)Main.time * 0.15f + Projectile.whoAmI) * 0.25f + 1); + Rectangle frame = new Rectangle(0, 90 * Projectile.frame, 90, 90); + Main.EntitySpriteDraw(tex, Projectile.Center - Main.screenPosition, frame, new Color(1f, 1f, 1f, 1), 0, frame.Size() * 0.5f, drawScale, SpriteEffects.None, 0); + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball.png new file mode 100644 index 000000000..202f3e320 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_In_AbsorbVortex.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_In_AbsorbVortex.cs new file mode 100644 index 000000000..e66bea781 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_In_AbsorbVortex.cs @@ -0,0 +1,219 @@ +using Everglow.Commons.DataStructures; +using Everglow.Commons.Graphics; +using Everglow.Yggdrasil.KelpCurtain.NPCs.VampireMat; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Enemies; + +public class VampireMat_Attack_Proj_Ball_In_AbsorbVortex : ModProjectile +{ + public int TargetPlayerIndex => (int)Projectile.ai[0]; + + public int ParentNPCIndex => (int)Projectile.ai[1]; + + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicProjectiles; + + public int Timer = 0; + + public struct SubProj + { + public Vector2 Position; + public Vector2 Velocity; + public bool Active; + public float Scale; + public float MaxTime; + public float Timer; + } + + public List SubProjs = new List(); + + public List SubProjs_Style2 = new List(); + + public override void SetDefaults() + { + Projectile.width = 20; + Projectile.height = 20; + Projectile.aiStyle = -1; + Projectile.timeLeft = 1200; + Projectile.penetrate = -1; + Projectile.tileCollide = false; + Projectile.ignoreWater = true; + Projectile.friendly = false; + Projectile.hostile = true; + ProjectileID.Sets.DrawScreenCheckFluff[Type] = 4096; + ProjectileID.Sets.PlayerHurtDamageIgnoresDifficultyScaling[Type] = true; + } + + private bool initialized; + + public override bool PreAI() + { + if (initialized) + { + return true; + } + initialized = true; + for (int k = 0; k < 15; k++) + { + for (int j = 0; j < 8; j++) + { + var sproj = default(SubProj); + sproj.Position = Projectile.Center; + sproj.Velocity = new Vector2(0, -j * 10).RotatedBy(k / 15f * MathHelper.TwoPi); + sproj.Active = true; + sproj.Scale = 0.4f; + sproj.MaxTime = 540; + sproj.Timer = 0; + SubProjs_Style2.Add(sproj); + } + } + return true; + } + + public override void AI() + { + if (Timer % 24 == 0 && Timer < 450) + { + var sproj = default(SubProj); + sproj.Position = Projectile.Center; + sproj.Velocity = new Vector2(0, -11).RotatedBy(-Timer * 0.02f); + sproj.Active = true; + sproj.Scale = 0.4f; + sproj.MaxTime = 360; + sproj.Timer = 0; + SubProjs.Add(sproj); + + var sproj2 = default(SubProj); + sproj2.Position = Projectile.Center; + sproj2.Velocity = new Vector2(0, 11).RotatedBy(-Timer * 0.02f); + sproj2.Active = true; + sproj2.Scale = 0.4f; + sproj2.MaxTime = 360; + sproj2.Timer = 0; + SubProjs.Add(sproj2); + } + Projectile.velocity *= 0; + for (int i = SubProjs.Count - 1; i >= 0; i--) + { + var sp = SubProjs[i]; + Lighting.AddLight(sp.Position, new Vector3(1f, 0.1f, 0.2f) * sp.Scale); + sp.Position += sp.Velocity; + sp.Velocity = sp.Velocity.NormalizeSafe() * (4f + MathF.Sin(i / 3f * MathHelper.TwoPi + (float)Main.time * 0.03f + Projectile.whoAmI) * 0.3f * MathF.Cos(Projectile.timeLeft / 60f)); + sp.Timer++; + if (sp.MaxTime - sp.Timer < 60) + { + sp.Scale *= 0.96f; + } + SubProjs[i] = sp; + if (sp.Timer >= sp.MaxTime) + { + sp.Active = false; + SubProjs.RemoveAt(i); + } + } + + for (int i = SubProjs_Style2.Count - 1; i >= 0; i--) + { + var sp = SubProjs_Style2[i]; + Lighting.AddLight(sp.Position, new Vector3(1f, 0.1f, 0.2f) * sp.Scale); + float distance = 60; + if (sp.Timer % 120 >= 50 && sp.Timer % 120 < 60) + { + float value = (Timer - 50) / 10f; + value = MathF.Sin(value * MathHelper.Pi - MathHelper.PiOver2) + 1; + value *= 0.5f; + distance = (float)Utils.Lerp(60, 750, value); + } + if (sp.Timer % 120 >= 60 && sp.Timer % 120 < 110) + { + distance = 750; + } + if (sp.Timer % 120 >= 110 && sp.Timer % 120 < 120) + { + float value = (Timer - 110) / 10f; + value = MathF.Sin(value * MathHelper.Pi - MathHelper.PiOver2) + 1; + value *= 0.5f; + distance = (float)Utils.Lerp(750, 60, value); + } + sp.Position = Projectile.Center + sp.Velocity.NormalizeSafe() * distance + sp.Velocity; + sp.Timer++; + if (sp.MaxTime - sp.Timer < 60) + { + sp.Scale *= 0.96f; + } + SubProjs_Style2[i] = sp; + if (sp.Timer >= sp.MaxTime) + { + sp.Active = false; + SubProjs_Style2.RemoveAt(i); + } + } + if (SubProjs.Count + SubProjs_Style2.Count <= 0) + { + Projectile.Kill(); + } + Timer++; + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + foreach (var sp in SubProjs) + { + int x = (int)sp.Position.X; + int y = (int)sp.Position.Y; + Rectangle subHitbox = new Rectangle(x - 10, y - 10, 20, 20); + if (subHitbox.Intersects(targetHitbox)) + { + return true; + } + } + foreach (var sp in SubProjs_Style2) + { + int x = (int)sp.Position.X; + int y = (int)sp.Position.Y; + Rectangle subHitbox = new Rectangle(x - 10, y - 10, 20, 20); + if (subHitbox.Intersects(targetHitbox)) + { + return true; + } + } + return false; + } + + public override void OnHitPlayer(Player target, Player.HurtInfo info) + { + VampireMat.OnVampireMatHitPlayer(target, info.Damage); + base.OnHitPlayer(target, info); + } + + public override bool PreDraw(ref Color lightColor) + { + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, CustomBlendStates.Reverse, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + foreach (var sp in SubProjs) + { + DrawSubProj(sp); + } + + foreach (var sp in SubProjs_Style2) + { + DrawSubProj(sp); + } + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + return false; + } + + public void DrawSubProj(SubProj sp) + { + Texture2D star = Commons.ModAsset.CrossStar.Value; + Main.EntitySpriteDraw(star, sp.Position - Main.screenPosition, null, new Color(1f, 0.2f, 0.3f, 0f) * MathF.Min(sp.Scale, 0.5f), 0, star.Size() * 0.5f, sp.Scale * 2f, SpriteEffects.None, 0); + Texture2D tex = ModAsset.VampireMat_Attack_Proj_Ball.Value; + int frameNumber = (int)(TileUtils.GetFixedRandomNumber_SingleSeed(sp.GetHashCode(), 10) + Projectile.timeLeft / 12f) % 10; + Rectangle frame = new Rectangle(0, 90 * frameNumber, 90, 90); + Main.EntitySpriteDraw(tex, sp.Position - Main.screenPosition, frame, new Color(1f, 0.2f, 0.3f, 1f), 0, frame.Size() * 0.5f, sp.Scale, SpriteEffects.None, 0); + frame.X += 90; + Main.EntitySpriteDraw(tex, sp.Position - Main.screenPosition, frame, new Color(1f, 1f, 1f, 1f), 0, frame.Size() * 0.5f, sp.Scale, SpriteEffects.None, 0); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_In_AbsorbVortex.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_In_AbsorbVortex.png new file mode 100644 index 000000000..9df834d5b Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_In_AbsorbVortex.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_In_AbsorbVortex2.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_In_AbsorbVortex2.cs new file mode 100644 index 000000000..c225bb2be --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_In_AbsorbVortex2.cs @@ -0,0 +1,221 @@ +using Everglow.Commons.DataStructures; +using Everglow.Commons.Graphics; +using Everglow.Yggdrasil.KelpCurtain.NPCs.VampireMat; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Enemies; + +public class VampireMat_Attack_Proj_Ball_In_AbsorbVortex2 : ModProjectile +{ + public int TargetPlayerIndex => (int)Projectile.ai[0]; + + public int ParentNPCIndex => (int)Projectile.ai[1]; + + public int Timer = 0; + + public float RotationValue = 0; + + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicProjectiles; + + public override string Texture => ModAsset.VampireMat_Attack_Proj_Ball_In_AbsorbVortex_Mod; + + public struct SubProj + { + public Vector2 Position; + public Vector2 Velocity; + public bool Active; + public float Scale; + public float MaxTime; + public float Timer; + } + + public List SubProjs = new List(); + + public List SubProjs_Style2 = new List(); + + public override void SetDefaults() + { + Projectile.width = 20; + Projectile.height = 20; + Projectile.aiStyle = -1; + Projectile.timeLeft = 1200; + Projectile.penetrate = -1; + Projectile.tileCollide = false; + Projectile.ignoreWater = true; + Projectile.friendly = false; + Projectile.hostile = true; + ProjectileID.Sets.DrawScreenCheckFluff[Type] = 4096; + ProjectileID.Sets.PlayerHurtDamageIgnoresDifficultyScaling[Type] = true; + } + + private bool initialized; + + public override bool PreAI() + { + if (initialized) + { + return true; + } + initialized = true; + for (int k = 1; k < 3; k++) + { + for (int j = 0; j < k * 10; j++) + { + var sproj = default(SubProj); + sproj.Position = Projectile.Center; + sproj.Velocity = new Vector2(0, -k * 320).RotatedBy(j / (k * 10f) * MathHelper.TwoPi); + sproj.Active = true; + sproj.Scale = 0f; + sproj.MaxTime = 540; + sproj.Timer = 0; + SubProjs_Style2.Add(sproj); + } + } + return true; + } + + public override void AI() + { + if (Timer % 24 == 0 && Timer < 450) + { + var sproj = default(SubProj); + sproj.Position = Projectile.Center; + sproj.Velocity = new Vector2(0, -11).RotatedBy(-Timer * 0.02f); + sproj.Active = true; + sproj.Scale = 0.4f; + sproj.MaxTime = 360; + sproj.Timer = 0; + SubProjs.Add(sproj); + + var sproj2 = default(SubProj); + sproj2.Position = Projectile.Center; + sproj2.Velocity = new Vector2(0, 11).RotatedBy(-Timer * 0.02f); + sproj2.Active = true; + sproj2.Scale = 0.4f; + sproj2.MaxTime = 360; + sproj2.Timer = 0; + SubProjs.Add(sproj2); + } + Projectile.velocity *= 0; + for (int i = SubProjs.Count - 1; i >= 0; i--) + { + var sp = SubProjs[i]; + Lighting.AddLight(sp.Position, new Vector3(1f, 0.1f, 0.2f) * sp.Scale); + sp.Position += sp.Velocity; + sp.Velocity = sp.Velocity.NormalizeSafe() * (4f + MathF.Sin(i / 3f * MathHelper.TwoPi + (float)Main.time * 0.03f + Projectile.whoAmI) * 0.3f * MathF.Cos(Projectile.timeLeft / 60f)); + sp.Timer++; + if (sp.MaxTime - sp.Timer < 60) + { + sp.Scale *= 0.96f; + } + SubProjs[i] = sp; + if (sp.Timer >= sp.MaxTime) + { + sp.Active = false; + SubProjs.RemoveAt(i); + } + } + + for (int i = SubProjs_Style2.Count - 1; i >= 0; i--) + { + var sp = SubProjs_Style2[i]; + Lighting.AddLight(sp.Position, new Vector3(1f, 0.1f, 0.2f) * sp.Scale); + int dir = -1; + sp.Position = Projectile.Center + sp.Velocity.RotatedBy(RotationValue / MathF.Pow(sp.Velocity.Length(), 2) * dir * 2400f); + sp.Timer++; + if (sp.MaxTime - sp.Timer < 60) + { + sp.Scale *= 0.96f; + } + else + { + if (sp.Scale < 0.4f) + { + sp.Scale += 0.01f; + } + } + SubProjs_Style2[i] = sp; + if (sp.Timer >= sp.MaxTime) + { + sp.Active = false; + SubProjs_Style2.RemoveAt(i); + } + } + if (SubProjs.Count + SubProjs_Style2.Count <= 0) + { + Projectile.Kill(); + } + Timer++; + float rotSpeed = 1f; + if (Timer < 60) + { + rotSpeed *= Timer / 60f; + } + if (540 - Timer < 60) + { + rotSpeed *= (540 - Timer) / 60f; + } + RotationValue += rotSpeed; + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + foreach (var sp in SubProjs) + { + int x = (int)sp.Position.X; + int y = (int)sp.Position.Y; + Rectangle subHitbox = new Rectangle(x - 10, y - 10, 20, 20); + if (subHitbox.Intersects(targetHitbox)) + { + return true; + } + } + foreach (var sp in SubProjs_Style2) + { + int x = (int)sp.Position.X; + int y = (int)sp.Position.Y; + Rectangle subHitbox = new Rectangle(x - 10, y - 10, 20, 20); + if (subHitbox.Intersects(targetHitbox)) + { + return true; + } + } + return false; + } + + public override void OnHitPlayer(Player target, Player.HurtInfo info) + { + VampireMat.OnVampireMatHitPlayer(target, info.Damage); + base.OnHitPlayer(target, info); + } + + public override bool PreDraw(ref Color lightColor) + { + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, CustomBlendStates.Reverse, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + foreach (var sp in SubProjs) + { + DrawSubProj(sp); + } + + foreach (var sp in SubProjs_Style2) + { + DrawSubProj(sp); + } + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + return false; + } + + public void DrawSubProj(SubProj sp) + { + Texture2D star = Commons.ModAsset.CrossStar.Value; + Main.EntitySpriteDraw(star, sp.Position - Main.screenPosition, null, new Color(1f, 0.2f, 0.3f, 0f) * MathF.Min(sp.Scale, 0.5f), 0, star.Size() * 0.5f, sp.Scale * 2f, SpriteEffects.None, 0); + Texture2D tex = ModAsset.VampireMat_Attack_Proj_Ball.Value; + int frameNumber = (int)(TileUtils.GetFixedRandomNumber_SingleSeed(sp.GetHashCode(), 10) + Projectile.timeLeft / 12f) % 10; + Rectangle frame = new Rectangle(0, 90 * frameNumber, 90, 90); + Main.EntitySpriteDraw(tex, sp.Position - Main.screenPosition, frame, new Color(1f, 0.2f, 0.3f, 1f), 0, frame.Size() * 0.5f, sp.Scale, SpriteEffects.None, 0); + frame.X += 90; + Main.EntitySpriteDraw(tex, sp.Position - Main.screenPosition, frame, new Color(1f, 1f, 1f, 1f), 0, frame.Size() * 0.5f, sp.Scale, SpriteEffects.None, 0); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_Small_Group.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_Small_Group.cs new file mode 100644 index 000000000..fe2afe9a2 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_Small_Group.cs @@ -0,0 +1,138 @@ +using Everglow.Commons.DataStructures; +using Everglow.Commons.Graphics; +using Everglow.Yggdrasil.KelpCurtain.NPCs.VampireMat; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Enemies; + +public class VampireMat_Attack_Proj_Ball_Small_Group : ModProjectile +{ + public int TargetPlayerIndex => (int)Projectile.ai[0]; + + public int ParentNPCIndex => (int)Projectile.ai[1]; + + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicProjectiles; + + public struct SubProj + { + public Vector2 Position; + public Vector2 Velocity; + public bool Active; + public float Scale; + public float MaxTime; + public float Timer; + } + + public List SubProjs = new List(); + + public override void SetDefaults() + { + Projectile.width = 20; + Projectile.height = 20; + Projectile.aiStyle = -1; + Projectile.timeLeft = 1200; + Projectile.penetrate = -1; + Projectile.tileCollide = false; + Projectile.ignoreWater = true; + Projectile.friendly = false; + Projectile.hostile = true; + ProjectileID.Sets.DrawScreenCheckFluff[Type] = 4096; + } + + private bool initialized; + + public override bool PreAI() + { + if (initialized) + { + return true; + } + initialized = true; + for (int k = 0; k < 24; k++) + { + var sproj = default(SubProj); + sproj.Position = Projectile.Center; + sproj.Velocity = new Vector2(0, -4).RotatedBy(k * MathHelper.TwoPi / 24f); + sproj.Active = true; + sproj.Scale = 0.4f; + sproj.MaxTime = 360; + sproj.Timer = 0; + SubProjs.Add(sproj); + } + return true; + } + + public override void AI() + { + Projectile.velocity *= 0; + for (int i = SubProjs.Count - 1; i >= 0; i--) + { + var sp = SubProjs[i]; + Lighting.AddLight(sp.Position, new Vector3(1f, 0.1f, 0.2f) * sp.Scale); + sp.Position += sp.Velocity; + sp.Velocity = sp.Velocity.NormalizeSafe() * (4f + MathF.Sin(i / 3f * MathHelper.TwoPi + (float)Main.time * 0.03f + Projectile.whoAmI) * 0.3f * MathF.Cos(Projectile.timeLeft / 60f)); + sp.Timer++; + if (sp.MaxTime - sp.Timer < 60) + { + sp.Scale *= 0.96f; + } + SubProjs[i] = sp; + if (sp.Timer >= sp.MaxTime) + { + sp.Active = false; + SubProjs.RemoveAt(i); + } + } + if (SubProjs.Count <= 0) + { + Projectile.Kill(); + } + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + foreach (var sp in SubProjs) + { + int x = (int)sp.Position.X; + int y = (int)sp.Position.Y; + Rectangle subHitbox = new Rectangle(x - 10, y - 10, 20, 20); + if (subHitbox.Intersects(targetHitbox)) + { + return true; + } + } + return false; + } + + public override void OnHitPlayer(Player target, Player.HurtInfo info) + { + VampireMat.OnVampireMatHitPlayer(target, info.Damage); + base.OnHitPlayer(target, info); + } + + public override bool PreDraw(ref Color lightColor) + { + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, CustomBlendStates.Reverse, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + Texture2D tex = ModAsset.VampireMat_Attack_Proj_Ball.Value; + foreach (var sp in SubProjs) + { + DrawSubProj(sp); + } + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + return false; + } + + public void DrawSubProj(SubProj sp) + { + Texture2D star = Commons.ModAsset.CrossStar.Value; + Main.EntitySpriteDraw(star, sp.Position - Main.screenPosition, null, new Color(1f, 0.2f, 0.3f, 0f) * MathF.Min(sp.Scale, 0.5f), 0, star.Size() * 0.5f, sp.Scale, SpriteEffects.None, 0); + Texture2D tex = ModAsset.VampireMat_Attack_Proj_Ball.Value; + int frameNumber = (int)(TileUtils.GetFixedRandomNumber_SingleSeed(sp.GetHashCode(), 10) + Projectile.timeLeft / 12f) % 10; + Rectangle frame = new Rectangle(0, 90 * frameNumber, 90, 90); + Main.EntitySpriteDraw(tex, sp.Position - Main.screenPosition, frame, new Color(1f, 0.2f, 0.3f, 1f), 0, frame.Size() * 0.5f, sp.Scale, SpriteEffects.None, 0); + frame.X += 90; + Main.EntitySpriteDraw(tex, sp.Position - Main.screenPosition, frame, new Color(1f, 1f, 1f, 1f), 0, frame.Size() * 0.5f, sp.Scale, SpriteEffects.None, 0); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_Small_Group.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_Small_Group.png new file mode 100644 index 000000000..4b09e9117 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_Small_Group.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_Small_Group_1.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_Small_Group_1.cs new file mode 100644 index 000000000..c0909ec15 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_Small_Group_1.cs @@ -0,0 +1,147 @@ +using Everglow.Commons.DataStructures; +using Everglow.Commons.Graphics; +using Everglow.Yggdrasil.KelpCurtain.NPCs.VampireMat; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Enemies; + +public class VampireMat_Attack_Proj_Ball_Small_Group_1 : ModProjectile +{ + public int TargetPlayerIndex => (int)Projectile.ai[0]; + + public int ParentNPCIndex => (int)Projectile.ai[1]; + + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicProjectiles; + + public int Timer; + + public struct SubProj + { + public Vector2 Position; + public Vector2 Velocity; + public bool Active; + public float Scale; + public float MaxTime; + public float Timer; + } + + public List SubProjs = new List(); + + public override void SetDefaults() + { + Projectile.width = 20; + Projectile.height = 20; + Projectile.aiStyle = -1; + Projectile.timeLeft = 1200; + Projectile.penetrate = -1; + Projectile.tileCollide = false; + Projectile.ignoreWater = true; + Projectile.friendly = false; + Projectile.hostile = true; + ProjectileID.Sets.DrawScreenCheckFluff[Type] = 4096; + } + + public override void OnSpawn(IEntitySource source) + { + } + + public override void AI() + { + Projectile.velocity *= 0; + if (Timer <= 300 && Timer % 15 == 0) + { + int flat = Timer / 15 + 1; + int count = 2 * flat; + for (int k = 0; k < count; k++) + { + var sproj = default(SubProj); + sproj.Position = Projectile.Center + new Vector2(0, -60 * flat).RotatedBy(k * MathHelper.TwoPi / count + Projectile.whoAmI); + sproj.Velocity = Vector2.zeroVector; + sproj.Active = true; + sproj.Scale = 0f; + sproj.MaxTime = 30; + sproj.Timer = 0; + SubProjs.Add(sproj); + } + } + Timer++; + for (int i = SubProjs.Count - 1; i >= 0; i--) + { + var sp = SubProjs[i]; + Lighting.AddLight(sp.Position, new Vector3(1f, 0.1f, 0.2f) * sp.Scale); + sp.Timer++; + if (sp.MaxTime - sp.Timer < 10) + { + sp.Scale *= 0.8f; + } + else + { + if (sp.Scale < 0.4f) + { + sp.Scale += 0.04f; + } + } + SubProjs[i] = sp; + if (sp.Timer >= sp.MaxTime) + { + sp.Active = false; + SubProjs.RemoveAt(i); + } + } + if (SubProjs.Count <= 0) + { + Projectile.Kill(); + } + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + foreach (var sp in SubProjs) + { + if (sp.Scale <= 0.2f) + { + continue; + } + int x = (int)sp.Position.X; + int y = (int)sp.Position.Y; + Rectangle subHitbox = new Rectangle(x - 10, y - 10, 20, 20); + if (subHitbox.Intersects(targetHitbox)) + { + return true; + } + } + return false; + } + + public override void OnHitPlayer(Player target, Player.HurtInfo info) + { + VampireMat.OnVampireMatHitPlayer(target, info.Damage); + base.OnHitPlayer(target, info); + } + + public override bool PreDraw(ref Color lightColor) + { + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, CustomBlendStates.Reverse, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + foreach (var sp in SubProjs) + { + DrawSubProj(sp); + } + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + return false; + } + + public void DrawSubProj(SubProj sp) + { + Texture2D star = Commons.ModAsset.CrossStar.Value; + Main.EntitySpriteDraw(star, sp.Position - Main.screenPosition, null, new Color(1f, 0.2f, 0.3f, 0f) * MathF.Min(sp.Scale, 0.5f), 0, star.Size() * 0.5f, sp.Scale, SpriteEffects.None, 0); + Texture2D tex = ModAsset.VampireMat_Attack_Proj_Ball.Value; + int frameNumber = (int)(TileUtils.GetFixedRandomNumber_SingleSeed(sp.GetHashCode(), 10) + Projectile.timeLeft / 12f) % 10; + Rectangle frame = new Rectangle(0, 90 * frameNumber, 90, 90); + Main.EntitySpriteDraw(tex, sp.Position - Main.screenPosition, frame, new Color(1f, 0.2f, 0.3f, 1f), 0, frame.Size() * 0.5f, sp.Scale, SpriteEffects.None, 0); + frame.X += 90; + Main.EntitySpriteDraw(tex, sp.Position - Main.screenPosition, frame, new Color(1f, 1f, 1f, 1f), 0, frame.Size() * 0.5f, sp.Scale, SpriteEffects.None, 0); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_Small_Group_1.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_Small_Group_1.png new file mode 100644 index 000000000..4b09e9117 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_Small_Group_1.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_black.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_black.png new file mode 100644 index 000000000..c877a3374 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_black.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_highlight.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_highlight.png new file mode 100644 index 000000000..72e4f093d Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Ball_highlight.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Tusk.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Tusk.cs new file mode 100644 index 000000000..be8c8b082 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Tusk.cs @@ -0,0 +1,95 @@ +using Everglow.Yggdrasil.KelpCurtain.Gores; +using Everglow.Yggdrasil.KelpCurtain.NPCs.VampireMat; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Enemies; + +public class VampireMat_Attack_Proj_Tusk : ModProjectile +{ + public int TargetPlayerIndex => (int)Projectile.ai[0]; + + public int ParentNPCIndex => (int)Projectile.ai[1]; + + public override string LocalizationCategory => LocalizationUtils.Categories.MagicProjectiles; + + public int Timer = 0; + + public override void SetDefaults() + { + Projectile.width = 10; + Projectile.height = 10; + Projectile.aiStyle = -1; + Projectile.timeLeft = 600; + Projectile.penetrate = -1; + Projectile.tileCollide = true; + Projectile.ignoreWater = true; + Projectile.friendly = false; + Projectile.hostile = true; + } + + public override void AI() + { + Projectile.rotation = Projectile.velocity.ToRotationSafe(); + Timer++; + } + + public override void OnKill(int timeLeft) + { + for (int x = 0; x < 7; x++) + { + VampireMat_Attack_Proj_Tusk_Gore gore = new VampireMat_Attack_Proj_Tusk_Gore(); + gore.Position = Projectile.Center + Projectile.rotation.ToRotationVector2() * 10 * (x - 3); + gore.Velocity = new Vector2(Main.rand.NextFloat(5), 0).RotatedByRandom(MathHelper.TwoPi); + gore.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + gore.RotateSpeed = Main.rand.NextFloat(-0.1f, 0.1f); + gore.Active = true; + gore.Visible = true; + switch (x) + { + case 0: + gore.Frame = new Rectangle(0, 0, 32, 14); + break; + case 1: + gore.Frame = new Rectangle(0, 16, 36, 18); + break; + case 2: + gore.Frame = new Rectangle(0, 36, 28, 16); + break; + case 3: + gore.Frame = new Rectangle(0, 54, 12, 10); + break; + case 4: + gore.Frame = new Rectangle(20, 54, 14, 18); + break; + case 5: + gore.Frame = new Rectangle(0, 66, 16, 10); + break; + case 6: + gore.Frame = new Rectangle(0, 78, 26, 10); + break; + } + Ins.VFXManager.Add(gore); + } + } + + public override void OnHitPlayer(Player target, Player.HurtInfo info) + { + VampireMat.OnVampireMatHitPlayer(target, info.Damage); + base.OnHitPlayer(target, info); + } + + public override bool PreDraw(ref Color lightColor) + { + Texture2D tex = ModContent.Request(Texture).Value; + Texture2D bloom = ModAsset.VampireMat_Attack_Proj_Tusk_bloom.Value; + Texture2D white = ModAsset.VampireMat_Attack_Proj_Tusk_White.Value; + float drawScale = Projectile.scale; + lightColor = Lighting.GetColor(Projectile.Center.ToTileCoordinates()); + Main.EntitySpriteDraw(tex, Projectile.Center - Main.screenPosition, null, lightColor, Projectile.rotation, tex.Size() * 0.5f, drawScale, SpriteEffects.None, 0); + Main.EntitySpriteDraw(bloom, Projectile.Center - Main.screenPosition, null, new Color(1f, 1f, 1f, 0) * (MathF.Sin(Projectile.timeLeft * 0.5f) * 0.35f + 1f) * 0.5f, Projectile.rotation, bloom.Size() * 0.5f, drawScale, SpriteEffects.None, 0); + if (Timer < 6 || (Timer < 30 && Timer % 8 < 4)) + { + Main.EntitySpriteDraw(white, Projectile.Center - Main.screenPosition, null, Color.Lerp(Color.White, lightColor, 0.75f), Projectile.rotation, white.Size() * 0.5f, drawScale, SpriteEffects.None, 0); + } + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Tusk.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Tusk.png new file mode 100644 index 000000000..5f5cb1c50 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Tusk.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Tusk_White.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Tusk_White.png new file mode 100644 index 000000000..fa8e61acc Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Tusk_White.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Tusk_bloom.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Tusk_bloom.png new file mode 100644 index 000000000..1a36d8a61 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Attack_Proj_Tusk_bloom.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Tentacle.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Tentacle.cs new file mode 100644 index 000000000..d7222f44e --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Tentacle.cs @@ -0,0 +1,136 @@ +using Everglow.Commons.DataStructures; +using Everglow.Yggdrasil.KelpCurtain.NPCs.VampireMat; +using Microsoft.CodeAnalysis; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Enemies; + +public class VampireMat_Tentacle : ModProjectile +{ + public int TargetPlayerIndex => (int)Projectile.ai[0]; + + public int ParentNPCIndex => (int)Projectile.ai[1]; + + private float InitialRotation => Projectile.ai[2]; + + public NPC ParentVampireMat + { + get + { + if (ParentNPCIndex < 0 || ParentNPCIndex >= Main.maxNPCs) + { + return null; + } + NPC parent = Main.npc[ParentNPCIndex]; + return parent is { active: true, ModNPC: VampireMat } ? parent : null; + } + } + + public int Timer; + + public override void SetDefaults() + { + Projectile.width = 80; + Projectile.height = 80; + Projectile.hostile = true; + Projectile.friendly = false; + Projectile.timeLeft = 180; + Projectile.tileCollide = false; + Projectile.ignoreWater = true; + Projectile.penetrate = -1; + Projectile.aiStyle = -1; + Projectile.hide = true; + ProjectileID.Sets.PlayerHurtDamageIgnoresDifficultyScaling[Type] = true; + } + + public override void OnSpawn(IEntitySource source) + { + Projectile.rotation = InitialRotation; + } + + public override void AI() + { + if (ParentVampireMat is null || !ParentVampireMat.active) + { + Projectile.active = false; + return; + } + Projectile.rotation = InitialRotation; + Projectile.Center = ParentVampireMat.Center; + Timer++; + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + float tentacle_dis = MathF.Sin(Timer / 180f * MathHelper.Pi) * 900; + return CollisionUtils.Intersect(targetHitbox.Top(), targetHitbox.Bottom(), targetHitbox.Width, Projectile.Center, Projectile.Center + new Vector2(tentacle_dis, 0).RotatedBy(Projectile.rotation), 110); + } + + public override void OnHitPlayer(Player target, Player.HurtInfo info) + { + VampireMat.OnVampireMatHitPlayer(target, info.Damage); + base.OnHitPlayer(target, info); + } + + public override void DrawBehind(int index, List behindNPCsAndTiles, List behindNPCs, List behindProjectiles, List overPlayers, List overWiresUI) + { + behindNPCs.Add(index); + base.DrawBehind(index, behindNPCsAndTiles, behindNPCs, behindProjectiles, overPlayers, overWiresUI); + } + + public override bool PreDraw(ref Color lightColor) + { + if (ParentVampireMat is null || !ParentVampireMat.active || ParentVampireMat.type != ModContent.NPCType()) + { + return false; + } + VampireMat vampireMat = ParentVampireMat.ModNPC as VampireMat; + Texture2D texture = ModContent.Request(Texture).Value; + float tentacle_dis = MathF.Sin(Timer / 180f * MathHelper.Pi) * 900; + List tentacleCurve = new List(); + for (int i = 0; i <= tentacle_dis; i += 10) + { + float wave = 0; + if (Timer > 60) + { + float decay = i / 600f; + if (decay > 1) + { + decay = 1; + } + wave = MathF.Sin((Timer - 60) / 120f * MathHelper.Pi) * MathF.Sin(i / 30f + Projectile.whoAmI + (float)Main.time * 0.06f) * 30 * decay; + } + tentacleCurve.Add(Projectile.Center + new Vector2(tentacle_dis - i, wave).RotatedBy(Projectile.rotation) - Main.screenPosition); + } + List bars = SpriteBatchUtils.DrawCurveStrip_EnvironmentLight(tentacleCurve, 110, 1, (float)(texture.Width - tentacle_dis) / texture.Width); + if (bars.Count > 2) + { + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + Main.graphics.GraphicsDevice.Textures[0] = texture; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + + if (vampireMat is not null && vampireMat.HitTimer > 0) + { + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + Effect effect = ModAsset.VampireMat_HitEffect.Value; + effect.Parameters["hitTimer"].SetValue(vampireMat.HitTimer); + effect.CurrentTechnique.Passes[0].Apply(); + + Main.graphics.GraphicsDevice.Textures[0] = texture; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + } + } + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Tentacle.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Tentacle.png new file mode 100644 index 000000000..7bf3d2144 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Tentacle.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Tentacle_FromBackground.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Tentacle_FromBackground.cs new file mode 100644 index 000000000..665ed17c7 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Enemies/VampireMat_Tentacle_FromBackground.cs @@ -0,0 +1,201 @@ +using Everglow.Commons.DataStructures; +using Everglow.Yggdrasil.KelpCurtain.NPCs.VampireMat; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Enemies; + +public class VampireMat_Tentacle_FromBackground : ModProjectile +{ + public int TargetPlayerIndex => (int)Projectile.ai[0]; + + public int ParentNPCIndex => (int)Projectile.ai[1]; + + private float InitialRotation => Projectile.ai[2]; + + public NPC ParentVampireMat + { + get + { + if (ParentNPCIndex < 0 || ParentNPCIndex >= Main.maxNPCs) + { + return null; + } + NPC parent = Main.npc[ParentNPCIndex]; + return parent is { active: true, ModNPC: VampireMat } ? parent : null; + } + } + + public int Timer = 0; + + public int Duration = 0; + + public override string Texture => ModAsset.VampireMat_Tentacle_Mod; + + public override void SetDefaults() + { + Projectile.width = 80; + Projectile.height = 80; + Projectile.hostile = true; + Projectile.friendly = false; + Projectile.timeLeft = 330; + Projectile.tileCollide = false; + Projectile.ignoreWater = true; + Projectile.penetrate = -1; + Projectile.aiStyle = -1; + Projectile.hide = true; + ProjectileID.Sets.PlayerHurtDamageIgnoresDifficultyScaling[Type] = true; + } + + public override void OnSpawn(IEntitySource source) + { + Projectile.rotation = InitialRotation; + } + + public override void AI() + { + if (ParentVampireMat is null || !ParentVampireMat.active) + { + Projectile.active = false; + return; + } + if (Timer == 0) + { + Projectile.rotation = InitialRotation; + } + Timer++; + if (Timer < 10 || Timer > 90) + { + Duration++; + } + else + { + int playerIndex = TargetPlayerIndex; + if (playerIndex >= 0 && playerIndex < Main.maxPlayers && Main.player[playerIndex] is { active: true, dead: false }) + { + Player target = Main.player[playerIndex]; + Projectile.rotation = (target.Center - Projectile.Center).ToRotationSafe(); + } + } + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + if (Duration < 12 || Duration > 170) + { + return false; + } + float tentacle_dis = MathF.Sin(Duration / 180f * MathHelper.Pi) * 900; + return CollisionUtils.Intersect(targetHitbox.Top(), targetHitbox.Bottom(), targetHitbox.Width, Projectile.Center, Projectile.Center + new Vector2(tentacle_dis, 0).RotatedBy(Projectile.rotation), 110); + } + + public override void OnHitPlayer(Player target, Player.HurtInfo info) + { + VampireMat.OnVampireMatHitPlayer(target, info.Damage); + base.OnHitPlayer(target, info); + } + + public override void DrawBehind(int index, List behindNPCsAndTiles, List behindNPCs, List behindProjectiles, List overPlayers, List overWiresUI) + { + behindNPCs.Add(index); + base.DrawBehind(index, behindNPCsAndTiles, behindNPCs, behindProjectiles, overPlayers, overWiresUI); + } + + public override bool PreDraw(ref Color lightColor) + { + if (ParentVampireMat is null || !ParentVampireMat.active || ParentVampireMat.type != ModContent.NPCType()) + { + return false; + } + VampireMat vampireMat = ParentVampireMat.ModNPC as VampireMat; + Texture2D texture = ModContent.Request(Texture).Value; + float tentacle_dis = MathF.Sin(Duration / 180f * MathHelper.Pi) * 900; + List tentacleCurve = new List(); + for (int i = 0; i <= tentacle_dis; i += 10) + { + float wave = 0; + if (Duration > 60) + { + float decay = i / 600f; + if (decay > 1) + { + decay = 1; + } + wave = MathF.Sin((Duration - 60) / 120f * MathHelper.Pi) * MathF.Sin(i / 30f + Projectile.whoAmI + (float)Main.time * 0.06f) * 30 * decay; + } + tentacleCurve.Add(Projectile.Center + new Vector2(tentacle_dis - i, wave).RotatedBy(Projectile.rotation) - Main.screenPosition); + } + List bars = DrawCurveStrip_EnvironmentLight_ForTentacles(tentacleCurve, 110, 1, (float)(texture.Width - tentacle_dis) / texture.Width); + if (bars.Count > 2) + { + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + Main.graphics.GraphicsDevice.Textures[0] = texture; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + + if (vampireMat is not null && vampireMat.HitTimer > 0) + { + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + Effect effect = ModAsset.VampireMat_HitEffect.Value; + effect.Parameters["hitTimer"].SetValue(vampireMat.HitTimer); + effect.CurrentTechnique.Passes[0].Apply(); + + Main.graphics.GraphicsDevice.Textures[0] = texture; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + } + } + return false; + } + + private List DrawCurveStrip_EnvironmentLight_ForTentacles(List curve, float width, float coord_x_min, float coord_x_max, float coord_y_min = 0, float coord_y_max = 1, bool curveHasScreenPos = false) + { + if (curve.Count < 2) + { + return []; + } + Vector2 lightSamplingOffset = Vector2.zeroVector; + if (!curveHasScreenPos) + { + lightSamplingOffset = Main.screenPosition; + } + List bars = new List(); + for (int i = 0; i < curve.Count; i++) + { + Vector2 pos = curve[i]; + Vector2 dir; + if (i == 0) + { + dir = curve[i + 1] - curve[i]; + } + else + { + dir = curve[i] - curve[i - 1]; + } + dir = dir.NormalizeSafe(); + Vector2 normal = new Vector2(dir.Y, -dir.X) * width / 2f; + float value = i / (float)(curve.Count - 1); + float coordX = float.Lerp(coord_x_min, coord_x_max, value); + int rev_i = curve.Count - i; + if (rev_i < 5) + { + SpriteBatchUtils.AddVertexWithEnv_Light(bars, pos + normal + lightSamplingOffset, new Vector3(coordX, coord_y_min, 0), true, rev_i / 5f); + SpriteBatchUtils.AddVertexWithEnv_Light(bars, pos - normal + lightSamplingOffset, new Vector3(coordX, coord_y_max, 0), true, rev_i / 5f); + } + else + { + SpriteBatchUtils.AddVertexWithEnv_Light(bars, pos + normal + lightSamplingOffset, new Vector3(coordX, coord_y_min, 0)); + SpriteBatchUtils.AddVertexWithEnv_Light(bars, pos - normal + lightSamplingOffset, new Vector3(coordX, coord_y_max, 0)); + } + } + return bars; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Legacies/AncientSyringe_proj.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Legacies/AncientSyringe_proj.cs index 1d34cd2ef..a64d27e72 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Legacies/AncientSyringe_proj.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Legacies/AncientSyringe_proj.cs @@ -17,12 +17,14 @@ public override void SetDef() Projectile.localNPCHitCooldown = 20; base.SetDef(); } + public override void OnSpawn(IEntitySource source) { Player player = Main.player[Projectile.owner]; int timeMax = (int)(player.itemTimeMax / player.meleeSpeed); player.itemTime = timeMax; } + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { int times = 10; @@ -37,7 +39,7 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) position = target.Center, maxTime = Main.rand.Next(12, 28), scale = Main.rand.NextFloat(6f, 18f), - ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), 0, Main.rand.NextFloat(20.0f, 40.0f) } + ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), 0, Main.rand.NextFloat(20.0f, 40.0f) }, }; Ins.VFXManager.Add(splash); } @@ -54,17 +56,19 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) maxTime = Main.rand.Next(32, 64), scale = mulScale, rotation = Main.rand.NextFloat(6.283f), - ai = new float[] { 0f, Main.rand.NextFloat(0.0f, 4.93f) } + ai = new float[] { 0f, Main.rand.NextFloat(0.0f, 4.93f) }, }; Ins.VFXManager.Add(blood); } target.AddBuff(ModContent.BuffType(), 480); base.OnHitNPC(target, hit, damageDone); } + public override void AI() { base.AI(); } + public override void HeldProjectileAI() { Player player = Main.player[Projectile.owner]; @@ -112,26 +116,31 @@ public override void HeldProjectileAI() Projectile.Center = ArmRootPos + new Vector2(0, 1).RotatedBy(Projectile.rotation - Math.PI * 0.75) * DepartLength; Projectile.timeLeft = timeMax; - } if (!player.controlUseItem) { Projectile.Kill(); } if (Projectile.Center.X < ArmRootPos.X) + { player.direction = -1; + } else { player.direction = 1; } } + public override bool PreDraw(ref Color lightColor) { Player player = Main.player[Projectile.owner]; var texMain = (Texture2D)ModContent.Request(Texture); SpriteEffects se = SpriteEffects.None; if (player.direction == -1) + { se = SpriteEffects.FlipVertically; + } + float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction; Main.spriteBatch.Draw(texMain, Projectile.Center - Main.screenPosition + DrawOffset - new Vector2(54, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, lightColor, rot, texMain.Size() / 2f, 1f, se, 0); int timeMax = (int)(player.itemTimeMax / player.meleeSpeed); diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/EmptyWaterStaff_proj.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/EmptyWaterStaff_proj.cs new file mode 100644 index 000000000..6ae6421ae --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/EmptyWaterStaff_proj.cs @@ -0,0 +1,295 @@ +using Everglow.Commons.DataStructures; +using Everglow.Commons.Graphics; +using Everglow.Commons.Templates.Weapons; +using Everglow.Yggdrasil.KelpCurtain.VFXs; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Magic; + +public class EmptyWaterStaff_proj : TrailingProjectile +{ + public override void SetCustomDefaults() + { + TrailColor = new Color(0.85f, 0.75f, 0.65f, 0f); + TrailWidth = 12f; + TrailTexture = Commons.ModAsset.Trail_8.Value; + TrailTextureBlack = Commons.ModAsset.Trail_8_black.Value; + ProjectileID.Sets.TrailCacheLength[Projectile.type] = 20; + + Projectile.DamageType = DamageClass.Magic; + Projectile.width = 20; + Projectile.height = 20; + ProjTrailColor.colorList.Add((new Color(15, 231, 255, 0), 0)); + ProjTrailColor.colorList.Add((new Color(63, 181, 255, 0), 0.4f)); + ProjTrailColor.colorList.Add((new Color(69, 112, 255, 0), 0.8f)); + ProjTrailColor.colorList.Add((new Color(36, 46, 76, 0), 1f)); + } + + public GradientColor ProjTrailColor = new(); + + public override void AI() + { + base.AI(); + if (Main.rand.NextBool(4)) + { + Vector2 vel = new Vector2(0, Main.rand.NextFloat(0.6f, 1.4f)).RotatedByRandom(MathHelper.TwoPi) + Projectile.velocity; + var dust = new EmptyWaterStaff_BubbleBreak + { + velocity = vel, + Active = true, + Visible = true, + position = Projectile.Center, + maxTime = Main.rand.Next(60, 90), + scale = Main.rand.NextFloat(3f, 5f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(4.0f, 10.93f) }, + }; + Ins.VFXManager.Add(dust); + } + } + + public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) + { + bool safe = true; + foreach (var proj in Main.projectile) + { + if (proj is not null && proj.active && proj.type == ModContent.ProjectileType()) + { + EmptyWaterStaff_proj_bubble eWS = proj.ModProjectile as EmptyWaterStaff_proj_bubble; + if (eWS is not null) + { + if (eWS.Target == target) + { + safe = false; + break; + } + } + } + } + if (safe) + { + Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), target.Center, Vector2.zeroVector, ModContent.ProjectileType(), Projectile.damage, 0, Projectile.owner, target.whoAmI); + } + } + + public override void DestroyEntity() + { + for (int i = 0; i < 12; i++) + { + Vector2 vel = new Vector2(0, Main.rand.NextFloat(5.6f, 8.4f)).RotatedByRandom(MathHelper.TwoPi); + var dust = new EmptyWaterStaff_BubbleBreak + { + velocity = vel, + Active = true, + Visible = true, + position = Projectile.Center, + maxTime = Main.rand.Next(60, 120), + scale = Main.rand.NextFloat(3f, 5f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(4.0f, 10.93f) }, + }; + Ins.VFXManager.Add(dust); + } + base.DestroyEntity(); + } + + public override bool PreDraw(ref Color lightColor) + { + DrawTrail(); + if (TimeAfterEntityDestroy <= 0) + { + DrawSelf(); + } + return false; + } + + public override void DrawSelf() + { + var texMain = (Texture2D)ModContent.Request(Texture); + var color = new Color(1f, 1f, 1f, 0); + Main.spriteBatch.Draw(texMain, Projectile.Center - Main.screenPosition - Projectile.velocity, null, color, Projectile.velocity.ToRotation() - MathHelper.PiOver2, texMain.Size() / 2f, 0.6f, SpriteEffects.None, 0); + } + + public override Vector3 ModifyTrailTextureCoordinate(float factor, float timeValue, float phase, float widthValue) + { + float x = factor - timeValue * 0.6f; + float y = 1; + float z = widthValue; + if (phase == 2) + { + y = 0; + } + if (phase % 2 == 1) + { + y = 0.5f; + } + return new Vector3(x, y, z); + } + + public override Color GetTrailColor(int style, Vector2 worldPos, int index, ref float factor, float extraValue0 = 0, float extraValue1 = 0) + { + if (style == 1) + { + return ProjTrailColor.GetColor(factor); + } + else + { + return base.GetTrailColor(style, worldPos, index, ref factor, extraValue0, extraValue1); + } + } + + //public override void DrawTrail() + //{ + // var unSmoothPos = new List(); + // for (int i = 0; i < Projectile.oldPos.Length; ++i) + // { + // if (Projectile.oldPos[i] == Vector2.Zero) + // { + // break; + // } + + // unSmoothPos.Add(Projectile.oldPos[i]); + // } + // List smoothTrail_current = GraphicsUtils.CatmullRom(unSmoothPos); // 平滑 + // var SmoothTrail = new List(); + // for (int x = 0; x < smoothTrail_current.Count - 1; x++) + // { + // SmoothTrail.Add(smoothTrail_current[x]); + // } + // if (unSmoothPos.Count != 0) + // { + // SmoothTrail.Add(unSmoothPos[unSmoothPos.Count - 1]); + // } + + // Vector2 halfSize = new Vector2(Projectile.width, Projectile.height) / 2f; + // var bars = new List(); + // var bars2 = new List(); + // var bars3 = new List(); + // for (int i = 1; i < SmoothTrail.Count; ++i) + // { + // float mulFac = Timer / (float)ProjectileID.Sets.TrailCacheLength[Projectile.type]; + // if (mulFac > 1f) + // { + // mulFac = 1f; + // } + // float factor = i / (float)SmoothTrail.Count * mulFac; + // float width = TrailWidthFunction(factor); + // float timeValue = (float)Main.time * 0.06f; + + // Vector2 drawPos = SmoothTrail[i] + halfSize; + // Color drawC = ProjTrailColor.GetColor(i / (float)SmoothTrail.Count); + // factor *= 1.5f; + // bars.Add(new Vertex2D(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 2f / 3f) * TrailWidth, drawC, new Vector3(-factor * 2 + timeValue, 1, width))); + // bars.Add(new Vertex2D(drawPos, drawC, new Vector3(-factor * 2 + timeValue, 0.5f, width))); + // bars2.Add(new Vertex2D(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 1f / 3f) * TrailWidth, drawC, new Vector3(-factor * 2 + timeValue, 0, width))); + // bars2.Add(new Vertex2D(drawPos, drawC, new Vector3(-factor * 2 + timeValue, 0.5f, width))); + // bars3.Add(new Vertex2D(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 0f / 3f) * TrailWidth, drawC, new Vector3(-factor * 2 + timeValue, 1, width))); + // bars3.Add(new Vertex2D(drawPos, drawC, new Vector3(-factor * 2 + timeValue, 0.5f, width))); + // } + // SpriteBatchState sBS = Main.spriteBatch.GetState().Value; + // Main.spriteBatch.End(); + // Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + // Effect effect = TrailShader; + // var projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1); + // var model = Matrix.CreateTranslation(new Vector3(-Main.screenPosition, 0)) * Main.GameViewMatrix.TransformationMatrix; + // effect.Parameters["uTransform"].SetValue(model * projection); + // effect.CurrentTechnique.Passes[0].Apply(); + // Main.graphics.GraphicsDevice.RasterizerState = RasterizerState.CullNone; + // Main.graphics.GraphicsDevice.Textures[0] = TrailTexture; + // Main.graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap; + // if (bars.Count > 3) + // { + // Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + // } + + // if (bars2.Count > 3) + // { + // Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars2.ToArray(), 0, bars2.Count - 2); + // } + + // if (bars3.Count > 3) + // { + // Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars3.ToArray(), 0, bars3.Count - 2); + // } + + // Main.spriteBatch.End(); + // Main.spriteBatch.Begin(sBS); + //} + + //public override void DrawTrailDark() + //{ + // var unSmoothPos = new List(); + // for (int i = 0; i < Projectile.oldPos.Length; ++i) + // { + // if (Projectile.oldPos[i] == Vector2.Zero) + // { + // break; + // } + + // unSmoothPos.Add(Projectile.oldPos[i]); + // } + // List smoothTrail_current = GraphicsUtils.CatmullRom(unSmoothPos); // 平滑 + // var SmoothTrail = new List(); + // for (int x = 0; x < smoothTrail_current.Count - 1; x++) + // { + // SmoothTrail.Add(smoothTrail_current[x]); + // } + // if (unSmoothPos.Count != 0) + // { + // SmoothTrail.Add(unSmoothPos[unSmoothPos.Count - 1]); + // } + + // Vector2 halfSize = new Vector2(Projectile.width, Projectile.height) / 2f; + // var bars = new List(); + // var bars2 = new List(); + // var bars3 = new List(); + // for (int i = SmoothTrail.Count - 1; i > 0; --i) + // { + // float mulFac = Timer / (float)ProjectileID.Sets.TrailCacheLength[Projectile.type]; + // if (mulFac > 1f) + // { + // mulFac = 1f; + // } + // float factor = i / (float)SmoothTrail.Count * mulFac; + // float width = TrailWidthFunction(factor); + // float timeValue = (float)Main.time * 0.06f; + + // Vector2 drawPos = SmoothTrail[i] + halfSize; + // Color drawC = Color.White; + // factor *= 1.5f; + // bars.Add(new Vertex2D(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 2f / 3f) * TrailWidth, drawC, new Vector3(-factor * 2 + timeValue, 1, width))); + // bars.Add(new Vertex2D(drawPos, drawC, new Vector3(-factor * 2 + timeValue, 0.5f, width))); + // bars2.Add(new Vertex2D(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 1f / 3f) * TrailWidth, drawC, new Vector3(-factor * 2 + timeValue, 0, width))); + // bars2.Add(new Vertex2D(drawPos, drawC, new Vector3(-factor * 2 + timeValue, 0.5f, width))); + // bars3.Add(new Vertex2D(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 0f / 3f) * TrailWidth, drawC, new Vector3(-factor * 2 + timeValue, 1, width))); + // bars3.Add(new Vertex2D(drawPos, drawC, new Vector3(-factor * 2 + timeValue, 0.5f, width))); + // } + // SpriteBatchState sBS = Main.spriteBatch.GetState().Value; + // Main.spriteBatch.End(); + // Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + // Effect effect = TrailShader; + // var projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1); + // var model = Matrix.CreateTranslation(new Vector3(-Main.screenPosition, 0)) * Main.GameViewMatrix.TransformationMatrix; + // effect.Parameters["uTransform"].SetValue(model * projection); + // effect.CurrentTechnique.Passes[0].Apply(); + // Main.graphics.GraphicsDevice.RasterizerState = RasterizerState.CullNone; + // Main.graphics.GraphicsDevice.Textures[0] = TrailTextureBlack; + // Main.graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap; + // if (bars.Count > 3) + // { + // Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + // } + + // if (bars2.Count > 3) + // { + // Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars2.ToArray(), 0, bars2.Count - 2); + // } + + // if (bars3.Count > 3) + // { + // Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars3.ToArray(), 0, bars3.Count - 2); + // } + + // Main.spriteBatch.End(); + // Main.spriteBatch.Begin(sBS); + //} +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/EmptyWaterStaff_proj.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/EmptyWaterStaff_proj.png new file mode 100644 index 000000000..ec42c6d98 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/EmptyWaterStaff_proj.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/EmptyWaterStaff_proj_black.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/EmptyWaterStaff_proj_black.png new file mode 100644 index 000000000..2044d8304 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/EmptyWaterStaff_proj_black.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/EmptyWaterStaff_proj_bubble.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/EmptyWaterStaff_proj_bubble.cs new file mode 100644 index 000000000..e15499e0c --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/EmptyWaterStaff_proj_bubble.cs @@ -0,0 +1,324 @@ +using Everglow.Commons.DataStructures; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Magic; + +public class EmptyWaterStaff_proj_bubble : ModProjectile, IWarpProjectile_warpStyle2 +{ + public NPC Target; + + public int Timer; + + public float BubbleScale = 1f; + + public List BubbleBound = new List(); + + public override string Texture => ModAsset.EmptyWaterStaff_Mod; + + public override void SetDefaults() + { + Projectile.friendly = false; + Projectile.width = 10; + Projectile.height = 10; + Projectile.aiStyle = -1; + Projectile.tileCollide = false; + Projectile.timeLeft = 180; + Projectile.penetrate = -1; + Projectile.hide = true; + } + + public override void OnSpawn(IEntitySource source) + { + if (Projectile.ai[0] >= 0 && Projectile.ai[0] < Main.npc.Length) + { + Target = Main.npc[(int)Projectile.ai[0]]; + Projectile.velocity = new Vector2(0, -2); + if (Projectile.wet) + { + Projectile.timeLeft = 360; + } + } + else + { + Projectile.active = false; + } + } + + public override void AI() + { + Timer++; + if (!CanTrap(Target)) + { + if (Timer > 5) + { + if (Projectile.timeLeft > 2) + { + Projectile.timeLeft = 1; + } + } + return; + } + if (Timer < 20) + { + BubbleScale = (MathF.Sin(Timer / 20f * MathHelper.Pi * 1.5f - MathHelper.PiOver2) + 1) / 2f * CalculateTargetScale() * 1.5f; + } + else + { + BubbleScale = CalculateTargetScale(); + } + if (Timer == 20) + { + Vector2 oldCenter = Projectile.Center; + Projectile.width = Projectile.height = (int)(BubbleScale * 1.6f); + Projectile.Center = oldCenter; + } + Projectile.velocity *= 0.99f; + Vector2 targetToProj = Projectile.Center + new Vector2(0, -15f) - Target.Center - Target.velocity; + targetToProj /= 30f; + Target.velocity += targetToProj; + Target.velocity *= 0.95f; + if (Collision.IsWorldPointSolid(Target.Top + new Vector2(0, -4)) || (Target.collideY && !Collision.IsWorldPointSolid(Target.Bottom + new Vector2(0, 2)))) + { + Projectile.velocity.Y *= 0; + } + if (Projectile.timeLeft == 1) + { + Projectile.friendly = true; + } + } + + public void GenerateBubbleBound() + { + BubbleBound = new List(); + float radius = BubbleScale; + for (int k = 0; k < 121; k++) + { + Vector2 bound = new Vector2(0, radius + GetRandomValueMove(k) * 3).RotatedBy(k / 120f * MathHelper.TwoPi); + BubbleBound.Add(bound); + } + } + + public float GetRandomValueMove(float index) + { + float value = 0; + for (int i = 0; i < 2; i++) + { + float timeValue = (float)Main.time / 24f * MathF.Pow(2, i) + Projectile.whoAmI; + timeValue = MathF.Cos(timeValue); + value += MathF.Sin(index / 60f * MathHelper.TwoPi * MathF.Pow(2, i) * 0.5f + timeValue * MathF.Sin(index / 40f * MathHelper.TwoPi) * MathF.Pow(2, i)) * MathF.Pow(2, -i); + } + return value; + } + + public bool CanTrap(NPC npc) + { + if (npc is null || !npc.active || npc.dontTakeDamage || npc.boss || npc.friendly || npc.knockBackResist == 0 || npc.type == NPCID.TargetDummy || npc.type == NPCID.WindyBalloon) + { + return false; + } + return true; + } + + public float CalculateTargetScale() + { + float scale = Math.Max(Target.width, Target.height); + return scale * 1.5f; + } + + public override void DrawBehind(int index, List behindNPCsAndTiles, List behindNPCs, List behindProjectiles, List overPlayers, List overWiresUI) + { + overPlayers.Add(index); + } + + public override bool PreDraw(ref Color lightColor) + { + GenerateBubbleBound(); + if (BubbleBound.Count <= 0) + { + return false; + } + List bars_dark = new List(); + List bars = new List(); + List innerBound = new List(); + List highlightBound = new List(); + float width = 10f; + + float timeValue = (float)Main.time / 150f + Projectile.whoAmI / 7f; + + for (int k = 0; k < BubbleBound.Count; k++) + { + Vector2 bound = BubbleBound[k]; + Vector2 drawWorldPos = bound + Projectile.Center; + Vector2 drawPos = drawWorldPos - Main.screenPosition; + Vector2 radDir = Vector2.Normalize(bound) * width; + Color drawColor = new Color(0.1f, 0.4f, 0.7f, 0); + drawColor = Lighting.GetColor(drawWorldPos.ToTileCoordinates(), drawColor); + drawColor.A = 0; + + bars_dark.Add(drawPos, Color.White * 0.5f, new Vector3(k / 30f, 0, 0)); + bars_dark.Add(drawPos - radDir, Color.White * 0.5f, new Vector3(k / 30f, 1, 0)); + + bars.Add(drawPos, drawColor, new Vector3(k / 30f, 0, 0)); + bars.Add(drawPos - radDir, drawColor, new Vector3(k / 30f, 1, 0)); + + Color drawRainbowColor = GetColorFromWavelength(580 + 200 * Math.Sin(k / 60f * MathHelper.TwoPi)); + drawRainbowColor = Color.Lerp(drawColor, drawRainbowColor, 0.9f); + Color drawRainbowColor2 = GetColorFromWavelength(580 + 200 * Math.Sin((k + 30) / 60f * MathHelper.TwoPi)); + drawRainbowColor2 = Color.Lerp(drawColor, drawRainbowColor2, 0.1f); + drawRainbowColor = Lighting.GetColor(drawWorldPos.ToTileCoordinates(), drawRainbowColor); + drawRainbowColor2 = Lighting.GetColor(drawWorldPos.ToTileCoordinates(), drawRainbowColor2); + drawRainbowColor.A = 0; + drawRainbowColor2.A = 0; + + innerBound.Add(drawPos, drawRainbowColor * 0.9f, new Vector3(k / 60f + timeValue, 0, 0)); + innerBound.Add(drawPos - radDir * 2, drawRainbowColor2 * 0.1f, new Vector3(k / 60f + timeValue, 1, 0)); + + Color highlightColor = Lighting.GetColor(drawWorldPos.ToTileCoordinates(), new Color(1f, 1f, 1f, 0)) * 2; + highlightColor.A = 0; + highlightBound.Add(drawPos, highlightColor, new Vector3(k / 40f - timeValue, 0.5f, 0)); + highlightBound.Add(drawPos - radDir * 2, highlightColor, new Vector3(k / 40f - timeValue, 0.7f, 0)); + } + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + if (bars.Count > 2) + { + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Wave_full_black.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_dark.ToArray(), 0, bars_dark.Count - 2); + + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Wave_full.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Noise_forceField_sparse.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, innerBound.ToArray(), 0, innerBound.Count - 2); + + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Textures_Star.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, highlightBound.ToArray(), 0, highlightBound.Count - 2); + } + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + + //Vector2 sunDir = GetSunPos() - new Vector2(Main.screenWidth, Main.screenHeight) * 0.5f; + //sunDir = sunDir.NormalizeSafe(); + Vector2 spotPos = Projectile.Center + new Vector2(-1, -1) * BubbleScale * 0.5f; + Texture2D highlightSpot = Commons.ModAsset.LightPoint2.Value; + Color highlightColor2 = Lighting.GetColor(spotPos.ToTileCoordinates(), new Color(1f, 1f, 1f, 0)) * 2; + highlightColor2.A = 0; + Main.EntitySpriteDraw(highlightSpot, spotPos - Main.screenPosition, null, highlightColor2, 0, highlightSpot.Size() * 0.5f, 1f, SpriteEffects.None, 0); + return false; + } + + public Vector2 GetSunPos() + { + float HalfMaxTime = Main.dayTime ? 27000 : 16200; + float bgTop = -Main.screenPosition.Y / (float)(Main.worldSurface * 16.0 - 600.0) * 200f; + float value = 1 - (float)Main.time / HalfMaxTime; + float StarX = (1 - value) * Main.screenWidth / 2f - 100 * value; + float t = value * value; + float StarY = bgTop + t * 250f + 180; + if (Main.LocalPlayer != null) + { + if (Main.LocalPlayer.gravDir == -1) + { + return new Vector2(StarX, Main.screenHeight - StarY); + } + } + + return new Vector2(StarX, StarY); + } + + public Color GetColorFromWavelength(double wavelength) + { + double r = 0, g = 0, b = 0; + + if (wavelength >= 380 && wavelength < 440) + { + r = -(wavelength - 440) / (440 - 380); + g = 0; + b = 1; + } + else if (wavelength >= 440 && wavelength < 490) + { + r = 0; + g = (wavelength - 440) / (490 - 440); + b = 1; + } + else if (wavelength >= 490 && wavelength < 510) + { + r = 0; + g = 1; + b = -(wavelength - 510) / (510 - 490); + } + else if (wavelength >= 510 && wavelength < 580) + { + r = (wavelength - 510) / (580 - 510); + g = 1; + b = 0; + } + else if (wavelength >= 580 && wavelength < 645) + { + r = 1; + g = -(wavelength - 645) / (645 - 580); + b = 0; + } + else if (wavelength >= 645 && wavelength <= 780) + { + r = 1; + g = 0; + b = 0; + } + else + { + r = 0; + g = 0; + b = 0; + } + return new Color((float)r, (float)g, (float)b, 0); + } + + public override void OnKill(int timeLeft) + { + for (int k = 0; k < BubbleScale; k++) + { + Vector2 startVel = new Vector2(0, MathF.Sqrt(Main.rand.NextFloat(1))).RotatedBy(Main.rand.NextFloat(MathHelper.TwoPi)) * BubbleScale; + var branch = new EmptyWaterStaff_BubbleBreak + { + velocity = startVel * 0.5f, + Active = true, + Visible = true, + position = Projectile.Center + startVel, + maxTime = Main.rand.Next(30, 40), + scale = Main.rand.Next(10, 16), + ai = new float[] { Main.rand.NextFloat(1f, 8f), Projectile.timeLeft }, + }; + Ins.VFXManager.Add(branch); + } + } + + public void DrawWarp(VFXBatch spriteBatch) + { + List bars_outer = new List(); + + List bars_inner = new List(); + float width = BubbleScale * 0.25f; + float timeValue = (float)Main.time / 450f; + float warpValue = BubbleScale / 40f * 0.02f; + for (int k = 0; k < BubbleBound.Count; k++) + { + Vector2 bound = BubbleBound[k] * 0.92f; + Vector2 drawPos = bound + Projectile.Center - Main.screenPosition; + Vector2 radDir = Vector2.Normalize(bound) * width; + Vector2 warpDir = bound.RotatedBy(MathHelper.Pi); + Color drawColor = new Color(0.5f, 0.5f, 0, 0); + Color drawColorInner = new Color(0.5f + warpDir.X / BubbleScale, 0.5f + warpDir.Y / BubbleScale, warpValue, 0); + bars_outer.Add(drawPos, drawColor, new Vector3(k / 40f + timeValue, 0, 0)); + bars_outer.Add(drawPos - radDir, drawColorInner, new Vector3(k / 40f + timeValue, 1, 0)); + + bars_inner.Add(drawPos - radDir, drawColorInner, new Vector3(k / 40f + timeValue, 1, 0)); + bars_inner.Add(drawPos - radDir * 2, drawColor, new Vector3(k / 40f + timeValue, 0, 0)); + } + spriteBatch.Draw(Commons.ModAsset.Noise_flame_2.Value, bars_outer, PrimitiveType.TriangleStrip); + spriteBatch.Draw(Commons.ModAsset.Noise_flame_2.Value, bars_inner, PrimitiveType.TriangleStrip); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloShield_A.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloShield_A.cs index 40e435f00..3ed747de3 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloShield_A.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloShield_A.cs @@ -50,7 +50,7 @@ public override void AI() timer -= 0.2f; } - if (timer == 0) + if (timer <= 0) { Projectile.Kill(); } @@ -58,8 +58,6 @@ public override void AI() Lighting.AddLight(Projectile.Center, new Vector3(0.375f, 0.75f, 0.375f) * timer / 157); } - - public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) { target.AddElementalDebuffBuildUp(Main.player[Projectile.owner], NecrosisDebuff.ID, Projectile.damage * 3); diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloShield_B.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloShield_B.cs index f5078882a..cd42d25f6 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloShield_B.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloShield_B.cs @@ -45,7 +45,7 @@ public override void AI() timer -= 0.2f; } - if (timer == 0) + if (timer <= 0) { Projectile.Kill(); } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloSpore.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloSpore.cs index 8a322400f..d9a3fb959 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloSpore.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloSpore.cs @@ -2,7 +2,9 @@ using Everglow.Commons.Graphics; using Everglow.Commons.Templates.Weapons; using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Bosses.KingJellyBall; using Terraria; +using static Terraria.ModLoader.BackupIO; namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Magic; @@ -31,6 +33,14 @@ public override void Behaviors() public override void OnKill(int timeLeft) { + foreach (Projectile p in Main.projectile) + { + if (p.type == ModContent.ProjectileType() && p.owner == Projectile.owner) + { + p.Kill(); + } + } + int tileX = ((int)Projectile.Center.X) / 16; int tileY = ((int)Projectile.Center.Y) / 16; do @@ -45,8 +55,8 @@ public override void OnKill(int timeLeft) { } - Vector2 pos = new Vector2(tileX * 16, tileY * 16 + 16); - Projectile.NewProjectileDirect(null, pos, Vector2.Zero, ModContent.ProjectileType(), 0, 0, Projectile.owner); + Vector2 pos = new Vector2(tileX * 16, tileY * 16); + Projectile.NewProjectileDirect(null, pos, Vector2.Zero, ModContent.ProjectileType(), Projectile.damage, 0, Projectile.owner); } public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloThorns.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloThorns.cs index 2b2b9f260..fce6efa78 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloThorns.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/GreenSungloThorns.cs @@ -1,4 +1,11 @@ +using Everglow.Commons.VFX.CommonVFXDusts; +using Everglow.Yggdrasil.Common.Elevator.Tiles; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using MathNet.Numerics.Distributions; +using Microsoft.Xna.Framework.Graphics.PackedVector; using Terraria.DataStructures; +using Terraria.GameContent.RGB; +using Terraria.Graphics.CameraModifiers; namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Magic; @@ -6,9 +13,9 @@ internal class GreenSungloThorns : ModProjectile { public override void SetDefaults() { - Projectile.width = 70; - Projectile.height = 78; - Projectile.friendly = false; + Projectile.width = 48; + Projectile.height = 144; + Projectile.friendly = true; Projectile.DamageType = DamageClass.Magic; Projectile.aiStyle = -1; Projectile.penetrate = -1; @@ -16,6 +23,9 @@ public override void SetDefaults() Projectile.hostile = false; Projectile.tileCollide = false; Projectile.ignoreWater = true; + Projectile.hide = true; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 30; } internal Vector2[] Position = new Vector2[900]; @@ -37,6 +47,11 @@ public override void OnSpawn(IEntitySource source) } } + public override void DrawBehind(int index, List behindNPCsAndTiles, List behindNPCs, List behindProjectiles, List overPlayers, List overWiresUI) + { + behindNPCsAndTiles.Add(index); + } + public override void AI() { Player player = Main.player[Projectile.owner]; @@ -45,7 +60,10 @@ public override void AI() Projectile.velocity *= 0; UpdateMoving(); - + if (t < 550) + { + t += 3.75f; + } if (Projectile.timeLeft <= 2) { for (int i = 0; i < 900; i++) @@ -199,7 +217,7 @@ public void DrawVine() var factor = j / 60f; var w = MathHelper.Lerp(1f, 0.05f, factor); Lighting.AddLight(OldPosition[i, j], colorLight * 0f * (1 - factor), colorLight * 0.3f * (1 - factor), 0); - Vector2 DrawPos = Projectile.Center + OldPosition[i, j] - StartPosition[i] + new Vector2(4) - Main.screenPosition; + Vector2 DrawPos = Projectile.Center + OldPosition[i, j] - StartPosition[i] + new Vector2(4, 48) - Main.screenPosition; var color = new Color(0.01f, 1f, 0.5f, 0f); if (Smaller[i]) { @@ -235,13 +253,81 @@ public void DrawVine() } } } + + private float t = 1f; + private float a = Main.rand.NextFloat(2.5f, 3.5f); + private float b = Main.rand.NextFloat(2.5f, 3.5f); + public void DrawThorn() { - Main.spriteBatch.End(); Main.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + float Width = 15f; + var thorn1 = new List(); + var thorn2 = new List(); + thorn1.Clear(); + thorn2.Clear(); + Main.NewText(t); + + for (float i = 0; i <= t; i++) + { + Vector2 pos = new Vector2(MathF.Cos(i * 0.01f * 2 - 3) * (MathF.Sqrt(i * 0.01f) - a) * 0.25f, -i * 0.01f) * 25; + Vector2 pos2 = new Vector2(MathF.Cos((i + 1) * 0.01f * 2 - 3) * (MathF.Sqrt((i + 1) * 0.01f) - a) * 0.25f, -i * 0.01f - 1) * 25; + Vector2 normal = MathUtils.NormalizeSafe(pos - pos2).RotatedBy(MathF.PI * 0.5f); + float y = (float)(-i / 320f); + float process = MathF.Min(1, (t - i) / t * 5f); + Width = 15f * process; + thorn1.Add(new Vertex2D(Projectile.Center + pos + normal * Width - Main.screenPosition + Vector2.UnitY * 48, Color.Green, new Vector3(0, y % 1 + 1, Width))); + thorn1.Add(new Vertex2D(Projectile.Center + pos - normal * Width - Main.screenPosition + Vector2.UnitY * 48, Color.Green, new Vector3(1, y % 1 + 1, Width))); + } + + Main.graphics.GraphicsDevice.Textures[0] = ModAsset.GreenSungloThorns.Value; + + if (thorn1.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, thorn1.ToArray(), 0, thorn1.Count - 2); + } + for (int i = 0; i <= t; i++) + { + Vector2 pos = new Vector2(-MathF.Cos(i * 0.01f * 2 - 3) * (MathF.Sqrt(i * 0.01f) - b) * 0.25f, -i * 0.01f) * 25; + Vector2 pos2 = new Vector2(-MathF.Cos((i + 1) * 0.01f * 2 - 3) * (MathF.Sqrt((i + 1) * 0.01f) - b) * 0.25f, -i * 0.01f - 1) * 25; + Vector2 normal = MathUtils.NormalizeSafe(pos - pos2).RotatedBy(MathF.PI * 0.5f); + float y = (float)(-i / 320f); + float process = MathF.Min(1, (t - i) / t * 5f); + Width = 15f * process; + thorn2.Add(new Vertex2D(Projectile.Center + pos + normal * Width - Main.screenPosition + Vector2.UnitY * 48, Color.White, new Vector3(0, y % 1 + 1, Width))); + thorn2.Add(new Vertex2D(Projectile.Center + pos - normal * Width - Main.screenPosition + Vector2.UnitY * 48, Color.White, new Vector3(1, y % 1 + 1, Width))); + } + + Main.graphics.GraphicsDevice.Textures[0] = ModAsset.GreenSungloThorns.Value; + + if (thorn2.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, thorn2.ToArray(), 0, thorn2.Count - 2); + } + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + } + public override void OnKill(int timeLeft) + { + for (int g = 0; g < 100; g++) + { + Vector2 newVelocity = new Vector2(0, Main.rand.NextFloat(2f, 15f)).RotatedByRandom(MathHelper.TwoPi); + var spark = new JungleSporeDust + { + velocity = newVelocity, + Active = true, + Visible = true, + position = Projectile.Center + new Vector2(Main.rand.NextFloat(-6f, 6f), 0).RotatedByRandom(6.283) + newVelocity, + maxTime = Main.rand.Next(137, 245), + scale = Main.rand.NextFloat(12f, Main.rand.NextFloat(8f, 16f)), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(0.0f, Main.rand.NextFloat(0.5f, 1.0f)), Main.rand.NextFloat(-0.03f, 0.03f) }, + }; + Ins.VFXManager.Add(spark); + } } } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicSpellBook_proj.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicSpellBook_proj.cs new file mode 100644 index 000000000..54f8aa73d --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicSpellBook_proj.cs @@ -0,0 +1,371 @@ +using Everglow.Commons.DataStructures; +using Everglow.Yggdrasil.KelpCurtain.Buffs; +using Everglow.Yggdrasil.KelpCurtain.Items.Weapons; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Magic; + +public class RedAlgaeMagicSpellBook_proj : ModProjectile +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicProjectiles; + + public float Range = 0; + + public float MaxRange = 320; + + public bool Released = false; + + public List SurfaceTiles = new List(); + + public override void SetDefaults() + { + Projectile.width = 28; + Projectile.height = 28; + Projectile.friendly = true; + Projectile.tileCollide = false; + Projectile.hostile = false; + Projectile.penetrate = -1; + Projectile.timeLeft = 36000; + Projectile.DamageType = DamageClass.Magic; + Projectile.hide = true; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 120; + } + + public override void OnSpawn(IEntitySource source) => base.OnSpawn(source); + + public override void AI() + { + Player player = Main.player[Projectile.owner]; + Vector2 toMouse = Main.MouseWorld - Projectile.Center; + if (!Released) + { + Vector2 toPlayer = player.Center + toMouse.NormalizeSafe() * 30f - Projectile.Center; + if (toPlayer.Length() > 50f) + { + Projectile.velocity = toPlayer.NormalizeSafe() * 10f; + } + else + { + Projectile.velocity = toPlayer / 5f; + } + if (player.controlUseItem) + { + float maxFlucRange = MaxRange + 20 * MathF.Sin((float)Main.time * 0.08f); + if (Range < maxFlucRange) + { + Range = Range * 0.99f + maxFlucRange * 0.01f; + } + else + { + Projectile.velocity = toMouse.NormalizeSafe() * 12f; + Released = true; + } + } + if ((Projectile.Center - player.Center).Length() > 1000 || player.HeldItem.type != ModContent.ItemType()) + { + Released = true; + } + } + else + { + Projectile.velocity *= 0.995f; + Range -= 0.45f; + if (Range <= 0) + { + Projectile.Kill(); + } + } + + int rangeInt = (int)Range / 16 + 1; + Point centerPoint = Projectile.Center.ToTileCoordinates(); + SurfaceTiles = new List(); + for (int x = -rangeInt; x <= rangeInt; x++) + { + for (int y = -rangeInt; y <= rangeInt; y++) + { + if (new Vector2(x, y).Length() < rangeInt) + { + Vector2 checkPos = centerPoint.ToWorldCoordinates() + new Vector2(x, y) * 16; + if (Collision.IsWorldPointSolid(checkPos)) + { + for (int r = 0; r < 4; r++) + { + if (!Collision.IsWorldPointSolid(checkPos + new Vector2(0, 16).RotatedBy(r * MathHelper.PiOver2))) + { + SurfaceTiles.Add(new Point(x, y) + centerPoint); + break; + } + } + } + } + } + } + if (Main.rand.NextBool(2)) + { + Vector2 pos = new Vector2(0, Range * 1.05f).RotatedByRandom(MathHelper.TwoPi); + var redAlgaeDust = new RedAlgaeDust(); + redAlgaeDust.Position = Projectile.Center + pos; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = pos.NormalizeSafe().RotatedBy(-MathHelper.PiOver2) * 2f; + redAlgaeDust.ai = new float[] { -0.05f }; + redAlgaeDust.MaxScale = Main.rand.NextFloat(0.47f, 0.6f); + redAlgaeDust.MaxTime = 70; + redAlgaeDust.Frame = Main.rand.Next(4); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + + for (int i = 0; i <= Range; i += 40) + { + var redAlgaeDust = new RedAlgae_Small_Dust_SpinAroundEntity(); + redAlgaeDust.ParentEntity = Projectile; + redAlgaeDust.Position = Projectile.Center; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = Vector2.zeroVector; + redAlgaeDust.ai = new float[] { Main.rand.NextFloat(Range / 8f, Range / 2f), Main.rand.NextFloat(MathHelper.TwoPi) }; + redAlgaeDust.MaxTime = 30; + redAlgaeDust.MaxScale = Main.rand.NextFloat(2f); + redAlgaeDust.Frame = Main.rand.Next(10); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + if (Main.rand.NextBool(2)) + { + var redAlgaeDust = new RedAlgae_Spark_SpinAroundEntity(); + redAlgaeDust.ParentEntity = Projectile; + redAlgaeDust.Position = Projectile.Center; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = Vector2.zeroVector; + redAlgaeDust.ai = new float[] { Main.rand.NextFloat(Range * 0.07f, Range * 0.27f), Main.rand.NextFloat(MathHelper.TwoPi) }; + redAlgaeDust.MaxTime = 30; + redAlgaeDust.MaxScale = Main.rand.NextFloat(3f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + foreach (var pos in SurfaceTiles) + { + for (int r = 0; r < 4; r++) + { + Vector2 checkPos = pos.ToWorldCoordinates() + new Vector2(16, 0).RotatedBy(r * MathHelper.PiOver2); + if (!Collision.IsWorldPointSolid(checkPos)) + { + checkPos += new Vector2(12, 0).RotatedBy(r * MathHelper.PiOver2) - new Vector2(12); + Rectangle rectangle = new Rectangle((int)checkPos.X, (int)checkPos.Y, 24, 24); + if (rectangle.Intersects(targetHitbox)) + { + return true; + } + } + } + } + return base.Colliding(projHitbox, targetHitbox); + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + int type = ModContent.BuffType(); + if (!target.HasBuff(type)) + { + target.AddBuff(type, 900); + } + } + + public override void DrawBehind(int index, List behindNPCsAndTiles, List behindNPCs, List behindProjectiles, List overPlayers, List overWiresUI) + { + overPlayers.Add(index); + base.DrawBehind(index, behindNPCsAndTiles, behindNPCs, behindProjectiles, overPlayers, overWiresUI); + } + + public override bool PreDraw(ref Color lightColor) + { + float fade = 1f; + if (Released) + { + if (Range < 50) + { + fade = Range / 50f; + } + } + Texture2D spot = Commons.ModAsset.LightPoint2.Value; + Texture2D spot_dark = Commons.ModAsset.LightPoint2_black.Value; + Texture2D star = Commons.ModAsset.StarSlash.Value; + Vector2 drawPos = Projectile.Center - Main.screenPosition; + Main.EntitySpriteDraw(spot_dark, drawPos, null, Color.White, 0, spot_dark.Size() * 0.5f, 1f * fade, SpriteEffects.None); + Main.EntitySpriteDraw(spot, drawPos, null, new Color(1f, 0.9f, 0.8f, 0), 0, spot.Size() * 0.5f, 1f * fade, SpriteEffects.None); + float flucTime = MathF.Sin(Main.GlobalTimeWrappedHourly * 2.5f) * 0.5f + 1f; + Main.EntitySpriteDraw(star, drawPos, null, new Color(1f, 0.9f, 0.8f, 0) * 0.25f, 0, star.Size() * 0.5f, new Vector2(1f, 0.5f) * fade, SpriteEffects.None); + Main.EntitySpriteDraw(star, drawPos, null, new Color(1f, 0.9f, 0.8f, 0) * 0.25f, MathHelper.PiOver2, star.Size() * 0.5f, new Vector2(1f, 1f * flucTime) * fade, SpriteEffects.None); + Lighting.AddLight(Projectile.Center, new Vector3(1f, 0.9f, 0.8f)); + + List bars = new List(); + List bars_dark = new List(); + float rate = 6f; + float timeValue = Main.GlobalTimeWrappedHourly * 0.5f; + for (int h = 0; h <= 60; h++) + { + float value = h / 60f; + float coordX = value * rate + timeValue; + Vector2 outerRing = new Vector2(Range + 70, 0).RotatedBy(value * MathHelper.TwoPi); + Vector2 innerRing = new Vector2(Range, 0).RotatedBy(value * MathHelper.TwoPi); + if (h > 0) + { + Lighting.AddLight(drawPos + Main.screenPosition + (innerRing + outerRing) * 0.5f + Projectile.velocity * 3, new Vector3(0.4f, 0.05f, 0.3f) * 2); + } + bars_dark.Add(drawPos + outerRing, Color.White * fade, new Vector3(coordX, 0, 0)); + bars_dark.Add(drawPos + innerRing, Color.White * fade, new Vector3(coordX, 1, 0)); + + bars.Add(drawPos + outerRing, new Color(1f, 0.2f, 0.4f, 0) * fade, new Vector3(coordX, 0, 0)); + bars.Add(drawPos + innerRing, new Color(0.7f, 0.1f, 0.3f, 0) * fade, new Vector3(coordX, 1, 0)); + } + + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + + if (bars_dark.Count > 0 && bars.Count > 0) + { + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Trail_16_black.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_dark.ToArray(), 0, bars_dark.Count - 2); + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_dark.ToArray(), 0, bars_dark.Count - 2); + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Trail_16.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + } + + List algae = new List(); + foreach (var pos in SurfaceTiles) + { + for (int r = 0; r < 4; r++) + { + if (!Collision.IsWorldPointSolid(pos.ToWorldCoordinates() + new Vector2(16, 0).RotatedBy(r * MathHelper.PiOver2))) + { + AddDrawPiece(algae, pos, r * MathHelper.PiOver2); + } + } + } + + if (algae.Count > 0) + { + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + var projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1); + var model = Matrix.CreateTranslation(new Vector3(-Main.screenPosition, 0)) * Main.GameViewMatrix.TransformationMatrix; + Effect algaeEffect = ModAsset.RedAlgaeMagicSpellBook_proj_algaeEffect.Value; + algaeEffect.Parameters["uTransform"].SetValue(model * projection); + algaeEffect.CurrentTechnique.Passes[0].Apply(); + Main.graphics.GraphicsDevice.Textures[0] = ModAsset.RedAlgae_EffectTexture.Value; + Main.graphics.GraphicsDevice.Textures[1] = ModAsset.RedAlgaeMagicSpellBook_proj_heatmap.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, algae.ToArray(), 0, algae.Count / 3); + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + } + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + return false; + } + + public void AddDrawPiece(List drawList, Point tilePos, float rotation) + { + Vector2 platformOffset = Vector2.zeroVector; + var tile = TileUtils.SafeGetTile(tilePos); + float frameCount = 8; + int style = TileUtils.GetFixedRandomNumber(tilePos.X, tilePos.Y + (int)(rotation * 12), (int)frameCount); + if (MathF.Abs(rotation - MathHelper.PiOver2) < 0.01f) + { + if (tile.HasTile && TileID.Sets.Platforms[tile.TileType]) + { + platformOffset = new Vector2(0, -8); + } + } + if (MathF.Abs(rotation - MathHelper.PiOver2 * 3) < 0.01f) + { + if (tile.HasTile && tile.IsHalfBlock) + { + platformOffset = new Vector2(0, 8); + } + } + if (!tile.HasTile) + { + style = 1; + } + Vector2 drawPos = tilePos.ToWorldCoordinates() + new Vector2(8, 0).RotatedBy(rotation) + platformOffset; + Vector2 pos0 = drawPos + new Vector2(0, -24).RotatedBy(rotation); + Vector2 pos1 = drawPos + new Vector2(54, -24).RotatedBy(rotation); + Vector2 pos2 = drawPos + new Vector2(54, 24).RotatedBy(rotation); + Vector2 pos3 = drawPos + new Vector2(0, 24).RotatedBy(rotation); + drawList.Add(pos0, Lighting.GetColor(pos0.ToTileCoordinates()), new Vector3(style / frameCount, 1, GetAlgaeValueDistance(pos0))); + drawList.Add(pos1, Lighting.GetColor(pos1.ToTileCoordinates()), new Vector3(style / frameCount, 0, GetAlgaeValueDistance(pos1))); + drawList.Add(pos3, Lighting.GetColor(pos3.ToTileCoordinates()), new Vector3((style + 1f) / frameCount, 1, GetAlgaeValueDistance(pos3))); + + drawList.Add(pos3, Lighting.GetColor(pos3.ToTileCoordinates()), new Vector3((style + 1f) / frameCount, 1, GetAlgaeValueDistance(pos3))); + drawList.Add(pos1, Lighting.GetColor(pos1.ToTileCoordinates()), new Vector3(style / frameCount, 0, GetAlgaeValueDistance(pos1))); + drawList.Add(pos2, Lighting.GetColor(pos2.ToTileCoordinates()), new Vector3((style + 1f) / frameCount, 0, GetAlgaeValueDistance(pos2))); + + Vector2 center = (pos0 + pos3) * 0.5f; + Lighting.AddLight(center, new Vector3(0.7f, 0.1f, 0.6f) * GetAlgaeValueDistance(center)); + if (!Main.gamePaused && Main.rand.NextBool(240)) + { + Vector2 pos = new Vector2(0, 20).RotatedByRandom(MathHelper.TwoPi); + var redAlgaeDust = new RedAlgae_Small_Dust(); + redAlgaeDust.Position = drawPos; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = new Vector2(1, 0).RotatedBy(rotation + Main.rand.NextFloat(-1f, 1f)); + redAlgaeDust.ai = new float[] { 0.99f }; + redAlgaeDust.MaxTime = 240; + redAlgaeDust.Scale = 0.5f; + redAlgaeDust.Frame = Main.rand.Next(10); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + } + + public float GetAlgaeValueDistance(Vector2 pos) + { + return Math.Min(1, ((Range * 1.02f - (pos - Projectile.Center).Length()) / MaxRange) * 5); + } + + public override void OnKill(int timeLeft) + { + for (int k = 0; k < 20; k++) + { + var redAlgaeDust = new RedAlgae_Small_Dust(); + redAlgaeDust.Position = Projectile.Center; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = new Vector2(0, Main.rand.NextFloat(12f)).RotatedByRandom(MathHelper.TwoPi); + redAlgaeDust.ai = new float[] { 0.99f }; + redAlgaeDust.MaxTime = 60; + redAlgaeDust.Scale = Main.rand.NextFloat(1f, 4f); + redAlgaeDust.Frame = Main.rand.Next(10); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + for (int k = 0; k < 20; k++) + { + var redAlgaeDust = new RedAlgae_Spark(); + redAlgaeDust.Position = Projectile.Center; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = new Vector2(0, Main.rand.NextFloat(12f)).RotatedByRandom(MathHelper.TwoPi); + redAlgaeDust.ai = new float[] { 0.99f }; + redAlgaeDust.MaxTime = 60; + redAlgaeDust.Scale = Main.rand.NextFloat(1f, 5f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + base.OnKill(timeLeft); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicSpellBook_proj.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicSpellBook_proj.png new file mode 100644 index 000000000..83ae67644 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicSpellBook_proj.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicSpellBook_proj_algaeEffect.fx b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicSpellBook_proj_algaeEffect.fx new file mode 100644 index 000000000..fd7d0d83a --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicSpellBook_proj_algaeEffect.fx @@ -0,0 +1,45 @@ +sampler2D uImage0 : register(s0); +sampler2D uImage1 : register(s1); +float4x4 uTransform; +struct VSInput +{ + float2 Pos : POSITION0; + float4 Color : COLOR0; + float3 Texcoord : TEXCOORD0; +}; + +struct PSInput +{ + float4 Pos : SV_POSITION; + float4 Color : COLOR0; + float3 Texcoord : TEXCOORD0; +}; + +PSInput VertexShaderFunction(VSInput input) +{ + PSInput output; + output.Color = input.Color; + output.Texcoord = input.Texcoord; + output.Pos = mul(float4(input.Pos, 0, 1), uTransform); + return output; +} + +float4 PixelShaderFunction(PSInput input) : COLOR0 +{ + float4 color0 = tex2D(uImage0, input.Texcoord.xy); + if (color0.r > 0 && color0.r < input.Texcoord.z) + { + float4 color1 = tex2D(uImage1, float2(color0.r / input.Texcoord.z, 0.5)); + return color1 * input.Color; + } + return float4(0, 0, 0, 0); +} + +technique Technique1 +{ + pass Test + { + VertexShader = compile vs_3_0 VertexShaderFunction(); + PixelShader = compile ps_3_0 PixelShaderFunction(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicSpellBook_proj_heatmap.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicSpellBook_proj_heatmap.png new file mode 100644 index 000000000..c6f27d330 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicSpellBook_proj_heatmap.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicStaff_Proj.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicStaff_Proj.cs new file mode 100644 index 000000000..2077770f7 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicStaff_Proj.cs @@ -0,0 +1,139 @@ +using Everglow.Yggdrasil.KelpCurtain.Buffs; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Terraria; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Magic; + +public class RedAlgaeMagicStaff_Proj : ModProjectile +{ + public float Timer = 0; + + public override void SetDefaults() + { + Projectile.width = 20; + Projectile.height = 20; + Projectile.aiStyle = -1; + Projectile.tileCollide = true; + Projectile.friendly = true; + Projectile.hostile = false; + Projectile.penetrate = 1; + Projectile.DamageType = DamageClass.Magic; + } + + public override void AI() + { + Timer++; + Projectile.rotation = Projectile.velocity.ToRotation(); + Projectile.velocity = Projectile.velocity.RotatedBy(MathF.Sin(Timer * 0.1f + Projectile.ai[0]) * 0.01f); + for (int k = 0; k < 2; k++) + { + var redAlgaeDust = new RedAlgae_Small_Dust(); + redAlgaeDust.Position = Projectile.Center - Projectile.velocity * k * 0.5f; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = Vector2.zeroVector; + redAlgaeDust.ai = new float[] { 0 }; + redAlgaeDust.MaxTime = 60; + redAlgaeDust.Scale = Main.rand.NextFloat(1.2f, 2.4f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + if (Timer % 8 == 4) + { + var redAlgaeDust = new RedAlgaeDust(); + redAlgaeDust.Position = Projectile.Center - Projectile.velocity.NormalizeSafe().RotatedBy(MathHelper.PiOver2) * 12; + redAlgaeDust.Rotation = Projectile.rotation + MathHelper.PiOver4 * 3; + redAlgaeDust.Velocity = Vector2.zeroVector; + redAlgaeDust.ai = new float[] { 0, 0 }; + redAlgaeDust.MaxScale = Main.rand.NextFloat(0.47f, 0.6f); + redAlgaeDust.MaxTime = 50; + redAlgaeDust.Frame = Main.rand.Next(4); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + if (Timer % 8 == 0) + { + var redAlgaeDust = new RedAlgaeDust(); + redAlgaeDust.Position = Projectile.Center + Projectile.velocity.NormalizeSafe().RotatedBy(MathHelper.PiOver2) * 12; + redAlgaeDust.Rotation = Projectile.rotation - MathHelper.PiOver4; + redAlgaeDust.Velocity = Vector2.zeroVector; + redAlgaeDust.ai = new float[] { 0, 0 }; + redAlgaeDust.MaxScale = Main.rand.NextFloat(0.47f, 0.6f); + redAlgaeDust.MaxTime = 50; + redAlgaeDust.Frame = Main.rand.Next(4); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + Lighting.AddLight(Projectile.Center, new Vector3(1f, 0.9f, 0.8f) * 0.5f); + + Vector2 closestTargetPos = new Vector2(-10000); + foreach (var npc in Main.npc) + { + if (npc is not null && npc.active) + { + if (!npc.friendly && !npc.dontTakeDamage && npc.CanBeChasedBy(Projectile)) + { + Vector2 toTargetCheck = npc.Center - Projectile.Center; + if (toTargetCheck.Length() < (closestTargetPos - Projectile.Center).Length()) + { + closestTargetPos = npc.Center; + } + } + } + } + Vector2 toTarget = closestTargetPos - Projectile.Center - Projectile.velocity; + float distance = toTarget.Length(); + if (distance < 600) + { + float value = distance / 600f; + value = Math.Clamp(value, 0.1f, 0.95f); + Projectile.velocity = Projectile.velocity * value + toTarget.NormalizeSafe() * 12 * (1 - value); + Projectile.velocity = Projectile.velocity.NormalizeSafe() * 12f; + } + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + int type = ModContent.BuffType(); + if (!target.HasBuff(type)) + { + target.AddBuff(type, 900); + } + } + + public override bool PreDraw(ref Color lightColor) + { + Texture2D texture = ModContent.Request(Texture).Value; + Main.EntitySpriteDraw(texture, Projectile.Center - Main.screenPosition, null, new Color(1f, 1f, 1f, 1f), Projectile.rotation, texture.Size() * 0.5f, 1, SpriteEffects.None); + return false; + } + + public override void OnKill(int timeLeft) + { + if (timeLeft != 0) + { + var star = new RedAlgaeHitStar(); + star.Position = Projectile.Center; + star.MaxTime = 10; + star.Scale = 1.2f; + star.Visible = true; + star.Active = true; + Ins.VFXManager.Add(star); + for (int k = 0; k < 12; k++) + { + var redAlgaeDust = new RedAlgae_Spark(); + redAlgaeDust.Position = Projectile.Center; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = new Vector2(0, Main.rand.NextFloat(6f)).RotatedByRandom(MathHelper.TwoPi); + redAlgaeDust.ai = new float[] { 0.99f }; + redAlgaeDust.MaxTime = 30; + redAlgaeDust.Scale = Main.rand.NextFloat(1f, 2f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicStaff_Proj.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicStaff_Proj.png new file mode 100644 index 000000000..0e82b3c65 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgaeMagicStaff_Proj.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgae_EffectTexture.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgae_EffectTexture.png new file mode 100644 index 000000000..2c0d65856 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgae_EffectTexture.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgae_EffectTexture_GaussBlur.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgae_EffectTexture_GaussBlur.png new file mode 100644 index 000000000..2f49e7919 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Magic/RedAlgae_EffectTexture_GaussBlur.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/BladeOfGreenMoss_Proj .cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/BladeOfGreenMoss_Proj .cs index e58fd7eee..8be390141 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/BladeOfGreenMoss_Proj .cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/BladeOfGreenMoss_Proj .cs @@ -1,8 +1,5 @@ -using System.Threading; -using Everglow.Commons.DataStructures; using Everglow.Yggdrasil.KelpCurtain.Buffs; using Everglow.Yggdrasil.KelpCurtain.Dusts; -using Spine; using Terraria.Audio; namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Melee; @@ -19,10 +16,12 @@ public override void SetDef() canLongLeftClick = true; maxClickTimer = 240; } + public override string TrailShapeTex() { return Commons.ModAsset.Melee_Mod; } + public override string TrailColorTex() { return ModAsset.BladeOfGreenMoss_Color_Mod; @@ -32,10 +31,12 @@ public override float TrailAlpha(float factor) { return base.TrailAlpha(factor) * 2f; } + public override BlendState TrailBlendState() { return BlendState.AlphaBlend; } + public override void DrawSelf(SpriteBatch spriteBatch, Color lightColor, Vector4 diagonal = default, Vector2 drawScale = default, Texture2D glowTexture = null) { glowTexture = ModAsset.BladeOfGreenMoss_glow.Value; @@ -72,7 +73,6 @@ public override bool PreDraw(ref Color lightColor) return false; } - public override void Attack() { Player player = Main.player[Projectile.owner]; @@ -80,7 +80,6 @@ public override void Attack() Tplayer.HideLeg = true; if (Main.myPlayer == Projectile.owner && Main.mouseRight && Main.mouseRightRelease) { - } useSlash = true; @@ -92,12 +91,16 @@ public override void Attack() if (player.direction == -1) { if (AddHeadRotation >= 0.57f && AddHeadRotation < 2) + { AddHeadRotation = 0.57f; + } } else { if (AddHeadRotation <= -0.57f) + { AddHeadRotation = -0.57f; + } } } else @@ -105,18 +108,21 @@ public override void Attack() if (player.direction == -1) { if (AddHeadRotation >= 2 && AddHeadRotation < 5.71f) + { AddHeadRotation = 5.71f; + } } else { if (AddHeadRotation >= 0.57f) + { AddHeadRotation = 0.57f; + } } } if (currantAttackType <= 2) { - if (timer < 30) { Projectile.ai[0] = GetAngToMouse(); @@ -141,7 +147,9 @@ public override void Attack() mainAxisDirection = Vector2Elipse(100, Projectile.rotation, -0.75f, Projectile.ai[0]); } if (timer > 50) + { NextAttackType(); + } else if (timer > 1) { float BodyRotation = (float)Math.Sin((timer - 10) / 30d * Math.PI) * 0.2f * player.direction * player.gravDir; @@ -197,7 +205,6 @@ public override void Attack() Projectile p = Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), pos, v, type, Projectile.damage / 4, Projectile.knockBack * 0.25f, Projectile.owner); p.timeLeft = (int)(p.timeLeft * 1.5f); } - } if (currantAttackType == 4) { @@ -215,7 +222,10 @@ public override void Attack() } if (timer == 65) + { AttSound(new SoundStyle(Commons.ModAsset.TrueMeleePowerSwing_Mod)); + } + if (timer > 60) { canHit = true; @@ -228,7 +238,6 @@ public override void Attack() } BodyRotation = (float)Math.Sin((timer - 114.514) / 18d * Math.PI) * 0.7f * player.direction * player.gravDir; - } else { @@ -256,6 +265,7 @@ public override void Attack() } } } + public override void DrawTrail(Color color) { base.DrawTrail(color); @@ -270,7 +280,10 @@ public override void DrawTrail(Color color) int length = SmoothTrail.Count; if (length <= 3) + { return; + } + Vector2[] trail = SmoothTrail.ToArray(); var bars = new List(); @@ -306,8 +319,8 @@ public override void DrawTrail(Color color) Main.spriteBatch.End(); Main.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); - } + public override void End() { Player player = Main.player[Projectile.owner]; @@ -321,9 +334,9 @@ public override void End() Projectile.Kill(); player.GetModPlayer().isUsingMeleeProj = false; } + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { - Player player = Main.player[Projectile.owner]; player.AddBuff(ModContent.BuffType(), 180); if (Main.rand.NextBool(8)) @@ -333,6 +346,7 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) base.OnHitNPC(target, hit, damageDone); } + public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) { @@ -341,9 +355,6 @@ public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) modifiers.FinalDamage *= 2f; target.AddBuff(BuffID.Poisoned, 420); - } - } } - diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/Barnacle_Color.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/Barnacle_Color.png new file mode 100644 index 000000000..3b3bb25da Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/Barnacle_Color.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/Barnacle_Color_Trail.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/Barnacle_Color_Trail.png new file mode 100644 index 000000000..cd3accaf4 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/Barnacle_Color_Trail.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/Barnacle_Color_Trail2.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/Barnacle_Color_Trail2.png new file mode 100644 index 000000000..07e7834fe Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/Barnacle_Color_Trail2.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_ShootShuttle.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_ShootShuttle.cs new file mode 100644 index 000000000..34b9036b3 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_ShootShuttle.cs @@ -0,0 +1,137 @@ +using Everglow.Yggdrasil.KelpCurtain.VFXs; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Melee.EvilHalbertBarnacle; + +public class EvilHalbertBarnacle_ShootShuttle : ModProjectile +{ + public int Timer = 0; + + public int State = 0; + + public Vector2 Offset = Vector2.zeroVector; + + public Vector2 OffsetVel = Vector2.zeroVector; + + public override string Texture => ModAsset.EvilHalbertBarnacle_proj_Mod; + + public override void SetDefaults() + { + Projectile.width = 30; + Projectile.height = 30; + Projectile.aiStyle = -1; + Projectile.penetrate = -1; + Projectile.tileCollide = false; + Projectile.timeLeft = 120000; + } + + public override void AI() + { + Player player = Main.player[Projectile.owner]; + if (player.ownedProjectileCounts[ModContent.ProjectileType()] <= 0) + { + State = 0; + } + else + { + State = 1; + } + Timer++; + if (Projectile.timeLeft > 60) + { + player.ListenMouseWorld(); + Projectile.velocity = (player.MouseWorld() - player.MountedCenter).NormalizeSafe(); + Projectile.rotation = Projectile.velocity.ToRotation() + MathHelper.PiOver4 * 3; + if (Projectile.velocity.X > 0) + { + Projectile.spriteDirection = 1; + } + else + { + Projectile.spriteDirection = -1; + Projectile.rotation -= MathHelper.PiOver2; + } + player.direction = Projectile.spriteDirection; + Projectile.velocity = Vector2.Normalize(Projectile.velocity); + + Projectile.Center = player.MountedCenter + Projectile.velocity * 120; + if (Timer > 3 && Main.mouseRightRelease) + { + Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center - Projectile.velocity * 85f, Projectile.velocity * 75, ModContent.ProjectileType(), Projectile.damage, 2.4f, Projectile.owner); + Projectile.timeLeft = 20; + OffsetVel = -Projectile.velocity.RotatedByRandom(0.3f) * 35; + for (int i = 0; i < 18; ++i) + { + Vector2 vel = Projectile.velocity.RotateRandom(0.6f) * Main.rand.NextFloat(0.35f, 1.15f) * 45f; + var dust = new BarnacleTissueDust + { + velocity = vel, + Active = true, + Visible = true, + position = Projectile.Center + Projectile.velocity * 5, + maxTime = Main.rand.Next(60, 90), + scale = Main.rand.NextFloat(8f, 12f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(6f, 8f), Main.rand.NextFloat(1f) }, + }; + Ins.VFXManager.Add(dust); + } + for (int i = 0; i < 6; ++i) + { + Vector2 vel = Projectile.velocity.RotateRandom(0.6f) * Main.rand.NextFloat(0.35f, 1.15f) * 45f; + var dust = new BarnacleTissueDust + { + velocity = vel, + Active = true, + Visible = true, + position = Projectile.Center + Projectile.velocity * 5, + maxTime = Main.rand.Next(60, 90), + scale = Main.rand.NextFloat(36f, 48f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(6f, 8f), Main.rand.NextFloat(1f) }, + }; + Ins.VFXManager.Add(dust); + } + } + } + else + { + Offset += OffsetVel; + OffsetVel += -Offset * 0.3f; + OffsetVel *= 0.7f; + player.ListenMouseWorld(); + Projectile.rotation = (Projectile.Center - player.MountedCenter).ToRotation() + MathHelper.PiOver4 * 3; + if (Projectile.velocity.X > 0) + { + Projectile.spriteDirection = 1; + } + else + { + Projectile.spriteDirection = -1; + Projectile.rotation -= MathHelper.PiOver2; + } + player.direction = Projectile.spriteDirection; + player.direction = Projectile.spriteDirection; + Projectile.Center = player.MountedCenter + Projectile.velocity * 120 + Offset; + } + player.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, Projectile.rotation + MathHelper.PiOver4 * 3); + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + return false; + } + + public Vector2 oldPos; + + public override bool PreDraw(ref Color lightColor) + { + Texture2D tex = ModContent.Request(Texture).Value; + if (State == 1) + { + tex = ModAsset.EvilHalbertBarnacle_proj_released.Value; + } + Vector2 velNor2 = Projectile.velocity.NormalizeSafe() * tex.Width / MathF.Sqrt(2f); + Main.EntitySpriteDraw(tex, Projectile.Center - Main.screenPosition - velNor2, null, lightColor, Projectile.rotation, tex.Size() * 0.5f, Projectile.scale, Projectile.spriteDirection == 1 ? SpriteEffects.FlipHorizontally : SpriteEffects.None, 0); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj.cs new file mode 100644 index 000000000..0dc1bf3a9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj.cs @@ -0,0 +1,452 @@ +using Everglow.Commons.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Melee.EvilHalbertBarnacle; + +public class EvilHalbertBarnacle_proj : MeleeProj +{ + public float Omega; + + public bool NoTrail = false; + + public bool NoWeapon = false; + + public float RotationTowardScreen = 0; + + public Queue DrawTrailFade = new Queue(); + + public float CurrentFade = 1; + + public Vector2 TargetVel; + + public int State = 0; + + public override void SetDef() + { + maxAttackType = 5; + maxSlashTrailLength = 20; + longHandle = true; + autoEnd = true; + canLongLeftClick = true; + Omega = 0; + } + + public override string TrailShapeTex() + { + return Commons.ModAsset.Melee_Mod; + } + + public override string TrailColorTex() + { + return ModAsset.Barnacle_Color_Mod; + } + + public override void AI() + { + base.AI(); + Player player = Main.player[Projectile.owner]; + if (player.ownedProjectileCounts[ModContent.ProjectileType()] <= 0) + { + State = 0; + } + else + { + State = 1; + } + if (!NoTrail) + { + CurrentFade = CurrentFade * 0.5f + 0.5f; + } + else + { + CurrentFade *= 0.5f; + } + DrawTrailFade.Enqueue(CurrentFade); + if (DrawTrailFade.Count > maxSlashTrailLength) + { + DrawTrailFade.Dequeue(); + } + } + + public override float TrailAlpha(float factor) + { + return base.TrailAlpha(factor) * 1.3f; + } + + public override BlendState TrailBlendState() + { + return BlendState.NonPremultiplied; + } + + public override void DrawSelf(SpriteBatch spriteBatch, Color lightColor, Vector4 diagonal = default, Vector2 drawScale = default, Texture2D glowTexture = null) + { + if (NoWeapon) + { + return; + } + else + { + if (diagonal == default) + { + diagonal = new Vector4(0, 1, 1, 0); + } + if (drawScale == default) + { + drawScale = new Vector2(0, 1); + if (longHandle) + { + drawScale = new Vector2(-0.6f, 1); + } + drawScale *= drawScaleFactor; + } + Texture2D tex = Terraria.GameContent.TextureAssets.Projectile[Projectile.type].Value; + if (State == 1) + { + tex = ModAsset.EvilHalbertBarnacle_proj_released.Value; + } + Vector2 drawCenter = Projectile.Center - Main.screenPosition; + + SpriteBatchState sBS = GraphicsUtils.GetState(spriteBatch).Value; + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, Main.DefaultSamplerState, DepthStencilState.None, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + DrawVertexByTwoLine(tex, lightColor, diagonal.XY(), diagonal.ZW(), drawCenter + mainAxisDirection * drawScale.X, drawCenter + mainAxisDirection * drawScale.Y); + if (glowTexture != null) + { + DrawVertexByTwoLine(glowTexture, new Color(1f, 1f, 1f, 0), diagonal.XY(), diagonal.ZW(), drawCenter + mainAxisDirection * drawScale.X, drawCenter + mainAxisDirection * drawScale.Y); + } + + spriteBatch.End(); + spriteBatch.Begin(sBS); + } + } + + public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) + { + } + + public override void Attack() + { + Player player = Main.player[Projectile.owner]; + + // Melee time parameter, the faster, the smaller. + float meleeTime = 1f / player.meleeSpeed; + if (currantAttackType == 0) + { + NoWeapon = false; + if (timer < 16 * meleeTime) + { + NoTrail = true; + LockPlayerDir(Player); + float targetRot = -MathHelper.PiOver2 - Projectile.spriteDirection * 2f; + mainAxisDirection = Vector2.Lerp(mainAxisDirection, Vector2Elipse(162, targetRot, -1.2f), 0.15f); + mainAxisDirection += Projectile.DirectionFrom(Player.Center) * 3; + Omega = 0; + Projectile.rotation = mainAxisDirection.ToRotation(); + RotationTowardScreen = RotationTowardScreen * 0.8f; + } + else if (timer < 50 * meleeTime) + { + if (timer > 24 * meleeTime) + { + NoTrail = false; + } + canHit = true; + if (timer < 32 * meleeTime) + { + Omega += 0.02f / meleeTime; + } + if (timer > 40 * meleeTime) + { + Omega *= 0.85f / MathF.Log(meleeTime * MathHelper.E); + NoTrail = true; + } + Projectile.rotation += Projectile.spriteDirection * Omega; + mainAxisDirection = Vector2Elipse(162, Projectile.rotation, -1.3f, RotationTowardScreen, 1000); + } + if (timer > 56 * meleeTime) + { + NextAttackType(); + } + } + if (currantAttackType == 1) + { + if (timer < 4 * meleeTime) + { + NoTrail = true; + LockPlayerDir(Player); + mainAxisDirection = mainAxisDirection * 0.9f + Vector2Elipse(162, -MathHelper.PiOver2 + Projectile.rotation, -1.3f, RotationTowardScreen, 1000) * 0.1f; + Omega *= 0.4f / MathF.Log(meleeTime * MathHelper.E); + Projectile.rotation += Projectile.spriteDirection * Omega; + Projectile.rotation = mainAxisDirection.ToRotation(); + RotationTowardScreen = RotationTowardScreen * 0.75f + 0.6f * 0.25f * (-Projectile.spriteDirection); + } + else if (timer < 42 * meleeTime) + { + if (timer > 12 * meleeTime) + { + NoTrail = false; + } + canHit = true; + if (timer < 16 * meleeTime) + { + Omega += 0.026f / meleeTime; + } + if (timer > 28 * meleeTime) + { + Omega *= 0.85f / MathF.Log(meleeTime * MathHelper.E); + NoTrail = true; + } + Projectile.rotation += Projectile.spriteDirection * Omega; + mainAxisDirection = Vector2Elipse(162, Projectile.rotation, -1.3f, RotationTowardScreen, 1000); + } + if (timer > 36 * meleeTime) + { + NextAttackType(); + } + } + if (currantAttackType == 2) + { + if (timer < 4 * meleeTime) + { + NoTrail = true; + LockPlayerDir(Player); + mainAxisDirection = mainAxisDirection * 0.9f + Vector2Elipse(162, -MathHelper.PiOver2 + Projectile.rotation, -1.3f, RotationTowardScreen, 1000) * 0.1f; + Omega *= 0.4f / MathF.Log(meleeTime * MathHelper.E); + Projectile.rotation += Projectile.spriteDirection * Omega; + Projectile.rotation = mainAxisDirection.ToRotation(); + RotationTowardScreen = RotationTowardScreen * 0.75f - 0.6f * 0.25f * (-Projectile.spriteDirection); + } + else if (timer < 42 * meleeTime) + { + if (timer > 12 * meleeTime) + { + NoTrail = false; + } + canHit = true; + if (timer < 12 * meleeTime) + { + Omega -= 0.04f / meleeTime; + } + if (timer > 28 * meleeTime) + { + Omega *= 0.5f / MathF.Log(meleeTime * MathHelper.E); + } + Projectile.rotation += Projectile.spriteDirection * Omega; + mainAxisDirection = Vector2Elipse(162, Projectile.rotation, -1.3f, RotationTowardScreen, 1000); + } + if (timer > 26 * meleeTime) + { + NextAttackType(); + } + } + if (currantAttackType == 3) + { + NoTrail = true; + NoWeapon = true; + if (timer == 1) + { + TargetVel = Main.MouseWorld - player.MountedCenter; + TargetVel = TargetVel.NormalizeSafe(); + } + if (timer % 5 == 1 && timer < 27) + { + Vector2 dir = TargetVel.RotatedBy((timer - 11) / 10f); + Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), player.Center, dir * 5, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, player.whoAmI); + } + if (timer > 54 * meleeTime) + { + NoWeapon = false; + NextAttackType(); + } + } + if (currantAttackType == 4) + { + if (timer < 4 * meleeTime) + { + NoWeapon = false; + LockPlayerDir(Player); + mainAxisDirection = mainAxisDirection * 0.6f + Vector2Elipse(162, -MathHelper.PiOver2 + Projectile.rotation, 0, RotationTowardScreen, 1000) * 0.4f; + Omega *= 0.4f / MathF.Log(meleeTime * MathHelper.E); + Projectile.rotation += Projectile.spriteDirection * Omega; + Projectile.rotation = mainAxisDirection.ToRotation(); + RotationTowardScreen = RotationTowardScreen * 0.75f - 0.6f * 0.25f * (-Projectile.spriteDirection); + } + else if (timer < 42 * meleeTime) + { + if (timer > 12 * meleeTime) + { + NoTrail = false; + } + canHit = true; + if (timer < 12 * meleeTime) + { + Omega -= 0.04f / meleeTime; + } + if (timer > 28 * meleeTime) + { + Omega *= 0.5f / MathF.Log(meleeTime * MathHelper.E); + } + Projectile.rotation += Projectile.spriteDirection * Omega; + mainAxisDirection = Vector2Elipse(154, Projectile.rotation, 0, RotationTowardScreen, 1000); + } + if (timer > 36 * meleeTime) + { + NextAttackType(); + } + } + + if (currantAttackType == 5) + { + if (timer < 4 * meleeTime) + { + NoTrail = true; + LockPlayerDir(Player); + mainAxisDirection = mainAxisDirection * 0.9f + Vector2Elipse(162, -MathHelper.PiOver2 + Projectile.rotation, -0.8f, RotationTowardScreen, 1000) * 0.1f; + Omega *= 0.4f / MathF.Log(meleeTime * MathHelper.E); + Projectile.rotation += Projectile.spriteDirection * Omega; + Projectile.rotation = mainAxisDirection.ToRotation(); + RotationTowardScreen = RotationTowardScreen * 0.75f + 0.6f * 0.25f * (-Projectile.spriteDirection); + } + else if (timer < 42 * meleeTime) + { + if (timer > 12 * meleeTime) + { + NoTrail = false; + } + canHit = true; + if (timer < 12 * meleeTime) + { + Omega += 0.04f / meleeTime; + } + if (timer > 28 * meleeTime) + { + Omega *= 0.5f / MathF.Log(meleeTime * MathHelper.E); + } + Projectile.rotation += Projectile.spriteDirection * Omega; + mainAxisDirection = Vector2Elipse(154, Projectile.rotation, -0.8f, RotationTowardScreen, 1000); + } + if (timer > 36 * meleeTime) + { + NextAttackType(); + } + } + } + + public override bool PreDraw(ref Color lightColor) + { + DrawSelf(Main.spriteBatch, lightColor); + DrawTrail(lightColor); + return false; + } + + public override void DrawTrail(Color color) + { + List smoothTrail_current = GraphicsUtils.CatmullRom(slashTrail.ToList()); // 平滑 + var SmoothTrail = new List(); + for (int x = 0; x < smoothTrail_current.Count - 1; x++) + { + Vector2 vec = smoothTrail_current[x]; + + SmoothTrail.Add(Vector2.Normalize(vec) * (vec.Length() + disFromPlayer)); + } + if (slashTrail.Count != 0) + { + Vector2 vec = slashTrail.ToArray()[slashTrail.Count - 1]; + + SmoothTrail.Add(Vector2.Normalize(vec) * (vec.Length() + disFromPlayer)); + } + Vector2 center = Projectile.Center - Vector2.Normalize(mainAxisDirection) * disFromPlayer; + int length = SmoothTrail.Count; + if (length <= 3) + { + return; + } + + Vector2[] trail = SmoothTrail.ToArray(); + var bars = new List(); + var bars_Side = new List(); + float fadeIndexScale = slashTrail.Count / (float)length; + for (int i = 0; i < length; i++) + { + float factor = i / (length - 1f); + if (i == length - 1) + { + factor = 0; + } + float w = TrailAlpha(factor); + Color drawColor = Lighting.GetColor((center + trail[i] * 0.9f * Projectile.scale).ToTileCoordinates()) * 0.6f; + drawColor.A = 255; + int fadeIndex = (int)Math.Clamp(i * fadeIndexScale, 0, DrawTrailFade.Count - 1); + drawColor *= DrawTrailFade.ToArray()[fadeIndex]; + int invisible = 0; + + if (timer < 24) + { + invisible = length; + } + if (timer < 44 && timer >= 24) + { + invisible = (int)Utils.Lerp(length, 0, MathF.Pow((timer - 24) / 20f, 2)); + } + if (i < invisible) + { + w = 0; + } + bars.Add(center + trail[i] * 0.3f * Projectile.scale, drawColor, new Vector3(factor, 0.7f, 0f)); + bars.Add(center + trail[i] * 1.1f * Projectile.scale, drawColor, new Vector3(factor, 0, w)); + + bars_Side.Add(center + trail[i] * 0.3f * Projectile.scale, drawColor, new Vector3(factor, 0.8f, 0f)); + bars_Side.Add(center + trail[i] * 1.15f * Projectile.scale, drawColor, new Vector3(factor, 0, w)); + } + + var projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1); + var model = Matrix.CreateTranslation(new Vector3(-Main.screenPosition, 0)) * Main.GameViewMatrix.TransformationMatrix; + SpriteBatchState sBS = Main.spriteBatch.GetState().Value; + + Effect meleetrail = ModAsset.EvilHalbertBarnacle_proj_MeleeTrail.Value; + Main.spriteBatch.End(); + + Main.spriteBatch.Begin(SpriteSortMode.Immediate, TrailBlendState(), SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone); + meleetrail.Parameters["uTransform"].SetValue(model * projection); + meleetrail.CurrentTechnique.Passes["ArcBladeConvertTransparent"].Apply(); + Main.graphics.GraphicsDevice.Textures[0] = ModAsset.Barnacle_Color_Trail.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + + Main.graphics.GraphicsDevice.Textures[0] = ModAsset.Barnacle_Color_Trail2.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_Side.ToArray(), 0, bars_Side.Count - 2); + Main.spriteBatch.End(); + + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone); + Main.graphics.GraphicsDevice.Textures[0] = ModAsset.Barnacle_Color_Trail.Value; + meleetrail.Parameters["tex1"].SetValue(ModContent.Request(TrailColorTex(), ReLogic.Content.AssetRequestMode.ImmediateLoad).Value); + meleetrail.CurrentTechnique.Passes["ArcBladeAffectByEnvironmentLight"].Apply(); + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + Main.spriteBatch.End(); + + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone); + Main.graphics.GraphicsDevice.Textures[0] = ModAsset.Barnacle_Color_Trail2.Value; + meleetrail.CurrentTechnique.Passes["ArcBladeAffectByEnvironmentLightPlus"].Apply(); + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_Side.ToArray(), 0, bars_Side.Count - 2); + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + } + + public override void End() + { + Player player = Main.player[Projectile.owner]; + TestPlayerDrawer Tplayer = player.GetModPlayer(); + player.legFrame = new Rectangle(0, 0, player.legFrame.Width, player.legFrame.Height); + player.fullRotation = 0; + player.legRotation = 0; + Tplayer.HeadRotation = 0; + Tplayer.HideLeg = false; + player.legPosition = Vector2.Zero; + Projectile.Kill(); + player.GetModPlayer().isUsingMeleeProj = false; + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj.png new file mode 100644 index 000000000..f9fc9ac9b Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_MeleeTrail.fx b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_MeleeTrail.fx new file mode 100644 index 000000000..b9e0c66a9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_MeleeTrail.fx @@ -0,0 +1,90 @@ +texture2D tex0; +sampler2D uShapeTex = sampler_state +{ + Texture = ; + MinFilter = Linear; + MagFilter = Linear; + AddressU = Wrap; + AddressV = Wrap; +}; +texture2D tex1; +sampler2D uColorTex = sampler_state +{ + Texture = ; + MinFilter = Linear; + MagFilter = Linear; + AddressU = Clamp; + AddressV = Clamp; +}; +float4x4 uTransform; +struct VSInput +{ + float2 Pos : POSITION0; + float4 Color : COLOR0; + float3 Texcoord : TEXCOORD0; +}; + +struct PSInput +{ + float4 Pos : SV_POSITION; + float4 Color : COLOR0; + float3 Texcoord : TEXCOORD0; +}; +PSInput VertexShaderFunction(VSInput input) +{ + PSInput output; + output.Texcoord = input.Texcoord; + output.Color = input.Color; + output.Pos = mul(float4(input.Pos, 0, 1), uTransform); + return output; +} + +float4 PixelShaderFunction2(PSInput input) : COLOR0 +{ + float3 coord = input.Texcoord; + float4 light = tex2D(uShapeTex, coord.xy); //ä¸»çº¹ç† + float4 c = tex2D(uColorTex, float2(clamp(light.r, 0.03f, 0.97f), 0.5f)); + c *= input.Color; + c.a = 0; + return c * 1.7; +} + +float4 PixelShaderFunction3(PSInput input) : COLOR0 +{ + float3 coord = input.Texcoord; + float4 light = tex2D(uShapeTex, coord.xy); //ä¸»çº¹ç† + float4 c = tex2D(uColorTex, float2(clamp(light.r, 0.01f, 0.99f), 0.5f)); + c *= input.Color; + c.a = 0; + return c; +} + +float4 PixelShaderFunction4(PSInput input) : COLOR0 +{ + float3 coord = input.Texcoord; + float4 c = tex2D(uShapeTex, coord.xy); //ä¸»çº¹ç† + c.a = c.r; + c.r = 0; + c.g = 0; + c.b = 0; + return c * input.Color; +} + +technique Technique1 +{ + pass ArcBladeAffectByEnvironmentLightPlus + { + VertexShader = compile vs_2_0 VertexShaderFunction(); + PixelShader = compile ps_2_0 PixelShaderFunction2(); + } + pass ArcBladeAffectByEnvironmentLight + { + VertexShader = compile vs_2_0 VertexShaderFunction(); + PixelShader = compile ps_2_0 PixelShaderFunction3(); + } + pass ArcBladeConvertTransparent + { + VertexShader = compile vs_2_0 VertexShaderFunction(); + PixelShader = compile ps_2_0 PixelShaderFunction4(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_Thrust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_Thrust.cs new file mode 100644 index 000000000..4e205610e --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_Thrust.cs @@ -0,0 +1,222 @@ +using Everglow.Commons.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Melee.EvilHalbertBarnacle; + +public class EvilHalbertBarnacle_proj_Thrust : ModProjectile +{ + public int State = 0; + + public override string Texture => ModAsset.EvilHalbertBarnacle_proj_Mod; + + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MeleeProjectiles; + + public float HoldoutRangeMin => -24f; + + public float HoldoutRangeMax => 162f; + + public override void SetDefaults() + { + Projectile.width = 30; + Projectile.height = 30; + Projectile.aiStyle = -1; + Projectile.friendly = true; + Projectile.penetrate = -1; + Projectile.tileCollide = false; + Projectile.timeLeft = 40; + } + + public override bool PreAI() + { + Projectile.rotation = Projectile.velocity.ToRotation() + MathHelper.PiOver4 * 3; + if (Projectile.velocity.X > 0) + { + Projectile.spriteDirection = 1; + } + else + { + Projectile.spriteDirection = -1; + Projectile.rotation -= MathHelper.PiOver2; + } + Player player = Main.player[Projectile.owner]; + int duration = (int)(14 / player.meleeSpeed); + + player.heldProj = Projectile.whoAmI; + + if (Projectile.timeLeft > duration) + { + Projectile.timeLeft = duration; + } + + Projectile.velocity = Vector2.Normalize(Projectile.velocity); + + float halfDuration = duration * 0.5f; + float progress; + + if (Projectile.timeLeft < halfDuration) + { + progress = Projectile.timeLeft / halfDuration; + } + else + { + progress = (duration - Projectile.timeLeft) / halfDuration; + } + + Projectile.Center = player.MountedCenter + Vector2.SmoothStep(Projectile.velocity * HoldoutRangeMin, Projectile.velocity * HoldoutRangeMax, progress); + + if (player.ownedProjectileCounts[ModContent.ProjectileType()] <= 0) + { + State = 0; + } + else + { + State = 1; + } + return false; + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + for (int i = 0; i < 12; i++) + { + Rectangle rec = projHitbox; + rec.X += (int)(Projectile.velocity.X * i * 10); + rec.Y += (int)(Projectile.velocity.Y * i * 10); + if (targetHitbox.Intersects(rec)) + { + return true; + } + } + return false; + } + + public Vector2 oldPos; + + public override bool PreDraw(ref Color lightColor) + { + Texture2D tex = ModContent.Request(Texture).Value; + if (State == 1) + { + tex = ModAsset.EvilHalbertBarnacle_proj_released.Value; + } + Vector2 velNor2 = Projectile.velocity.NormalizeSafe() * tex.Width / MathF.Sqrt(2f); + Main.EntitySpriteDraw(tex, Projectile.Center - Main.screenPosition - velNor2, null, lightColor, Projectile.rotation, tex.Size() * 0.5f, Projectile.scale, Projectile.spriteDirection == 1 ? SpriteEffects.FlipHorizontally : SpriteEffects.None, 0); + return false; + } + + public override void PostDraw(Color lightColor) + { + Vector2 drawCenter = Projectile.Center; + float timeValue = 1f; + if (Projectile.timeLeft < 4) + { + timeValue = Projectile.timeLeft / 4f; + } + Vector2 vel = Vector2.Normalize(Projectile.velocity); + Vector2 width = vel.RotatedBy(MathHelper.PiOver2) * 60 * timeValue; + float timeEffectValue = (float)(Main.time * 0.06f) + Projectile.whoAmI * 0.27f; + + Player player = Main.player[Projectile.owner]; + int duration = (int)(14 / player.meleeSpeed); + float progress2; + float halfDuration = duration * 0.5f; + if (Projectile.timeLeft < halfDuration) + { + progress2 = 2 - Projectile.timeLeft / halfDuration; + drawCenter = player.MountedCenter + Vector2.Lerp(Projectile.velocity * HoldoutRangeMin, Projectile.velocity * HoldoutRangeMax, progress2 * 0.5f + 1.5f * 0.5f); + } + else + { + progress2 = (duration - Projectile.timeLeft) / halfDuration; + } + if (progress2 <= 0) + { + return; + } + float unitDistance = (HoldoutRangeMax - HoldoutRangeMin) / 19f * progress2 * 1.4f; + + // dark bottom + List bars = new List(); + + // light cover + List bars2 = new List(); + + // light cover 3 + List bars3 = new List(); + for (int x = 0; x < 20; x++) + { + Vector2 drawPos = drawCenter - vel * unitDistance * x; + Color drawColor = Lighting.GetColor(drawPos.ToTileCoordinates()); + drawColor.A = 255; + float mulWidth = MathF.Sin(x / 23f * MathHelper.PiOver2); + float value = 19 - x; + float fade = 1; + if (value < 5) + { + fade *= 0.2f; + } + int fadeDis = 7; + if (x > Projectile.timeLeft * 3 - fadeDis) + { + fade *= Math.Clamp((Projectile.timeLeft * 3 - x) / (float)fadeDis, 0, 1); + } + drawColor *= fade; + bars.Add(drawPos + width, drawColor, new Vector3(-x / 20f - timeEffectValue, 1, mulWidth)); + bars.Add(drawPos - width, drawColor, new Vector3(-x / 20f - timeEffectValue, 0, mulWidth)); + + drawColor.A = 0; + drawColor *= 0.7f; + bars2.Add(drawPos + width, drawColor, new Vector3(-x / 20f - timeEffectValue, 1, mulWidth)); + bars2.Add(drawPos - width, drawColor, new Vector3(-x / 20f - timeEffectValue, 0, mulWidth)); + + drawColor = Lighting.GetColor(drawPos.ToTileCoordinates()); + drawColor.A = 0; + fade = 19 - x; + if (value < 5) + { + fade *= 0.2f; + } + fadeDis = 150; + if (x > Projectile.timeLeft * 1 - fadeDis) + { + fade *= Math.Max(0, (Projectile.timeLeft * 1 - x) / (float)fadeDis); + } + drawColor *= fade; + drawColor *= 2; + bars3.Add(drawPos + width, drawColor, new Vector3(-x / 20f - timeEffectValue, 1, mulWidth)); + bars3.Add(drawPos - width, drawColor, new Vector3(-x / 20f - timeEffectValue, 0, mulWidth)); + } + + SpriteBatchState sBS = Main.spriteBatch.GetState().Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone); + Effect effect = ModAsset.EvilHalbertBarnacle_proj_Thrust.Value; + var projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1); + var model = Matrix.CreateTranslation(new Vector3(-Main.screenPosition, 0)) * Main.GameViewMatrix.TransformationMatrix; + effect.Parameters["uTransform"].SetValue(model * projection); + effect.CurrentTechnique.Passes["DarkEffect"].Apply(); + + Main.graphics.graphicsDevice.Textures[0] = Commons.ModAsset.Trail_8.Value; + Main.graphics.graphicsDevice.Textures[1] = ModAsset.Barnacle_Color.Value; + Main.graphics.graphicsDevice.SamplerStates[0] = SamplerState.PointWrap; + Main.graphics.graphicsDevice.SamplerStates[1] = SamplerState.PointClamp; + + if (bars.Count > 0) + { + Main.graphics.graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + Main.graphics.graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.Default, RasterizerState.CullNone); + effect.CurrentTechnique.Passes["LightEffect"].Apply(); + + if (bars2.Count > 0 && bars3.Count > 0) + { + Main.graphics.graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars2.ToArray(), 0, bars2.Count - 2); + Main.graphics.graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars3.ToArray(), 0, bars3.Count - 2); + } + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_Thrust.fx b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_Thrust.fx new file mode 100644 index 000000000..f0e9bd8a9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_Thrust.fx @@ -0,0 +1,71 @@ +sampler2D uImage : register(s0); +sampler2D uImage1 : register(s1); +float4x4 uTransform; +struct VSInput +{ + float2 Pos : POSITION0; + float4 Color : COLOR0; + float3 Texcoord : TEXCOORD0; +}; + +struct PSInput +{ + float4 Pos : SV_POSITION; + float4 Color : COLOR0; + float3 Texcoord : TEXCOORD0; +}; + +PSInput VertexShaderFunction(VSInput input) +{ + PSInput output; + output.Color = input.Color; + output.Texcoord = input.Texcoord; + output.Pos = mul(float4(input.Pos, 0, 1), uTransform); + return output; +} + +float4 PixelShaderFunction(PSInput input) : COLOR0 +{ + float newX = input.Texcoord.x % 1; + float newY = input.Texcoord.y - 0.5; + newY *= 1 / sin(input.Texcoord.z * 3.141592653589793238); + newY += 0.5; + newY = clamp(newY, 0, 1); + float2 newCoord = float2(newX, newY); + float4 light = tex2D(uImage, newCoord); + float4 c = tex2D(uImage1, float2(clamp(light.r, 0.01f, 0.99f), 0.5f)); + c *= input.Color; + return c; +} + +float4 PixelShaderFunction_Dark(PSInput input) : COLOR0 +{ + float newX = input.Texcoord.x % 1; + float newY = input.Texcoord.y - 0.5; + newY *= 1 / sin(input.Texcoord.z * 3.141592653589793238); + newY += 0.5; + newY = clamp(newY, 0, 1); + float2 newCoord = float2(newX, newY); + float4 c = tex2D(uImage, newCoord); + c.a = c.r; + c.r = 0; + c.g = 0; + c.b = 0; + c *= input.Color; + return c; +} + +technique Technique1 +{ + pass LightEffect + { + VertexShader = compile vs_3_0 VertexShaderFunction(); + PixelShader = compile ps_3_0 PixelShaderFunction(); + } + + pass DarkEffect + { + VertexShader = compile vs_3_0 VertexShaderFunction(); + PixelShader = compile ps_3_0 PixelShaderFunction_Dark(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_released.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_released.png new file mode 100644 index 000000000..40813361f Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_released.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_shuttle.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_shuttle.cs new file mode 100644 index 000000000..0351fb64c --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_shuttle.cs @@ -0,0 +1,517 @@ +using Everglow.Commons.DataStructures; +using Everglow.Commons.Templates.Weapons; +using Everglow.Yggdrasil.KelpCurtain.VFXs; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Melee.EvilHalbertBarnacle; + +public class EvilHalbertBarnacle_proj_shuttle : TrailingProjectile +{ + public new int Timer = 0; + + /// + /// 0: shoot; 1 hit; 2 back; 3 being controlled + /// + public int State = 0; + + public int ParentProjectile = -1; + + public float TrailDuration = 0; + + public float Power = 0f; + + public float ThinnerFactor = 0; + + public Queue ThinnerTrail = new Queue(); + + public override void SetDefaults() + { + Projectile.width = 20; + Projectile.height = 20; + Projectile.aiStyle = -1; + Projectile.friendly = true; + Projectile.penetrate = -1; + Projectile.tileCollide = false; + Projectile.timeLeft = 120000; + ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + ProjectileID.Sets.TrailCacheLength[Projectile.type] = 10; + TrailColor = new Color(0.8f, 0.2f, 0.3f, 0f); + TrailWidth = 30f; + SelfLuminous = false; + TrailTexture = Commons.ModAsset.Trail_8.Value; + TrailTextureBlack = Commons.ModAsset.Trail_8_black.Value; + TrailShader = Commons.ModAsset.Trailing.Value; + } + + public override void AI() + { + Timer++; + if (TimeAfterEntityDestroy >= 0 && TimeAfterEntityDestroy <= 2) + { + Projectile.Kill(); + } + TimeAfterEntityDestroy--; + if (TimeAfterEntityDestroy >= 0) + { + Projectile.velocity *= 0f; + return; + } + Player player = Main.player[Projectile.owner]; + + ThinnerTrail.Enqueue(ThinnerFactor); + if (ThinnerTrail.Count > Projectile.oldPos.Length) + { + ThinnerTrail.Dequeue(); + } + + if (State == 0) + { + ThinnerFactor = ThinnerFactor * 0.75f + 0.025f; + Projectile.rotation = Projectile.velocity.ToRotation() + MathHelper.PiOver4 * 1; + for (int v = 0; v < 15; v++) + { + if (Collision.SolidCollision(Projectile.position + Projectile.velocity.NormalizeSafe() * v * 5, Projectile.width, Projectile.height)) + { + Projectile.Center = Projectile.Center + Projectile.velocity.NormalizeSafe() * v * 5; + Projectile.velocity *= 0; + State = 1; + Power = 100; + Timer = 0; + CollideEffect(); + break; + } + } + if (Timer > 30) + { + Power = 70; + Projectile.velocity -= (Projectile.rotation - MathHelper.PiOver4).ToRotationVector2() * 35; + Timer = 0; + State = 2; + } + } + if (State == 1) + { + ThinnerFactor = ThinnerFactor * 0.75f + 0.025f; + Projectile.friendly = false; + Timer++; + if (HasTarget()) + { + State = 3; + return; + } + if (Power > 0) + { + Power--; + } + else + { + Power = 0; + } + if (Timer >= 300) + { + Power = 70; + Projectile.velocity -= (Projectile.rotation - MathHelper.PiOver4).ToRotationVector2() * 35; + Timer = 0; + State = 2; + } + } + if (State == 2) + { + ThinnerFactor = ThinnerFactor * 0.75f + 0.025f; + Projectile.friendly = true; + Power--; + Projectile.velocity *= 0.9f; + Vector2 target = player.Center; + Vector2 toTarget = target - Projectile.Center - Projectile.velocity * 0.2f; + if (HasTarget()) + { + State = 3; + return; + } + if (toTarget.Length() < 20) + { + Projectile.Kill(); + } + toTarget = toTarget.NormalizeSafe() * 24; + toTarget.Y *= 0.5f; + Projectile.velocity += toTarget * 0.1f; + Projectile.rotation = Projectile.velocity.ToRotation() + MathHelper.PiOver4; + } + if (State == 3) + { + Projectile.friendly = true; + Projectile meleeWeapon = default; + if (ParentProjectile >= 0) + { + meleeWeapon = Main.projectile[ParentProjectile]; + } + if (meleeWeapon == null || !meleeWeapon.active || meleeWeapon.type != ModContent.ProjectileType() || meleeWeapon.owner != Projectile.owner) + { + State = 2; + return; + } + Power = 70; + Projectile.velocity *= 0.9f; + Vector2 target = player.Center; + EvilHalbertBarnacle_proj melee = meleeWeapon.ModProjectile as EvilHalbertBarnacle_proj; + if (melee == null) + { + State = 2; + return; + } + TrailDuration += Math.Abs(melee.Omega); + Vector2 offsetTarget = new Vector2(0, 240).RotatedBy(TrailDuration); + offsetTarget.Y *= 0.35f; + offsetTarget = offsetTarget.RotatedBy(Math.Sin(Main.time / 24f + Projectile.whoAmI)); + offsetTarget.X *= player.direction; + target += offsetTarget; + Vector2 toTarget = target - Projectile.Center - Projectile.velocity; + if (toTarget.Length() > 300) + { + Vector2 v0 = toTarget.NormalizeSafe(); + Vector2 v1 = Projectile.velocity.NormalizeSafe(); + if (Vector2.Dot(v0, v1) < 0) + { + Projectile.velocity *= 0.6f; + } + } + + float speed = Math.Abs(melee.Omega) * 540 + 12; + ThinnerFactor = Math.Clamp(Projectile.velocity.Length() / 30f - 1, 0, 1); + toTarget = toTarget.NormalizeSafe() * speed; + toTarget.Y *= 0.5f; + Projectile.velocity += toTarget * 0.1f; + if (Projectile.velocity.Length() > 15f) + { + Vector2 vel = Projectile.velocity * Main.rand.NextFloat(0.5f, 1.15f) * 0.1f; + var dust = new BarnacleTissueDust + { + velocity = vel, + Active = true, + Visible = true, + position = Projectile.Center + Projectile.velocity * 5, + maxTime = Main.rand.Next(20, 30), + scale = Main.rand.NextFloat(5f, 30f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(6f, 8f), Main.rand.NextFloat(1f) }, + }; + Ins.VFXManager.Add(dust); + } + Projectile.rotation = Projectile.velocity.ToRotation() + MathHelper.PiOver4; + } + Lighting.AddLight(Projectile.Center, new Vector3(0.7f, 0.4f, 0.3f) * Power / 70f); + } + + public void CollideEffect() + { + for (int i = 0; i < 16; ++i) + { + Vector2 vel = new Vector2(0, 1).RotateRandom(MathHelper.TwoPi) * Main.rand.NextFloat(0.5f, 1.15f) * 15f; + var dust = new BarnacleTissueDust + { + velocity = vel, + Active = true, + Visible = true, + position = Projectile.Center + Projectile.velocity * 5, + maxTime = Main.rand.Next(20, 30), + scale = Main.rand.NextFloat(8f, 45f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(6f, 8f), Main.rand.NextFloat(1f) }, + }; + Ins.VFXManager.Add(dust); + } + for (int i = 0; i < 6; ++i) + { + Vector2 vel = new Vector2(0, 1).RotateRandom(MathHelper.TwoPi) * Main.rand.NextFloat(0.5f, 1.15f) * 35f; + var dust = new BarnacleTissueDust + { + velocity = vel, + Active = true, + Visible = true, + position = Projectile.Center + Projectile.velocity * 5, + maxTime = Main.rand.Next(10, 26), + scale = Main.rand.NextFloat(60f, 150f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(6f, 8f), Main.rand.NextFloat(1f) }, + }; + Ins.VFXManager.Add(dust); + } + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + float length = Projectile.velocity.Length() / 4f; + Vector2 norVel = Projectile.velocity.NormalizeSafe(); + for (int i = 0; i <= length; i++) + { + Rectangle rec = projHitbox; + rec.X += (int)(norVel.X * i * 4); + rec.Y += (int)(norVel.Y * i * 4); + if (rec.Intersects(targetHitbox)) + { + return true; + } + } + return false; + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + if (State == 0) + { + Projectile.velocity *= 0; + Projectile.Center = target.Center; + State = 1; + Power = 100; + Timer = 0; + CollideEffect(); + } + } + + public bool HasTarget() + { + foreach (var proj in Main.projectile) + { + if (proj != null && proj.active && proj.type == ModContent.ProjectileType() && proj.owner == Projectile.owner) + { + ParentProjectile = proj.whoAmI; + return true; + } + } + return false; + } + + public override void OnKill(int timeLeft) => base.OnKill(timeLeft); + + public override bool PreDraw(ref Color lightColor) + { + DrawTrailDark(); + DrawTrailDark(); + DrawTrail(); + if (TimeAfterEntityDestroy <= 0) + { + DrawSelf(); + } + return false; + } + + public override void DrawTrail() + { + var unSmoothPos = new List(); + for (int i = 0; i < Projectile.oldPos.Length; ++i) + { + if (Projectile.oldPos[i] == Vector2.Zero) + { + break; + } + + unSmoothPos.Add(Projectile.oldPos[i]); + } + float smoothIndexRatio = unSmoothPos.Count; + List SmoothTrailX = GraphicsUtils.CatmullRom(unSmoothPos); // 平滑 + var SmoothTrail = new List(); + for (int x = 0; x < SmoothTrailX.Count - 1; x++) + { + SmoothTrail.Add(SmoothTrailX[x]); + } + if (unSmoothPos.Count != 0) + { + SmoothTrail.Add(unSmoothPos[unSmoothPos.Count - 1]); + } + smoothIndexRatio /= SmoothTrail.Count; + Vector2 halfSize = new Vector2(Projectile.width, Projectile.height) / 2f; + var bars = new List(); + var bars2 = new List(); + var bars3 = new List(); + + var bars4 = new List(); + var bars5 = new List(); + var bars6 = new List(); + for (int i = 0; i < SmoothTrail.Count; ++i) + { + float mulFac = Timer / (float)ProjectileID.Sets.TrailCacheLength[Projectile.type]; + if (mulFac > 1f) + { + mulFac = 1f; + } + float factor = i / (float)SmoothTrail.Count * mulFac; + float width = TrailWidthFunction(factor); + if (i == 0) + { + width = 0; + } + int trailThinnerIndex = Math.Clamp((int)(smoothIndexRatio * i), 0, ThinnerTrail.Count - 1); + float timeValue = (float)Main.time * 0.0005f; + factor *= 3; + factor += timeValue; + + Vector2 drawPos = SmoothTrail[i] + halfSize; + Color drawC = TrailColor; + if (!SelfLuminous) + { + Color lightC = Lighting.GetColor((drawPos / 16f).ToPoint()); + drawC.R = (byte)(lightC.R * drawC.R / 255f); + drawC.G = (byte)(lightC.G * drawC.G / 255f); + drawC.B = (byte)(lightC.B * drawC.B / 255f); + } + bars.Add(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 2f / 3f) * TrailWidth, drawC, new Vector3(factor, 1, width)); + bars.Add(drawPos, drawC, new Vector3(factor, 0.5f, width)); + bars2.Add(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 1f / 3f) * TrailWidth, drawC, new Vector3(factor, 1, width)); + bars2.Add(drawPos, drawC, new Vector3(factor, 0.5f, width)); + bars3.Add(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 0f / 3f) * TrailWidth, drawC, new Vector3(factor, 1, width)); + bars3.Add(drawPos, drawC, new Vector3(factor, 0.5f, width)); + + float trailWidth2 = TrailWidth * 0.4f; + float oldThin = ThinnerTrail.ToArray()[trailThinnerIndex]; + Color trailColor2 = Color.Lerp(TrailColor * 0.3f, new Color(0.2f, 0.8f, 1, 0), 1 - Math.Clamp((oldThin - 0.5f) * 2, 0, 1)); + trailColor2 *= 2; + width *= MathF.Pow(oldThin, 3f); + bars4.Add(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 2f / 3f) * trailWidth2, trailColor2, new Vector3(factor, 1, width)); + bars4.Add(drawPos, trailColor2, new Vector3(factor, 0.5f, width)); + bars5.Add(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 1f / 3f) * trailWidth2, trailColor2, new Vector3(factor, 1, width)); + bars5.Add(drawPos, trailColor2, new Vector3(factor, 0.5f, width)); + bars6.Add(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 0f / 3f) * trailWidth2, trailColor2, new Vector3(factor, 1, width)); + bars6.Add(drawPos, trailColor2, new Vector3(factor, 0.5f, width)); + } + SpriteBatchState sBS = Main.spriteBatch.GetState().Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + Effect effect = TrailShader; + var projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1); + var model = Matrix.CreateTranslation(new Vector3(-Main.screenPosition, 0)) * Main.GameViewMatrix.TransformationMatrix; + effect.Parameters["uTransform"].SetValue(model * projection); + effect.CurrentTechnique.Passes[0].Apply(); + Main.graphics.GraphicsDevice.RasterizerState = RasterizerState.CullNone; + Main.graphics.GraphicsDevice.Textures[0] = TrailTexture; + Main.graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap; + if (bars.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + if (bars2.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars2.ToArray(), 0, bars2.Count - 2); + } + if (bars3.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars3.ToArray(), 0, bars3.Count - 2); + } + + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Trail_7.Value; + if (bars4.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars4.ToArray(), 0, bars4.Count - 2); + } + if (bars5.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars5.ToArray(), 0, bars5.Count - 2); + } + if (bars6.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars6.ToArray(), 0, bars6.Count - 2); + } + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + } + + public void DrawTrailDark() + { + var unSmoothPos = new List(); + for (int i = 0; i < Projectile.oldPos.Length; ++i) + { + if (Projectile.oldPos[i] == Vector2.Zero) + { + break; + } + + unSmoothPos.Add(Projectile.oldPos[i]); + } + float smoothIndexRatio = unSmoothPos.Count; + List SmoothTrailX = GraphicsUtils.CatmullRom(unSmoothPos); // 平滑 + var SmoothTrail = new List(); + for (int x = 0; x < SmoothTrailX.Count - 1; x++) + { + SmoothTrail.Add(SmoothTrailX[x]); + } + if (unSmoothPos.Count != 0) + { + SmoothTrail.Add(unSmoothPos[unSmoothPos.Count - 1]); + } + Vector2 halfSize = new Vector2(Projectile.width, Projectile.height) / 2f; + var bars = new List(); + var bars2 = new List(); + var bars3 = new List(); + for (int i = 0; i < SmoothTrail.Count; ++i) + { + float mulFac = Timer / (float)ProjectileID.Sets.TrailCacheLength[Projectile.type]; + if (mulFac > 1f) + { + mulFac = 1f; + } + float factor = i / (float)SmoothTrail.Count * mulFac; + float width = TrailWidthFunction(factor); + if (i == 0) + { + width = 0; + } + float timeValue = (float)Main.time * 0.0005f; + factor *= 3; + factor += timeValue; + + Vector2 drawPos = SmoothTrail[i] + halfSize; + Color drawC = new Color(1, 1, 1, 1f); + bars.Add(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 2f / 3f) * TrailWidth, drawC, new Vector3(factor, 1, width)); + bars.Add(drawPos, drawC, new Vector3(factor, 0.5f, width)); + bars2.Add(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 1f / 3f) * TrailWidth, drawC, new Vector3(factor, 1, width)); + bars2.Add(drawPos, drawC, new Vector3(factor, 0.5f, width)); + bars3.Add(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 0f / 3f) * TrailWidth, drawC, new Vector3(factor, 1, width)); + bars3.Add(drawPos, drawC, new Vector3(factor, 0.5f, width)); + } + SpriteBatchState sBS = Main.spriteBatch.GetState().Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + Effect effect = TrailShader; + var projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1); + var model = Matrix.CreateTranslation(new Vector3(-Main.screenPosition, 0)) * Main.GameViewMatrix.TransformationMatrix; + effect.Parameters["uTransform"].SetValue(model * projection); + effect.CurrentTechnique.Passes[0].Apply(); + Main.graphics.GraphicsDevice.RasterizerState = RasterizerState.CullNone; + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Trail_8_black.Value; + Main.graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap; + if (bars.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + if (bars2.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars2.ToArray(), 0, bars2.Count - 2); + } + if (bars3.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars3.ToArray(), 0, bars3.Count - 2); + } + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + } + + public override void DrawSelf() + { + var texMain = (Texture2D)ModContent.Request(Texture); + var texGlow = ModAsset.EvilHalbertBarnacle_proj_shuttle_glow.Value; + var texBloom = ModAsset.EvilHalbertBarnacle_proj_shuttle_bloom.Value; + if (Power > 50) + { + float value = Power - 50; + value /= 50f; + Color drawColor = new Color(value, value, value, 0); + Main.spriteBatch.Draw(texBloom, Projectile.Center - Main.screenPosition, null, drawColor, Projectile.rotation, texBloom.Size() / 2f, 1f, SpriteEffects.None, 0); + } + Main.spriteBatch.Draw(texMain, Projectile.Center - Main.screenPosition, null, Lighting.GetColor(Projectile.Center.ToTileCoordinates()), Projectile.rotation, texMain.Size() / 2f, 1f, SpriteEffects.None, 0); + if (Power > 0) + { + float value = Power / 100f; + Color drawColor = new Color(value, value, value, 0); + Main.spriteBatch.Draw(texGlow, Projectile.Center - Main.screenPosition, null, drawColor, Projectile.rotation, texGlow.Size() / 2f, 1f, SpriteEffects.None, 0); + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_shuttle.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_shuttle.png new file mode 100644 index 000000000..dd9f83974 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_shuttle.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_shuttle_bloom.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_shuttle_bloom.png new file mode 100644 index 000000000..84933170c Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_shuttle_bloom.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_shuttle_glow.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_shuttle_glow.png new file mode 100644 index 000000000..b7687dc82 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/EvilHalbertBarnacle/EvilHalbertBarnacle_proj_shuttle_glow.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/MeatLantern_Proj.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/MeatLantern_Proj.cs index f24c6e06a..b66b1a46d 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/MeatLantern_Proj.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Melee/MeatLantern_Proj.cs @@ -130,6 +130,7 @@ public override void Attack() if (currantAttackType == 0) { + LockPlayerDir(Player); float rot = player.direction; if (timer < 20) { @@ -167,6 +168,7 @@ public override void Attack() } if (currantAttackType == 1) { + LockPlayerDir(Player); float rot = -player.direction; if (timer < 20) { @@ -204,6 +206,7 @@ public override void Attack() } if (currantAttackType == 2) { + LockPlayerDir(Player); if (timer < 20) { useSlash = false; @@ -250,6 +253,7 @@ public override void Attack() } if (currantAttackType == 3) { + LockPlayerDir(Player); float rot = -player.direction; if (timer < 20) { diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/BlackAwningBoat_WaterDistort.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/BlackAwningBoat_WaterDistort.cs new file mode 100644 index 000000000..adc2b6d07 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/BlackAwningBoat_WaterDistort.cs @@ -0,0 +1,45 @@ +using Everglow.Yggdrasil.KelpCurtain.CustomTiles; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Miscs; + +public class BlackAwningBoat_WaterDistort : ModProjectile +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MiscsProjectiles; + + public override string Texture => Commons.ModAsset.Empty_Mod; + + public BlackAwningBoat ParentBoat; + + public override void SetDefaults() + { + Projectile.width = 90; + Projectile.height = 64; + Projectile.aiStyle = -1; + Projectile.penetrate = -1; + Projectile.friendly = false; + Projectile.hostile = false; + Projectile.tileCollide = false; + Projectile.ignoreWater = false; + Projectile.timeLeft = 600000; + base.SetDefaults(); + } + + public override void AI() + { + if (ParentBoat is null || !ParentBoat.Active || ParentBoat.Velocity.Length() <= 0.001f) + { + Projectile.active = false; + return; + } + else + { + Projectile.Center = new Vector2(ParentBoat.Box.Center.X + MathF.Sign(ParentBoat.Velocity.X) * 64, ParentBoat.Box.Bottom); + Projectile.velocity = ParentBoat.Velocity * 2; + } + } + + public override bool PreDraw(ref Color lightColor) + { + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/BlackAwningBoat_WaterDistort.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/BlackAwningBoat_WaterDistort.png new file mode 100644 index 000000000..a859ccdc9 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/BlackAwningBoat_WaterDistort.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/VineWand/VineEnergyBeam.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/VineWand/VineEnergyBeam.cs new file mode 100644 index 000000000..e1725464e --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/VineWand/VineEnergyBeam.cs @@ -0,0 +1,167 @@ +using Everglow.Commons.DataStructures; +using Everglow.Yggdrasil.KelpCurtain.Items.Tools; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Miscs.VineWand; + +public class VineEnergyBeam : ModProjectile +{ + public Vector2 StartPosition; + public Vector2 EndPosition; + + public override void SetStaticDefaults() + { + ProjectileID.Sets.TrailCacheLength[Projectile.type] = 0; + } + + public override void SetDefaults() + { + Projectile.width = 2; + Projectile.height = 2; + Projectile.friendly = true; + Projectile.hostile = false; + Projectile.penetrate = -1; + Projectile.timeLeft = 2000000; + Projectile.tileCollide = false; + Projectile.ignoreWater = true; + Projectile.alpha = 100; + } + + public override void AI() + { + Player player = Main.player[Projectile.owner]; + if (player.active) + { + StartPosition = player.Center; + } + if (player.HeldItem is not null && player.HeldItem.ModItem is not null && player.HeldItem.ModItem is VineRepairWand vWand) + { + if (!vWand.IsAdjusting(EndPosition.ToTileCoordinates())) + { + ReadyToKill(); + } + else + { + if (Projectile.timeLeft < 2000000) + { + Projectile.timeLeft = 3000000; + } + } + } + else + { + ReadyToKill(); + } + + Projectile.Center = (StartPosition + EndPosition) / 2f; + Projectile.rotation = (EndPosition - StartPosition).ToRotation(); + } + + public void ReadyToKill() + { + if (Projectile.timeLeft > 10) + { + Projectile.timeLeft = 10; + } + } + + public override bool PreDraw(ref Color lightColor) + { + Vector2 start = StartPosition - Main.screenPosition; + Vector2 end = EndPosition - Main.screenPosition; + + Vector2 direction = end - start; + start += direction.NormalizeSafe() * 36; + float length = direction.Length(); + direction = direction.NormalizeSafe(); + float fade = 1; + if (Projectile.timeLeft < 10) + { + fade = Projectile.timeLeft / 10f; + } + Vector2 thick = direction.RotatedBy(MathHelper.PiOver2) * 20f * Projectile.ai[0]; + float time = -(float)Main.time * 0.03f; + Color[] flowColors = new Color[] + { + new Color(187, 224, 163, 0), + new Color(64, 186, 82, 0), + new Color(51, 147, 64, 0), + new Color(64, 104, 82, 0), + }; + + List bars_dark = []; + List bars = []; + + bars_dark.Add(start + thick, Color.White * fade, new Vector3(time, 0, 0)); + bars_dark.Add(start - thick, Color.White * fade, new Vector3(time, 1, 0)); + bars.Add(start + thick, new Color(187, 224, 163, 0) * fade, new Vector3(time, 0, 0)); + bars.Add(start - thick, new Color(187, 224, 163, 0) * fade, new Vector3(time, 1, 0)); + + Vector2 dustPosOld = start; + int index = 0; + for (int k = 0; k < length - 45; k += 45 + TileUtils.GetFixedRandomNumber(Projectile.whoAmI, k, 45)) + { + index++; + float deltaValue = index % 2 - 0.5f; + var color = flowColors[Math.Min(index, 3)]; + Vector2 wave = thick * MathF.Sin(k * 0.07f + time) * 1.2f * MathF.Sin(k / length * MathHelper.Pi); + + bars_dark.Add(start + direction * k + thick + wave, Color.White * fade, new Vector3(time + deltaValue, 0, 0)); + bars_dark.Add(start + direction * k - thick + wave, Color.White * fade, new Vector3(time + deltaValue, 1, 0)); + bars.Add(start + direction * k + thick + wave, color * fade, new Vector3(time + deltaValue, 0, 0)); + bars.Add(start + direction * k - thick + wave, color * fade, new Vector3(time + deltaValue, 1, 0)); + + // 生æˆç²’å­æ•ˆæžœ - 使用更深的颜色 + if (Main.rand.NextBool((int)(12 / Projectile.ai[0])) && !Main.gamePaused) + { + Vector2 randomPos = Vector2.Lerp(start + direction * k + wave, dustPosOld, Main.rand.NextFloat()) + Main.screenPosition; + + // ä½¿ç”¨æ›´æ·±çš„ç»¿è‰²ç²’å­ + Color[] dustColors = new Color[] + { + new Color(20, 80, 20), // 深绿 + new Color(30, 100, 30), // 中深绿 + new Color(40, 120, 40), // 中绿 + new Color(60, 140, 60), // 浅深绿 + new Color(80, 160, 80), // 浅绿 + }; + + Color dustColor = dustColors[Main.rand.Next(dustColors.Length)]; + Dust dust = Dust.NewDustPerfect(randomPos, DustID.TerraBlade, Vector2.Zero, 0, dustColor, 0.8f); + dust.rotation = Main.rand.NextFloat(MathHelper.TwoPi); + dust.noGravity = true; + + if (k + 45 + TileUtils.GetFixedRandomNumber(Projectile.whoAmI, k, 45) >= length - 45) + { + randomPos = Vector2.Lerp(end, start + direction * k + wave, Main.rand.NextFloat()) + Main.screenPosition; + dustColor = dustColors[Main.rand.Next(dustColors.Length)]; + Dust dust2 = Dust.NewDustPerfect(randomPos, DustID.TerraBlade, Vector2.Zero, 0, dustColor, 0.8f); + dust2.rotation = Main.rand.NextFloat(MathHelper.TwoPi); + dust2.noGravity = true; + } + } + + dustPosOld = start + direction * k + wave; + } + + bars_dark.Add(end + thick, Color.White * fade, new Vector3(time + length / 500f, 0, 0)); + bars_dark.Add(end - thick, Color.White * fade, new Vector3(time + length / 500f, 1, 0)); + bars.Add(end + thick, new Color(64, 104, 82, 0) * fade, new Vector3(time + length / 500f, 0, 0)); + bars.Add(end - thick, new Color(64, 104, 82, 0) * fade, new Vector3(time + length / 500f, 1, 0)); + + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + Texture2D flow_dark = Commons.ModAsset.Trail_9_black.Value; + Main.graphics.graphicsDevice.Textures[0] = flow_dark; + Main.graphics.graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_dark.ToArray(), 0, bars_dark.Count - 2); + + Texture2D flow = Commons.ModAsset.Trail_9.Value; + Main.graphics.graphicsDevice.Textures[0] = flow; + Main.graphics.graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/VineWand/VineEnergyBeam.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/VineWand/VineEnergyBeam.png new file mode 100644 index 000000000..8e4a991f8 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/VineWand/VineEnergyBeam.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/VineWand/VineEnergyOrb.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/VineWand/VineEnergyOrb.cs new file mode 100644 index 000000000..1930de965 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/VineWand/VineEnergyOrb.cs @@ -0,0 +1,265 @@ +using Terraria.GameContent; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Miscs.VineWand; + +public class VineEnergyOrb : ModProjectile +{ + public Vector2 StartPosition; + public Vector2 EndPosition; + + public Vector2 TileDestination = Vector2.zeroVector; + public float Progress = 0f; + public float Speed = 0.03f; + + // 用于存储轨迹点以实现拖尾效果 + private List trailPositions = new List(); + private List trailRotations = new List(); + private const int MaxTrailLength = 20; + + // æ·»åŠ åŠ¨æ€æ•ˆæžœå˜é‡ + private float timer = 0f; + private float pulseTimer = 0f; + private float pulse = 0f; + + public override void SetStaticDefaults() + { + ProjectileID.Sets.TrailCacheLength[Projectile.type] = 6; + ProjectileID.Sets.TrailingMode[Projectile.type] = 0; + } + + public override void SetDefaults() + { + Projectile.width = 4; + Projectile.height = 4; + Projectile.friendly = true; + Projectile.hostile = false; + Projectile.penetrate = -1; + Projectile.timeLeft = 180; + Projectile.tileCollide = false; + Projectile.ignoreWater = true; + Projectile.alpha = 100; + } + + public override void AI() + { + Player player = Main.player[Projectile.owner]; + + // 如果ä½ç½®ä¿¡æ¯ä¸ºé›¶ï¼Œåˆ™ä»Žai傿•°è¯»å– + if (StartPosition == Vector2.Zero) + { + StartPosition = Projectile.Center; + } + if (TileDestination == Vector2.zeroVector) + { + EndPosition = player.Center; + } + else + { + EndPosition = TileDestination; + } + + // 移动能é‡çƒï¼šæ²¿ç€è´å¡žå°”曲线从起点移动到终点 + Progress += Speed; + + // 计算è´å¡žå°”曲线上的ä½ç½® + Vector2 currentPosition = CalculateBezierPosition(Progress); + + // 计算移动方å‘(用于拖尾旋转) + Vector2 velocity = currentPosition - Projectile.Center; + float rotation = velocity != Vector2.Zero ? velocity.ToRotation() : Projectile.rotation; + + Projectile.Center = currentPosition; + Projectile.rotation = rotation; + + // æ›´æ–°æ‹–å°¾ + UpdateTrail(currentPosition, rotation); + + // 动æ€å¤§å°å’Œé€æ˜Žåº¦ + Projectile.scale = 0.3f + pulse * 0.15f; + Projectile.alpha = (int)(80 + Math.Sin(pulseTimer * 2) * 20); + + // 生æˆç²’å­æ•ˆæžœ + SpawnParticles(currentPosition); + + // 如果到达终点,销æ¯å¼¹å¹• + if (Progress >= 1f) + { + Projectile.Kill(); + } + } + + private void SpawnParticles(Vector2 position) + { + // éšæœºç”Ÿæˆç²’å­ + if (Main.rand.NextBool(60)) + { + Color[] dustColors = new Color[] + { + new Color(30, 120, 30), + new Color(60, 180, 60), + new Color(120, 220, 120), + new Color(180, 230, 100), + new Color(220, 255, 150), + }; + + Color dustColor = dustColors[Main.rand.Next(dustColors.Length)]; + Dust dust = Dust.NewDustPerfect( + position + Main.rand.NextVector2Circular(10, 10), + DustID.TerraBlade, + Main.rand.NextVector2Circular(2, 2), + 0, dustColor, 0.5f); + dust.noGravity = true; + dust.fadeIn = 1f; + } + } + + private void UpdateTrail(Vector2 newPosition, float newRotation) + { + // 添加新ä½ç½®å’Œæ—‹è½¬åˆ°æ‹–å°¾ + trailPositions.Insert(0, newPosition); + trailRotations.Insert(0, newRotation); + + // é™åˆ¶æ‹–尾长度 + if (trailPositions.Count > MaxTrailLength) + { + trailPositions.RemoveAt(trailPositions.Count - 1); + trailRotations.RemoveAt(trailRotations.Count - 1); + } + } + + private Vector2 CalculateBezierPosition(float t) + { + // 计算控制点:在连线中点附近åç§»ï¼Œå½¢æˆæ›²çº¿ + Vector2 lineCenter = (StartPosition + EndPosition) / 2f; + Vector2 lineDirection = (EndPosition - StartPosition).SafeNormalize(Vector2.UnitY); + Vector2 perpendicular = new Vector2(-lineDirection.Y, lineDirection.X); + + // 使用基于时间的å移,使曲线有动æ€å˜åŒ– + float offsetAmount = 40f; + float timeOffset = (float)Main.timeForVisualEffects * 0.03f; + float sinOffset = (float)System.Math.Sin(timeOffset + Projectile.identity * 0.5f) * offsetAmount; + + Vector2 controlPoint = lineCenter + perpendicular * sinOffset; + + // è´å¡žå°”曲线计算 + float u = 1 - t; + Vector2 position = u * u * StartPosition + + 2 * u * t * controlPoint + + t * t * EndPosition; + + return position; + } + + public override bool PreDraw(ref Color lightColor) + { + // 绘制细长拖尾 + DrawTrail(); + + // 绘制能é‡çƒå¤´éƒ¨ + DrawHead(); + + + return false; + } + + private void DrawHead() + { + Texture2D tex = ModAsset.ForestRainVine_Cut.Value; + Texture2D bloom = ModAsset.ForestRainVine_Cut_Bloom.Value; + Main.spriteBatch.Draw(bloom, Projectile.Center - Main.screenPosition, null, new Color(0.13f, 0.4f, 0.04f, 0f), Projectile.rotation + MathHelper.PiOver2, bloom.Size() * 0.5f, Projectile.ai[0], SpriteEffects.None, 0); + Main.spriteBatch.Draw(tex, Projectile.Center - Main.screenPosition, null, new Color(0.7f, 1f, 0.4f, 1f), Projectile.rotation + MathHelper.PiOver2, tex.Size() * 0.5f, Projectile.ai[0], SpriteEffects.None, 0); + } + + private void DrawTrail() + { + Texture2D texture = TextureAssets.MagicPixel.Value; + Rectangle sourceRect = new Rectangle(0, 0, 1, 1); + + for (int i = 0; i < trailPositions.Count - 1; i++) + { + float progress = (float)i / trailPositions.Count; + Vector2 currentPos = trailPositions[i] - Main.screenPosition; + Vector2 nextPos = trailPositions[i + 1] - Main.screenPosition; + + // 计算两点之间的å‘é‡ + Vector2 segmentVector = nextPos - currentPos; + float segmentLength = segmentVector.Length(); + + if (segmentLength > 0) + { + Vector2 segmentDirection = segmentVector / segmentLength; + float segmentRotation = segmentDirection.ToRotation(); + + // æ‹–å°¾é€æ¸å˜å°å’Œé€æ˜Ž + float trailAlpha = (1f - progress) * 0.7f; + float trailWidth = 8f * (1f - progress) * 0.5f; // å®½åº¦åŠ å€ + + // æ ¹æ®æ‹–å°¾ä½ç½®ä½¿ç”¨ä¸åŒé¢œè‰² + Color trailColor; + if (progress < 0.2f) + { + trailColor = new Color(140, 250, 160, 255); + } + else if (progress < 0.3f) + { + trailColor = new Color(60, 140, 60, 30); + } + else if (progress < 0.7f) + { + trailColor = new Color(20, 90, 120, 15); + } + else + { + trailColor = new Color(1, 12, 70, 6); + } + + trailColor *= Projectile.alpha / 255f; + + // 绘制细长拖尾段 - ä½¿ç”¨çŸ©å½¢çº¹ç† + Main.EntitySpriteDraw( + texture, + currentPos, + sourceRect, + Color.Black * (1 - progress) * 0.5f, + segmentRotation, + new Vector2(0, 0.5f), + new Vector2(segmentLength, trailWidth * Projectile.ai[0]), + SpriteEffects.None, + 0); + Main.EntitySpriteDraw( + texture, + currentPos, + sourceRect, + trailColor, + segmentRotation, + new Vector2(0, 0.5f), + new Vector2(segmentLength, trailWidth * Projectile.ai[0]), + SpriteEffects.None, + 0); + } + + if (i % 3 == 0) + { + Texture2D orbTexture = GetOrbTexture(); + float pointScale = 0.1f + (1f - progress) * 0.2f; + Color pointColor = new Color(150, 255, 150, (int)(200 * (1f - progress))) * (Projectile.alpha / 255f); + + Main.EntitySpriteDraw( + orbTexture, + currentPos, + null, + pointColor, + 0f, + orbTexture.Size() * 0.5f, + pointScale * Projectile.ai[0], + SpriteEffects.None, + 0); + } + } + } + + private Texture2D GetOrbTexture() + { + return (Texture2D)ModContent.Request(Texture); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/VineWand/VineEnergyOrb.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/VineWand/VineEnergyOrb.png new file mode 100644 index 000000000..8e4a991f8 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Miscs/VineWand/VineEnergyOrb.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Pets/Photophore_lightPetProj.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Pets/Photophore_lightPetProj.cs new file mode 100644 index 000000000..6b3100862 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Pets/Photophore_lightPetProj.cs @@ -0,0 +1,52 @@ +using Everglow.Yggdrasil.KelpCurtain.Buffs; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Pets +{ + public class Photophore_lightPetProj : ModProjectile + { + public override void SetStaticDefaults() + { + Main.projPet[Projectile.type] = true; + ProjectileID.Sets.LightPet[Projectile.type] = true; + } + + public override void SetDefaults() + { + Projectile.width = 30; + Projectile.height = 30; + Projectile.penetrate = -1; + Projectile.netImportant = true; + Projectile.timeLeft *= 5; + Projectile.friendly = true; + Projectile.ignoreWater = true; + Projectile.scale = 0.8f; + Projectile.tileCollide = false; + Projectile.aiStyle = -1; + } + + public override void AI() + { + Player player = Main.player[Projectile.owner]; + + // If the player is no longer active (online) - deactivate (remove) the projectile. + if (!player.active) + { + Projectile.active = false; + return; + } + + // Keep the projectile disappearing as long as the player isn't dead and has the pet buff. + if (!player.dead && player.HasBuff(ModContent.BuffType())) + { + Projectile.timeLeft = 2; + } + Projectile.Center = player.MountedCenter + new Vector2(0, -32); + + // Lights up area around it. + if (!Main.dedServ) + { + Lighting.AddLight(Projectile.Center, Projectile.Opacity * 0.9f, Projectile.Opacity * 0.1f, Projectile.Opacity * 0.3f); + } + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Pets/Photophore_lightPetProj.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Pets/Photophore_lightPetProj.png new file mode 100644 index 000000000..145ce775a Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Pets/Photophore_lightPetProj.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Ranged/ArcI_Current.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Ranged/ArcI_Current.cs new file mode 100644 index 000000000..07ab0ed57 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Ranged/ArcI_Current.cs @@ -0,0 +1,260 @@ +using Everglow.Commons.DataStructures; +using Everglow.Commons.Graphics; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Terraria.DataStructures; +using Terraria.Utilities; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Ranged; + +public class ArcI_Current : ModProjectile +{ + public Projectile ParentProj; + + public NPC Target; + + public Vector2 TargetCenter; + + public List LightningWay = new List(); + + public int Timer = 0; + + public Vector2 ToParent = Vector2.One; + + public override void SetDefaults() + { + Projectile.timeLeft = 60; + Projectile.extraUpdates = 2; + Projectile.aiStyle = -1; + Projectile.penetrate = -1; + Projectile.friendly = true; + Projectile.width = 30; + Projectile.height = 30; + Projectile.tileCollide = false; + Projectile.hide = true; + } + + public override string Texture => Commons.ModAsset.Trail_10_black_Mod; + + public override void DrawBehind(int index, List behindNPCsAndTiles, List behindNPCs, List behindProjectiles, List overPlayers, List overWiresUI) + { + overPlayers.Add(index); + } + + public override void OnSpawn(IEntitySource source) + { + foreach (var proj in Main.projectile) + { + if (proj is not null && proj.active && proj.owner == Projectile.owner && proj.type == ModContent.ProjectileType()) + { + if ((proj.Center - Projectile.Center).Length() < 60) + { + ParentProj = proj; + break; + } + } + } + base.OnSpawn(source); + } + + public override void AI() + { + Timer++; + if (Timer < 2) + { + return; + } + if (ParentProj is not null && ParentProj.active) + { + var toMuzzle = new Vector2(12, -4 * ParentProj.spriteDirection); + toMuzzle = toMuzzle.RotatedBy(ParentProj.rotation); + Projectile.Center = ParentProj.Center + toMuzzle; + } + if (Target is not null && Target.active) + { + TargetCenter = Target.Center; + if (Timer == 2) + { + for (int k = 0; k < 12; k++) + { + var branch = new LightningDust_Trail + { + velocity = new Vector2(0, Main.rand.NextFloat(1, 10)).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + position = TargetCenter, + maxTime = Main.rand.Next(30, 40), + scale = Main.rand.Next(10, 16), + ai = new float[] { Main.rand.NextFloat(1f, 8f), Projectile.timeLeft }, + }; + Ins.VFXManager.Add(branch); + } + for (int k = 0; k < 60; k++) + { + var branch = new LightningDust_Trail + { + velocity = new Vector2(0, Main.rand.NextFloat(3, 6)).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + position = TargetCenter, + maxTime = Main.rand.Next(18, 25), + scale = Main.rand.Next(4, 6), + ai = new float[] { Main.rand.NextFloat(1f, 8f), Projectile.timeLeft }, + }; + Ins.VFXManager.Add(branch); + } + } + } + GenerateLightningWay(); + if (Projectile.timeLeft < 57) + { + Projectile.friendly = false; + } + } + + public void GenerateLightningWay() + { + LightningWay = new List(); + Vector2 mouseVec = Main.player[Projectile.owner].MouseWorld() - Projectile.Center; + mouseVec = mouseVec.NormalizeSafe() * 32f; + Vector2 cursorLightning = Projectile.Center + mouseVec; + Vector2 totalDirection = TargetCenter - cursorLightning; + totalDirection = totalDirection.NormalizeSafe(); + for (int k = 0; k < 200; k++) + { + LightningWay.Add(cursorLightning); + Vector2 moveStep = TargetCenter - cursorLightning; + moveStep = moveStep.NormalizeSafe() * 16; + Vector2 randomVec = totalDirection.RotatedBy(MathHelper.PiOver2) * GetRandomValueMove(k) * Timer / 8f; + moveStep += randomVec; + cursorLightning += moveStep; + if ((TargetCenter - cursorLightning).Length() < 24) + { + break; + } + } + LightningWay.Add(cursorLightning); + LightningWay.Add(TargetCenter); + } + + public void UpdateLightningWay() + { + if (LightningWay.Count <= 2) + { + return; + } + Vector2 totalDirection = LightningWay[^1] - LightningWay[0]; + totalDirection = totalDirection.NormalizeSafe(); + for (int k = 0; k < LightningWay.Count(); k++) + { + LightningWay[k] += totalDirection.RotatedBy(MathHelper.PiOver2 + GetRandomValueMove(k) * 0.5f) * GetRandomValueMove(k); + } + if (ToParent != Vector2.One) + { + for (int k = 0; k < LightningWay.Count(); k++) + { + LightningWay[k] *= (Projectile.Center - TargetCenter) / ToParent; + } + } + List lightning = new List(); + for (int k = 0; k < LightningWay.Count() - 1; k++) + { + lightning.Add(LightningWay[k]); + if ((LightningWay[k] - LightningWay[k + 1]).Length() > 28) + { + lightning.Add((LightningWay[k] + LightningWay[k + 1]) * 0.5f); + } + } + lightning.Add(LightningWay[^1]); + LightningWay = [.. lightning]; + ToParent = Projectile.Center - TargetCenter; + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + if (LightningWay.Count <= 2) + { + return false; + } + foreach (var pos in LightningWay) + { + Rectangle rectangle = new Rectangle((int)pos.X - 12, (int)pos.Y - 12, 24, 24); + if (rectangle.Intersects(targetHitbox)) + { + return true; + } + } + return false; + } + + public float GetRandomValueMove(float index) + { + float value = 0; + for (int i = 0; i < 8; i++) + { + value += MathF.Sin((i + index) * MathF.Pow(2, i) * 0.5f + (float)Main.time / 264f + Projectile.ai[0]) * MathF.Pow(2, -i); + } + return value; + } + + public override bool PreDraw(ref Color lightColor) + { + if (LightningWay.Count <= 2) + { + return false; + } + List bars = new List(); + + float width = Projectile.timeLeft / 60f; + width = MathF.Pow(width, 2); + float value = Timer / 60f; + GradientColor gradientColor = new GradientColor(); + gradientColor.colorList.Add((new Color(1f, 1f, 1f, 0), 0)); + gradientColor.colorList.Add((new Color(140, 232, 255, 0), 0.2f)); + gradientColor.colorList.Add((new Color(252, 170, 255, 0), 0.4f)); + gradientColor.colorList.Add((new Color(255, 166, 114, 0), 0.6f)); + gradientColor.colorList.Add((new Color(255, 84, 81, 0), 0.8f)); + gradientColor.colorList.Add((new Color(0, 0, 0, 0), 1)); + Color drawColor = gradientColor.GetColor(value); + + for (int k = 0; k < LightningWay.Count(); k++) + { + Vector2 dir = Vector2.One; + if (k < LightningWay.Count() - 1) + { + dir = LightningWay[k + 1] - LightningWay[k]; + } + else + { + dir = LightningWay[k] - LightningWay[k - 1]; + } + dir = dir.NormalizeSafe().RotatedBy(MathHelper.PiOver2) * 36 * width; + Vector2 drawPos = LightningWay[k] - Main.screenPosition; + bars.Add(drawPos + dir, drawColor, new Vector3(k / 30f, 0, 0)); + bars.Add(drawPos - dir, drawColor, new Vector3(k / 30f, 1, 0)); + } + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + if (bars.Count > 2) + { + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Trail_10.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + + width *= 26; + Texture2D star = Commons.ModAsset.StarSlash.Value; + Texture2D bloom = Commons.ModAsset.LightPoint2.Value; + value = 1 - value; + Vector2 scaleH = new Vector2(value, 0.5f + value * 0.5f) * MathF.Pow(width, 0.5f) / 10f; + Main.EntitySpriteDraw(bloom, LightningWay[0] - Main.screenPosition, null, drawColor, 0, bloom.Size() * 0.5f, MathF.Pow(width, 0.2f) * 1f, SpriteEffects.None, 0); + Main.EntitySpriteDraw(star, LightningWay[0] - Main.screenPosition, null, drawColor, 0, star.Size() * 0.5f, scaleH, SpriteEffects.None, 0); + Main.EntitySpriteDraw(star, LightningWay[0] - Main.screenPosition, null, drawColor, MathHelper.PiOver2, star.Size() * 0.5f, scaleH, SpriteEffects.None, 0); + + Main.EntitySpriteDraw(bloom, LightningWay[^1] - Main.screenPosition, null, drawColor, 0, bloom.Size() * 0.5f, MathF.Pow(width, 0.2f) * 1f, SpriteEffects.None, 0); + Main.EntitySpriteDraw(star, LightningWay[^1] - Main.screenPosition, null, drawColor, 0, star.Size() * 0.5f, scaleH, SpriteEffects.None, 0); + Main.EntitySpriteDraw(star, LightningWay[^1] - Main.screenPosition, null, drawColor, MathHelper.PiOver2, star.Size() * 0.5f, scaleH, SpriteEffects.None, 0); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Ranged/ArcI_proj.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Ranged/ArcI_proj.cs new file mode 100644 index 000000000..f086ef677 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Ranged/ArcI_proj.cs @@ -0,0 +1,203 @@ +using Everglow.Yggdrasil.KelpCurtain.Items.Weapons.UnderwaterTreasury; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Ranged; + +public class ArcI_proj : ModProjectile +{ + public Player Owner; + + public int useCount = 0; + + public int overridedamage; + + public IEntitySource shootSource = null; + + private Vector2 OwnerMouseWorld => Main.player[Projectile.owner].MouseWorld(); + + public override void SetDefaults() + { + Projectile.timeLeft = 6000000; + Projectile.aiStyle = -1; + Projectile.penetrate = -1; + Projectile.friendly = false; + Projectile.width = 30; + Projectile.height = 30; + Projectile.tileCollide = false; + } + + public override void OnSpawn(IEntitySource source) + { + Owner = Main.player[Projectile.owner]; + shootSource = source; + if (source is EntitySource_ItemUse_WithAmmo withammo && withammo.Entity is Player owner) + { + var modifer = owner.GetTotalDamage(withammo.Item.DamageType); + modifer.CombineWith(owner.bulletDamage); + CombinedHooks.ModifyWeaponDamage(owner, withammo.Item, ref modifer); + overridedamage = Math.Max( + 1, + (int)modifer.ApplyTo(withammo.Item.damage + ContentSamples.ItemsByType[withammo.AmmoItemIdUsed].damage)); + } + else + { + overridedamage = -1; + } + Projectile.hide = true; + base.OnSpawn(source); + } + + public override void AI() + { + if (Owner is null || !Owner.active || Owner.dead) + { + Projectile.Kill(); + return; + } + Projectile.Center = Owner.MountedCenter; + Projectile.velocity *= 0; + + var arcI = Owner.HeldItem.ModItem as ArcI; + if (arcI == null) + { + Projectile.Kill(); + return; + } + int controlCount = 0; + Vector2 toMouse = OwnerMouseWorld - Owner.MountedCenter; + toMouse = Vector2.Normalize(toMouse); + if (toMouse.X > 0) + { + Projectile.spriteDirection = 1; + } + if (toMouse.X < 0) + { + Projectile.spriteDirection = -1; + } + Projectile.rotation = toMouse.ToRotationSafe(); + Owner.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, Projectile.rotation - MathHelper.PiOver2); + if (Owner.controlUseItem) + { + if (Projectile.timeLeft % Owner.HeldItem.useTime == 0) + { + if (Owner.HasAmmo(Owner.HeldItem)) + { + Shoot(); + } + else + { + Projectile.Kill(); + } + } + controlCount++; + } + if (controlCount == 0) + { + Projectile.Kill(); + } + } + + private void Shoot() + { + var toMuzzle = new Vector2(12, -4 * Projectile.spriteDirection); + toMuzzle = toMuzzle.RotatedBy(Projectile.rotation); + Player player = Main.player[Projectile.owner]; + Vector2 toMouse = OwnerMouseWorld - Projectile.Center; + toMouse = Vector2.Normalize(toMouse); + Vector2 velocity = Vector2.Normalize(toMouse) * 27; + Item item = player.HeldItem; + if (item.ModItem is ArcI) + { + ShakerManager.AddShaker(Projectile.Center, new Vector2(0, -1).RotatedByRandom(MathHelper.TwoPi), 1, 5, 15, 0.9f, 0.8f, 120); + var arc = item.ModItem as ArcI; + arc.Power++; + float kb = item.knockBack; + float speed = 1f; + player.PickAmmo(item, out arc.ShootType, out speed, out overridedamage, out kb, out _, useCount == 0); + speed /= 20f; + if (arc.Power >= 5) + { + arc.Power = 0; + arc.CurrencyCount++; + if (arc.CurrencyCount > 3) + { + arc.CurrencyCount = 3; + } + } + var p = Projectile.NewProjectileDirect( + shootSource, + Projectile.Center + toMuzzle, + velocity * speed, + arc.ShootType, + overridedamage == -1 ? item.damage : overridedamage, + kb, + player.whoAmI); + p.CritChance = (int)(item.crit + player.GetCritChance(DamageClass.Generic)); + if (arc.CurrencyCount > 0) + { + int target = FindTarget(); + if (target >= 0) + { + Projectile p0 = Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center + toMuzzle, Vector2.zeroVector, ModContent.ProjectileType(), 120, 1, Projectile.owner); + ArcI_Current aIC = p0.ModProjectile as ArcI_Current; + if (aIC != null) + { + aIC.ParentProj = Projectile; + aIC.Target = Main.npc[target]; + } + arc.CurrencyCount--; + } + } + } + useCount++; + } + + public int FindTarget() + { + float closest = 360; + float nearestToMouse = 240; + int index = -1; + foreach (var npc in Main.npc) + { + if (npc is not null && npc.active && !npc.dontTakeDamage && !npc.friendly) + { + float distance = (npc.Center - Projectile.Center).Length(); + if (distance < closest) + { + Vector2 toMouse = Owner.MouseWorld() - npc.Center; + if (toMouse.Length() < nearestToMouse) + { + nearestToMouse = toMouse.Length(); + index = npc.whoAmI; + } + } + } + } + return index; + } + + public override void DrawBehind(int index, List behindNPCsAndTiles, List behindNPCs, List behindProjectiles, List overPlayers, List overWiresUI) + { + overPlayers.Add(index); + } + + public override bool PreDraw(ref Color lightColor) + { + Texture2D tex = ModAsset.ArcI_proj.Value; + Texture2D tex_glow = ModAsset.ArcI_glow.Value; + SpriteEffects spriteEffects = SpriteEffects.None; + if (Projectile.spriteDirection == -1) + { + spriteEffects = SpriteEffects.FlipVertically; + } + lightColor = Lighting.GetColor(Projectile.Center.ToTileCoordinates()); + Color glowColor = new Color(1f, 1f, 1f, 0); + Vector2 drawPos = Projectile.Center - Main.screenPosition; + Vector2 toMouse = OwnerMouseWorld - Projectile.Center; + toMouse = Vector2.Normalize(toMouse); + drawPos += toMouse * 24; + Main.EntitySpriteDraw(tex, drawPos, null, lightColor, Projectile.rotation, tex.Size() * 0.5f, 1f, spriteEffects, 0); + Main.EntitySpriteDraw(tex_glow, drawPos, null, glowColor, Projectile.rotation, tex.Size() * 0.5f, 1f, spriteEffects, 0); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Ranged/ArcI_proj.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Ranged/ArcI_proj.png new file mode 100644 index 000000000..d30af3f4f Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Ranged/ArcI_proj.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Ranged/GreenThornLauncher_Proj.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Ranged/GreenThornLauncher_Proj.cs index 59b952b8c..54a930be5 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Ranged/GreenThornLauncher_Proj.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Ranged/GreenThornLauncher_Proj.cs @@ -150,7 +150,9 @@ public override bool PreDraw(ref Color lightColor) { Vector2 drawPos = Projectile.oldPos[i] + Projectile.Size / 2f - Main.screenPosition; float fade = (Projectile.oldPos.Length - i) / (float)Projectile.oldPos.Length; - Color color = Color.Lerp(new Color(131, 219, 0, 100), Color.Transparent, 1f - fade); + Color color = Lighting.GetColor(Projectile.Center.ToTileCoordinates(), new Color(131, 219, 0, 100)); + color.A = 100; + color = Color.Lerp(color, Color.Transparent, 1f - fade); color *= 0.5f * fade; Main.spriteBatch.Draw(texture, drawPos, null, color, Projectile.rotation, origin, Projectile.scale, SpriteEffects.None, 0f); diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion.cs new file mode 100644 index 000000000..92b4239fa --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion.cs @@ -0,0 +1,308 @@ +using Everglow.Yggdrasil.KelpCurtain.Buffs; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Summon; + +public class CrimsonMoonAlgaeSummonStaff_minion : ModProjectile +{ + // Minion data + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.SummonProjectiles; + + // Minion data + public const float Minion_Knockback = 1f; + + /// + /// The distance to teleport back to the owner if the minion is too far away. + /// + private const int TeleportDistance = 1000; + + /// + /// The distance to search for target npc. + /// + private const int SearchDistance = 800; + + public int ProjectileAttackCooling = 0; + + public int ProjectileAttackCoolingMax = 60; + + public int ProjectileAttackCount = 6; + + public int BlockedTimer = 0; + + public int BlockedTimeMax = 120; + + public enum AttackState + { + None, + SelfKillingAttack, + ProjectileAttack, + } + + private Player Owner => Main.player[Projectile.owner]; + + /// + /// A timer that is used to control the minion's attack state and cooldown. Has different meanings in different states. + /// + private ref float Timer => ref Projectile.localAI[0]; + + /// + /// The whoAmI of the target npc that the minion is currently attacking. + /// Defaults to -1, and it will be reset to -1 if the target npc is not found or is inactive. + /// + private int TargetWhoAmI { get; set; } = -1; + + public AttackState MinionAttackState { get; private set; } = AttackState.None; + + public override void SetStaticDefaults() + { + Main.projFrames[Projectile.type] = 8; + } + + public override void SetDefaults() + { + Projectile.width = 20; + Projectile.height = 42; + + Projectile.DamageType = DamageClass.Summon; + Projectile.netImportant = true; + + Projectile.friendly = true; + Projectile.hostile = false; + Projectile.penetrate = -1; + Projectile.tileCollide = false; + Projectile.ignoreWater = true; + + Projectile.minionSlots = 1; + Projectile.minion = true; + + Projectile.timeLeft = 2; + + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 20; + } + + /// + /// Checks if the minion can deal damage to the target npc. + /// Can only do contact damage when the minion is in a normal attack state and charging or decelerating. + /// + /// + public override bool? CanDamage() => false; + + public override void AI() + { + UpdtateLifeCycle(); + Lighting.AddLight(Projectile.Center, new Vector3(1f, 0.9f, 0.8f)); + + // If the minion is too far from the player, reset state and teleport back to owner. + if (Vector2.Distance(Projectile.Center, Owner.Center) > TeleportDistance) + { + ResetTarget(); + Projectile.Center = Owner.Center; // Teleport back to owner + } + + // Check if the target npc is active. + if (!ProjectileUtils.MinionCheckTargetActive(TargetWhoAmI)) + { + ResetTarget(); + } + + if (TargetWhoAmI < 0) + { + ChasePlayer(Owner); + + // Search target npc around the owner + TargetWhoAmI = ProjectileUtils.FindTarget(Owner.Center, SearchDistance); + } + else + { + Attack(); + } + } + + private void ResetTarget() + { + TargetWhoAmI = -1; + } + + /// + /// Update timeleft and frame of the projectile. + /// + private void UpdtateLifeCycle() + { + Timer++; + + // Update timeleft + if (Owner.HasBuff()) + { + Projectile.timeLeft = 2; // Reset time left if the buff is active + } + else + { + Projectile.Kill(); // Kill the projectile if the buff is not active + } + + // Update frame + if (Main.timeForVisualEffects % 5 == 0) + { + Projectile.frame = ++Projectile.frame % Main.projFrames[Projectile.type]; + } + } + + private void ChasePlayer(Player player) + { + if (!Collision.IsWorldPointSolid(Projectile.Center)) + { + var destination = player.Center + new Vector2(-90 * player.direction, -60) + new Vector2(MathF.Sin(Timer * 0.0759537f + Projectile.whoAmI) * 160, MathF.Sin(Timer * 0.0324789f - Projectile.whoAmI) * 80); + var movement = destination - Projectile.Center; + if (movement.Length() < 1) + { + Projectile.velocity = movement; + return; + } + + var velocityMax = 5f; + if (movement.Length() >= 160f) + { + velocityMax = MathF.Max(5f, Owner.velocity.Length()); + } + + var toVelocity = movement.NormalizeSafe() * MathF.Min(movement.Length(), velocityMax); + Projectile.velocity = Vector2.Lerp(Projectile.velocity, toVelocity, 0.2f); + if (BlockedTimer > 0) + { + BlockedTimer--; + } + } + else + { + BlockedTimer += 3; + Vector2 toAir = TileUtils.ToNearestTypeOfTile(Projectile.Center, -1); + Projectile.velocity = Projectile.velocity * 0.95f + toAir.NormalizeSafe() * 16f * 0.05f; + if (BlockedTimer >= BlockedTimeMax) + { + ResetTarget(); + Projectile.Center = Owner.Center; + BlockedTimer = 0; + } + } + } + + private void Attack() + { + if (TargetWhoAmI <= -1) + { + return; + } + var target = Main.npc[TargetWhoAmI]; + Vector2 toTarget = target.Center - Projectile.Center; + if (ProjectileAttackCount > 0) + { + if (!Collision.IsWorldPointSolid(Projectile.Center)) + { + Vector2 chaseAim = target.Center - toTarget.NormalizeSafe() * 150f; + Vector2 toAim = chaseAim - Projectile.Center; + if (Collision.IsWorldPointSolid(toAim)) + { + toAim += TileUtils.ToNearestTypeOfTile(toAim, -1); + } + if (toAim.Length() > 120) + { + toAim = toAim.NormalizeSafe() * 12f; + } + else + { + toAim = toAim / 10f; + } + Projectile.velocity = Projectile.velocity * 0.95f + toAim * 0.05f; + foreach (var proj in Main.projectile) + { + if (proj is not null && proj.active && proj.type == Projectile.type && proj.owner == Projectile.owner) + { + Vector2 toProj = proj.Center - Projectile.Center; + if (toProj.Length() < 30f) + { + Projectile.Center -= toProj.NormalizeSafe() * (30f - toProj.Length()) / 10f; + } + } + } + if (toTarget.Length() < 300 && Projectile.velocity.Length() < 5f) + { + if (ProjectileAttackCooling == 0) + { + Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center, toTarget.NormalizeSafe() * 8f, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner); + ProjectileAttackCount--; + ProjectileAttackCooling = ProjectileAttackCoolingMax; + } + else + { + ProjectileAttackCooling--; + } + } + } + else + { + Vector2 toAir = TileUtils.ToNearestTypeOfTile(Projectile.Center, -1); + Projectile.velocity = Projectile.velocity * 0.95f + toAir.NormalizeSafe() * 16f * 0.05f; + } + } + else + { + if (ProjectileAttackCooling <= 0) + { + Projectile.velocity = Projectile.velocity * 0.95f + toTarget.NormalizeSafe() * 16f * 0.05f; + if (toTarget.Length() < 20f || Projectile.Hitbox.Intersects(target.Hitbox)) + { + Projectile.Kill(); + Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center, Vector2.zeroVector, ModContent.ProjectileType(), Projectile.damage * 3, Projectile.knockBack, Projectile.owner); + } + } + else + { + if (ProjectileAttackCooling > 40) + { + ProjectileAttackCooling = 40; + } + ProjectileAttackCooling--; + } + } + } + + public override bool PreDraw(ref Color lightColor) + { + var texture = ModContent.Request(Texture).Value; + var texture_glow = ModAsset.CrimsonMoonAlgaeSummonStaff_minion_glow.Value; + var texture_bloom = ModAsset.CrimsonMoonAlgaeSummonStaff_minion_bloom.Value; + var texture_sub = ModAsset.CrimsonMoonAlgaeSummonStaff_minion_spore.Value; + var frame = texture.Frame(1, Main.projFrames[Projectile.type], 0, Projectile.frame); + + // Fix projectile direction when chasing owner. + if (MathF.Abs(Projectile.velocity.X) <= 1E-05f && TargetWhoAmI == -1) + { + Projectile.direction = Owner.direction; + } + var spriteEffect = Projectile.direction < 0 ? SpriteEffects.None : SpriteEffects.FlipHorizontally; + Main.spriteBatch.Draw(texture, Projectile.Center - Main.screenPosition, frame, lightColor, Projectile.rotation, frame.Size() / 2f, Projectile.scale, spriteEffect, 0f); + Main.spriteBatch.Draw(texture_glow, Projectile.Center - Main.screenPosition, frame, Color.White, Projectile.rotation, frame.Size() / 2f, Projectile.scale, spriteEffect, 0f); + Main.spriteBatch.Draw(texture_bloom, Projectile.Center - Main.screenPosition, frame, new Color(1f, 1f, 1f, 0), Projectile.rotation, frame.Size() / 2f, Projectile.scale, spriteEffect, 0f); + if (ProjectileAttackCount > 0) + { + int offsetY = 0; + if (Projectile.frame == 3 || Projectile.frame == 4) + { + offsetY = 1; + } + if (Projectile.frame == 6) + { + offsetY = -2; + } + if (Projectile.frame == 7) + { + offsetY = -1; + } + for (int k = 0; k < ProjectileAttackCount; k++) + { + Main.spriteBatch.Draw(texture_sub, Projectile.Center + new Vector2(1 * Projectile.direction, -1 + offsetY) - Main.screenPosition + new Vector2(6, 0).RotatedBy(k / (float)ProjectileAttackCount * MathHelper.TwoPi + Projectile.whoAmI + Main.GlobalTimeWrappedHourly), null, new Color(1f, 1f, 1f, 0), Projectile.rotation + Projectile.whoAmI, texture_sub.Size() * 0.5f, Projectile.scale * 0.5f, SpriteEffects.None, 0f); + } + } + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion.png new file mode 100644 index 000000000..e89b85313 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_Explosion.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_Explosion.cs new file mode 100644 index 000000000..dc43cf1b9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_Explosion.cs @@ -0,0 +1,105 @@ +using Everglow.Yggdrasil.KelpCurtain.Buffs; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Summon; + +public class CrimsonMoonAlgaeSummonStaff_minion_Explosion : ModProjectile +{ + public override void SetDefaults() + { + Projectile.width = 60; + Projectile.height = 60; + Projectile.friendly = true; + Projectile.hostile = false; + Projectile.timeLeft = 60; + Projectile.aiStyle = -1; + Projectile.tileCollide = false; + Projectile.ignoreWater = true; + Projectile.penetrate = -1; + } + + public override void OnSpawn(IEntitySource source) + { + var gasRing = new RedAlgae_GasRing(); + gasRing.Position = Projectile.Center; + gasRing.MaxTime = 60; + gasRing.Scale = 14f; + gasRing.Visible = true; + gasRing.Active = true; + Ins.VFXManager.Add(gasRing); + float randomRot = Main.rand.NextFloat(MathHelper.TwoPi); + float randomSize = Main.rand.NextFloat(0.85f, 1.15f); + for (int k = 0; k < 36; k++) + { + var redAlgaeDust = new RedAlgae_Spark(); + redAlgaeDust.Position = Projectile.Center; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = new Vector2(0, 12 * randomSize).RotatedBy(MathHelper.TwoPi * k / 18f + randomRot); + redAlgaeDust.ai = new float[] { 0.9f }; + redAlgaeDust.MaxTime = 50; + redAlgaeDust.Scale = Main.rand.NextFloat(4.7f, 8f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + for (int k = 0; k < 18; k++) + { + var redAlgaeDust = new RedAlgae_Spark(); + redAlgaeDust.Position = Projectile.Center; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = new Vector2(0, 6 * randomSize).RotatedBy(MathHelper.TwoPi * k / 18f + randomRot); + redAlgaeDust.ai = new float[] { 0.9f }; + redAlgaeDust.MaxTime = 50; + redAlgaeDust.Scale = Main.rand.NextFloat(4.7f, 8f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + for (int k = 0; k < 20; k++) + { + var redAlgaeDust = new RedAlgae_Small_Dust(); + redAlgaeDust.Position = Projectile.Center; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = new Vector2(0, Main.rand.NextFloat(8f, 24f)).RotatedByRandom(MathHelper.TwoPi); + redAlgaeDust.ai = new float[] { 0.9f }; + redAlgaeDust.Frame = Main.rand.Next(10); + redAlgaeDust.MaxTime = 60; + redAlgaeDust.Scale = Main.rand.NextFloat(1.7f, 2f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + var star = new RedAlgaeHitStar(); + star.Position = Projectile.Center; + star.MaxTime = 30; + star.Scale = 2.2f; + star.Visible = true; + star.Active = true; + Ins.VFXManager.Add(star); + } + + public override void AI() + { + Projectile.velocity *= 0; + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + int type = ModContent.BuffType(); + if (!target.HasBuff(type)) + { + target.AddBuff(type, 900); + } + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + return MathUtils.IntersectsCircleAABB(Projectile.Center, 120, targetHitbox); + } + + public override bool PreDraw(ref Color lightColor) + { + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_Explosion.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_Explosion.png new file mode 100644 index 000000000..a310ea727 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_Explosion.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_bloom.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_bloom.png new file mode 100644 index 000000000..22d09cdff Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_bloom.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_glow.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_glow.png new file mode 100644 index 000000000..cbc60cc8f Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_glow.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_medium.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_medium.png new file mode 100644 index 000000000..a7cd704be Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_medium.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_spore.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_spore.cs new file mode 100644 index 000000000..5d1ece08c --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_spore.cs @@ -0,0 +1,107 @@ +using Everglow.Commons.DataStructures; +using Everglow.Commons.Templates.Weapons; +using Everglow.Commons.VFX.CommonVFXDusts; +using Everglow.Yggdrasil.KelpCurtain.Buffs; +using Everglow.Yggdrasil.KelpCurtain.VFXs; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Summon; + +public class CrimsonMoonAlgaeSummonStaff_minion_spore : ModProjectile +{ + public float Timer = 0; + + public override void SetDefaults() + { + Projectile.width = 20; + Projectile.height = 20; + Projectile.aiStyle = -1; + Projectile.tileCollide = true; + Projectile.friendly = true; + Projectile.hostile = false; + Projectile.penetrate = 1; + Projectile.DamageType = DamageClass.Summon; + } + + public override void AI() + { + Timer++; + Projectile.velocity = Projectile.velocity.RotatedBy(MathF.Sin(Timer * 0.1f + Projectile.ai[0]) * 0.01f); + Lighting.AddLight(Projectile.Center, new Vector3(1f, 0.9f, 0.8f) * 0.5f); + + Vector2 closestTargetPos = new Vector2(-10000); + foreach (var npc in Main.npc) + { + if (npc is not null && npc.active) + { + if (!npc.friendly && !npc.dontTakeDamage && npc.CanBeChasedBy(Projectile)) + { + Vector2 toTargetCheck = npc.Center - Projectile.Center; + if (toTargetCheck.Length() < (closestTargetPos - Projectile.Center).Length()) + { + closestTargetPos = npc.Center; + } + } + } + } + Vector2 toTarget = closestTargetPos - Projectile.Center - Projectile.velocity; + float distance = toTarget.Length(); + if (distance < 600) + { + float value = distance / 600f; + value = Math.Clamp(value, 0.1f, 0.95f); + Projectile.velocity = Projectile.velocity * value + toTarget.NormalizeSafe() * 12 * (1 - value); + Projectile.velocity = Projectile.velocity.NormalizeSafe() * 12f; + } + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + int type = ModContent.BuffType(); + if (!target.HasBuff(type)) + { + target.AddBuff(type, 900); + } + } + + public override bool PreDraw(ref Color lightColor) + { + Texture2D texture = ModContent.Request(Texture).Value; + Main.EntitySpriteDraw(texture, Projectile.Center - Main.screenPosition, null, new Color(1f, 1f, 1f, 1f), Projectile.rotation, texture.Size() * 0.5f, 1, SpriteEffects.None); + return false; + } + + public override void OnKill(int timeLeft) + { + if (timeLeft != 0) + { + for (int k = 0; k < 12; k++) + { + var redAlgaeDust = new RedAlgae_Spark(); + redAlgaeDust.Position = Projectile.Center; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = new Vector2(0, Main.rand.NextFloat(3f)).RotatedByRandom(MathHelper.TwoPi); + redAlgaeDust.ai = new float[] { 0.99f }; + redAlgaeDust.MaxTime = 30; + redAlgaeDust.Scale = Main.rand.NextFloat(1f, 2f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + float randomRot = Main.rand.NextFloat(MathHelper.TwoPi); + float randomSize = Main.rand.NextFloat(0.85f, 1.15f); + for (int k = 0; k < 18; k++) + { + var redAlgaeDust = new RedAlgae_Spark(); + redAlgaeDust.Position = Projectile.Center; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = new Vector2(0, 3 * randomSize).RotatedBy(MathHelper.TwoPi * k / 18f + randomRot); + redAlgaeDust.ai = new float[] { 0.9f }; + redAlgaeDust.MaxTime = 50; + redAlgaeDust.Scale = Main.rand.NextFloat(2.7f, 5f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_spore.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_spore.png new file mode 100644 index 000000000..1e73a341f Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/CrimsonMoonAlgaeSummonStaff_minion_spore.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMagicWhip_Proj.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMagicWhip_Proj.cs new file mode 100644 index 000000000..166eadff6 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMagicWhip_Proj.cs @@ -0,0 +1,136 @@ +using Everglow.Commons.Templates.Weapons.Whips; +using Everglow.Yggdrasil.KelpCurtain.Buffs; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Terraria.GameContent; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Summon; + +public class RedAlgaeMagicWhip_Proj : WhipProjectile +{ + public override void SetDef() + { + WhipLength = 420; + DustType = ModContent.DustType(); + } + + public override void GenerateDusts() + { + Player player = Main.player[Projectile.owner]; + float t = Projectile.ai[0] / TimeToFlyOut; + if (t > 0.4f && t < 0.9f) + { + float times = 3 * player.meleeSpeed; + if (times < 0) + { + times = 0; + } + if (WhipPointsForCollision.Count > 10) + { + for (int x = 0; x < times; x++) + { + int randSegment = WhipPointsForCollision.Count - 1; + Vector2 spinningpoint = WhipPointsForCollision[randSegment] - WhipPointsForCollision[randSegment - 1]; + + var redAlgaeDust = new RedAlgae_Spark(); + redAlgaeDust.Position = WhipPointsForCollision[randSegment]; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = Vector2.Zero; + redAlgaeDust.ai = new float[] { 0.9f }; + redAlgaeDust.MaxTime = 30; + redAlgaeDust.Scale = Main.rand.NextFloat(1f, 2f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + + if (Main.rand.NextBool(2)) + { + int randSegment = Main.rand.Next(WhipPointsForCollision.Count - 10, WhipPointsForCollision.Count); + Vector2 spinningpoint = WhipPointsForCollision[randSegment] - WhipPointsForCollision[randSegment - 1]; + + if (!Main.rand.NextBool(6)) + { + var redAlgaeDust = new RedAlgae_Small_Dust(); + redAlgaeDust.Position = WhipPointsForCollision[randSegment]; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = spinningpoint.RotatedBy((double)(player.direction * MathHelper.PiOver2), default); + redAlgaeDust.ai = new float[] { 0.9f }; + redAlgaeDust.MaxTime = 60; + redAlgaeDust.Scale = Main.rand.NextFloat(1f, 2f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + redAlgaeDust.Frame = Main.rand.Next(10); + Ins.VFXManager.Add(redAlgaeDust); + } + else + { + var redAlgaeDust = new RedAlgaeDust(); + redAlgaeDust.Position = WhipPointsForCollision[randSegment]; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = spinningpoint.RotatedBy((double)(player.direction * MathHelper.PiOver2), default) * 0.5f; + redAlgaeDust.ai = new float[] { Main.rand.NextFloat(-0.1f, 0.1f) }; + redAlgaeDust.MaxTime = 60; + redAlgaeDust.MaxScale = Main.rand.NextFloat(0.3f, 0.6f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + redAlgaeDust.Frame = Main.rand.Next(4); + Ins.VFXManager.Add(redAlgaeDust); + } + } + } + } + } + + public override void DrawWhip(float foreStep = 0) + { + Texture2D mainTexture = TextureAssets.Projectile[Projectile.type].Value; + int frameHeight = mainTexture.Height / VerticalFrameCount; + + var list0 = new List(); + FillWhipControlPoints(list0, foreStep); + for (int i = 0; i < list0.Count - 1; i++) + { + int frame = TileUtils.GetFixedRandomNumber_SingleSeed(i, 3) + 1; + if (frame == 0 && i > 0) + { + frame = 1; + } + if (frame != 0 && i == 0) + { + frame = 0; + } + if (i == list0.Count - 2) + { + frame = 4; + } + var rectangle = new Rectangle(0, frameHeight * frame, mainTexture.Width, frameHeight); + var origin = new Vector2(rectangle.Width / 2, 2f); + Vector2 positionNow = list0[i]; + Vector2 positionAdd = list0[i + 1] - positionNow; + float rotation = positionAdd.ToRotation() - MathHelper.PiOver2; + Color color = Lighting.GetColor(positionNow.ToTileCoordinates()); + Color glowColor = new Color(1f, 1f, 1f, 0); + if (foreStep != 0) + { + color *= (1 - foreStep / 3f) * 0.2f; + glowColor *= (1 - foreStep / 3f) * 0.2f; + } + var scale = new Vector2(1f, (positionAdd.Length() + 2f) / rectangle.Height * 2f); + Main.spriteBatch.Draw(mainTexture, list0[i] - Main.screenPosition, new Rectangle?(rectangle), color, rotation, origin, scale, SpriteEffects.None, 0f); + if (frame == 4) + { + Main.spriteBatch.Draw(mainTexture, list0[i] - Main.screenPosition, new Rectangle?(rectangle), glowColor, rotation, origin, scale, SpriteEffects.None, 0f); + } + } + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + int type = ModContent.BuffType(); + if (!target.HasBuff(type)) + { + target.AddBuff(type, 900); + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMagicWhip_Proj.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMagicWhip_Proj.png new file mode 100644 index 000000000..cd64c57a4 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMagicWhip_Proj.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMinionGyroscope_Proj.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMinionGyroscope_Proj.cs new file mode 100644 index 000000000..22c2c979e --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMinionGyroscope_Proj.cs @@ -0,0 +1,221 @@ +using Everglow.Commons.Templates.Weapons.Gyroscopes; +using Everglow.Yggdrasil.KelpCurtain.Buffs; +using Everglow.Yggdrasil.KelpCurtain.VFXs; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Summon; + +/// +/// Non-air summon projectile. +/// +public class RedAlgaeMinionGyroscope_Proj : GyroscopeProjectile +{ + public override void SetDefaults() + { + base.SetDefaults(); + SummonBuffType = ModContent.BuffType(); + } + + /// + /// Generate spark VFX from bottom; + /// + /// + public override void BottomSpark(int count = 1) + { + for (int i = 0; i < count; ++i) + { + if (Main.rand.NextBool(2)) + { + var redAlgaeDust = new RedAlgae_Small_Dust(); + redAlgaeDust.Position = Projectile.Bottom; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = new Vector2(0, Main.rand.NextFloat(0.2f)).RotatedByRandom(MathHelper.TwoPi); + redAlgaeDust.ai = new float[] { 0.99f }; + redAlgaeDust.MaxTime = 30; + redAlgaeDust.Scale = Main.rand.NextFloat(0.7f, 2f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + } + } + + /// + /// Low speed and high speed behave differently. + /// + public override void FindFrame() + { + Projectile.frameCounter += Math.Clamp((int)Power, 300, 600); + if (Power < 400) + { + if (Projectile.frameCounter > 1200) + { + Projectile.frame++; + Projectile.frameCounter = 0; + } + if (Projectile.frame >= 4) + { + Projectile.frame = 0; + } + } + else + { + if (Projectile.frameCounter > 1200) + { + Projectile.frame++; + Projectile.frameCounter = 0; + } + if (Projectile.frame >= 7) + { + Projectile.frame = 4; + } + } + if (Power > 100) + { + Projectile.rotation = Math.Clamp(Projectile.velocity.X * 0.05f, -0.8f, 0.8f); + } + else + { + float targetRot = (1.5f - Power / 100f) * MathF.Sin((float)Main.time * 0.24f + Projectile.whoAmI); + Projectile.rotation = targetRot * 0.1f + Projectile.rotation * 0.9f; + } + base.FindFrame(); + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + int type = ModContent.BuffType(); + if (!target.HasBuff(type)) + { + target.AddBuff(type, 900); + } + } + + /// + /// If rightclick to cancel the summon buff, remove projectile. + /// + public override void CheckKill() + { + Player player = Main.player[Projectile.owner]; + if (player.dead || !player.active) + { + player.ClearBuff(SummonBuffType); + Projectile.Kill(); + } + if (player.HasBuff(SummonBuffType)) + { + Projectile.timeLeft = 2; + } + else + { + Projectile.Kill(); + } + } + + public override void KillingSpark(int count = 20) => base.KillingSpark(count); + + public override void WhipSpark(int count = 20) + { + for (int k = 0; k < 18; k++) + { + var redAlgaeDust = new RedAlgae_Spark(); + redAlgaeDust.Position = Projectile.Center; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = new Vector2(0, 6).RotatedBy(MathHelper.TwoPi * k / 18f); + redAlgaeDust.ai = new float[] { 0.9f }; + redAlgaeDust.MaxTime = 50; + redAlgaeDust.Scale = Main.rand.NextFloat(2.7f, 5f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + for (int k = 0; k < 12; k++) + { + var redAlgaeDust = new RedAlgae_Spark(); + redAlgaeDust.Position = Projectile.Center; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = new Vector2(0, 3).RotatedBy(MathHelper.TwoPi * k / 12f); + redAlgaeDust.ai = new float[] { 0.9f }; + redAlgaeDust.MaxTime = 50; + redAlgaeDust.Scale = Main.rand.NextFloat(2.7f, 5f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + for (int k = 0; k < 20; k++) + { + var redAlgaeDust = new RedAlgae_Small_Dust(); + redAlgaeDust.Position = Projectile.Center; + redAlgaeDust.Rotation = Main.rand.NextFloat(MathHelper.TwoPi); + redAlgaeDust.Velocity = new Vector2(0, Main.rand.NextFloat(8f, 24f)).RotatedByRandom(MathHelper.TwoPi); + redAlgaeDust.ai = new float[] { 0.9f }; + redAlgaeDust.Frame = Main.rand.Next(10); + redAlgaeDust.MaxTime = 60; + redAlgaeDust.Scale = Main.rand.NextFloat(1.7f, 2f); + redAlgaeDust.Visible = true; + redAlgaeDust.Active = true; + Ins.VFXManager.Add(redAlgaeDust); + } + var gasRing = new RedAlgae_GasRing(); + gasRing.Position = Projectile.Center; + gasRing.MaxTime = 60; + gasRing.Scale = 10f; + gasRing.Visible = true; + gasRing.Active = true; + Ins.VFXManager.Add(gasRing); + int type = ModContent.BuffType(); + foreach (var npc in Main.npc) + { + if (npc is not null && npc.active) + { + if (!npc.friendly && !npc.dontTakeDamage && MathUtils.IntersectsCircleAABB(Projectile.Center, 180, npc.position, npc.position + npc.Size)) + { + if (!npc.HasBuff(type)) + { + npc.AddBuff(type, 900); + } + } + } + } + } + + public override bool PreDraw(ref Color lightColor) + { + Texture2D texture = ModAsset.RedAlgaeMinionGyroscope_Proj.Value; + Texture2D textureBloom = ModAsset.RedAlgaeMinionGyroscope_bloom.Value; + Texture2D textureGlow = ModAsset.RedAlgaeMinionGyroscope_Proj_glow.Value; + var frame = new Rectangle(0, 32 * Projectile.frame, 32, 32); + if (Projectile.frame >= 4) + { + frame = new Rectangle(32, 32 * (Projectile.frame - 4), 32, 32); + } + int whipCooling = 0; + foreach (var pC in WhipCoolingsForProjectileWhoAmI) + { + if (pC.CoolingTimer > whipCooling) + { + whipCooling = pC.CoolingTimer; + } + } + if (whipCooling > 0) + { + float value = whipCooling / 10f; + Main.spriteBatch.Draw(textureBloom, Projectile.Bottom - Main.screenPosition, null, new Color(value, value, value, 0), Projectile.rotation, new Vector2(64, 80), Projectile.scale, SpriteEffects.None, 0); + } + Main.spriteBatch.Draw(texture, Projectile.Bottom - Main.screenPosition, frame, lightColor, Projectile.rotation, new Vector2(frame.Width * 0.5f, frame.Height), Projectile.scale, SpriteEffects.None, 0); + Vector2 randomVec = new Vector2(0, Main.rand.NextFloat(2f)).RotatedByRandom(MathHelper.TwoPi); + if (Power > 500) + { + Main.spriteBatch.Draw(texture, Projectile.Bottom - Main.screenPosition + randomVec, frame, lightColor * 0.5f, Projectile.rotation, new Vector2(frame.Width * 0.5f, frame.Height), Projectile.scale, SpriteEffects.None, 0); + } + if (Owner != null) + { + var gyroscopePlayer = Owner.GetModPlayer(); + if (gyroscopePlayer != null && gyroscopePlayer.EnablePowerBarUI) + { + DrawPowerBar(); + } + } + Main.spriteBatch.Draw(textureGlow, Projectile.Bottom - Main.screenPosition, frame, new Color(1f, 1f, 1f, 0), Projectile.rotation, new Vector2(frame.Width * 0.5f, frame.Height), Projectile.scale, SpriteEffects.None, 0); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMinionGyroscope_Proj.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMinionGyroscope_Proj.png new file mode 100644 index 000000000..cc1cb4ad5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMinionGyroscope_Proj.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMinionGyroscope_Proj_glow.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMinionGyroscope_Proj_glow.png new file mode 100644 index 000000000..f100b763d Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMinionGyroscope_Proj_glow.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMinionGyroscope_bloom.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMinionGyroscope_bloom.png new file mode 100644 index 000000000..c135a06b5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/RedAlgaeMinionGyroscope_bloom.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog.cs new file mode 100644 index 000000000..1fb3dce15 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog.cs @@ -0,0 +1,534 @@ +using Everglow.Yggdrasil.KelpCurtain.Buffs; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Summon; + +public class Wither_Activated_Dog : ModProjectile +{ + /// + /// 0: Stand; 1: Walk; 2: Run + /// + public int State = 0; + + public Player Owner => Main.player[Projectile.owner]; + + public int EnemyTarget = -1; + + public float MaxSearchRange = 1600; + + /// + /// Allow ignore gravity for a few seconds while attacking. + /// + public int AttackingFlyTimer = 0; + + /// + /// Attacks Cooling. + /// + public int AttackingFlyCooling = 0; + + /// + /// If jumped to hit a target, set true. + /// + public bool AttackSetOff = false; + + /// + /// When there is no enemy, where should stay in. + /// + public Vector2 SitPosition = default; + + public Queue OldPositions = new Queue(); + + public Queue OldDirectionsAnsOldFrames = new Queue(); + + public int Timer = 0; + + public override void SetStaticDefaults() + { + Main.projFrames[Type] = 13; + base.SetStaticDefaults(); + } + + public override void SetDefaults() + { + Projectile.friendly = false; + Projectile.hostile = false; + Projectile.width = 70; + Projectile.height = 24; + Projectile.tileCollide = false; + Projectile.timeLeft = 300; + Projectile.aiStyle = -1; + Projectile.penetrate = -1; + Projectile.DamageType = DamageClass.Summon; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 12; + Projectile.minionSlots = 1; + Projectile.minion = true; + } + + public override void AI() + { + Timer++; + CheckKill(); + GravityBehavior(); + UpdateFrame(); + + if (EnemyTarget < 0) + { + EnemyTarget = FindEnemy(); + } + if (EnemyTarget != -1) + { + AttackEnemies(); + } + else + { + ApproachMyOwner(); + } + OldPositions.Enqueue(Projectile.Center); + OldDirectionsAnsOldFrames.Enqueue(new Vector2(Projectile.spriteDirection, Projectile.frame)); + if (OldPositions.Count > 15) + { + OldPositions.Dequeue(); + } + if (OldDirectionsAnsOldFrames.Count > 15) + { + OldDirectionsAnsOldFrames.Dequeue(); + } + } + + public Vector2 FindTargetPosWhenNoEnemies() + { + for (int x = 0; x < 200; x++) + { + Vector2 ownerPos = Owner.Center + new Vector2((GetOrderFromOwner() + 3) * 48 * Owner.direction * -1 + x * (x % 2 - 0.5f) * 100, 0); + Vector2 targetPos_Bottom = ownerPos; + int safeCount = 0; + for (int k = 0; k < 200; k++) + { + safeCount++; + if (Collision.IsWorldPointSolid(targetPos_Bottom)) + { + targetPos_Bottom.Y -= 4; + } + else + { + break; + } + } + for (int k = 0; k < 200; k++) + { + safeCount++; + if (!Collision.IsWorldPointSolid(targetPos_Bottom)) + { + targetPos_Bottom.Y += 2; + } + else + { + break; + } + } + if (safeCount <= 166) + { + return targetPos_Bottom; + } + } + return Vector2.zeroVector; + } + + /// + /// Get a unique order by Projectile.whoAmI. + /// + /// + public int GetOrderFromOwner() + { + int count = 0; + for (int i = 0; i < Main.projectile.Length; i++) + { + Projectile projectile = Main.projectile[i]; + if (projectile.active && projectile.owner == Owner.whoAmI) + { + if (projectile == Projectile) + { + return count; + } + if (projectile.type == Type) + { + count++; + } + } + } + return 0; + } + + /// + /// When there are no enemies, try go back to player. + /// + public void ApproachMyOwner() + { + ResetAttackState(); + float maxSpeed = 5f; + Vector2 targetPos = FindTargetPosWhenNoEnemies(); + if ((targetPos - SitPosition).Length() > 250 + MathF.Sin(Projectile.whoAmI) * 20) + { + SitPosition = targetPos; + } + Vector2 toTarget = SitPosition - Projectile.velocity - (Projectile.Bottom + new Vector2(0, 16)); + if (toTarget.Length() > 2400) + { + Projectile.Center = Owner.Center; + } + else if (toTarget.Length() > 300) + { + maxSpeed = 10f; + var normalToTarget = Vector2.Normalize(toTarget); + Projectile.velocity.X += normalToTarget.X * 0.5f; + if (MathF.Abs(Projectile.velocity.X) > maxSpeed) + { + Projectile.velocity.X = Math.Sign(Projectile.velocity.X) * maxSpeed; + } + if (Collision.IsWorldPointSolid(Projectile.Bottom + new Vector2(0, 16))) + { + Projectile.velocity.Y -= 1.5f; + } + } + else if (toTarget.Length() > 10) + { + var normalToTarget = Vector2.Normalize(toTarget); + Projectile.velocity.X += normalToTarget.X * 0.5f; + if (MathF.Abs(Projectile.velocity.X) > maxSpeed) + { + Projectile.velocity.X = Math.Sign(Projectile.velocity.X) * maxSpeed; + } + if (Collision.IsWorldPointSolid(Projectile.Bottom + new Vector2(0, 16))) + { + Projectile.velocity.Y -= 1f; + } + } + else if (toTarget.Length() > 5) + { + Projectile.velocity *= 0.5f; + } + else + { + Projectile.velocity *= 0; + } + if (MathF.Abs(Projectile.velocity.X) > 5) + { + State = 2; + } + else if (MathF.Abs(Projectile.velocity.X) > 1) + { + State = 1; + } + else + { + State = 0; + } + + if (Projectile.velocity.X < -1) + { + Projectile.spriteDirection = -1; + } + if (Projectile.velocity.X > 1) + { + Projectile.spriteDirection = 1; + } + } + + /// + /// Attack. + /// + public void AttackEnemies() + { + NPC npc = Main.npc[EnemyTarget]; + + // if target is invalid, discard. + if (npc == null || !npc.active || npc.life <= 0) + { + EnemyTarget = -1; + ResetAttackState(); + return; + } + if ((npc.Center - Projectile.Center).Y < -300) + { + EnemyTarget = -1; + ResetAttackState(); + return; + } + + if (AttackingFlyCooling <= 0) + { + AttackingFlyTimer++; + if (AttackingFlyTimer >= 60) + { + ResetAttackState(); + } + float maxSpeed = 10f; + Vector2 targetPos = npc.Center; + Vector2 toTarget = targetPos - Projectile.Center; + if (toTarget.Length() < 20) + { + ResetAttackState(); + } + if (toTarget.Length() <= 240 && !AttackSetOff) + { + AttackSetOff = true; + Projectile.friendly = true; + Projectile.velocity = toTarget.NormalizeSafe() * 24f; + } + if (!AttackSetOff) + { + toTarget = Vector2.Normalize(toTarget); + Projectile.velocity.X += toTarget.X * 0.5f; + if (MathF.Abs(Projectile.velocity.X) > maxSpeed) + { + Projectile.velocity.X = Math.Sign(Projectile.velocity.X) * maxSpeed; + } + } + if (AttackSetOff) + { + float cosTheta = Vector2.Dot(Projectile.velocity.NormalizeSafe(), toTarget.NormalizeSafe()); + if (cosTheta <= 0) + { + ResetAttackState(); + } + } + } + else + { + AttackSetOff = false; + AttackingFlyTimer = 0; + if (Projectile.velocity.Y < 0) + { + Projectile.velocity *= 0.8f; + } + else + { + Projectile.velocity.X *= 0.8f; + } + AttackingFlyCooling--; + if (AttackingFlyCooling <= 0) + { + AttackingFlyCooling = 0; + } + } + if (MathF.Abs(Projectile.velocity.X) > 10) + { + State = 2; + } + else if (MathF.Abs(Projectile.velocity.X) > 1) + { + State = 1; + } + else + { + State = 0; + } + + if (Projectile.velocity.X < -1) + { + Projectile.spriteDirection = -1; + } + if (Projectile.velocity.X > 1) + { + Projectile.spriteDirection = 1; + } + } + + public void ResetAttackState() + { + Projectile.friendly = false; + AttackingFlyCooling = Main.rand.Next(20, 50); + AttackSetOff = false; + AttackingFlyTimer = 0; + } + + /// + /// Find a npc index which can be an enemy. + /// + /// + public int FindEnemy() + { + if (Owner.MinionAttackTargetNPC != -1) + { + return Owner.MinionAttackTargetNPC; + } + float minDetectionRange = MaxSearchRange; + int targeWhoAmI = -1; + foreach (NPC npc in Main.npc) + { + if (npc != null && npc.active && npc.life > 0 && !npc.friendly && npc.type != NPCID.TargetDummy && !npc.CountsAsACritter && npc.CanBeChasedBy() && !npc.dontTakeDamage) + { + float distance = (npc.Center - Owner.Center).Length(); + if (distance < MaxSearchRange) + { + if (Collision.CanHit(npc.Center - Vector2.One, 2, 2, Projectile.Center - Vector2.One, 2, 2)) + { + if (npc.boss) + { + distance -= 600; + } + if (distance < minDetectionRange) + { + targeWhoAmI = npc.whoAmI; + minDetectionRange = distance; + } + } + } + } + } + return targeWhoAmI; + } + + public void UpdateFrame() + { + switch (State) + { + case 0: + Projectile.frame = 0; + break; + case 1: + Projectile.frameCounter++; + if (Projectile.frameCounter > 5) + { + Projectile.frame++; + Projectile.frameCounter = 0; + if (Projectile.frame >= 8) + { + Projectile.frame = 2; + } + } + break; + case 2: + if (Projectile.frame < 8) + { + Projectile.frame = 8; + } + Projectile.frameCounter++; + if (Projectile.frameCounter > 5) + { + Projectile.frame++; + Projectile.frameCounter = 0; + if (Projectile.frame >= 13) + { + Projectile.frame = 8; + } + } + break; + } + } + + public void GravityBehavior() + { + if (AttackingFlyTimer > 0) + { + return; + } + if (!Collision.IsWorldPointSolid(Projectile.Center + new Vector2(0, 28))) + { + Projectile.velocity.Y += 0.3f; + if (Projectile.velocity.Y > 20) + { + Projectile.velocity.Y = 20; + } + } + else + { + Projectile.velocity.Y *= 0; + for (int j = 0; j < 32; j++) + { + Projectile.position.Y -= 1; + if (!Collision.IsWorldPointSolid(Projectile.Center + new Vector2(0, 28))) + { + Projectile.position.Y += 1; + break; + } + } + } + } + + /// + /// If rightclick to cancel the summon buff, remove projectile. + /// + public void CheckKill() + { + Player player = Main.player[Projectile.owner]; + if (player.dead || !player.active) + { + player.ClearBuff(ModContent.BuffType()); + Projectile.Kill(); + } + if (player.HasBuff(ModContent.BuffType())) + { + Projectile.timeLeft = 2; + } + else + { + Projectile.Kill(); + } + } + + public void FindFrame() + { + if (State == 0) + { + Projectile.frame = 0; + } + } + + public override void OnKill(int timeLeft) + { + if (Owner.ownedProjectileCounts[Type] <= 1) + { + Owner.ClearBuff(ModContent.BuffType()); + } + } + + public override bool PreDraw(ref Color lightColor) + { + Rectangle drawFrame = new Rectangle(0, Projectile.frame * 64, 94, 64); + Texture2D mainTex = ModAsset.Wither_Activated_Dog.Value; + Texture2D glowTex = ModAsset.Wither_Activated_Dog_glow.Value; + Texture2D glowTex_c = ModAsset.Wither_Activated_Dog_glow_collar.Value; + Texture2D bloomTex = ModAsset.Wither_Activated_Dog_bloom.Value; + SpriteEffects spriteEffects = SpriteEffects.None; + if (Projectile.spriteDirection == -1) + { + spriteEffects = SpriteEffects.FlipHorizontally; + } + lightColor = Lighting.GetColor(Projectile.Center.ToTileCoordinates()); + Color glowColor = new Color(1f, 1f, 1f, 0); + float count = OldPositions.Count; + for (int t = 0; t < count; t++) + { + Rectangle trailFrame = new Rectangle(0, (int)(OldDirectionsAnsOldFrames.ToArray()[t].Y * 64), 94, 64); + SpriteEffects trailSpriteEffects = SpriteEffects.None; + if (OldDirectionsAnsOldFrames.ToArray()[t].X == -1) + { + trailSpriteEffects = SpriteEffects.FlipHorizontally; + } + Vector2 trailPos = OldPositions.ToArray()[t] - Main.screenPosition; + float trailFade = t / count * 0.5f; + Main.spriteBatch.Draw(mainTex, trailPos, trailFrame, lightColor * trailFade * 0.2f, Projectile.rotation, drawFrame.Size() * 0.5f, Projectile.scale, trailSpriteEffects, 0); + } + Main.spriteBatch.Draw(mainTex, Projectile.Center - Main.screenPosition, drawFrame, lightColor, Projectile.rotation, drawFrame.Size() * 0.5f, Projectile.scale, spriteEffects, 0); + Main.spriteBatch.Draw(glowTex, Projectile.Center - Main.screenPosition, drawFrame, glowColor, Projectile.rotation, drawFrame.Size() * 0.5f, Projectile.scale, spriteEffects, 0); + Main.spriteBatch.Draw(glowTex_c, Projectile.Center - Main.screenPosition, drawFrame, glowColor, Projectile.rotation, drawFrame.Size() * 0.5f, Projectile.scale, spriteEffects, 0); + Main.spriteBatch.Draw(bloomTex, Projectile.Center - Main.screenPosition, drawFrame, glowColor, Projectile.rotation, drawFrame.Size() * 0.5f, Projectile.scale, spriteEffects, 0); + + for (int t = 0; t < count; t++) + { + Rectangle trailFrame = new Rectangle(0, (int)(OldDirectionsAnsOldFrames.ToArray()[t].Y * 64), 94, 64); + SpriteEffects trailSpriteEffects = SpriteEffects.None; + if (OldDirectionsAnsOldFrames.ToArray()[t].X == -1) + { + trailSpriteEffects = SpriteEffects.FlipHorizontally; + } + Vector2 trailPos = OldPositions.ToArray()[t] - Main.screenPosition; + float trailFade = t / count * 0.5f; + Main.spriteBatch.Draw(glowTex, trailPos, trailFrame, glowColor * trailFade, Projectile.rotation, drawFrame.Size() * 0.5f, Projectile.scale, trailSpriteEffects, 0); + } + + Lighting.AddLight(Projectile.Center + new Vector2(36 * Projectile.spriteDirection, 0), new Vector3(0.1f, 0.6f, 0.2f)); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog.png new file mode 100644 index 000000000..e6562868b Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_Summon.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_Summon.cs new file mode 100644 index 000000000..19b4542b0 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_Summon.cs @@ -0,0 +1,251 @@ +using Everglow.Commons.DataStructures; +using Everglow.Yggdrasil.KelpCurtain.Buffs; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Summon; + +public class Wither_Activated_Dog_Summon : ModProjectile +{ + public int Timer = 0; + + public override void SetDefaults() + { + Projectile.friendly = false; + Projectile.hostile = false; + Projectile.width = 40; + Projectile.height = 40; + Projectile.tileCollide = false; + Projectile.timeLeft = 60; + Projectile.aiStyle = -1; + Projectile.penetrate = -1; + } + + public override void DrawBehind(int index, List behindNPCsAndTiles, List behindNPCs, List behindProjectiles, List overPlayers, List overWiresUI) + { + overPlayers.Add(index); + } + + public override void OnSpawn(IEntitySource source) + { + float minRange = 40f; + float maxRange = 120f; + for (int k = 0; k < 30; k++) + { + var leaf = new ActivatedDogStaff_Leaf + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2) + Projectile.velocity, + Active = true, + Visible = true, + Position = Projectile.Center + new Vector2(0, Main.rand.NextFloat(minRange, maxRange)).RotatedByRandom(MathHelper.TwoPi), + MaxTime = Main.rand.Next(70, 120), + Scale = Main.rand.Next(8, 10), + ParentEneity = Projectile, + ai = new float[] { Main.rand.NextFloat(1f, 8f), Projectile.timeLeft }, + }; + Ins.VFXManager.Add(leaf); + } + for (int k = 0; k < 10; k++) + { + var branch = new ActivatedDogStaff_Branch + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2) + Projectile.velocity, + Active = true, + Visible = true, + Position = Projectile.Center + new Vector2(0, Main.rand.NextFloat(minRange, maxRange)).RotatedByRandom(MathHelper.TwoPi), + MaxTime = Main.rand.Next(70, 120), + Scale = Main.rand.Next(18, 30), + ParentEneity = Projectile, + Frame = Main.rand.Next(5), + ai = new float[] { Main.rand.NextFloat(1f, 8f), Projectile.timeLeft }, + }; + Ins.VFXManager.Add(branch); + } + } + + public override void AI() + { + Timer++; + if (Projectile.timeLeft < 30f) + { + return; + } + float minRange = 40f; + float maxRange = 120f; + for (int k = 0; k < 3; k++) + { + var leaf = new ActivatedDogStaff_Leaf + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2) + Projectile.velocity, + Active = true, + Visible = true, + Position = Projectile.Center + new Vector2(0, Main.rand.NextFloat(minRange, maxRange)).RotatedByRandom(MathHelper.TwoPi), + MaxTime = Main.rand.Next(70, 120), + Scale = Main.rand.Next(8, 10), + ParentEneity = Projectile, + ai = new float[] { Main.rand.NextFloat(1f, 8f), Projectile.timeLeft }, + }; + Ins.VFXManager.Add(leaf); + } + for (int k = 0; k < 1; k++) + { + var branch = new ActivatedDogStaff_Branch + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2) + Projectile.velocity, + Active = true, + Visible = true, + Position = Projectile.Center + new Vector2(0, Main.rand.NextFloat(minRange, maxRange)).RotatedByRandom(MathHelper.TwoPi), + MaxTime = Main.rand.Next(70, 120), + Scale = Main.rand.Next(18, 30), + ParentEneity = Projectile, + Frame = Main.rand.Next(5), + ai = new float[] { Main.rand.NextFloat(1f, 8f), Projectile.timeLeft }, + }; + Ins.VFXManager.Add(branch); + } + } + + public override void OnKill(int timeLeft) + { + base.OnKill(timeLeft); + Player player = Main.player[Projectile.owner]; + Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center, Vector2.zeroVector, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner); + player.AddBuff(ModContent.BuffType(), 1800000); + + float minRange = 10f; + float maxRange = 40f; + for (int k = 0; k < 30; k++) + { + var leaf = new ActivatedDogStaff_Leaf_physical + { + Velocity = new Vector2(0, Main.rand.NextFloat(7, 12)).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = Projectile.Center + new Vector2(0, Main.rand.NextFloat(minRange, maxRange)).RotatedByRandom(MathHelper.TwoPi), + MaxTime = Main.rand.Next(70, 120), + Scale = Main.rand.Next(8, 10), + ai = new float[] { Main.rand.NextFloat(1f, 8f), Projectile.timeLeft }, + }; + Ins.VFXManager.Add(leaf); + } + for (int k = 0; k < 10; k++) + { + var branch = new ActivatedDogStaff_Branch_physical + { + Velocity = new Vector2(0, Main.rand.NextFloat(7, 12)).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = Projectile.Center + new Vector2(0, Main.rand.NextFloat(minRange, maxRange)).RotatedByRandom(MathHelper.TwoPi), + MaxTime = Main.rand.Next(70, 120), + Scale = Main.rand.Next(18, 30), + Frame = Main.rand.Next(5), + ai = new float[] { Main.rand.NextFloat(1f, 8f), Projectile.timeLeft }, + }; + Ins.VFXManager.Add(branch); + } + for (int k = 0; k < 10; k++) + { + var branch = new ActivatedDogStaff_green_Dust_Trail + { + velocity = new Vector2(0, Main.rand.NextFloat(7, 12)).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + position = Projectile.Center + new Vector2(0, Main.rand.NextFloat(minRange, maxRange)).RotatedByRandom(MathHelper.TwoPi), + maxTime = Main.rand.Next(70, 120), + scale = Main.rand.Next(18, 30), + ai = new float[] { Main.rand.NextFloat(1f, 8f), Projectile.timeLeft }, + }; + Ins.VFXManager.Add(branch); + } + for (int k = 0; k < 30; k++) + { + var branch = new ActivatedDogStaff_green_Dust_Trail + { + velocity = new Vector2(0, Main.rand.NextFloat(4, 8)).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + position = Projectile.Center + new Vector2(0, Main.rand.NextFloat(minRange, maxRange)).RotatedByRandom(MathHelper.TwoPi), + maxTime = Main.rand.Next(35, 50), + scale = Main.rand.Next(6, 12), + ai = new float[] { Main.rand.NextFloat(1f, 8f), Projectile.timeLeft }, + }; + Ins.VFXManager.Add(branch); + } + } + + public override bool PreDraw(ref Color lightColor) + { + float radius = 20 + MathF.Pow(Projectile.timeLeft / 60f, 0.5f) * 120; + float fade = MathF.Pow(Timer / 60f, 2.5f); + Vector2 ringWidth = new Vector2(0, -20f).RotatedBy(Projectile.spriteDirection); + Color drawColor = new Color(155, 62, 48, 0); + Color drawColor2 = new Color(255, 201, 0, 0); + float timeValue = Timer * 0.05f; + List bars = new List(); + List bars_Dark = new List(); + List bars2 = new List(); + for (int i = 0; i < 30; i++) + { + Vector2 circlePos = new Vector2(radius, 0).RotatedBy(i / 30f * MathHelper.TwoPi); + Vector2 oval = circlePos; + oval.Y *= 0.5f; + oval = oval.RotatedBy(Projectile.spriteDirection); + Vector2 drawPos = Projectile.Center + oval - Main.screenPosition; + bars.Add(drawPos + ringWidth, drawColor * fade, new Vector3(i / 10f * Projectile.spriteDirection + timeValue, 0, 0)); + bars.Add(drawPos - ringWidth, drawColor * fade, new Vector3(i / 10f * Projectile.spriteDirection + timeValue, 1, 0)); + + bars_Dark.Add(drawPos + ringWidth, Color.White * fade, new Vector3(i / 10f * Projectile.spriteDirection + timeValue, 0, 0)); + bars_Dark.Add(drawPos - ringWidth, Color.White * fade, new Vector3(i / 10f * Projectile.spriteDirection + timeValue, 1, 0)); + + bars2.Add(drawPos + ringWidth * 2f, drawColor2 * fade * 2, new Vector3(-i / 3f * Projectile.spriteDirection - timeValue * 1.5f, 0, 0)); + bars2.Add(drawPos - ringWidth * 2f, drawColor2 * fade * 2, new Vector3(-i / 3f * Projectile.spriteDirection - timeValue * 1.5f, 1, 0)); + + if (((-i / 3f * Projectile.spriteDirection - timeValue * 1.5f) + 10000) % 1 is > 0.5f and < 0.75f) + { + Lighting.AddLight(drawPos + Main.screenPosition, new Vector3(1f, 0.9f, 0.2f) * fade); + } + } + List lightRays = new List(); + for (int r = 0; r <= 60; r++) + { + lightRays.Add(Projectile.Center - Main.screenPosition, new Color(0.0f, 0.4f, 0.2f, 0), new Vector3(r / 60f, Timer / 160f, 0)); + lightRays.Add(Projectile.Center + new Vector2(0, 50).RotatedBy(r / 60f * MathHelper.TwoPi) - Main.screenPosition, new Color(0, 0, 0, 0), new Vector3(r / 60f, Timer / 160f, 0)); + } + if (bars.Count > 0 && bars_Dark.Count > 0 && bars2.Count > 0 && lightRays.Count > 0) + { + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullCounterClockwise, null, Main.GameViewMatrix.TransformationMatrix); + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Trail_9_black.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_Dark.ToArray(), 0, bars_Dark.Count - 2); + + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Trail_9.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.LightPoint2.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars2.ToArray(), 0, bars2.Count - 2); + + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Noise_hiveCyber.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, lightRays.ToArray(), 0, lightRays.Count - 2); + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + } + + Texture2D star = Commons.ModAsset.StarSlash.Value; + Texture2D star_black = Commons.ModAsset.StarSlash_black.Value; + float scaleValue = Timer / 60f; + scaleValue = MathF.Pow(scaleValue, 0.5f); + if (Projectile.timeLeft <= 5) + { + scaleValue *= Projectile.timeLeft / 5f; + } + Main.spriteBatch.Draw(star_black, Projectile.Center - Main.screenPosition, null, Color.White * 0.2f * scaleValue, 0, star.Size() * 0.5f, scaleValue, SpriteEffects.None, 0); + Main.spriteBatch.Draw(star_black, Projectile.Center - Main.screenPosition, null, Color.White * 0.2f * scaleValue, MathHelper.PiOver2, star.Size() * 0.5f, scaleValue * 1.3f, SpriteEffects.None, 0); + + Main.spriteBatch.Draw(star, Projectile.Center - Main.screenPosition, null, new Color(0.3f, 1f, 0.1f, 0) * scaleValue, 0, star.Size() * 0.5f, scaleValue, SpriteEffects.None, 0); + Main.spriteBatch.Draw(star, Projectile.Center - Main.screenPosition, null, new Color(0.3f, 1f, 0.1f, 0) * scaleValue, MathHelper.PiOver2, star.Size() * 0.5f, scaleValue * 1.3f, SpriteEffects.None, 0); + + Lighting.AddLight(Projectile.Center, new Vector3(0.3f, 1f, 0.1f) * scaleValue * 3); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_Summon.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_Summon.png new file mode 100644 index 000000000..d12857ab9 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_Summon.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_Summon_background.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_Summon_background.cs new file mode 100644 index 000000000..1c5b76a88 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_Summon_background.cs @@ -0,0 +1,89 @@ +using Everglow.Commons.DataStructures; +using Everglow.Yggdrasil.KelpCurtain.Buffs; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Terraria.DataStructures; +using Terraria.Utilities; + +namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Summon; + +public class Wither_Activated_Dog_Summon_background : ModProjectile +{ + public int Timer = 0; + + public override string Texture => ModAsset.Wither_Activated_Dog_Summon_Mod; + + public override void SetDefaults() + { + Projectile.friendly = false; + Projectile.hostile = false; + Projectile.width = 40; + Projectile.height = 40; + Projectile.tileCollide = false; + Projectile.timeLeft = 60; + Projectile.aiStyle = -1; + Projectile.penetrate = -1; + Projectile.hide = true; + } + + public override void AI() + { + Timer++; + } + + public override void DrawBehind(int index, List behindNPCsAndTiles, List behindNPCs, List behindProjectiles, List overPlayers, List overWiresUI) + { + behindProjectiles.Add(index); + } + + public override bool PreDraw(ref Color lightColor) + { + float radius = 20 + MathF.Pow(Projectile.timeLeft / 60f, 0.5f) * 120; + float fade = MathF.Pow(Timer / 60f, 2.5f); + Vector2 ringWidth = new Vector2(0, -20f).RotatedBy(Projectile.spriteDirection); + Color drawColor = new Color(155, 62, 48, 0); + Color drawColor2 = new Color(255, 201, 0, 0); + float timeValue = Timer * 0.05f; + List bars = new List(); + List bars_Dark = new List(); + List bars2 = new List(); + for (int i = 0; i < 30; i++) + { + Vector2 circlePos = new Vector2(radius, 0).RotatedBy(i / 30f * MathHelper.TwoPi); + Vector2 oval = circlePos; + oval.Y *= 0.5f; + oval = oval.RotatedBy(Projectile.spriteDirection); + Vector2 drawPos = Projectile.Center + oval - Main.screenPosition; + bars.Add(drawPos + ringWidth, drawColor * fade, new Vector3(i / 10f * Projectile.spriteDirection + timeValue, 0, 0)); + bars.Add(drawPos - ringWidth, drawColor * fade, new Vector3(i / 10f * Projectile.spriteDirection + timeValue, 1, 0)); + + bars_Dark.Add(drawPos + ringWidth, Color.White * fade, new Vector3(i / 10f * Projectile.spriteDirection + timeValue, 0, 0)); + bars_Dark.Add(drawPos - ringWidth, Color.White * fade, new Vector3(i / 10f * Projectile.spriteDirection + timeValue, 1, 0)); + + bars2.Add(drawPos + ringWidth * 2f, drawColor2 * fade * 2, new Vector3(-i / 3f * Projectile.spriteDirection - timeValue * 1.5f, 0, 0)); + bars2.Add(drawPos - ringWidth * 2f, drawColor2 * fade * 2, new Vector3(-i / 3f * Projectile.spriteDirection - timeValue * 1.5f, 1, 0)); + + if (((-i / 3f * Projectile.spriteDirection - timeValue * 1.5f) + 10000) % 1 is > 0.5f and < 0.75f) + { + Lighting.AddLight(drawPos + Main.screenPosition, new Vector3(1f, 0.9f, 0.2f) * fade); + } + } + if (bars.Count > 0 && bars_Dark.Count > 0 && bars2.Count > 0) + { + SpriteBatchState sBS = GraphicsUtils.GetState(Main.spriteBatch).Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullClockwise, null, Main.GameViewMatrix.TransformationMatrix); + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Trail_9_black.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_Dark.ToArray(), 0, bars_Dark.Count - 2); + + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.Trail_9.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + + Main.graphics.GraphicsDevice.Textures[0] = Commons.ModAsset.LightPoint2.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars2.ToArray(), 0, bars2.Count - 2); + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + } + + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_bloom.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_bloom.png new file mode 100644 index 000000000..454d7f799 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_bloom.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_glow.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_glow.png new file mode 100644 index 000000000..83de2fa74 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_glow.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_glow_collar.png b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_glow_collar.png new file mode 100644 index 000000000..3d641f51c Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Summon/Wither_Activated_Dog_glow_collar.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/TileEffect/SpongeOxygenBubble.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/TileEffect/SpongeOxygenBubble.cs index 624b88d4b..24dfd12a2 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/TileEffect/SpongeOxygenBubble.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/TileEffect/SpongeOxygenBubble.cs @@ -14,12 +14,10 @@ public override void SetDefaults() Projectile.height = 16; Projectile.friendly = false; Projectile.hostile = true; - Projectile.DamageType = DamageClass.Ranged; Projectile.penetrate = -1; Projectile.timeLeft = 120000; Projectile.tileCollide = true; Projectile.ignoreWater = false; - //Projectile.extraUpdates = 2; } public override void AI() diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DarkLakeBottomMud.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DarkLakeBottomMud.cs index 65de21cd1..96be8cf23 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DarkLakeBottomMud.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DarkLakeBottomMud.cs @@ -1,3 +1,4 @@ +using Everglow.Yggdrasil.Common.Tiles; using Everglow.Yggdrasil.KelpCurtain.Dusts; using Everglow.Yggdrasil.WorldGeneration; @@ -11,6 +12,8 @@ public override void PostSetDefaults() Main.tileMergeDirt[Type] = true; Main.tileBlockLight[Type] = true; Main.tileNoSunLight[Type] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[ModContent.TileType()][Type] = true; DustType = DustType = ModContent.DustType(); MinPick = 50; HitSound = SoundID.Dig; diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DarkLakeBottomMud.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DarkLakeBottomMud.png index 701eda68c..ee5b2ecc6 100644 Binary files a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DarkLakeBottomMud.png and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DarkLakeBottomMud.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AbandonedFishingNet.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AbandonedFishingNet.cs new file mode 100644 index 000000000..026587fc4 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AbandonedFishingNet.cs @@ -0,0 +1,82 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Terraria.GameContent.Drawing; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class AbandonedFishingNet : ModTile, ITileFluentlyDrawn +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 2; + TileObjectData.newTile.Width = 1; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 18, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(109, 92, 75)); + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + var tile = Main.tile[i, j]; + if (tile.TileFrameY == 0) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + } + return base.PreDraw(i, j, spriteBatch); + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + DrawFluctuatingFishingNet(pos, pos.ToWorldCoordinates() - screenPosition, spriteBatch, tileDrawing); + } + + /// + /// Draw a piece of lotus + /// + private void DrawFluctuatingFishingNet(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + var tile = Main.tile[tilePos]; + if (!TileDrawing.IsVisible(tile)) + { + return; + } + int paint = Main.tile[tilePos].TileColor; + Texture2D tex = PaintedTextureSystem.TryGetPaintedTexture(ModAsset.AbandonedFishingNet_Path, tile.TileType, 1, paint, tileDrawing); + tex ??= ModAsset.JadeLakeGreenAlgae.Value; + Rectangle frame = new Rectangle(2, 50, 48, 18); + int dir = 1; + if (tile.TileFrameX >= 54) + { + dir = -1; + } + List bars = new List(); + for (int k = 0; k <= 8; k++) + { + float value = k / 8f; + float offsetY = (float)Math.Sin((float)Main.time * 0.04f + tilePos.Y * 0.5f + k * 0.25f) * 6 * Math.Clamp(k / 3f, 0, 1) + 16; + Vector2 offset = new Vector2(value * frame.Width * dir, offsetY); + Vector2 drawPos = drawCenterPos + offset; + Color lightColor = Lighting.GetColor((drawCenterPos + Main.screenPosition).ToTileCoordinates()); + float coordX = (float)(Utils.Lerp(frame.X, frame.X + frame.Width, value) / tex.Width); + bars.Add(drawPos + new Vector2(0, frame.Height * 0.5f), lightColor, new Vector3(coordX, (float)(frame.Y + frame.Height) / tex.Height, 0)); + bars.Add(drawPos + new Vector2(0, -frame.Height * 0.5f), lightColor, new Vector3(coordX, (float)frame.Y / tex.Height, 0)); + } + if (bars.Count > 2) + { + spriteBatch.GraphicsDevice.Textures[0] = tex; + spriteBatch.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AbandonedFishingNet.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AbandonedFishingNet.png new file mode 100644 index 000000000..328ffa296 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AbandonedFishingNet.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AbandonedShrimpCage.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AbandonedShrimpCage.cs new file mode 100644 index 000000000..62c3a37ab --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AbandonedShrimpCage.cs @@ -0,0 +1,27 @@ +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class AbandonedShrimpCage : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 2; + TileObjectData.newTile.Width = 2; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 18, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(109, 92, 75)); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AbandonedShrimpCage.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AbandonedShrimpCage.png new file mode 100644 index 000000000..b09344787 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AbandonedShrimpCage.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AgedOxygenTank.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AgedOxygenTank.cs new file mode 100644 index 000000000..d6ec0c7e1 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AgedOxygenTank.cs @@ -0,0 +1,45 @@ +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.Projectiles.TileEffect; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class AgedOxygenTank : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 2; + TileObjectData.newTile.Width = 2; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 18, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(57, 83, 107)); + } + + public override void KillMultiTile(int i, int j, int frameX, int frameY) + { + if (frameX % 36 == 0 && frameY == 0) + { + Vector2 pos = new Point(i, j).ToWorldCoordinates() + new Vector2(8, 16); + var p0 = Projectile.NewProjectileDirect(WorldGen.GetProjectileSource_TileBreak(i, j), pos, new Vector2(0, -5), ModContent.ProjectileType(), 20, 0); + for (int k = 0; k < 6; k++) + { + var dust = Dust.NewDustDirect(pos - new Vector2(4) + new Vector2(-8, 0), 16, 16, ModContent.DustType()); + dust.customData = p0; + dust.velocity *= 0.3f; + dust.velocity.Y -= 2f; + } + } + base.KillMultiTile(i, j, frameX, frameY); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AgedOxygenTank.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AgedOxygenTank.png new file mode 100644 index 000000000..6c48e7af0 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/AgedOxygenTank.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/BrokenOxygenTank.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/BrokenOxygenTank.cs new file mode 100644 index 000000000..78316d985 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/BrokenOxygenTank.cs @@ -0,0 +1,27 @@ +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class BrokenOxygenTank : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 2; + TileObjectData.newTile.Width = 2; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 18, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(57, 83, 107)); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/BrokenOxygenTank.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/BrokenOxygenTank.png new file mode 100644 index 000000000..30e23e7b8 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/BrokenOxygenTank.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/CrimsonMoonAlgea.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/CrimsonMoonAlgea.cs new file mode 100644 index 000000000..5159c3de8 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/CrimsonMoonAlgea.cs @@ -0,0 +1,235 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Terraria.GameContent.Drawing; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class CrimsonMoonAlgea : ModTile, ITileFluentlyDrawn +{ + public override void PostSetDefaults() + { + Main.tileFrameImportant[Type] = false; + Main.tileNoAttach[Type] = true; + Main.tileCut[Type] = false; + Main.tileLavaDeath[Type] = true; + TileID.Sets.TouchDamageImmediate[Type] = 30; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 1; + TileObjectData.newTile.Width = 1; + TileObjectData.newTile.CoordinateWidth = 16; + TileObjectData.addTile(Type); + + DustType = ModContent.DustType(); + + AddMapEntry(new Color(127, 36, 89)); + HitSound = SoundID.Grass; + } + + public override bool IsTileDangerous(int i, int j, Player player) + { + if (player.HasBuff(BuffID.Dangersense)) + { + return true; + } + return false; + } + + public override void RandomUpdate(int i, int j) + { + var tile = Main.tile[i, j]; + if (tile.LiquidAmount <= 0) + { + WorldGen.KillTile(i, j); + return; + } + var tile2 = Main.tile[i, j - 1]; + + if (tile2.TileType != tile.TileType && !tile2.HasTile && tile2.LiquidAmount > 0) + { + tile2.TileType = (ushort)ModContent.TileType(); + tile2.HasTile = true; + } + } + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + Tile bottomTile = TileUtils.SafeGetTile(i, j + 1); + Tile tile = Main.tile[i, j]; + if (tile.HasTile && tile.TileType == Type) + { + if (!bottomTile.HasTile || (bottomTile.TileType != Type && !Main.tileSolid[bottomTile.type] && !Main.tileSolidTop[bottomTile.type])) + { + int deltaY = 0; + while (true) + { + Tile topTile = TileUtils.SafeGetTile(i, j - deltaY); + if (topTile.HasTile && topTile.TileType == Type && j - deltaY > 0) + { + WorldGen.KillTile(i, j - deltaY, false, false, true); + } + else + { + break; + } + deltaY++; + } + } + } + return base.TileFrame(i, j, ref resetFrame, ref noBreak); + } + + public override bool CreateDust(int i, int j, ref int type) + { + for (int k = 0; k < 2; k++) + { + Vector2 pos = new Point(i, j).ToWorldCoordinates(); + Dust d = Dust.NewDustDirect(pos - new Vector2(20, 40) + new Vector2(4), 40, 50, type); + d.noGravity = true; + } + return false; + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + if (Main.tile[i, j + 1].TileType != Type) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + } + else if (j == (Main.screenPosition + new Vector2(0, Main.screenHeight)).ToTileCoordinates().Y) + { + for (int y = 1; y < 133; y++) + { + Tile stepDown = TileUtils.SafeGetTile(i, j + y); + if (stepDown.TileType != Type) + { + TileFluentDrawManager.AddFluentPoint(this, i, j + y - 1); + break; + } + } + } + return false; + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + DrawAlgae(pos, pos.ToWorldCoordinates() - screenPosition, spriteBatch, tileDrawing); + } + + /// + /// Draw a piece of lotus + /// + private void DrawAlgae(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + var lastOffset = new Vector2(0, 12); + int height = 0; + for (int j = 0; j < 133; j++) + { + height++; + if (tilePos.Y - j < 21) + { + break; + } + var tile = Main.tile[tilePos + new Point(0, -j)]; + if (!(tile.TileType == Type && tile.HasTile)) + { + break; + } + } + for (int j = 0; j < 133; j++) + { + if (tilePos.Y - j < 21) + { + return; + } + var tile = Main.tile[tilePos + new Point(0, -j)]; + if (!(tile.TileType == Type && tile.HasTile)) + { + return; + } + var tileUp = Main.tile[tilePos + new Point(0, -j - 1)]; + bool lastTile = false; + bool lastTileHasFruit = false; + if (!(tileUp.TileType == Type && tileUp.HasTile)) + { + lastTile = true; + if (tileUp.TileType == ModContent.TileType()) + { + lastTileHasFruit = true; + } + } + ushort type = tile.TileType; + bool joint = (j + tilePos.X) % 2 == 1; + int style = TileUtils.GetFixedRandomNumber(tilePos.X, j + tilePos.Y) % 3; + var frame = new Rectangle(14, 132 + 34 * style, 36, 32); + if (lastTile) + { + if (lastTileHasFruit) + { + frame = new Rectangle(64 * style, 66, 64, 64); + } + else + { + frame = new Rectangle(64 * style, 0, 64, 64); + } + } + + // 回声涂料 + if (!TileDrawing.IsVisible(tile)) + { + continue; + } + + int paint = Main.tile[tilePos].TileColor; + Texture2D tex = PaintedTextureSystem.TryGetPaintedTexture(ModAsset.CrimsonMoonAlgea_Path, type, 1, paint, tileDrawing); + tex ??= ModAsset.CrimsonMoonAlgea.Value; + + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(tilePos.X, tilePos.Y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(tilePos.X, tilePos.Y, tileDrawing._sunflowerWindCounter); + } + + int totalPushTime = 140; + float pushForcePerFrame = 0.96f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X, tilePos.Y - j, 1, 1, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + windCycle += highestWindGridPushComplex; + float rotation = windCycle * 0.12f; + rotation -= lastOffset.X / (22f + j * 3f); + rotation += MathF.Sin(j / (float)height * MathHelper.Pi) * MathF.Sin(tilePos.X * 2 + tilePos.Y - j * 0.45f + (float)Main.time / 20f) * 0.15f; + rotation += MathF.Sin(j / (float)height * MathHelper.Pi) * MathF.Sin(tilePos.X * 2 + tilePos.Y + (float)Main.time / 20f) * 6f / (height + 25); + var tileLight = Lighting.GetColor(tilePos + new Point(0, -j)); + + // 支æŒå‘光涂料 + tileDrawing.DrawAnimatedTile_AdjustForVisionChangers(tilePos.X, tilePos.Y - j, tile, type, 0, 0, ref tileLight, tileDrawing._rand.NextBool(4)); + tileLight = tileDrawing.DrawTiles_GetLightOverride(tilePos.X, tilePos.Y - j, tile, type, 0, 0, tileLight); + + var origin = new Vector2(frame.Width * 0.5f, frame.Height); + + var drawPos = drawCenterPos + lastOffset; + var tileSpriteEffect = SpriteEffects.None; + + if (joint || j == 0 || lastTile) + { + spriteBatch.Draw(tex, drawPos, frame, tileLight, rotation, origin, 1f, tileSpriteEffect, 0f); + } + if (lastTile) + { + frame.X += 192; + spriteBatch.Draw(tex, drawPos, frame, new Color(0.1f, 0.1f, 0.1f, 0), rotation, origin, 1f, tileSpriteEffect, 0f); + if (lastTileHasFruit) + { + Lighting.AddLight(drawPos + new Vector2(0, -40).RotatedBy(rotation) + Main.screenPosition, new Vector3(1.5f, 1.3f, 1f) * (1.5f + MathF.Sin(Main.GlobalTimeWrappedHourly + TileUtils.GetFixedRandomNumber_SingleSeed(tilePos.GetHashCode())) * 0.5f)); + } + } + if (j == 0) + { + frame = new Rectangle(94, 244, 54, 16); + origin = new Vector2(frame.Width * 0.5f, frame.Height); + spriteBatch.Draw(tex, drawPos, frame, tileLight, rotation, origin, 1f, tileSpriteEffect, 0f); + } + lastOffset += new Vector2(0, -16).RotatedBy(rotation); + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/CrimsonMoonAlgea.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/CrimsonMoonAlgea.png new file mode 100644 index 000000000..3d70859af Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/CrimsonMoonAlgea.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/CrimsonMoonAlgea_fruit.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/CrimsonMoonAlgea_fruit.cs new file mode 100644 index 000000000..70cf7ed92 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/CrimsonMoonAlgea_fruit.cs @@ -0,0 +1,66 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.Items.Materials; +using Terraria.GameContent.Drawing; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class CrimsonMoonAlgea_fruit : ModTile +{ + public override void PostSetDefaults() + { + Main.tileFrameImportant[Type] = false; + Main.tileNoAttach[Type] = true; + Main.tileCut[Type] = true; + Main.tileLavaDeath[Type] = true; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 1; + TileObjectData.newTile.Width = 1; + TileObjectData.newTile.CoordinateWidth = 16; + TileObjectData.addTile(Type); + + DustType = ModContent.DustType(); + + AddMapEntry(new Color(255, 195, 153)); + HitSound = SoundID.Grass; + } + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + Tile bottomTile = TileUtils.SafeGetTile(i, j + 1); + Tile tile = Main.tile[i, j]; + if (tile.HasTile && tile.TileType == Type) + { + if (!bottomTile.HasTile || (bottomTile.TileType != ModContent.TileType() && !Main.tileSolid[bottomTile.type] && !Main.tileSolidTop[bottomTile.type])) + { + WorldGen.KillTile(i, j, false, false, true); + } + } + return base.TileFrame(i, j, ref resetFrame, ref noBreak); + } + + public override bool CreateDust(int i, int j, ref int type) + { + for (int k = 0; k < 20; k++) + { + Vector2 pos = new Point(i, j).ToWorldCoordinates(); + Vector2 vel = new Vector2(0, -MathF.Sqrt(Main.rand.NextFloat())).RotatedBy(Main.rand.NextFloat(-2.2f, 2.2f)) * 12; + Dust d = Dust.NewDustPerfect(pos + vel, ModContent.DustType()); + d.velocity = vel; + d.noGravity = true; + } + return false; + } + + public override IEnumerable GetItemDrops(int i, int j) + { + yield return new Item(ModContent.ItemType()); + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/CrimsonMoonAlgea_fruit.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/CrimsonMoonAlgea_fruit.png new file mode 100644 index 000000000..bfc72791d Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/CrimsonMoonAlgea_fruit.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/FluorescentHydraTree.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/FluorescentHydraTree.cs new file mode 100644 index 000000000..11b18645a --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/FluorescentHydraTree.cs @@ -0,0 +1,258 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Terraria.GameContent.Drawing; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class FluorescentHydraTree : ModTile, ITileFluentlyDrawn +{ + public const int MaxLength = 12; + + public override void PostSetDefaults() + { + Main.tileFrameImportant[Type] = false; + Main.tileNoAttach[Type] = true; + Main.tileCut[Type] = false; + Main.tileLavaDeath[Type] = true; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 1; + TileObjectData.newTile.Width = 1; + TileObjectData.newTile.CoordinateWidth = 16; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + + AddMapEntry(new Color(134, 183, 201)); + HitSound = SoundID.Dig; + } + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + Tile bottomTile = TileUtils.SafeGetTile(i, j + 1); + Tile tile = Main.tile[i, j]; + if (tile.HasTile && tile.TileType == Type) + { + if (!bottomTile.HasTile || (bottomTile.TileType != Type && !Main.tileSolid[bottomTile.type] && !Main.tileSolidTop[bottomTile.type])) + { + int deltaY = 0; + while (true) + { + Tile topTile = TileUtils.SafeGetTile(i, j - deltaY); + if (topTile.HasTile && topTile.TileType == Type && j - deltaY > 0) + { + WorldGen.KillTile(i, j - deltaY, false, false, true); + } + else + { + break; + } + deltaY++; + } + } + } + return base.TileFrame(i, j, ref resetFrame, ref noBreak); + } + + public override bool CreateDust(int i, int j, ref int type) + { + for (int k = 0; k < 2; k++) + { + Vector2 pos = new Point(i, j).ToWorldCoordinates(); + var d = Dust.NewDustDirect(pos - new Vector2(20, 40) + new Vector2(4), 40, 50, type); + d.noGravity = true; + } + return false; + } + + public override void RandomUpdate(int i, int j) + { + var tile = Main.tile[i, j]; + var tile2 = Main.tile[i, j - 1]; + + if (tile2.TileType != tile.TileType && !tile2.HasTile) + { + int length = 0; + int maxLengthHere = MaxLength - TileUtils.GetFixedRandomNumber(tile) % 3; + while (TileUtils.SafeGetTile(i, j + length).TileType == Type) + { + length++; + if (length >= maxLengthHere + 1) + { + break; + } + } + if (length <= maxLengthHere) + { + tile2.TileType = Type; + tile2.HasTile = true; + } + } + + int topY = j; + for (int y = 0; y < 12; y++) + { + if (TileUtils.SafeGetTile(i, j - y).TileType != Type) + { + topY = j - y + 1; + break; + } + } + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + Lighting.AddLight(i, j, 0.4f, 0.7f, 0.7f); + return false; + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + DrawFluorescentHydraTree(pos, pos.ToWorldCoordinates() - screenPosition, spriteBatch, tileDrawing); + } + + /// + /// Draw a piece of FluorescentHydra blossom + /// + private void DrawFluorescentHydraTree(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + int toBottom = 0; + int toTop = 0; + var tile = TileUtils.SafeGetTile(tilePos); + for (int j = 1; j < MaxLength; j++) + { + toBottom = j; + var checkTile = TileUtils.SafeGetTile(tilePos.X, tilePos.Y + j); + if (checkTile.type != Type) + { + break; + } + } + for (int j = 1; j < MaxLength; j++) + { + toTop = j; + var checkTile = TileUtils.SafeGetTile(tilePos.X, tilePos.Y - j); + if (checkTile.type != Type) + { + break; + } + } + Texture2D tex = ModAsset.FluorescentHydraTree.Value; + + // 回声涂料 + if (!TileDrawing.IsVisible(tile)) + { + return; + } + + int paint = Main.tile[tilePos].TileColor; + tex = PaintedTextureSystem.TryGetPaintedTexture(ModAsset.FluorescentHydraTree_Path, Type, 1, paint, tileDrawing); + tex ??= ModAsset.FluorescentHydraTree.Value; + + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(tilePos.X, tilePos.Y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(tilePos.X, tilePos.Y, tileDrawing._sunflowerWindCounter) * 0.25f; + } + + int totalPushTime = 140; + float pushForcePerFrame = 0.96f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X, tilePos.Y, 1, 1, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + windCycle += highestWindGridPushComplex * 0.25f; + float rotation = windCycle; + + var tileLight = Lighting.GetColor(tilePos); + + // 支æŒå‘光涂料 + tileDrawing.DrawAnimatedTile_AdjustForVisionChangers(tilePos.X, tilePos.Y, tile, Type, 0, 0, ref tileLight, tileDrawing._rand.NextBool(4)); + tileLight = tileDrawing.DrawTiles_GetLightOverride(tilePos.X, tilePos.Y, tile, Type, 0, 0, tileLight); + Rectangle frame = Rectangle.emptyRectangle; + Vector2 origin = Vector2.zeroVector; + + if (toTop == 1) + { + int style = TileUtils.GetFixedRandomNumber(tile) % 1; + frame = new Rectangle(74, 2, 162, 140); + origin = new Vector2(79, 124); + rotation *= 0.5f; + // switch (style) + // { + // case 0: + // frame = new Rectangle(14, 4, 340, 212); + // origin = new Vector2(167, 212); + // break; + // } + } + if (toTop > 1 && toBottom > 3) + { + int style = TileUtils.GetFixedRandomNumber(tile) % 4; + frame = new Rectangle(40, 18 + 18 * style, 22, 16); + origin = new Vector2(11, 16); + rotation *= 0; + } + if (toBottom == 1) + { + int style = TileUtils.GetFixedRandomNumber(tile) % 2; + frame = new Rectangle(34 * style, 90, 34, 56); + origin = new Vector2(17, 48); + rotation *= 0; + } + if (frame != Rectangle.Empty) + { + VertexDrawTree(drawCenterPos, frame, origin, tex, spriteBatch, rotation); + VertexDrawTree_glow(drawCenterPos, frame, origin, ModAsset.FluorescentHydraTree_glow.Value, spriteBatch, rotation); + } + } + + private void VertexDrawTree(Vector2 drawCenterPos, Rectangle frame, Vector2 origin, Texture2D tex, SpriteBatch spriteBatch, float rotation = 0) + { + var drawPos = drawCenterPos; + List bars = new List(); + Vector2 pos = drawPos + Main.screenPosition; + Vector2 offset0 = (new Vector2(0, 0) - origin).RotatedBy(rotation); + Vector2 offset1 = (new Vector2(frame.Width, 0) - origin).RotatedBy(rotation); + Vector2 offset2 = (new Vector2(0, frame.Height) - origin).RotatedBy(rotation); + Vector2 offset3 = (new Vector2(frame.Width, frame.Height) - origin).RotatedBy(rotation); + + AddLightColorVertex(bars, pos + offset0, new Vector3(new Vector2(frame.X, frame.Y) / tex.Size(), 0)); + AddLightColorVertex(bars, pos + offset1, new Vector3(new Vector2(frame.X + frame.Width, frame.Y) / tex.Size(), 0)); + AddLightColorVertex(bars, pos + offset2, new Vector3(new Vector2(frame.X, frame.Y + frame.Height) / tex.Size(), 0)); + AddLightColorVertex(bars, pos + offset3, new Vector3(new Vector2(frame.X + frame.Width, frame.Y + frame.Height) / tex.Size(), 0)); + if (bars.Count > 2) + { + spriteBatch.GraphicsDevice.Textures[0] = tex; + spriteBatch.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + } + + private void VertexDrawTree_glow(Vector2 drawCenterPos, Rectangle frame, Vector2 origin, Texture2D tex, SpriteBatch spriteBatch, float rotation = 0) + { + var drawPos = drawCenterPos; + float glowFade = 0.25f; + Vector2 pos = drawPos; + Vector2 offset0 = (new Vector2(0, 0) - origin).RotatedBy(rotation); + Vector2 offset1 = (new Vector2(frame.Width, 0) - origin).RotatedBy(rotation); + Vector2 offset2 = (new Vector2(0, frame.Height) - origin).RotatedBy(rotation); + Vector2 offset3 = (new Vector2(frame.Width, frame.Height) - origin).RotatedBy(rotation); + List bars = new List + { + { pos + offset0, new Color(1f, 1f, 1f, 0) * glowFade, new Vector3(new Vector2(frame.X, frame.Y) / tex.Size(), 0) }, + { pos + offset1, new Color(1f, 1f, 1f, 0) * glowFade, new Vector3(new Vector2(frame.X + frame.Width, frame.Y) / tex.Size(), 0) }, + { pos + offset2, new Color(1f, 1f, 1f, 0) * glowFade, new Vector3(new Vector2(frame.X, frame.Y + frame.Height) / tex.Size(), 0) }, + { pos + offset3, new Color(1f, 1f, 1f, 0) * glowFade, new Vector3(new Vector2(frame.X + frame.Width, frame.Y + frame.Height) / tex.Size(), 0) }, + }; + if (bars.Count > 2) + { + spriteBatch.GraphicsDevice.Textures[0] = tex; + spriteBatch.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + } + + private void AddLightColorVertex(List bars, Vector2 worldPos, Vector3 coord) + { + Color drawC = Lighting.GetColor(worldPos.ToTileCoordinates()); + drawC.A = 150; + bars.Add(worldPos - Main.screenPosition, drawC, coord); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/FluorescentHydraTree.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/FluorescentHydraTree.png new file mode 100644 index 000000000..f363f893e Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/FluorescentHydraTree.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/FluorescentHydraTree_glow.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/FluorescentHydraTree_glow.png new file mode 100644 index 000000000..e7f485344 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/FluorescentHydraTree_glow.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacleCollideTile.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacleCollideTile.cs index 9a1dc1f8d..5b8ff1b58 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacleCollideTile.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacleCollideTile.cs @@ -28,7 +28,7 @@ public override void Load() for (int x = 0; x < pixelRow.Length; x++) { ref var pixel = ref pixelRow[x]; - PixelHideForeground[x, y] = pixel.G; + PixelHideForeground[x, y] = pixel.B; } } }); @@ -148,9 +148,9 @@ public void AddScene(int i, int j) Tile tile = TileUtils.SafeGetTile(i, j); if (tile.TileFrameX == 0 && tile.TileFrameY == 36) { - GiantGhostClawBarnacle_VFX gGCBV = new GiantGhostClawBarnacle_VFX { position = new Vector2(i, j - 2) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + GiantGhostClawBarnacle_VFX gGCBV = new GiantGhostClawBarnacle_VFX { Position = new Vector2(i, j - 2) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(gGCBV); - GiantGhostClawBarnacle_Background gGCBB = new GiantGhostClawBarnacle_Background { position = new Vector2(i, j - 2) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + GiantGhostClawBarnacle_Background gGCBB = new GiantGhostClawBarnacle_Background { Position = new Vector2(i, j - 2) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(gGCBB); } } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacleCollideTile.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacleCollideTile.png index 5098209b9..458950b73 100644 Binary files a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacleCollideTile.png and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacleCollideTile.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacleCollideTile_shape.bmp b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacleCollideTile_shape.bmp index 0e0c1bf1b..d1d738824 100644 Binary files a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacleCollideTile_shape.bmp and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacleCollideTile_shape.bmp differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_Background.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_Background.cs index 98d65fdd4..5f000c463 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_Background.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_Background.cs @@ -1,27 +1,38 @@ using Everglow.Commons.VFX.Scene; -using SubworldLibrary; namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; [Pipeline(typeof(WCSPipeline))] -public class GiantGhostClawBarnacle_Background : BackgroundVFX +public class GiantGhostClawBarnacle_Background : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawBG; + public override void Update() { - if (!SubworldSystem.IsActive()) - { - Active = false; - } base.Update(); } public override void OnSpawn() { - texture = ModAsset.GiantGhostClawBarnacle_Background.Value; + Texture = ModAsset.GiantGhostClawBarnacle_Background.Value; } public override void Draw() { + for (int k = 0; k < 20; k++) + { + DrawTentacle(3, Position + new Vector2(100, 100 + k * 8.4f), 150 + 40 * MathF.Sin(k), 3); + } + for (int k = 0; k < 10; k++) + { + DrawTentacle(2, Position + new Vector2(110, 100 + k * 16.8f), 110 + 40 * MathF.Sin(k), 3); + } + for (int k = 0; k < 9; k++) + { + DrawTentacle(1, Position + new Vector2(110, 108 + k * 16.8f), 140 + 40 * MathF.Sin(k), 2); + } + Lighting.AddLight(Position + new Vector2(180, 122), new Vector3(3f, 0, 0)); + Lighting.AddLight(Position + new Vector2(180, 222), new Vector3(3f, 0, 0)); var frame = new Rectangle(0, 0, 304, 368); int widthSteps = frame.Width / 16; // 304 / 16 = 19. int heightSteps = frame.Height / 16; // 368 / 16 = 23; @@ -42,13 +53,36 @@ public override void Draw() } if (bars.Count > 0) { - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleList); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleList); + } + for (int k = 0; k < 5; k++) + { + DrawTentacle(1, Position + new Vector2(110, 100 + k * 33.6f), 140 + 40 * MathF.Sin(k), 2); + } + } + + public void DrawTentacle(int style, Vector2 position, float length, float width) + { + Texture2D tentacle = ModAsset.GiantGhostClawBarnacle_Tentacle.Value; + var frame = new Rectangle(0, style * 10, 144, 10); + int steps = 20; + var bars = new List(); + for (int i = 0; i < steps; i++) + { + float value = i / (float)steps; + float wave = MathF.Sin((float)Main.time * 0.06f + value * 5 + TileUtils.GetFixedRandomNumber_SingleSeed((int)(position.Y * 244.1268f))) * 6; + bars.Add(position + new Vector2(length * value, width + wave), Lighting.GetColor(position.ToTileCoordinates()), new Vector3(value, (frame.Y + frame.Height) / (float)tentacle.Height, 0)); + bars.Add(position + new Vector2(length * value, -width + wave), Lighting.GetColor(position.ToTileCoordinates()), new Vector3(value, frame.Y / (float)tentacle.Height, 0)); + } + if (bars.Count > 0) + { + Ins.Batch.Draw(tentacle, bars, PrimitiveType.TriangleStrip); } } public void AddBars(int i, int j, List bars) { var frame = new Rectangle(0, 0, 304, 368); - bars.Add(position + new Vector2(i, j) * 16, Lighting.GetColor(originTile + new Point(i, j)), new Vector3(i * 16 / (float)frame.Width, j * 16 / (float)frame.Height, 0)); + bars.Add(Position + new Vector2(i, j) * 16, Color.White, new Vector3(i * 16 / (float)frame.Width, j * 16 / (float)frame.Height, 0)); } } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_Background.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_Background.png index 24cd58a8f..cb6508e1b 100644 Binary files a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_Background.png and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_Background.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_Tentacle.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_Tentacle.png new file mode 100644 index 000000000..050d9c5bc Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_Tentacle.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_VFX.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_VFX.cs index accbb51e6..474e19757 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_VFX.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_VFX.cs @@ -1,11 +1,12 @@ using Everglow.Commons.VFX.Scene; -using SubworldLibrary; namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; [Pipeline(typeof(WCSPipeline))] -public class GiantGhostClawBarnacle_VFX : ForegroundVFX +public class GiantGhostClawBarnacle_VFX : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; + /// /// Became 0.05f when local player inside the barnacle. /// @@ -13,10 +14,6 @@ public class GiantGhostClawBarnacle_VFX : ForegroundVFX public override void Update() { - if (!SubworldSystem.IsActive()) - { - Active = false; - } bool inside = false; var collideMap = GiantGhostClawBarnacleCollideTile.PixelHideForeground; for (int i = 0; i < collideMap.GetLength(0); i++) @@ -25,7 +22,7 @@ public override void Update() { if (collideMap[i, j] >= 200) { - Point topLeft = originTile + new Point(i, j); + Point topLeft = OriginTilePos + new Point(i, j); Rectangle collisionFrame = new Rectangle(topLeft.X * 16, topLeft.Y * 16, 16, 16); if (Rectangle.Intersect(collisionFrame, Main.LocalPlayer.Hitbox) != Rectangle.emptyRectangle) { @@ -52,7 +49,7 @@ public override void Update() public override void OnSpawn() { - texture = ModAsset.GiantGhostClawBarnacle_VFX.Value; + Texture = ModAsset.GiantGhostClawBarnacle_VFX.Value; } public override void Draw() @@ -77,14 +74,14 @@ public override void Draw() } if (bars.Count > 0) { - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleList); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleList); } } public void AddBars(int i, int j, List bars) { var frameFront = new Rectangle(0, 0, 304, 368); - var drawColor = Lighting.GetColor(originTile + new Point(i, j)) * Transparency; - bars.Add(position + new Vector2(i, j) * 16, drawColor, new Vector3(i * 16 / (float)frameFront.Width, j * 16 / (float)frameFront.Height, 0)); + var drawColor = Lighting.GetColor(OriginTilePos + new Point(i, j)) * Transparency; + bars.Add(Position + new Vector2(i, j) * 16, drawColor, new Vector3(i * 16 / (float)frameFront.Width, j * 16 / (float)frameFront.Height, 0)); } } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_VFX.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_VFX.png index 31512e0d1..883663b7c 100644 Binary files a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_VFX.png and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_VFX.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_canvas.pdn b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_canvas.pdn new file mode 100644 index 000000000..4014a4d6a Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/GiantGhostClawBarnacle_canvas.pdn differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HumicMud.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HumicMud.cs index 23c7b9ce5..415e41315 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HumicMud.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HumicMud.cs @@ -11,13 +11,15 @@ public override void PostSetDefaults() Main.tileSolid[Type] = true; Main.tileMergeDirt[Type] = true; Main.tileBlockLight[Type] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[ModContent.TileType()][Type] = true; DustType = ModContent.DustType(); AddMapEntry(new Color(34, 43, 39)); } public void AddScene(int i, int j) { - HumicMud_Algae_fore leaf = new HumicMud_Algae_fore { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + HumicMud_Algae_fore leaf = new HumicMud_Algae_fore { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; leaf.scale = 1f; leaf.style = (i + j) % 4; Ins.VFXManager.Add(leaf); diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HumicMud_Algae.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HumicMud_Algae.cs index ab573d436..c8a4eefec 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HumicMud_Algae.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HumicMud_Algae.cs @@ -3,38 +3,35 @@ namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; [Pipeline(typeof(WCSPipeline))] -public class HumicMud_Algae_fore : ForegroundVFX +public class HumicMud_Algae_fore : TileVFX { - public override void OnSpawn() - { - texture = ModAsset.DarkForestGrass_grass.Value; - } + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; public override void Update() { - if (originTile.X >= Main.maxTilesX - 1 || originTile.X <= 1) + if (OriginTilePos.X >= Main.maxTilesX - 1 || OriginTilePos.X <= 1) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - if (originTile.Y >= Main.maxTilesY - 1 || originTile.Y <= 1) + if (OriginTilePos.Y >= Main.maxTilesY - 1 || OriginTilePos.Y <= 1) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - if (!VFXManager.InScreen(originTile.ToWorldCoordinates(), 150)) + if (!VFXManager.InScreen(OriginTilePos.ToWorldCoordinates(), 150)) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - Tile tile = Main.tile[originTile]; - if (tile.TileType != originType || !tile.HasTile) + Tile tile = Main.tile[OriginTilePos]; + if (tile.TileType != OriginTileType || !tile.HasTile) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } @@ -44,23 +41,23 @@ public override void Update() public override void Draw() { - if (originTile.X >= Main.maxTilesX - 1 || originTile.X <= 1) + if (OriginTilePos.X >= Main.maxTilesX - 1 || OriginTilePos.X <= 1) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - if (originTile.Y >= Main.maxTilesY - 1 || originTile.Y <= 1) + if (OriginTilePos.Y >= Main.maxTilesY - 1 || OriginTilePos.Y <= 1) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - Tile tile = Main.tile[originTile]; - if (tile.TileType != originType || !tile.HasTile) + Tile tile = Main.tile[OriginTilePos]; + if (tile.TileType != OriginTileType || !tile.HasTile) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } var bars = new List(); @@ -68,199 +65,209 @@ public override void Draw() { if (tile.TileFrameX >= 18 && tile.TileFrameX <= 54 && tile.TileFrameY == 0) { - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameX >= 18 && tile.TileFrameX <= 54 && tile.TileFrameY == 36) { - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } if (tile.TileFrameX == 0 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) { - AddDrawingFace(bars, new Vector2(-1, 0), position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); } if (tile.TileFrameX == 72 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) { - AddDrawingFace(bars, new Vector2(1, 0), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); } if (tile.TileFrameX == 90 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(-1, 0), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); } if (tile.TileFrameY == 72 && tile.TileFrameX >= 108 && tile.TileFrameX <= 144) { - AddDrawingFace(bars, new Vector2(0, 1), position); - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameY == 0 && tile.TileFrameX >= 108 && tile.TileFrameX <= 144) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(-1, 0), position); - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameY == 54 && tile.TileFrameX >= 108 && tile.TileFrameX <= 144) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(-1, 0), position); - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } if (tile.TileFrameX == 162 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) { - AddDrawingFace(bars, new Vector2(0, 1), position); - AddDrawingFace(bars, new Vector2(0, -1), position); - AddDrawingFace(bars, new Vector2(-1, 0), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); } if (tile.TileFrameX == 216 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) { - AddDrawingFace(bars, new Vector2(0, 1), position); - AddDrawingFace(bars, new Vector2(0, -1), position); - AddDrawingFace(bars, new Vector2(1, 0), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); + AddDrawingFace(bars, new Vector2(1, 0), Position); } if (tile.TileFrameY == 54 && tile.TileFrameX >= 162 && tile.TileFrameX <= 198) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(-1, 0), position); - AddDrawingFace(bars, new Vector2(0, 1), position); - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameY == 54 && tile.TileFrameX % 36 == 0 && tile.TileFrameX <= 90) { - AddDrawingFace(bars, new Vector2(-1, 0), position); - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameY == 72 && tile.TileFrameX % 36 == 0 && tile.TileFrameX <= 90) { - AddDrawingFace(bars, new Vector2(-1, 0), position); - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } if (tile.TileFrameY == 54 && tile.TileFrameX % 36 == 18 && tile.TileFrameX <= 90) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameY == 72 && tile.TileFrameX % 36 == 18 && tile.TileFrameX <= 90) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } } else { if (tile.Slope == SlopeType.SlopeUpLeft) { - AddDrawingFace(bars, new Vector2(1, 1) * 0.85f, position, 1.4143f, new Vector2(-5, -5)); - Tile upTile = Main.tile[originTile + new Point(0, -1)]; + AddDrawingFace(bars, new Vector2(1, 1) * 0.85f, Position, 1.4143f, new Vector2(-5, -5)); + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; if (!upTile.HasTile) { - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } - Tile leftTile = Main.tile[originTile + new Point(-1, 0)]; + Tile leftTile = Main.tile[OriginTilePos + new Point(-1, 0)]; if (!leftTile.HasTile) { - AddDrawingFace(bars, new Vector2(-1, 0), position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); } - Tile downTile = Main.tile[originTile + new Point(0, 1)]; - if (downTile.HasTile && downTile.TileType == originType) + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; + if (downTile.HasTile && downTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(0, -1), position, 1, new Vector2(0, 16)); + AddDrawingFace(bars, new Vector2(0, -1), Position, 1, new Vector2(0, 16)); } } if (tile.Slope == SlopeType.SlopeDownLeft) { - AddDrawingFace(bars, new Vector2(1, -1) * 0.85f, position, 1.4143f, new Vector2(-5, 5)); - Tile downTile = Main.tile[originTile + new Point(0, 1)]; + AddDrawingFace(bars, new Vector2(1, -1) * 0.85f, Position, 1.4143f, new Vector2(-5, 5)); + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; if (!downTile.HasTile) { - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } - Tile leftTile = Main.tile[originTile + new Point(-1, 0)]; + Tile leftTile = Main.tile[OriginTilePos + new Point(-1, 0)]; if (!leftTile.HasTile) { - AddDrawingFace(bars, new Vector2(-1, 0), position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); } - Tile upTile = Main.tile[originTile + new Point(0, -1)]; - if (upTile.HasTile && upTile.TileType == originType) + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; + if (upTile.HasTile && upTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(0, 1), position, 1, new Vector2(0, -16)); + AddDrawingFace(bars, new Vector2(0, 1), Position, 1, new Vector2(0, -16)); } } if (tile.Slope == SlopeType.SlopeUpRight) { - AddDrawingFace(bars, new Vector2(-1, 1) * 0.85f, position, 1.4143f, new Vector2(5, -5)); - Tile upTile = Main.tile[originTile + new Point(0, -1)]; + AddDrawingFace(bars, new Vector2(-1, 1) * 0.85f, Position, 1.4143f, new Vector2(5, -5)); + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; if (!upTile.HasTile) { - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } - Tile rightTile = Main.tile[originTile + new Point(1, 0)]; + Tile rightTile = Main.tile[OriginTilePos + new Point(1, 0)]; if (!rightTile.HasTile) { - AddDrawingFace(bars, new Vector2(1, 0), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); } - Tile downTile = Main.tile[originTile + new Point(0, 1)]; - if (downTile.HasTile && downTile.TileType == originType) + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; + if (downTile.HasTile && downTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(0, -1), position, 1, new Vector2(0, 16)); + AddDrawingFace(bars, new Vector2(0, -1), Position, 1, new Vector2(0, 16)); } } if (tile.Slope == SlopeType.SlopeDownRight) { - AddDrawingFace(bars, new Vector2(-1, -1) * 0.85f, position, 1.4143f, new Vector2(5, 5)); - Tile downTile = Main.tile[originTile + new Point(0, 1)]; + AddDrawingFace(bars, new Vector2(-1, -1) * 0.85f, Position, 1.4143f, new Vector2(5, 5)); + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; if (!downTile.HasTile) { - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } - Tile rightTile = Main.tile[originTile + new Point(1, 0)]; + Tile rightTile = Main.tile[OriginTilePos + new Point(1, 0)]; if (!rightTile.HasTile) { - AddDrawingFace(bars, new Vector2(1, 0), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); } - Tile upTile = Main.tile[originTile + new Point(0, -1)]; - if (upTile.HasTile && upTile.TileType == originType) + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; + if (upTile.HasTile && upTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(0, 1), position, 1, new Vector2(0, -16)); + AddDrawingFace(bars, new Vector2(0, 1), Position, 1, new Vector2(0, -16)); } } if (tile.halfBrick()) { - AddDrawingFace(bars, new Vector2(0, -1), position, 1, new Vector2(0, 6)); - if (!Main.tile[originTile + new Point(0, 1)].HasTile) + AddDrawingFace(bars, new Vector2(0, -1), Position, 1, new Vector2(0, 6)); + if (!Main.tile[OriginTilePos + new Point(0, 1)].HasTile) { - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } - Tile upTile = Main.tile[originTile + new Point(0, -1)]; - if (upTile.HasTile && upTile.TileType == originType) + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; + if (upTile.HasTile && upTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(0, 1), position, 1, new Vector2(0, -16)); + AddDrawingFace(bars, new Vector2(0, 1), Position, 1, new Vector2(0, -16)); } - Tile leftTile = Main.tile[originTile + new Point(-1, 0)]; - if (leftTile.HasTile && leftTile.TileType == originType) + Tile leftTile = Main.tile[OriginTilePos + new Point(-1, 0)]; + if (leftTile.HasTile && leftTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(1, 0), position, 0.5f, new Vector2(-14, -4)); + AddDrawingFace(bars, new Vector2(1, 0), Position, 0.5f, new Vector2(-14, -4)); } if (!leftTile.HasTile) { - AddDrawingFace(bars, new Vector2(-1, 0), position, 0.5f, new Vector2(0, 4)); + AddDrawingFace(bars, new Vector2(-1, 0), Position, 0.5f, new Vector2(0, 4)); } - Tile rightTile = Main.tile[originTile + new Point(1, 0)]; - if (rightTile.HasTile && rightTile.TileType == originType) + Tile rightTile = Main.tile[OriginTilePos + new Point(1, 0)]; + if (rightTile.HasTile && rightTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(-1, 0), position, 0.5f, new Vector2(14, -4)); + AddDrawingFace(bars, new Vector2(-1, 0), Position, 0.5f, new Vector2(14, -4)); } if (!rightTile.HasTile) { - AddDrawingFace(bars, new Vector2(1, 0), position, 0.5f, new Vector2(0, 4)); + AddDrawingFace(bars, new Vector2(1, 0), Position, 0.5f, new Vector2(0, 4)); } } } Ins.Batch.Draw(ModAsset.HumicMud_Algae.Value, bars, PrimitiveType.TriangleList); } - public void AddDrawingFace(List bars, Vector2 direction, Vector2 position, float length = 1, Vector2 offset = default) + public void AddDrawingFace(List bars, Vector2 Direction, Vector2 Position, float length = 1, Vector2 offset = default) { - Vector2 drawCenter = position + new Vector2(8) + offset; - var directionN = Vector2.Normalize(direction); + Tile tile = Main.tile[OriginTilePos]; + if (tile.Slope == SlopeType.Solid && !tile.halfBrick()) + { + Tile directionTile = Main.tile[OriginTilePos + Direction.ToPoint()]; + if (TileUtils.IsTileSolid(directionTile)) + { + return; + } + } + + Vector2 drawCenter = Position + new Vector2(8) + offset; + var directionN = Vector2.Normalize(Direction); float texWidth = 64f; float frameWidth = 16f; float rot = -MathF.Asin(Vector3.Cross(new Vector3(directionN, 0), new Vector3(0, -1, 0)).Z); @@ -275,12 +282,12 @@ public void AddDrawingFace(List bars, Vector2 direction, Vector2 posit frameYModify = 0.5f; } float dLength = 16 / texWidth; - float sway0 = MathF.Sin((float)Main.time / 36f + position.X + position.Y) * 3; - float sway1 = MathF.Sin((float)Main.time / 36f + position.X + position.Y + 32) * 3; - Vector2 point0 = drawCenter + new Vector2(-8 * length + sway0, -18).RotatedBy(rot) + direction * 8; - Vector2 point1 = drawCenter + new Vector2(8 * length + sway1, -18).RotatedBy(rot) + direction * 8; - Vector2 point2 = drawCenter + new Vector2(-8 * length, 6).RotatedBy(rot) + direction * 12; - Vector2 point3 = drawCenter + new Vector2(8 * length, 6).RotatedBy(rot) + direction * 12; + float sway0 = MathF.Sin((float)Main.time / 36f + Position.X + Position.Y) * 3; + float sway1 = MathF.Sin((float)Main.time / 36f + Position.X + Position.Y + 32) * 3; + Vector2 point0 = drawCenter + new Vector2(-8 * length + sway0, -18).RotatedBy(rot) + Direction * 8; + Vector2 point1 = drawCenter + new Vector2(8 * length + sway1, -18).RotatedBy(rot) + Direction * 8; + Vector2 point2 = drawCenter + new Vector2(-8 * length, 6).RotatedBy(rot) + Direction * 12; + Vector2 point3 = drawCenter + new Vector2(8 * length, 6).RotatedBy(rot) + Direction * 12; Color color0 = Lighting.GetColor(point0.ToTileCoordinates()); Color color1 = Lighting.GetColor(point1.ToTileCoordinates()); diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBud1x1.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBud1x1.cs new file mode 100644 index 000000000..257167337 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBud1x1.cs @@ -0,0 +1,43 @@ +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.Projectiles.TileEffect; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class HydraBud1x1 : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + Main.tileLighted[Type] = true; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 1; + TileObjectData.newTile.Width = 1; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 24, + }; + TileObjectData.newTile.CoordinateWidth = 28; + TileObjectData.newTile.DrawYOffset = -8; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(0, 195, 255)); + } + + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + r = 0.7f; + g = 1f; + b = 1.1f; + base.ModifyLight(i, j, ref r, ref g, ref b); + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + base.PostDraw(i, j, spriteBatch); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBud1x1.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBud1x1.png new file mode 100644 index 000000000..46252e374 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBud1x1.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBud3x3.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBud3x3.cs new file mode 100644 index 000000000..5850b94b2 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBud3x3.cs @@ -0,0 +1,40 @@ +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class HydraBud3x3 : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + Main.tileLighted[Type] = true; + TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3); + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 16, + 18, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(0, 195, 255)); + } + + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + r = 0.7f; + g = 1f; + b = 1.1f; + base.ModifyLight(i, j, ref r, ref g, ref b); + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + base.PostDraw(i, j, spriteBatch); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBud3x3.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBud3x3.png new file mode 100644 index 000000000..5150e6644 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBud3x3.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBudWall.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBudWall.cs new file mode 100644 index 000000000..cdc9638d6 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBudWall.cs @@ -0,0 +1,56 @@ +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Terraria.DataStructures; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class HydraBudWall : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + Main.tileLighted[Type] = true; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 1; + TileObjectData.newTile.Width = 1; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.newTile.AnchorBottom = AnchorData.Empty; + TileObjectData.newTile.AnchorWall = true; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(0, 195, 255)); + } + + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + r = 0.7f; + g = 1f; + b = 1.1f; + base.ModifyLight(i, j, ref r, ref g, ref b); + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + Rectangle frame = new Rectangle(4, 26, 14, 12); + switch (TileUtils.GetFixedRandomNumber(i, j, 3)) + { + case 0: + frame = new Rectangle(4, 26, 14, 12); + break; + case 1: + frame = new Rectangle(28, 20, 22, 22); + break; + case 2: + frame = new Rectangle(60, 4, 54, 48); + break; + } + Texture2D tex = ModContent.Request(Texture).Value; + Vector2 zero = Main.drawToScreen ? Vector2.Zero : new Vector2(Main.offScreenRange); + Vector2 pos = new Vector2(i * 16, j * 16) + zero - Main.screenPosition; + spriteBatch.Draw(tex, pos, frame, Lighting.GetColor(i, j), TileUtils.GetFixedRandomNumber(i, j, 1024) / 1024f * MathHelper.TwoPi, frame.Size() * 0.5f, 1f, SpriteEffects.None, 0); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBudWall.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBudWall.png new file mode 100644 index 000000000..29c05555c Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraBudWall.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraMud.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraMud.cs new file mode 100644 index 000000000..a4c626cf3 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraMud.cs @@ -0,0 +1,40 @@ +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.LampWood; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class HydraMud : ModTile, ISceneTile +{ + public override void PostSetDefaults() + { + Main.tileSolid[Type] = true; + Main.tileMergeDirt[Type] = true; + Main.tileBlockLight[Type] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[ModContent.TileType()][Type] = true; + DustType = ModContent.DustType(); + AddMapEntry(new Color(34, 43, 39)); + } + + public void AddScene(int i, int j) + { + HydraMudTentacles_fore leaf = new HydraMudTentacles_fore { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; + leaf.scale = 1f; + leaf.style = (i + j) % 4; + Ins.VFXManager.Add(leaf); + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + Tile tile = Main.tile[i, j]; + Texture2D tex = ModContent.Request(Texture).Value; + Vector2 pos = new Vector2(i * 16, j * 16) - Main.screenPosition + zero; + spriteBatch.Draw(tex, pos, new Rectangle(tile.TileFrameX, tile.TileFrameY + 90, 16, 16), new Color(0.3f, 0.3f, 0.3f, 0)); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraMud.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraMud.png new file mode 100644 index 000000000..b86048504 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraMud.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraMudTentacles.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraMudTentacles.cs new file mode 100644 index 000000000..305f7f318 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraMudTentacles.cs @@ -0,0 +1,302 @@ +using Everglow.Commons.VFX.Scene; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +[Pipeline(typeof(WCSPipeline))] +public class HydraMudTentacles_fore : TileVFX +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; + + public override void Update() + { + if (OriginTilePos.X >= Main.maxTilesX - 1 || OriginTilePos.X <= 1) + { + Active = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; + return; + } + if (OriginTilePos.Y >= Main.maxTilesY - 1 || OriginTilePos.Y <= 1) + { + Active = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; + return; + } + if (!VFXManager.InScreen(OriginTilePos.ToWorldCoordinates(), 150)) + { + Active = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; + return; + } + Tile tile = Main.tile[OriginTilePos]; + if (tile.TileType != OriginTileType || !tile.HasTile) + { + Active = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; + return; + } + } + + public float scale; + public int style; + + public override void Draw() + { + if (OriginTilePos.X >= Main.maxTilesX - 1 || OriginTilePos.X <= 1) + { + Active = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; + return; + } + if (OriginTilePos.Y >= Main.maxTilesY - 1 || OriginTilePos.Y <= 1) + { + Active = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; + return; + } + Tile tile = Main.tile[OriginTilePos]; + if (tile.TileType != OriginTileType || !tile.HasTile) + { + Active = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; + return; + } + var bars = new List(); + if (tile.Slope == SlopeType.Solid && !tile.halfBrick()) + { + if (tile.TileFrameX >= 18 && tile.TileFrameX <= 54 && tile.TileFrameY == 0) + { + AddDrawingFace(bars, new Vector2(0, -1), Position); + } + if (tile.TileFrameX >= 18 && tile.TileFrameX <= 54 && tile.TileFrameY == 36) + { + AddDrawingFace(bars, new Vector2(0, 1), Position); + } + if (tile.TileFrameX == 0 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) + { + AddDrawingFace(bars, new Vector2(-1, 0), Position); + } + if (tile.TileFrameX == 72 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) + { + AddDrawingFace(bars, new Vector2(1, 0), Position); + } + if (tile.TileFrameX == 90 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) + { + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + } + if (tile.TileFrameY == 72 && tile.TileFrameX >= 108 && tile.TileFrameX <= 144) + { + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); + } + if (tile.TileFrameY == 0 && tile.TileFrameX >= 108 && tile.TileFrameX <= 144) + { + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); + } + if (tile.TileFrameY == 54 && tile.TileFrameX >= 108 && tile.TileFrameX <= 144) + { + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + } + if (tile.TileFrameX == 162 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) + { + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + } + if (tile.TileFrameX == 216 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) + { + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + } + if (tile.TileFrameY == 54 && tile.TileFrameX >= 162 && tile.TileFrameX <= 198) + { + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); + } + if (tile.TileFrameY == 54 && tile.TileFrameX % 36 == 0 && tile.TileFrameX <= 90) + { + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); + } + if (tile.TileFrameY == 72 && tile.TileFrameX % 36 == 0 && tile.TileFrameX <= 90) + { + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + } + if (tile.TileFrameY == 54 && tile.TileFrameX % 36 == 18 && tile.TileFrameX <= 90) + { + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); + } + if (tile.TileFrameY == 72 && tile.TileFrameX % 36 == 18 && tile.TileFrameX <= 90) + { + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + } + } + else + { + if (tile.Slope == SlopeType.SlopeUpLeft) + { + AddDrawingFace(bars, new Vector2(1, 1) * 0.85f, Position, 1.4143f, new Vector2(-5, -5)); + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; + if (!upTile.HasTile) + { + AddDrawingFace(bars, new Vector2(0, -1), Position); + } + Tile leftTile = Main.tile[OriginTilePos + new Point(-1, 0)]; + if (!leftTile.HasTile) + { + AddDrawingFace(bars, new Vector2(-1, 0), Position); + } + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; + if (downTile.HasTile && downTile.TileType == OriginTileType) + { + AddDrawingFace(bars, new Vector2(0, -1), Position, 1, new Vector2(0, 16)); + } + } + if (tile.Slope == SlopeType.SlopeDownLeft) + { + AddDrawingFace(bars, new Vector2(1, -1) * 0.85f, Position, 1.4143f, new Vector2(-5, 5)); + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; + if (!downTile.HasTile) + { + AddDrawingFace(bars, new Vector2(0, 1), Position); + } + Tile leftTile = Main.tile[OriginTilePos + new Point(-1, 0)]; + if (!leftTile.HasTile) + { + AddDrawingFace(bars, new Vector2(-1, 0), Position); + } + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; + if (upTile.HasTile && upTile.TileType == OriginTileType) + { + AddDrawingFace(bars, new Vector2(0, 1), Position, 1, new Vector2(0, -16)); + } + } + if (tile.Slope == SlopeType.SlopeUpRight) + { + AddDrawingFace(bars, new Vector2(-1, 1) * 0.85f, Position, 1.4143f, new Vector2(5, -5)); + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; + if (!upTile.HasTile) + { + AddDrawingFace(bars, new Vector2(0, -1), Position); + } + Tile rightTile = Main.tile[OriginTilePos + new Point(1, 0)]; + if (!rightTile.HasTile) + { + AddDrawingFace(bars, new Vector2(1, 0), Position); + } + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; + if (downTile.HasTile && downTile.TileType == OriginTileType) + { + AddDrawingFace(bars, new Vector2(0, -1), Position, 1, new Vector2(0, 16)); + } + } + if (tile.Slope == SlopeType.SlopeDownRight) + { + AddDrawingFace(bars, new Vector2(-1, -1) * 0.85f, Position, 1.4143f, new Vector2(5, 5)); + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; + if (!downTile.HasTile) + { + AddDrawingFace(bars, new Vector2(0, 1), Position); + } + Tile rightTile = Main.tile[OriginTilePos + new Point(1, 0)]; + if (!rightTile.HasTile) + { + AddDrawingFace(bars, new Vector2(1, 0), Position); + } + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; + if (upTile.HasTile && upTile.TileType == OriginTileType) + { + AddDrawingFace(bars, new Vector2(0, 1), Position, 1, new Vector2(0, -16)); + } + } + if (tile.halfBrick()) + { + AddDrawingFace(bars, new Vector2(0, -1), Position, 1, new Vector2(0, 6)); + if (!Main.tile[OriginTilePos + new Point(0, 1)].HasTile) + { + AddDrawingFace(bars, new Vector2(0, 1), Position); + } + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; + if (upTile.HasTile && upTile.TileType == OriginTileType) + { + AddDrawingFace(bars, new Vector2(0, 1), Position, 1, new Vector2(0, -16)); + } + Tile leftTile = Main.tile[OriginTilePos + new Point(-1, 0)]; + if (leftTile.HasTile && leftTile.TileType == OriginTileType) + { + AddDrawingFace(bars, new Vector2(1, 0), Position, 0.5f, new Vector2(-14, -4)); + } + if (!leftTile.HasTile) + { + AddDrawingFace(bars, new Vector2(-1, 0), Position, 0.5f, new Vector2(0, 4)); + } + Tile rightTile = Main.tile[OriginTilePos + new Point(1, 0)]; + if (rightTile.HasTile && rightTile.TileType == OriginTileType) + { + AddDrawingFace(bars, new Vector2(-1, 0), Position, 0.5f, new Vector2(14, -4)); + } + if (!rightTile.HasTile) + { + AddDrawingFace(bars, new Vector2(1, 0), Position, 0.5f, new Vector2(0, 4)); + } + } + } + Ins.Batch.Draw(ModAsset.HydraMudTentacles.Value, bars, PrimitiveType.TriangleList); + } + + public void AddDrawingFace(List bars, Vector2 Direction, Vector2 Position, float length = 1, Vector2 offset = default) + { + Tile tile = Main.tile[OriginTilePos]; + if (tile.Slope == SlopeType.Solid && !tile.halfBrick()) + { + Tile directionTile = Main.tile[OriginTilePos + Direction.ToPoint()]; + if (TileUtils.IsTileSolid(directionTile)) + { + return; + } + } + + Vector2 drawCenter = Position + new Vector2(8) + offset; + var directionN = Vector2.Normalize(Direction); + float texWidth = 64f; + float frameWidth = 16f; + float rot = -MathF.Asin(Vector3.Cross(new Vector3(directionN, 0), new Vector3(0, -1, 0)).Z); + float cos = Vector2.Dot(directionN, new Vector2(0, -1)); + if (cos < 0) + { + rot = MathHelper.Pi - rot; + } + float frameYModify = 0f; + if (cos < 0.2f) + { + frameYModify = 0.5f; + } + float dLength = 16 / texWidth; + float sway0 = MathF.Sin((float)Main.time / 36f + Position.X + Position.Y) * 3; + float sway1 = MathF.Sin((float)Main.time / 36f + Position.X + Position.Y + 32) * 3; + Vector2 point0 = drawCenter + new Vector2(-8 * length + sway0, -18).RotatedBy(rot) + Direction * 8; + Vector2 point1 = drawCenter + new Vector2(8 * length + sway1, -18).RotatedBy(rot) + Direction * 8; + Vector2 point2 = drawCenter + new Vector2(-8 * length, 6).RotatedBy(rot) + Direction * 12; + Vector2 point3 = drawCenter + new Vector2(8 * length, 6).RotatedBy(rot) + Direction * 12; + + Color color = new Color(0.5f, 0.5f, 0.5f, 0.5f); + + bars.Add(point0, color, new Vector3(frameWidth * style / texWidth, frameYModify, 0)); + bars.Add(point1, color, new Vector3(dLength + frameWidth * style / texWidth, frameYModify, 0)); + bars.Add(point3, color, new Vector3(dLength + frameWidth * style / texWidth, 0.5f + frameYModify, 0)); + + bars.Add(point2, color, new Vector3(frameWidth * style / texWidth, 0.5f + frameYModify, 0)); + bars.Add(point0, color, new Vector3(frameWidth * style / texWidth, frameYModify, 0)); + bars.Add(point3, color, new Vector3(dLength + frameWidth * style / texWidth, 0.5f + frameYModify, 0)); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraMudTentacles.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraMudTentacles.png new file mode 100644 index 000000000..ed0f608fd Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/HydraMudTentacles.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_90_Degree_Scan.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_90_Degree_Scan.cs index 248debc6c..98f50b61b 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_90_Degree_Scan.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_90_Degree_Scan.cs @@ -75,7 +75,7 @@ public void AddScene(int i, int j) rot = -1; break; } - var laser = new IRProbe_Normal_Laser { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + var laser = new IRProbe_Normal_Laser { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; laser.Style = 0; laser.NoneRotation = false; laser.StartRotation = rot; diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_90_Degree_Scan_Reverse.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_90_Degree_Scan_Reverse.cs index e9e1670c4..578fbd6c1 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_90_Degree_Scan_Reverse.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_90_Degree_Scan_Reverse.cs @@ -75,7 +75,7 @@ public void AddScene(int i, int j) rot = -1; break; } - var laser = new IRProbe_Normal_Laser { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + var laser = new IRProbe_Normal_Laser { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; laser.Style = 0; laser.NoneRotation = false; laser.StartRotation = rot; diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_Normal.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_Normal.cs index 0f17dcb5e..95fc3353b 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_Normal.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_Normal.cs @@ -75,7 +75,7 @@ public void AddScene(int i, int j) noneRot = true; break; } - var laser = new IRProbe_Normal_Laser { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + var laser = new IRProbe_Normal_Laser { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; laser.Style = 0; laser.NoneRotation = noneRot; laser.StartRotation = rot; diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_Normal_Laser.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_Normal_Laser.cs index e47e4f65e..2949ae0a5 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_Normal_Laser.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/IRProbe/IRProbe_Normal_Laser.cs @@ -4,8 +4,9 @@ namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.IRProbe; [Pipeline(typeof(WCSPipeline))] -public class IRProbe_Normal_Laser : ForegroundVFX +public class IRProbe_Normal_Laser : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; public float Rotation; public float Omega; public float StartRotation; @@ -24,7 +25,7 @@ public class IRProbe_Normal_Laser : ForegroundVFX public override void OnSpawn() { - texture = ModAsset.IRProbe_Normal.Value; + Texture = ModAsset.IRProbe_Normal.Value; } public Vector3 GetColor() @@ -55,10 +56,10 @@ public Vector3 GetColor() public override void Update() { bool oldPlayerHit = AnyPlayerCollision; - position = originTile.ToWorldCoordinates(); + Position = OriginTilePos.ToWorldCoordinates(); if (!NoneRotation) { - position += new Vector2(0, -8).RotatedBy(Rotation); + Position += new Vector2(0, -8).RotatedBy(Rotation); } Rotation = StartRotation; LaserScan?.Invoke(this); @@ -69,12 +70,12 @@ public override void Update() for (int step = 1; step < 1000; step++) { count++; - if (Collision.SolidCollision(position + step * collisionUnit - new Vector2(4), 8, 8)) + if (Collision.SolidCollision(Position + step * collisionUnit - new Vector2(4), 8, 8)) { AnyPlayerCollision = false; break; } - Vector2 pos = position + step * collisionUnit - new Vector2(4); + Vector2 pos = Position + step * collisionUnit - new Vector2(4); var collisionRectangle = new Rectangle((int)pos.X, (int)pos.Y, 8, 8); bool playerCollision = false; foreach (var player in Main.player) @@ -100,7 +101,7 @@ public override void Update() { length = 0; AnyPlayerCollision = false; - Vector2 pos = position - new Vector2(4); + Vector2 pos = Position - new Vector2(4); var collisionRectangle = new Rectangle((int)pos.X, (int)pos.Y, 8, 8); bool playerCollision = false; foreach (var player in Main.player) @@ -121,7 +122,7 @@ public override void Update() } if (AnyPlayerCollision && !oldPlayerHit) { - Wiring.TripWire(originTile.X, originTile.Y, 1, 1); + Wiring.TripWire(OriginTilePos.X, OriginTilePos.Y, 1, 1); } base.Update(); } @@ -143,52 +144,52 @@ public override void Draw() Vector2 starX = new Vector2(36, 0).RotatedBy(subRot); Vector2 starY = new Vector2(0, 11).RotatedBy(subRot); var star = new List(); - star.Add(position - starX - starY, laserColor, new Vector3(frame.X / (float)texture.Width, frame.Y / (float)texture.Height, 0)); - star.Add(position + starX - starY, laserColor, new Vector3((frame.X + frame.Width) / (float)texture.Width, frame.Y / (float)texture.Height, 0)); - star.Add(position - starX + starY, laserColor, new Vector3(frame.X / (float)texture.Width, (frame.Y + frame.Height) / (float)texture.Height, 0)); + star.Add(Position - starX - starY, laserColor, new Vector3(frame.X / (float)Texture.Width, frame.Y / (float)Texture.Height, 0)); + star.Add(Position + starX - starY, laserColor, new Vector3((frame.X + frame.Width) / (float)Texture.Width, frame.Y / (float)Texture.Height, 0)); + star.Add(Position - starX + starY, laserColor, new Vector3(frame.X / (float)Texture.Width, (frame.Y + frame.Height) / (float)Texture.Height, 0)); - star.Add(position - starX + starY, laserColor, new Vector3(frame.X / (float)texture.Width, (frame.Y + frame.Height) / (float)texture.Height, 0)); - star.Add(position + starX - starY, laserColor, new Vector3((frame.X + frame.Width) / (float)texture.Width, frame.Y / (float)texture.Height, 0)); - star.Add(position + starX + starY, laserColor, new Vector3((frame.X + frame.Width) / (float)texture.Width, (frame.Y + frame.Height) / (float)texture.Height, 0)); + star.Add(Position - starX + starY, laserColor, new Vector3(frame.X / (float)Texture.Width, (frame.Y + frame.Height) / (float)Texture.Height, 0)); + star.Add(Position + starX - starY, laserColor, new Vector3((frame.X + frame.Width) / (float)Texture.Width, frame.Y / (float)Texture.Height, 0)); + star.Add(Position + starX + starY, laserColor, new Vector3((frame.X + frame.Width) / (float)Texture.Width, (frame.Y + frame.Height) / (float)Texture.Height, 0)); subRot = Rotation - MathHelper.PiOver4; starX = new Vector2(36, 0).RotatedBy(subRot); starY = new Vector2(0, 11).RotatedBy(subRot); - star.Add(position - starX - starY, laserColor, new Vector3(frame.X / (float)texture.Width, frame.Y / (float)texture.Height, 0)); - star.Add(position + starX - starY, laserColor, new Vector3((frame.X + frame.Width) / (float)texture.Width, frame.Y / (float)texture.Height, 0)); - star.Add(position - starX + starY, laserColor, new Vector3(frame.X / (float)texture.Width, (frame.Y + frame.Height) / (float)texture.Height, 0)); + star.Add(Position - starX - starY, laserColor, new Vector3(frame.X / (float)Texture.Width, frame.Y / (float)Texture.Height, 0)); + star.Add(Position + starX - starY, laserColor, new Vector3((frame.X + frame.Width) / (float)Texture.Width, frame.Y / (float)Texture.Height, 0)); + star.Add(Position - starX + starY, laserColor, new Vector3(frame.X / (float)Texture.Width, (frame.Y + frame.Height) / (float)Texture.Height, 0)); - star.Add(position - starX + starY, laserColor, new Vector3(frame.X / (float)texture.Width, (frame.Y + frame.Height) / (float)texture.Height, 0)); - star.Add(position + starX - starY, laserColor, new Vector3((frame.X + frame.Width) / (float)texture.Width, frame.Y / (float)texture.Height, 0)); - star.Add(position + starX + starY, laserColor, new Vector3((frame.X + frame.Width) / (float)texture.Width, (frame.Y + frame.Height) / (float)texture.Height, 0)); + star.Add(Position - starX + starY, laserColor, new Vector3(frame.X / (float)Texture.Width, (frame.Y + frame.Height) / (float)Texture.Height, 0)); + star.Add(Position + starX - starY, laserColor, new Vector3((frame.X + frame.Width) / (float)Texture.Width, frame.Y / (float)Texture.Height, 0)); + star.Add(Position + starX + starY, laserColor, new Vector3((frame.X + frame.Width) / (float)Texture.Width, (frame.Y + frame.Height) / (float)Texture.Height, 0)); subRot = Rotation; starX = new Vector2(6, 0).RotatedBy(subRot); starY = new Vector2(0, 6).RotatedBy(subRot); frame = new Rectangle(0, 94, 24, 24); laserColor = Color.Lerp(laserColor, new Color(1f, 1f, 1f, 0), 0.2f); - star.Add(position - starX - starY, laserColor, new Vector3(frame.X / (float)texture.Width, frame.Y / (float)texture.Height, 0)); - star.Add(position + starX - starY, laserColor, new Vector3((frame.X + frame.Width) / (float)texture.Width, frame.Y / (float)texture.Height, 0)); - star.Add(position - starX + starY, laserColor, new Vector3(frame.X / (float)texture.Width, (frame.Y + frame.Height) / (float)texture.Height, 0)); - - star.Add(position - starX + starY, laserColor, new Vector3(frame.X / (float)texture.Width, (frame.Y + frame.Height) / (float)texture.Height, 0)); - star.Add(position + starX - starY, laserColor, new Vector3((frame.X + frame.Width) / (float)texture.Width, frame.Y / (float)texture.Height, 0)); - star.Add(position + starX + starY, laserColor, new Vector3((frame.X + frame.Width) / (float)texture.Width, (frame.Y + frame.Height) / (float)texture.Height, 0)); - Ins.Batch.Draw(texture, star, PrimitiveType.TriangleList); + star.Add(Position - starX - starY, laserColor, new Vector3(frame.X / (float)Texture.Width, frame.Y / (float)Texture.Height, 0)); + star.Add(Position + starX - starY, laserColor, new Vector3((frame.X + frame.Width) / (float)Texture.Width, frame.Y / (float)Texture.Height, 0)); + star.Add(Position - starX + starY, laserColor, new Vector3(frame.X / (float)Texture.Width, (frame.Y + frame.Height) / (float)Texture.Height, 0)); + + star.Add(Position - starX + starY, laserColor, new Vector3(frame.X / (float)Texture.Width, (frame.Y + frame.Height) / (float)Texture.Height, 0)); + star.Add(Position + starX - starY, laserColor, new Vector3((frame.X + frame.Width) / (float)Texture.Width, frame.Y / (float)Texture.Height, 0)); + star.Add(Position + starX + starY, laserColor, new Vector3((frame.X + frame.Width) / (float)Texture.Width, (frame.Y + frame.Height) / (float)Texture.Height, 0)); + Ins.Batch.Draw(Texture, star, PrimitiveType.TriangleList); } return; } - Vector2 stepPos = position; + Vector2 stepPos = Position; Vector2 collisionUnit = new Vector2(0, -8).RotatedBy(Rotation); Vector2 collisionUnit_T = new Vector2(0, -8).RotatedBy(Rotation + MathHelper.PiOver2); var bars = new List(); - bars.Add(stepPos + collisionUnit_T, laserColor, new Vector3(frame.X / (float)texture.Width, frame.Y / (float)texture.Height, 0)); - bars.Add(stepPos + collisionUnit + collisionUnit_T, laserColor, new Vector3((frame.X + frame.Width) / (float)texture.Width, frame.Y / (float)texture.Height, 0)); - bars.Add(stepPos - collisionUnit_T, laserColor, new Vector3(frame.X / (float)texture.Width, (frame.Y + frame.Height) / (float)texture.Height, 0)); + bars.Add(stepPos + collisionUnit_T, laserColor, new Vector3(frame.X / (float)Texture.Width, frame.Y / (float)Texture.Height, 0)); + bars.Add(stepPos + collisionUnit + collisionUnit_T, laserColor, new Vector3((frame.X + frame.Width) / (float)Texture.Width, frame.Y / (float)Texture.Height, 0)); + bars.Add(stepPos - collisionUnit_T, laserColor, new Vector3(frame.X / (float)Texture.Width, (frame.Y + frame.Height) / (float)Texture.Height, 0)); - bars.Add(stepPos - collisionUnit_T, laserColor, new Vector3(frame.X / (float)texture.Width, (frame.Y + frame.Height) / (float)texture.Height, 0)); - bars.Add(stepPos + collisionUnit + collisionUnit_T, laserColor, new Vector3((frame.X + frame.Width) / (float)texture.Width, frame.Y / (float)texture.Height, 0)); - bars.Add(stepPos + collisionUnit - collisionUnit_T, laserColor, new Vector3((frame.X + frame.Width) / (float)texture.Width, (frame.Y + frame.Height) / (float)texture.Height, 0)); + bars.Add(stepPos - collisionUnit_T, laserColor, new Vector3(frame.X / (float)Texture.Width, (frame.Y + frame.Height) / (float)Texture.Height, 0)); + bars.Add(stepPos + collisionUnit + collisionUnit_T, laserColor, new Vector3((frame.X + frame.Width) / (float)Texture.Width, frame.Y / (float)Texture.Height, 0)); + bars.Add(stepPos + collisionUnit - collisionUnit_T, laserColor, new Vector3((frame.X + frame.Width) / (float)Texture.Width, (frame.Y + frame.Height) / (float)Texture.Height, 0)); frame = new Rectangle(28, 74, 16, 16); for (int i = 0; i < length; i++) { @@ -197,20 +198,20 @@ public override void Draw() { frame = new Rectangle(56, 74, 16, 16); } - bars.Add(stepPos + collisionUnit_T, laserColor, new Vector3(frame.X / (float)texture.Width, frame.Y / (float)texture.Height, 0)); - bars.Add(stepPos + collisionUnit + collisionUnit_T, laserColor, new Vector3((frame.X + frame.Width) / (float)texture.Width, frame.Y / (float)texture.Height, 0)); - bars.Add(stepPos - collisionUnit_T, laserColor, new Vector3(frame.X / (float)texture.Width, (frame.Y + frame.Height) / (float)texture.Height, 0)); + bars.Add(stepPos + collisionUnit_T, laserColor, new Vector3(frame.X / (float)Texture.Width, frame.Y / (float)Texture.Height, 0)); + bars.Add(stepPos + collisionUnit + collisionUnit_T, laserColor, new Vector3((frame.X + frame.Width) / (float)Texture.Width, frame.Y / (float)Texture.Height, 0)); + bars.Add(stepPos - collisionUnit_T, laserColor, new Vector3(frame.X / (float)Texture.Width, (frame.Y + frame.Height) / (float)Texture.Height, 0)); - bars.Add(stepPos - collisionUnit_T, laserColor, new Vector3(frame.X / (float)texture.Width, (frame.Y + frame.Height) / (float)texture.Height, 0)); - bars.Add(stepPos + collisionUnit + collisionUnit_T, laserColor, new Vector3((frame.X + frame.Width) / (float)texture.Width, frame.Y / (float)texture.Height, 0)); - bars.Add(stepPos + collisionUnit - collisionUnit_T, laserColor, new Vector3((frame.X + frame.Width) / (float)texture.Width, (frame.Y + frame.Height) / (float)texture.Height, 0)); + bars.Add(stepPos - collisionUnit_T, laserColor, new Vector3(frame.X / (float)Texture.Width, (frame.Y + frame.Height) / (float)Texture.Height, 0)); + bars.Add(stepPos + collisionUnit + collisionUnit_T, laserColor, new Vector3((frame.X + frame.Width) / (float)Texture.Width, frame.Y / (float)Texture.Height, 0)); + bars.Add(stepPos + collisionUnit - collisionUnit_T, laserColor, new Vector3((frame.X + frame.Width) / (float)Texture.Width, (frame.Y + frame.Height) / (float)Texture.Height, 0)); } - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleList); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleList); } public override void Kill() { - UnregisterCustomLogic(LaserScan); + UnregisterCustomDraw(LaserScan); base.Kill(); } @@ -227,7 +228,7 @@ public void RegisterCustomLogic(ScanningLogic customLogic) /// Unregister a custom logic. /// /// - public void UnregisterCustomLogic(ScanningLogic customLogic) + public void UnregisterCustomDraw(ScanningLogic customLogic) { LaserScan -= customLogic; } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeGreenAlgae.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeGreenAlgae.cs index 7bb7c3dd5..a4e4ee66c 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeGreenAlgae.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeGreenAlgae.cs @@ -12,7 +12,6 @@ public override void PostSetDefaults() { Main.tileFrameImportant[Type] = false; Main.tileNoAttach[Type] = true; - Main.tileCut[Type] = true; Main.tileLavaDeath[Type] = true; TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); TileObjectData.newTile.Height = 1; @@ -94,7 +93,6 @@ public override void RandomUpdate(int i, int j) public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) { - var tile = Main.tile[i, j]; if (Main.tile[i, j + 1].TileType != Type) { TileFluentDrawManager.AddFluentPoint(this, i, j); @@ -127,7 +125,7 @@ private void DrawAlgae(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteB var lastOffset = new Vector2(0, 12); var lastOffset2 = new Vector2(0, 12); int height = 0; - for (int j = 0; j < 30; j++) + for (int j = 0; j < 40; j++) { height++; if (tilePos.Y - j < 21) @@ -140,7 +138,7 @@ private void DrawAlgae(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteB break; } } - for (int j = 0; j < 30; j++) + for (int j = 0; j < 40; j++) { if (tilePos.Y - j < 21) { diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeRedAlgae.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeRedAlgae.cs index 507f8557d..e5126bdc2 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeRedAlgae.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeRedAlgae.cs @@ -15,8 +15,8 @@ public override void PostSetDefaults() { Main.tileFrameImportant[Type] = false; Main.tileNoAttach[Type] = true; - Main.tileCut[Type] = true; Main.tileLavaDeath[Type] = true; + // TileObjectData assignment // The TileID.Signs TileObjectData doesn't set StyleMultiplier to 5, so we will not be copying from it in this case // Using Style1x1 as a base, we will create a TileObjectData with 5 alternate placements, each anchoring to a different anchor. @@ -92,7 +92,7 @@ public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBre var tileRight = Main.tile[tilePos + new Point(1, 0)]; var tileUp = Main.tile[tilePos + new Point(0, -1)]; var tileDown = Main.tile[tilePos + new Point(0, 1)]; - if (tile.wall == 0 && (!tileLeft.HasTile || !Main.tileSolid[tileLeft.TileType]) && (!tileRight.HasTile || !Main.tileSolid[tileRight.TileType]) + if (tile.WallType == 0 && (!tileLeft.HasTile || !Main.tileSolid[tileLeft.TileType]) && (!tileRight.HasTile || !Main.tileSolid[tileRight.TileType]) && (!tileUp.HasTile || !Main.tileSolid[tileUp.TileType]) && (!tileDown.HasTile || !Main.tileSolid[tileDown.TileType])) { WorldGen.KillTile(i, j); @@ -138,7 +138,7 @@ private void DrawAlgae(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteB var tileRight = Main.tile[tilePos + new Point(1, 0)]; var tileUp = Main.tile[tilePos + new Point(0, -1)]; var tileDown = Main.tile[tilePos + new Point(0, 1)]; - if (tile.wall > 0 && (!tileLeft.HasTile || !Main.tileSolid[tileLeft.TileType]) && (!tileRight.HasTile || !Main.tileSolid[tileRight.TileType]) + if (tile.WallType > 0 && (!tileLeft.HasTile || !Main.tileSolid[tileLeft.TileType]) && (!tileRight.HasTile || !Main.tileSolid[tileRight.TileType]) && (!tileUp.HasTile || !Main.tileSolid[tileUp.TileType]) && (!tileDown.HasTile || !Main.tileSolid[tileDown.TileType])) { styleWall = true; @@ -245,9 +245,8 @@ private void DrawAlgae(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteB windCycle += highestWindGridPushComplexRight; Vector2 movementRight = new Vector2(windCycle * 7.2f * hardness, 0); float midRot = (movementLeft.X + movementRight.X) * 0.015f + totalRot; - - algaes.Add(drawPos - deltaX.RotatedBy(midRot) + algeaPos + movementLeft, tileLight, new Vector3(frame.X / (float)tex.Width, (frame.Y + frame.Height - frame.Height / 16f * j) / tex.Height, 0)); algaes.Add(drawPos + deltaX.RotatedBy(midRot) + algeaPos + movementRight, tileLight, new Vector3((frame.X + frame.Width) / (float)tex.Width, (frame.Y + frame.Height - frame.Height / 16f * j) / tex.Height, 0)); + algaes.Add(drawPos - deltaX.RotatedBy(midRot) + algeaPos + movementLeft, tileLight, new Vector3(frame.X / (float)tex.Width, (frame.Y + frame.Height - frame.Height / 16f * j) / tex.Height, 0)); algeaPos += deltaY.RotatedBy(midRot); } } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeRedAlgae.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeRedAlgae.png index ab4e6173f..3da60f170 100644 Binary files a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeRedAlgae.png and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeRedAlgae.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeSponge.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeSponge.cs new file mode 100644 index 000000000..880bcbfa2 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeSponge.cs @@ -0,0 +1,46 @@ +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.Projectiles.TileEffect; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class JadeLakeSponge : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 1; + TileObjectData.newTile.Width = 1; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 30, + }; + TileObjectData.newTile.CoordinateWidth = 30; + TileObjectData.newTile.DrawYOffset = -12; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(129, 120, 97)); + } + + public override void KillMultiTile(int i, int j, int frameX, int frameY) + { + if (frameX % 30 == 0 && frameY == 0) + { + Vector2 pos = new Point(i, j).ToWorldCoordinates() + new Vector2(8, 16); + var p0 = Projectile.NewProjectileDirect(WorldGen.GetProjectileSource_TileBreak(i, j), pos, new Vector2(0, -5), ModContent.ProjectileType(), 20, 0); + for (int k = 0; k < 6; k++) + { + var dust = Dust.NewDustDirect(pos - new Vector2(4) + new Vector2(-8, 0), 16, 16, ModContent.DustType()); + dust.customData = p0; + dust.velocity *= 0.3f; + dust.velocity.Y -= 2f; + } + } + base.KillMultiTile(i, j, frameX, frameY); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeSponge.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeSponge.png new file mode 100644 index 000000000..5ed783fb4 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/JadeLakeSponge.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/LightningMechanism/UnderwaterLightningMechanism.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/LightningMechanism/UnderwaterLightningMechanism.cs index d5a876062..ad2376991 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/LightningMechanism/UnderwaterLightningMechanism.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/LightningMechanism/UnderwaterLightningMechanism.cs @@ -1,7 +1,5 @@ using Everglow.Yggdrasil.KelpCurtain.Dusts; using Everglow.Yggdrasil.KelpCurtain.Projectiles.TileEffect; -using Everglow.Yggdrasil.KelpCurtain.Tiles.GeyserAirBuds; -using Everglow.Yggdrasil.WorldGeneration; using Terraria.DataStructures; using Terraria.Enums; using Terraria.ObjectData; @@ -150,6 +148,7 @@ public Point BFSFindOtherMechanism(int i, int j) }; Queue queueChecked = new Queue(); Tile tile = Main.tile[i, j]; + // 将起始点加入队列 queueChecked.Enqueue(new Point(i, j)); List visited = new List(); diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/LightningMechanism/UnderwaterLightningMechanism_H.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/LightningMechanism/UnderwaterLightningMechanism_H.cs index 1a4635a29..18e452ede 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/LightningMechanism/UnderwaterLightningMechanism_H.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/LightningMechanism/UnderwaterLightningMechanism_H.cs @@ -56,7 +56,6 @@ public override void NumDust(int i, int j, bool fail, ref int num) public override void PlaceInWorld(int i, int j, Item item) { Tile tile = Main.tile[i, j]; - Main.NewText((tile.TileFrameX, tile.TileFrameY)); if (tile.TileFrameX == 72) { ModTileEntity.PlaceEntityNet(i - 4, j, ModContent.TileEntityType()); diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/UnderwaterTentDebris.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/UnderwaterTentDebris.cs new file mode 100644 index 000000000..f864b752e --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/UnderwaterTentDebris.cs @@ -0,0 +1,25 @@ +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class UnderwaterTentDebris : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + TileObjectData.newTile.CopyFrom(TileObjectData.Style3x2); + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 20, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(109, 92, 75)); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/UnderwaterTentDebris.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/UnderwaterTentDebris.png new file mode 100644 index 000000000..f152ebdb0 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/UnderwaterTentDebris.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_BoardSign.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_BoardSign.cs new file mode 100644 index 000000000..a18ca7101 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_BoardSign.cs @@ -0,0 +1,122 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.GameContent.Drawing; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class VampireMatCave_BoardSign : ShapeDataTile, ITileFluentlyDrawn +{ + public override void SetStaticDefaults() + { + TotalWidth = 5; + TotalHeight = 9; + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileWaterDeath[Type] = false; + TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3); + TileObjectData.newTile.Height = 9; + TileObjectData.newTile.Width = 5; + TileObjectData.newTile.CoordinateHeights = new int[9]; + Array.Fill(TileObjectData.newTile.CoordinateHeights, 16); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.SolidTile, 1, 2); + TileObjectData.newTile.Origin = new Point16(2, 8); + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(119, 116, 62)); + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + if (Main.tile[i, j + 1].TileType != Type && Main.tile[i, j].TileFrameX == 36) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + } + return false; + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + DrawSign(pos, pos.ToWorldCoordinates() - screenPosition, spriteBatch, tileDrawing); + } + + private void DrawSign(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + drawCenterPos += new Vector2(1, 10); + var tile = TileUtils.SafeGetTile(tilePos); + + // 回声涂料 + if (!TileDrawing.IsVisible(tile)) + { + return; + } + + int paint = Main.tile[tilePos].TileColor; + Texture2D tex = PaintedTextureSystem.TryGetPaintedTexture(ModAsset.VampireMatCave_BoardSign_Path, Type, 1, paint, tileDrawing); + tex ??= ModAsset.VampireMatCave_BoardSign.Value; + + var tileLight = Lighting.GetColor(tilePos); + + // 支æŒå‘光涂料 + tileDrawing.DrawAnimatedTile_AdjustForVisionChangers(tilePos.X, tilePos.Y, tile, Type, 0, 0, ref tileLight, tileDrawing._rand.NextBool(4)); + tileLight = tileDrawing.DrawTiles_GetLightOverride(tilePos.X, tilePos.Y, tile, Type, 0, 0, tileLight); + + var frame = new Rectangle(148, 16, 70, 146); + TileUtils.VertexDraw_Grid(drawCenterPos, frame, new Vector2(35, 146), tex, spriteBatch, 0); + + Vector2 kelpPos = drawCenterPos + new Vector2(-14, -50); + List bars = new List(); + for (int y = 0; y <= 3; y++) + { + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(tilePos.X - 1, tilePos.Y - 2 + y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(tilePos.X - 1, tilePos.Y - 2 + y, tileDrawing._sunflowerWindCounter); + } + int totalPushTime = 140; + float pushForcePerFrame = 0.96f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X - 1, tilePos.Y - 2 + y, 1, 1, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + windCycle += highestWindGridPushComplex; + windCycle *= y * 0.2f; + AddWorldVertex(bars, kelpPos + new Vector2(windCycle * 10 - 11, y * 16), new Vector2(92, 106 + y * 16), tex); + AddWorldVertex(bars, kelpPos + new Vector2(windCycle * 10 + 11, y * 16), new Vector2(114, 106 + y * 16), tex); + } + if (bars.Count > 2) + { + spriteBatch.GraphicsDevice.Textures[0] = tex; + spriteBatch.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + + kelpPos = drawCenterPos + new Vector2(12, -50); + bars = new List(); + for (int y = 0; y <= 3; y++) + { + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(tilePos.X + 1, tilePos.Y - 2 + y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(tilePos.X + 1, tilePos.Y - 2 + y, tileDrawing._sunflowerWindCounter); + } + int totalPushTime = 140; + float pushForcePerFrame = 0.96f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X + 1, tilePos.Y - 2 + y, 1, 1, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + windCycle += highestWindGridPushComplex; + windCycle *= y * 0.2f; + AddWorldVertex(bars, kelpPos + new Vector2(windCycle * 10 - 10, y * 16), new Vector2(126, 106 + y * 16), tex); + AddWorldVertex(bars, kelpPos + new Vector2(windCycle * 10 + 10, y * 16), new Vector2(146, 106 + y * 16), tex); + } + if (bars.Count > 2) + { + spriteBatch.GraphicsDevice.Textures[0] = tex; + spriteBatch.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + } + + private void AddWorldVertex(List bars, Vector2 worldPos, Vector2 coord, Texture2D tex) + { + bars.Add(worldPos, Lighting.GetColor((worldPos + Main.screenPosition).ToTileCoordinates()), new Vector3(coord / tex.Size(), 0)); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_BoardSign.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_BoardSign.png new file mode 100644 index 000000000..279476c51 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_BoardSign.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_BoardSign_shape.bmp b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_BoardSign_shape.bmp new file mode 100644 index 000000000..cb7991895 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_BoardSign_shape.bmp differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_HangingSign.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_HangingSign.cs new file mode 100644 index 000000000..30ff9adc3 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_HangingSign.cs @@ -0,0 +1,131 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.GameContent.Drawing; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class VampireMatCave_HangingSign : ShapeDataTile, ITileFluentlyDrawn +{ + public override void SetStaticDefaults() + { + TotalWidth = 5; + TotalHeight = 14; + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileWaterDeath[Type] = false; + TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3); + TileObjectData.newTile.Height = 14; + TileObjectData.newTile.Width = 5; + TileObjectData.newTile.CoordinateHeights = new int[14]; + Array.Fill(TileObjectData.newTile.CoordinateHeights, 16); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.newTile.AnchorBottom = AnchorData.Empty; + TileObjectData.newTile.AnchorTop = new AnchorData(AnchorType.SolidTile, 1, 2); + TileObjectData.newTile.Origin = new Point16(2, 0); + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(61, 34, 48)); + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + if (Main.tile[i, j - 1].TileType != Type && Main.tile[i, j].TileFrameY == 0) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + } + return false; + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + DrawSign(pos, pos.ToWorldCoordinates() - screenPosition, spriteBatch, tileDrawing); + } + + private void DrawSign(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + var lastOffset = new Vector2(0, -8); + for (int j = 0; j < 6; j++) + { + var offsetPos = tilePos + new Point(0, j); + var tile = Main.tile[offsetPos]; + ushort type = tile.TileType; + + // 回声涂料 + if (!TileDrawing.IsVisible(tile)) + { + continue; + } + + int paint = Main.tile[offsetPos].TileColor; + Texture2D tex = PaintedTextureSystem.TryGetPaintedTexture(ModAsset.VampireMatCave_HangingSign_Path, type, 1, paint, tileDrawing); + tex ??= ModAsset.VampireMatCave_HangingSign.Value; + + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(offsetPos.X, offsetPos.Y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(offsetPos.X, offsetPos.Y, tileDrawing._sunflowerWindCounter); + } + + int totalPushTime = 140; + float pushForcePerFrame = 0.96f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(offsetPos.X, offsetPos.Y, 1, 1, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + if (j == 5) + { + highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(offsetPos.X - 2, offsetPos.Y, 5, 9, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + } + windCycle -= highestWindGridPushComplex; + float rotation = windCycle * 0.21f; + if (j < 5) + { + rotation -= lastOffset.X / (22f + j * 3f); + } + else + { + rotation += lastOffset.X / (22f + j * 3f) * 0.25f; + } + var tileLight = Lighting.GetColor(offsetPos); + + // 支æŒå‘光涂料 + tileDrawing.DrawAnimatedTile_AdjustForVisionChangers(offsetPos.X, offsetPos.Y, tile, type, 0, 0, ref tileLight, tileDrawing._rand.NextBool(4)); + tileLight = tileDrawing.DrawTiles_GetLightOverride(offsetPos.X, offsetPos.Y, tile, type, 0, 0, tileLight); + + var origin = new Vector2(8, 0); + var frame = Rectangle.emptyRectangle; + switch (j) + { + case 0: + frame = new Rectangle(124, 0, 16, 16); + break; + case 1: + frame = new Rectangle(124, 18, 16, 16); + break; + case 2: + frame = new Rectangle(124, 36, 16, 20); + break; + case 3: + frame = new Rectangle(124, 58, 16, 20); + break; + case 4: + frame = new Rectangle(124, 80, 16, 14); + break; + case 5: + frame = new Rectangle(94, 96, 80, 160); + origin = new Vector2(40, 0); + break; + } + var drawPos = drawCenterPos + lastOffset; + var tileSpriteEffect = SpriteEffects.None; + spriteBatch.Draw(tex, drawPos, frame, tileLight, rotation, origin, 1f, tileSpriteEffect, 0f); + if (j == 5) + { + frame.X += 80; + spriteBatch.Draw(tex, drawPos, frame, tileLight * 3, rotation, origin, 1f, tileSpriteEffect, 0f); + } + lastOffset += new Vector2(0, frame.Height - 4).RotatedBy(rotation); + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_HangingSign.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_HangingSign.png new file mode 100644 index 000000000..00f686887 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_HangingSign.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_HangingSign_shape.bmp b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_HangingSign_shape.bmp new file mode 100644 index 000000000..f0c4a3576 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_HangingSign_shape.bmp differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoarding.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoarding.cs new file mode 100644 index 000000000..a0967e474 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoarding.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.KelpCurtain.Dusts; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class VampireMatCave_WoodenBoarding : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileSolid[Type] = true; + DustType = ModContent.DustType(); + AddMapEntry(new Color(63, 44, 44)); + } + + public override void KillTile(int i, int j, ref bool fail, ref bool effectOnly, ref bool noItem) => base.KillTile(i, j, ref fail, ref effectOnly, ref noItem); +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoarding.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoarding.png new file mode 100644 index 000000000..a74836041 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoarding.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoardingCore.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoardingCore.cs new file mode 100644 index 000000000..7e682b9a8 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoardingCore.cs @@ -0,0 +1,31 @@ +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.KelpCurtain.Dusts; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class VampireMatCave_WoodenBoardingCore : ModTile, ISceneTile +{ + public override void SetStaticDefaults() + { + Main.tileSolid[Type] = true; + DustType = ModContent.DustType(); + AddMapEntry(new Color(63, 44, 44)); + } + + public override void KillTile(int i, int j, ref bool fail, ref bool effectOnly, ref bool noItem) => base.KillTile(i, j, ref fail, ref effectOnly, ref noItem); + + public void AddScene(int i, int j) + { + var vfx = new VampireMatCave_WoodenBoardingCore_VFX + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Texture = ModAsset.VampireMatCave_WoodenBoardingCore_VFX.Value, + }; + Ins.VFXManager.Add(vfx); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoardingCore.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoardingCore.png new file mode 100644 index 000000000..a74836041 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoardingCore.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoardingCore_VFX.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoardingCore_VFX.cs new file mode 100644 index 000000000..0101b49c3 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoardingCore_VFX.cs @@ -0,0 +1,9 @@ +using Everglow.Commons.VFX.Scene; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +[Pipeline(typeof(WCSPipeline))] +public class VampireMatCave_WoodenBoardingCore_VFX : TileVFX +{ + public override void Draw() => base.Draw(); +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoardingCore_VFX.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoardingCore_VFX.png new file mode 100644 index 000000000..61db90c1d Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/VampireMatCave_WoodenBoardingCore_VFX.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHole_VFX_warp.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHole_VFX_warp.cs new file mode 100644 index 000000000..6924f3850 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHole_VFX_warp.cs @@ -0,0 +1,47 @@ +using Everglow.Commons.VFX.Scene; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +[Pipeline(typeof(WarpPipeline))] +public class WaterDeliveryHole_VFX_warp : TileVFX +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawTiles; + + public float Rotation; + + public override void Update() + { + base.Update(); + } + + public override void Draw() + { + float timeValue = (float)(Main.time * 0.001f); + var bars_side_left = new List(); + var bars_side_right = new List(); + for (int k = -2; k < 30; k++) + { + var pos = new Vector2(k * 3, 0).RotatedBy(Rotation); + float value = k / 300f; + float fade = 0.15f; + if (k > 20) + { + fade *= (30 - k) / 10f; + } + Vector2 dir = new Vector2(1, 0).RotatedBy(Rotation + MathHelper.PiOver2) + Vector2.One; + dir *= 0.5f; + Color drawColor = new Color(dir.X, dir.Y, fade, 1f); + Color drawColor_side = new Color(dir.X, dir.Y, 0, 1f); + float coordX = MathF.Pow(value, 2); + + bars_side_left.Add(Position + pos + new Vector2(0, -20 - k).RotatedBy(Rotation), drawColor_side, new Vector3(coordX + timeValue, 0, 0)); + bars_side_left.Add(Position + pos + new Vector2(0, 0), drawColor, new Vector3(coordX + timeValue, 0.5f, 0)); + + bars_side_right.Add(Position + pos + new Vector2(0, 20 + k).RotatedBy(Rotation), drawColor_side, new Vector3(coordX + timeValue, 1, 0)); + bars_side_right.Add(Position + pos + new Vector2(0, 0), drawColor, new Vector3(coordX + timeValue, 0.5f, 0)); + } + + Ins.Batch.Draw(Commons.ModAsset.Noise_flame_2.Value, bars_side_left, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Commons.ModAsset.Noise_flame_2.Value, bars_side_right, PrimitiveType.TriangleStrip); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole.cs new file mode 100644 index 000000000..7d95b38cf --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole.cs @@ -0,0 +1,113 @@ +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.WaterDeliveryHoles; + +public class WaterDeliveryHole : ModTile, ISceneTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + Main.tileBlendAll[Type] = true; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 2; + TileObjectData.newTile.Width = 5; + var SolidOrSolidSideAnchor1TilesLong = new AnchorData(AnchorType.SolidTile | AnchorType.SolidSide, 5, 0); + TileObjectData.newTile.AnchorBottom = AnchorData.Empty; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 16, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + + TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile); + TileObjectData.newAlternate.Origin = new Point16(2, 1); + TileObjectData.newAlternate.AnchorTop = SolidOrSolidSideAnchor1TilesLong; + TileObjectData.newAlternate.Style = 1; + TileObjectData.addAlternate(1); + + TileObjectData.newTile.Origin = new Point16(2, 0); + TileObjectData.newTile.AnchorBottom = SolidOrSolidSideAnchor1TilesLong; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(78, 162, 255)); + } + + public void AddScene(int i, int j) + { + Tile tile = Main.tile[i, j]; + if ((tile.TileFrameX == 36 && tile.TileFrameY == 18) || (tile.TileFrameX == 126 && tile.TileFrameY == 0)) + { + int dir = -1; + if (tile.TileFrameX == 126) + { + dir = 1; + } + var vfx = new WaterDeliveryHole_VFX + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = dir * MathHelper.PiOver2, + }; + Ins.VFXManager.Add(vfx); + var warp = new WaterDeliveryHole_VFX_warp + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = dir * MathHelper.PiOver2, + }; + Ins.VFXManager.Add(warp); + var foreground = new WaterDeliveryHole_foreground + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = dir * MathHelper.PiOver2, + }; + Ins.VFXManager.Add(foreground); + } + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + Tile tile = Main.tile[i, j]; + Texture2D tex = ModAsset.WaterDeliveryHole.Value; + Vector2 pos = new Vector2(i * 16, j * 16) - Main.screenPosition + zero; + spriteBatch.Draw(tex, pos, new Rectangle(tile.TileFrameX, tile.TileFrameY + 36, 16, 16), new Color(0f, 0f, 0.7f, 0)); + } + + public override void NearbyEffects(int i, int j, bool closer) + { + if (Main.dedServ) + { + base.NearbyEffects(i, j, closer); + return; + } + Lighting.AddLight(new Point(i, j).ToWorldCoordinates(), new Vector3(0.4f, 0.8f, 2f)); + WaterDeliveryHole_TeleportPlayer.GetDestinationAndTeleport(i, j); + base.NearbyEffects(i, j, closer); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole.png new file mode 100644 index 000000000..1712d36a8 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomLeft.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomLeft.cs new file mode 100644 index 000000000..06edd8d51 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomLeft.cs @@ -0,0 +1,108 @@ +using Everglow.Commons.TileHelper; +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.Items.Placeables; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.WaterDeliveryHoles; + +public class WaterDeliveryHole_BottomLeft : ShapeDataTile, ISceneTile +{ + public override void SetStaticDefaults() + { + TotalHeight = 4; + TotalWidth = 4; + CustomItemType = ModContent.ItemType(); + + Main.tileSolid[Type] = false; + Main.tileBlendAll[Type] = true; + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileWaterDeath[Type] = false; + Main.tileCut[Type] = false; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Origin = new Point16(1, 2); + TileObjectData.newTile.Height = TotalHeight; + TileObjectData.newTile.Width = TotalWidth; + TileObjectData.newTile.CoordinateHeights = new int[TotalHeight]; + for (int i = 0; i < TotalHeight; i++) + { + TileObjectData.newTile.CoordinateHeights[i] = 16; + } + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + TileObjectData.addTile(Type); + + DustType = ModContent.DustType(); + AddMapEntry(new Color(78, 162, 255)); + } + + public void AddScene(int i, int j) + { + Tile tile = Main.tile[i, j]; + if (tile.TileFrameX == 18 && tile.TileFrameY == 36) + { + var vfx = new WaterDeliveryHole_VFX + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = -MathHelper.PiOver4 * 5, + }; + Ins.VFXManager.Add(vfx); + var warp = new WaterDeliveryHole_VFX_warp + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = -MathHelper.PiOver4 * 5, + }; + Ins.VFXManager.Add(warp); + var foreground = new WaterDeliveryHole_Slope_foreground + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = -MathHelper.PiOver4 * 5, + }; + Ins.VFXManager.Add(foreground); + } + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + Tile tile = Main.tile[i, j]; + Texture2D tex = ModAsset.WaterDeliveryHole.Value; + Vector2 pos = new Vector2(i * 16, j * 16) - Main.screenPosition + zero; + spriteBatch.Draw(tex, pos, new Rectangle(tile.TileFrameX, tile.TileFrameY + 36, 16, 16), new Color(0f, 0f, 0.7f, 0)); + } + + public override void NearbyEffects(int i, int j, bool closer) + { + if (Main.dedServ) + { + base.NearbyEffects(i, j, closer); + return; + } + Lighting.AddLight(new Point(i, j).ToWorldCoordinates(), new Vector3(0.4f, 0.8f, 2f)); + WaterDeliveryHole_TeleportPlayer.GetDestinationAndTeleport(i, j); + base.NearbyEffects(i, j, closer); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomLeft.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomLeft.png new file mode 100644 index 000000000..807a32f4c Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomLeft.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomLeft_shape.bmp b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomLeft_shape.bmp new file mode 100644 index 000000000..4627a8350 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomLeft_shape.bmp differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomRight.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomRight.cs new file mode 100644 index 000000000..c11cd4de0 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomRight.cs @@ -0,0 +1,108 @@ +using Everglow.Commons.TileHelper; +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.Items.Placeables; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.WaterDeliveryHoles; + +public class WaterDeliveryHole_BottomRight : ShapeDataTile, ISceneTile +{ + public override void SetStaticDefaults() + { + TotalHeight = 4; + TotalWidth = 4; + CustomItemType = ModContent.ItemType(); + + Main.tileSolid[Type] = false; + Main.tileBlendAll[Type] = true; + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileWaterDeath[Type] = false; + Main.tileCut[Type] = false; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Origin = new Point16(2, 2); + TileObjectData.newTile.Height = TotalHeight; + TileObjectData.newTile.Width = TotalWidth; + TileObjectData.newTile.CoordinateHeights = new int[TotalHeight]; + for (int i = 0; i < TotalHeight; i++) + { + TileObjectData.newTile.CoordinateHeights[i] = 16; + } + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + TileObjectData.addTile(Type); + + DustType = ModContent.DustType(); + AddMapEntry(new Color(78, 162, 255)); + } + + public void AddScene(int i, int j) + { + Tile tile = Main.tile[i, j]; + if (tile.TileFrameX == 36 && tile.TileFrameY == 36) + { + var vfx = new WaterDeliveryHole_VFX + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = MathHelper.PiOver4, + }; + Ins.VFXManager.Add(vfx); + var warp = new WaterDeliveryHole_VFX_warp + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = MathHelper.PiOver4, + }; + Ins.VFXManager.Add(warp); + var foreground = new WaterDeliveryHole_Slope_foreground + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = MathHelper.PiOver4, + }; + Ins.VFXManager.Add(foreground); + } + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + Tile tile = Main.tile[i, j]; + Texture2D tex = ModAsset.WaterDeliveryHole.Value; + Vector2 pos = new Vector2(i * 16, j * 16) - Main.screenPosition + zero; + spriteBatch.Draw(tex, pos, new Rectangle(tile.TileFrameX, tile.TileFrameY + 36, 16, 16), new Color(0f, 0f, 0.7f, 0)); + } + + public override void NearbyEffects(int i, int j, bool closer) + { + if (Main.dedServ) + { + base.NearbyEffects(i, j, closer); + return; + } + Lighting.AddLight(new Point(i, j).ToWorldCoordinates(), new Vector3(0.4f, 0.8f, 2f)); + WaterDeliveryHole_TeleportPlayer.GetDestinationAndTeleport(i, j); + base.NearbyEffects(i, j, closer); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomRight.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomRight.png new file mode 100644 index 000000000..8cfbebe4d Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomRight.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomRight_shape.bmp b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomRight_shape.bmp new file mode 100644 index 000000000..f621462f5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_BottomRight_shape.bmp differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_Slope_foreground.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_Slope_foreground.cs new file mode 100644 index 000000000..dff35d964 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_Slope_foreground.cs @@ -0,0 +1,24 @@ +using Everglow.Commons.VFX.Scene; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.WaterDeliveryHoles; + +[Pipeline(typeof(WCSPipeline))] +public class WaterDeliveryHole_Slope_foreground : TileVFX +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; + + public float Rotation; + + public override void Update() + { + base.Update(); + } + + public override void Draw() + { + Texture2D tex = ModAsset.WaterDeliveryHole_Slope_foreground.Value; + Vector2 offset = new Vector2(-3, 3).RotatedBy(Rotation); + SpriteEffects effects = SpriteEffects.None; + Ins.Batch.Draw(tex, Position + offset, null, Lighting.GetColor(Position.ToTileCoordinates()), Rotation + MathHelper.PiOver4, new Vector2(40, 28), 1f, effects); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_Slope_foreground.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_Slope_foreground.png new file mode 100644 index 000000000..9487012c2 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_Slope_foreground.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TeleportPlayer.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TeleportPlayer.cs new file mode 100644 index 000000000..a09f88560 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TeleportPlayer.cs @@ -0,0 +1,205 @@ +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.WaterDeliveryHoles; + +public class WaterDeliveryHole_TeleportPlayer : ModPlayer +{ + public bool Active = false; + + public Vector2 OldPos; + + public float Timer; + + public float MaxTeleportTime = 30; + + public override void ModifyScreenPosition() + { + if (Active) + { + if (Timer > 0) + { + Timer--; + float value = 1f - Timer / MaxTeleportTime; + Main.screenPosition = value.Lerp(OldPos, Main.screenPosition); + } + else + { + Timer = 0; + Active = false; + } + } + base.ModifyScreenPosition(); + } + + public static void GetDestinationAndTeleport(int i, int j) + { + Player player = Main.LocalPlayer; + WaterDeliveryHole_TeleportPlayer modPlayer = player.GetModPlayer(); + if (!modPlayer.Active) + { + Vector2 currentPos = new Vector2(i, j); + int currentDir = -1; + var currentTile = TileUtils.SafeGetTile(i, j); + int currentStyle = TileObjectData.GetTileStyle(currentTile); + TileObjectData currentObjectData = TileObjectData.GetTileData(currentTile.TileType, currentStyle); + if (!TileAtOriginPos(currentTile, currentStyle, currentObjectData)) + { + return; + } + Vector2 currentWorldPos = currentPos * 16 + new Vector2(8); + if ((player.Center - currentWorldPos).Length() >= 32 || (player.Center - currentWorldPos).Length() < (player.Center + player.velocity - currentWorldPos).Length()) + { + return; + } + + // x, y, direction + List<(int, int, int)> destinations = new List<(int, int, int)>(); + for (int x = -40; x <= 40; x += 1) + { + for (int y = -40; y <= 40; y += 1) + { + var tile = TileUtils.SafeGetTile(i + x, j + y); + int style = TileObjectData.GetTileStyle(tile); + if (style >= 0) + { + int targetType = tile.TileType; + TileObjectData tileObjectData = TileObjectData.GetTileData(targetType, style); + int dir = GetDirection(tile); + if (x == 0 && y == 0) + { + currentDir = dir; + continue; + } + if (TileAtOriginPos(tile, style, tileObjectData) && dir >= 0) + { + if (!destinations.Contains((tile.X(), tile.Y(), dir))) + { + destinations.Add((tile.X(), tile.Y(), dir)); + } + } + } + } + } + var chosenDest = (-1, -1, -1); + if (destinations.Count > 0) + { + Vector2 closestDest = new Vector2(i + 100, j + 100); + float minDis = closestDest.Length() * 2; + int bestDir = -1; + float maxDirDis = 0; + foreach (var dest in destinations) + { + Vector2 directionDis = new Vector2(1, 0).RotatedBy(dest.Item3 * MathHelper.PiOver4) - new Vector2(1, 0).RotatedBy(currentDir * MathHelper.PiOver4); + if (directionDis.Length() > maxDirDis - 0.1f) + { + maxDirDis = directionDis.Length(); + bestDir = dest.Item3; + } + } + foreach (var dest in destinations) + { + if (dest.Item3 != bestDir) + { + continue; + } + Vector2 destination = new Vector2(dest.Item1, dest.Item2); + Vector2 toDes = destination - currentPos; + float dis = toDes.Length(); + float cosValue = Vector2.Dot(toDes.SafeNormalize(Vector2.Zero), new Vector2(1, 0).RotatedBy(bestDir * MathHelper.PiOver4)); + if (cosValue < 0.8) + { + dis += 50; + } + if (dis < minDis) + { + minDis = dis; + closestDest = destination; + chosenDest = dest; + } + } + if ((currentPos - closestDest).Length() < 40) + { + int destX = chosenDest.Item1; + int destY = chosenDest.Item2; + var destTile = TileUtils.SafeGetTile(destX, destY); + var vfx = new WaterDeliveryHole_VFX_Release + { + Active = true, + Visible = true, + Position = new Point(destX, destY).ToWorldCoordinates(), + OriginTilePos = new Point(destX, destY), + OriginTileType = destTile.TileType, + Direction = 1, + Rotation = chosenDest.Item3 * MathHelper.PiOver4, + MaxTime = 60, + }; + Ins.VFXManager.Add(vfx); + Teleport(player, closestDest * 16 + new Vector2(8), bestDir * MathHelper.PiOver4); + } + } + } + } + + public static int GetDirection(Tile tile) + { + int targetType = tile.TileType; + int dir = -1; + int style = TileObjectData.GetTileStyle(tile); + if (targetType == ModContent.TileType()) + { + if (style == 0) + { + dir = 6; + } + else + { + dir = 2; + } + } + if (targetType == ModContent.TileType()) + { + if (style == 0) + { + dir = 4; + } + else + { + dir = 0; + } + } + if (targetType == ModContent.TileType()) + { + dir = 1; + } + if (targetType == ModContent.TileType()) + { + dir = 3; + } + if (targetType == ModContent.TileType()) + { + dir = 5; + } + if (targetType == ModContent.TileType()) + { + dir = 7; + } + return dir; + } + + public static bool TileAtOriginPos(Tile tile, int style, TileObjectData tileObjectData) + { + return tile.TileFrameX - style * tileObjectData.Width * 18 == tileObjectData.Origin.X * 18 && tile.TileFrameY == tileObjectData.Origin.Y * 18; + } + + public static void Teleport(Player player, Vector2 destination, float rotation) + { + WaterDeliveryHole_TeleportPlayer modPlayer = player.GetModPlayer(); + modPlayer.Active = true; + modPlayer.Timer = modPlayer.MaxTeleportTime; + modPlayer.OldPos = Main.screenPosition; + player.MountedCenter = destination; + player.MountedCenter += new Vector2(20, 0).RotatedBy(rotation) + player.velocity; + + // player.velocity += new Vector2(-4, 0).RotatedBy(rotation); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopLeft.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopLeft.cs new file mode 100644 index 000000000..bdae5c40c --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopLeft.cs @@ -0,0 +1,108 @@ +using Everglow.Commons.TileHelper; +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.Items.Placeables; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.WaterDeliveryHoles; + +public class WaterDeliveryHole_TopLeft : ShapeDataTile, ISceneTile +{ + public override void SetStaticDefaults() + { + TotalHeight = 4; + TotalWidth = 4; + CustomItemType = ModContent.ItemType(); + + Main.tileSolid[Type] = false; + Main.tileBlendAll[Type] = true; + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileWaterDeath[Type] = false; + Main.tileCut[Type] = false; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Origin = new Point16(1, 1); + TileObjectData.newTile.Height = TotalHeight; + TileObjectData.newTile.Width = TotalWidth; + TileObjectData.newTile.CoordinateHeights = new int[TotalHeight]; + for (int i = 0; i < TotalHeight; i++) + { + TileObjectData.newTile.CoordinateHeights[i] = 16; + } + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + TileObjectData.addTile(Type); + + DustType = ModContent.DustType(); + AddMapEntry(new Color(78, 162, 255)); + } + + public void AddScene(int i, int j) + { + Tile tile = Main.tile[i, j]; + if (tile.TileFrameX == 18 && tile.TileFrameY == 18) + { + var vfx = new WaterDeliveryHole_VFX + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = -MathHelper.PiOver4 * 3, + }; + Ins.VFXManager.Add(vfx); + var warp = new WaterDeliveryHole_VFX_warp + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = -MathHelper.PiOver4 * 3, + }; + Ins.VFXManager.Add(warp); + var foreground = new WaterDeliveryHole_Slope_foreground + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = -MathHelper.PiOver4 * 3, + }; + Ins.VFXManager.Add(foreground); + } + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + Tile tile = Main.tile[i, j]; + Texture2D tex = ModAsset.WaterDeliveryHole.Value; + Vector2 pos = new Vector2(i * 16, j * 16) - Main.screenPosition + zero; + spriteBatch.Draw(tex, pos, new Rectangle(tile.TileFrameX, tile.TileFrameY + 36, 16, 16), new Color(0f, 0f, 0.7f, 0)); + } + + public override void NearbyEffects(int i, int j, bool closer) + { + if (Main.dedServ) + { + base.NearbyEffects(i, j, closer); + return; + } + Lighting.AddLight(new Point(i, j).ToWorldCoordinates(), new Vector3(0.4f, 0.8f, 2f)); + WaterDeliveryHole_TeleportPlayer.GetDestinationAndTeleport(i, j); + base.NearbyEffects(i, j, closer); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopLeft.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopLeft.png new file mode 100644 index 000000000..6de725f7b Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopLeft.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopLeft_shape.bmp b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopLeft_shape.bmp new file mode 100644 index 000000000..e6b8e1fe3 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopLeft_shape.bmp differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopRight.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopRight.cs new file mode 100644 index 000000000..00b87dc35 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopRight.cs @@ -0,0 +1,108 @@ +using Everglow.Commons.TileHelper; +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.Items.Placeables; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.WaterDeliveryHoles; + +public class WaterDeliveryHole_TopRight : ShapeDataTile, ISceneTile +{ + public override void SetStaticDefaults() + { + TotalHeight = 4; + TotalWidth = 4; + CustomItemType = ModContent.ItemType(); + + Main.tileSolid[Type] = false; + Main.tileBlendAll[Type] = true; + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileWaterDeath[Type] = false; + Main.tileCut[Type] = false; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Origin = new Point16(2, 1); + TileObjectData.newTile.Height = TotalHeight; + TileObjectData.newTile.Width = TotalWidth; + TileObjectData.newTile.CoordinateHeights = new int[TotalHeight]; + for (int i = 0; i < TotalHeight; i++) + { + TileObjectData.newTile.CoordinateHeights[i] = 16; + } + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + TileObjectData.addTile(Type); + + DustType = ModContent.DustType(); + AddMapEntry(new Color(78, 162, 255)); + } + + public void AddScene(int i, int j) + { + Tile tile = Main.tile[i, j]; + if (tile.TileFrameX == 36 && tile.TileFrameY == 18) + { + var vfx = new WaterDeliveryHole_VFX + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = -MathHelper.PiOver4, + }; + Ins.VFXManager.Add(vfx); + var warp = new WaterDeliveryHole_VFX_warp + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = -MathHelper.PiOver4, + }; + Ins.VFXManager.Add(warp); + var foreground = new WaterDeliveryHole_Slope_foreground + { + Active = true, + Visible = true, + Position = new Point(i, j).ToWorldCoordinates(), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = -MathHelper.PiOver4, + }; + Ins.VFXManager.Add(foreground); + } + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + Tile tile = Main.tile[i, j]; + Texture2D tex = ModAsset.WaterDeliveryHole.Value; + Vector2 pos = new Vector2(i * 16, j * 16) - Main.screenPosition + zero; + spriteBatch.Draw(tex, pos, new Rectangle(tile.TileFrameX, tile.TileFrameY + 36, 16, 16), new Color(0f, 0f, 0.7f, 0)); + } + + public override void NearbyEffects(int i, int j, bool closer) + { + if (Main.dedServ) + { + base.NearbyEffects(i, j, closer); + return; + } + Lighting.AddLight(new Point(i, j).ToWorldCoordinates(), new Vector3(0.4f, 0.8f, 2f)); + WaterDeliveryHole_TeleportPlayer.GetDestinationAndTeleport(i, j); + base.NearbyEffects(i, j, closer); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopRight.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopRight.png new file mode 100644 index 000000000..db11f7c32 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopRight.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopRight_shape.bmp b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopRight_shape.bmp new file mode 100644 index 000000000..abc9fb67a Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_TopRight_shape.bmp differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_V.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_V.cs new file mode 100644 index 000000000..d9768b163 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_V.cs @@ -0,0 +1,116 @@ +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.WaterDeliveryHoles; + +public class WaterDeliveryHole_V : ModTile, ISceneTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + Main.tileBlendAll[Type] = true; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 5; + TileObjectData.newTile.Width = 2; + var SolidOrSolidSideAnchor1TilesLong = new AnchorData(AnchorType.SolidTile, 5, 0); + TileObjectData.newTile.AnchorBottom = AnchorData.Empty; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 16, + 16, + 16, + 16, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + + TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile); + TileObjectData.newTile.Origin = new Point16(0, 2); + TileObjectData.newAlternate.AnchorLeft = SolidOrSolidSideAnchor1TilesLong; + TileObjectData.newAlternate.Style = 1; + TileObjectData.addAlternate(1); + + TileObjectData.newTile.Origin = new Point16(1, 2); + TileObjectData.newTile.AnchorRight = SolidOrSolidSideAnchor1TilesLong; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(78, 162, 255)); + } + + public void AddScene(int i, int j) + { + Tile tile = Main.tile[i, j]; + if (tile.TileFrameY == 36 && (tile.TileFrameX == 18 || tile.TileFrameX == 36)) + { + int dir = -1; + if (tile.TileFrameX == 36) + { + dir = 1; + } + var vfx = new WaterDeliveryHole_VFX + { + Active = true, + Visible = true, + Position = new Vector2(i, j).ToWorldCoordinates(8, 8), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = (dir - 1) * MathHelper.PiOver2, + }; + Ins.VFXManager.Add(vfx); + var warp = new WaterDeliveryHole_VFX_warp + { + Active = true, + Visible = true, + Position = new Vector2(i, j).ToWorldCoordinates(8, 8), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = (dir - 1) * MathHelper.PiOver2, + }; + Ins.VFXManager.Add(warp); + var foreground = new WaterDeliveryHole_foreground + { + Active = true, + Visible = true, + Position = new Vector2(i, j).ToWorldCoordinates(8, 8), + OriginTilePos = new Point(i, j), + OriginTileType = Type, + Direction = 1, + Rotation = (dir - 1) * MathHelper.PiOver2, + }; + Ins.VFXManager.Add(foreground); + } + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + Tile tile = Main.tile[i, j]; + Texture2D tex = ModAsset.WaterDeliveryHole.Value; + Vector2 pos = new Vector2(i * 16, j * 16) - Main.screenPosition + zero; + spriteBatch.Draw(tex, pos, new Rectangle(tile.TileFrameX, tile.TileFrameY + 90, 16, 16), new Color(0f, 0f, 0.7f, 0)); + } + + public override void NearbyEffects(int i, int j, bool closer) + { + if (Main.dedServ) + { + base.NearbyEffects(i, j, closer); + return; + } + Lighting.AddLight(new Point(i, j).ToWorldCoordinates(), new Vector3(0.4f, 0.8f, 2f)); + WaterDeliveryHole_TeleportPlayer.GetDestinationAndTeleport(i, j); + base.NearbyEffects(i, j, closer); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_V.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_V.png new file mode 100644 index 000000000..046b8147c Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_V.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_VFX.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_VFX.cs new file mode 100644 index 000000000..ceb08d0f5 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_VFX.cs @@ -0,0 +1,56 @@ +using Everglow.Commons.VFX.Scene; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.WaterDeliveryHoles; + +[Pipeline(typeof(WCSPipeline_PointWrap))] +public class WaterDeliveryHole_VFX : TileVFX +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawTiles; + + public float Rotation; + + public override void Update() + { + base.Update(); + } + + public override void Draw() + { + float timeValue = (float)(Main.time * 0.01f); + var bars_side_left = new List(); + var bars_side_right = new List(); + var bars_side_left_dark = new List(); + var bars_side_right_dark = new List(); + for (int k = -2; k < 30; k++) + { + var pos = new Vector2(k * 3, 0).RotatedBy(Rotation); + float value = k / 30f; + float fade = 1f; + if (k > 20) + { + fade *= (30 - k) / 10f; + } + Color drawColor = Color.Lerp(new Color(0.4f, 0.7f, 1f, 0f), new Color(0f, 0.2f, 1f, 0f), value) * fade * 0.5f; + var drawColor_dark = new Color(0, 0, 0, fade * 0.6f) * 0.5f; + float coordX = MathF.Pow(value, 2); + + bars_side_left.Add(Position + pos + new Vector2(0, -20 - k).RotatedBy(Rotation), drawColor * 0f, new Vector3(coordX + timeValue, 0, 0)); + bars_side_left.Add(Position + pos + new Vector2(0, 0), drawColor, new Vector3(coordX + timeValue, 0.5f, 0)); + + bars_side_right.Add(Position + pos + new Vector2(0, 20 + k).RotatedBy(Rotation), drawColor * 0f, new Vector3(coordX + timeValue, 1, 0)); + bars_side_right.Add(Position + pos + new Vector2(0, 0), drawColor, new Vector3(coordX + timeValue, 0.5f, 0)); + + bars_side_left_dark.Add(Position + pos + new Vector2(0, -20 - k).RotatedBy(Rotation), drawColor_dark * 0f, new Vector3(coordX + timeValue, 0, 0)); + bars_side_left_dark.Add(Position + pos + new Vector2(0, 0), drawColor_dark, new Vector3(coordX + timeValue, 0.5f, 0)); + + bars_side_right_dark.Add(Position + pos + new Vector2(0, 20 + k).RotatedBy(Rotation), drawColor_dark * 0, new Vector3(coordX + timeValue, 1, 0)); + bars_side_right_dark.Add(Position + pos + new Vector2(0, 0), drawColor_dark, new Vector3(coordX + timeValue, 0.5f, 0)); + } + + Ins.Batch.Draw(Commons.ModAsset.Noise_flame_3_black.Value, bars_side_left_dark, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Commons.ModAsset.Noise_flame_3_black.Value, bars_side_right_dark, PrimitiveType.TriangleStrip); + + Ins.Batch.Draw(Commons.ModAsset.Noise_flame_3.Value, bars_side_left, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Commons.ModAsset.Noise_flame_3.Value, bars_side_right, PrimitiveType.TriangleStrip); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_VFX_Release.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_VFX_Release.cs new file mode 100644 index 000000000..4b33e6d32 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_VFX_Release.cs @@ -0,0 +1,111 @@ +using Everglow.Commons.VFX.Scene; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.WaterDeliveryHoles; + +[Pipeline(typeof(WCSPipeline_PointWrap))] +public class WaterDeliveryHole_VFX_Release : TileVFX +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawTiles; + + public float Rotation; + + public float Timer; + + public float MaxTime; + + public override void Update() + { + base.Update(); + Timer++; + if (Timer > MaxTime) + { + Active = false; + return; + } + float fadeTime = 1f; + if (Timer < 10f) + { + fadeTime *= Timer / 10f; + } + float timeLeft = MaxTime - Timer; + if (timeLeft < 30) + { + fadeTime *= timeLeft / 30f; + } + Lighting.AddLight(Position, new Vector3(0.4f, 0.7f, 1.1f) * fadeTime * 4); + } + + public override void Draw() + { + float fadeTime = 1f; + if (Timer < 10f) + { + fadeTime *= Timer / 10f; + } + float timeLeft = MaxTime - Timer; + if (timeLeft < 30) + { + fadeTime *= timeLeft / 30f; + } + float timeValue = (float)(Main.time * 0.01f); + var bars_side_left = new List(); + var bars_side_right = new List(); + var bars_side_left_dark = new List(); + var bars_side_right_dark = new List(); + + var bars_strongBloom_left = new List(); + var bars_strongBloom_right = new List(); + Color strongBloomColor = Color.Transparent; + for (int k = -2; k < 30; k++) + { + var pos = new Vector2(k * 5, 0).RotatedBy(Rotation); + var pos2 = new Vector2(k * 2, 0).RotatedBy(Rotation); + float value = k / 30f; + float fade = 1f; + if (k > 20) + { + fade *= (30 - k) / 10f; + } + Color drawColor = Color.Lerp(new Color(0.5f, 1f, 1f, 0f), new Color(0.4f, 0.7f, 1f, 0f), value); + drawColor = Color.Lerp(drawColor, new Color(0f, 0f, 0.6f, 0), value) * fade * fadeTime; + var drawColor_dark = new Color(0, 0, 0, fade * 0.6f) * fade * fadeTime; + float coordX = 1 - MathF.Pow(value, 2); + + bars_side_left.Add(Position + pos + new Vector2(0, -30 - k).RotatedBy(Rotation), drawColor * 0f, new Vector3(coordX + timeValue, 0, 0)); + bars_side_left.Add(Position + pos + new Vector2(0, 0), drawColor, new Vector3(coordX + timeValue, 0.5f, 0)); + + bars_side_right.Add(Position + pos + new Vector2(0, 30 + k).RotatedBy(Rotation), drawColor * 0f, new Vector3(coordX + timeValue, 1, 0)); + bars_side_right.Add(Position + pos + new Vector2(0, 0), drawColor, new Vector3(coordX + timeValue, 0.5f, 0)); + + + if (k < Timer) + { + strongBloomColor = drawColor * 2 * fadeTime; + } + else + { + strongBloomColor *= 0.5f; + } + bars_strongBloom_left.Add(Position + pos2 + new Vector2(0, -25 - k).RotatedBy(Rotation), strongBloomColor * 0f, new Vector3(coordX + timeValue, 0, 0)); + bars_strongBloom_left.Add(Position + pos2 + new Vector2(0, 0), strongBloomColor, new Vector3(coordX + timeValue, 0.5f, 0)); + + bars_strongBloom_right.Add(Position + pos2 + new Vector2(0, 25 + k).RotatedBy(Rotation), strongBloomColor * 0f, new Vector3(coordX + timeValue, 1, 0)); + bars_strongBloom_right.Add(Position + pos2 + new Vector2(0, 0), strongBloomColor, new Vector3(coordX + timeValue, 0.5f, 0)); + + bars_side_left_dark.Add(Position + pos + new Vector2(0, -30 - k).RotatedBy(Rotation), drawColor_dark * 0f, new Vector3(coordX + timeValue, 0, 0)); + bars_side_left_dark.Add(Position + pos + new Vector2(0, 0), drawColor_dark, new Vector3(coordX + timeValue, 0.5f, 0)); + + bars_side_right_dark.Add(Position + pos + new Vector2(0, 30 + k).RotatedBy(Rotation), drawColor_dark * 0, new Vector3(coordX + timeValue, 1, 0)); + bars_side_right_dark.Add(Position + pos + new Vector2(0, 0), drawColor_dark, new Vector3(coordX + timeValue, 0.5f, 0)); + } + + Ins.Batch.Draw(Commons.ModAsset.Noise_flame_3_black.Value, bars_side_left_dark, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Commons.ModAsset.Noise_flame_3_black.Value, bars_side_right_dark, PrimitiveType.TriangleStrip); + + Ins.Batch.Draw(Commons.ModAsset.Noise_flame_3.Value, bars_side_left, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Commons.ModAsset.Noise_flame_3.Value, bars_side_right, PrimitiveType.TriangleStrip); + + Ins.Batch.Draw(Commons.ModAsset.Noise_melting.Value, bars_strongBloom_left, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Commons.ModAsset.Noise_melting.Value, bars_strongBloom_right, PrimitiveType.TriangleStrip); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_foreground.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_foreground.cs new file mode 100644 index 000000000..4f08b8b44 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_foreground.cs @@ -0,0 +1,24 @@ +using Everglow.Commons.VFX.Scene; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.WaterDeliveryHoles; + +[Pipeline(typeof(WCSPipeline))] +public class WaterDeliveryHole_foreground : TileVFX +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; + + public float Rotation; + + public override void Update() + { + base.Update(); + } + + public override void Draw() + { + Texture2D tex = ModAsset.WaterDeliveryHole_foreground.Value; + Vector2 offset = new Vector2(-12, 0).RotatedBy(Rotation); + SpriteEffects effects = SpriteEffects.None; + Ins.Batch.Draw(tex, Position + offset, null, Lighting.GetColor(Position.ToTileCoordinates()), Rotation + MathHelper.PiOver2, new Vector2(40, 28), 1f, effects); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_foreground.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_foreground.png new file mode 100644 index 000000000..954c9fc6c Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/WaterDeliveryHoles/WaterDeliveryHole_foreground.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/YggdrasilBlackRock_NoctilucentFluoriteLump_Platform.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/YggdrasilBlackRock_NoctilucentFluoriteLump_Platform.cs new file mode 100644 index 000000000..530e346b3 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/YggdrasilBlackRock_NoctilucentFluoriteLump_Platform.cs @@ -0,0 +1,68 @@ +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; + +public class YggdrasilBlackRock_NoctilucentFluoriteLump_Platform : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileLighted[Type] = true; + Main.tileFrameImportant[Type] = true; + Main.tileSolidTop[Type] = true; + Main.tileSolid[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileTable[Type] = true; + Main.tileLavaDeath[Type] = true; + TileID.Sets.Platforms[Type] = true; + TileID.Sets.DisableSmartCursor[Type] = true; + + AddToArray(ref TileID.Sets.RoomNeeds.CountsAsDoor); + AddMapEntry(new Color(0, 14, 175)); + + DustType = ModContent.DustType(); + AdjTiles = new int[] { TileID.Platforms }; + + // Placement + TileObjectData.newTile.CoordinateHeights = new[] { 16 }; + TileObjectData.newTile.CoordinateWidth = 16; + TileObjectData.newTile.CoordinatePadding = 2; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.StyleMultiplier = 27; + TileObjectData.newTile.StyleWrapLimit = 27; + TileObjectData.newTile.UsesCustomCanPlace = false; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.addTile(Type); + + AddMapEntry(new Color(191, 142, 111)); + } + + public override void PostSetDefaults() => Main.tileNoSunLight[Type] = false; + + public override void NumDust(int i, int j, bool fail, ref int num) => num = fail ? 1 : 3; + + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + r = 0.2f; + g = 0.8f; + b = 0.8f; + base.ModifyLight(i, j, ref r, ref g, ref b); + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + var tile = Main.tile[i, j]; + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + + Texture2D tex = ModAsset.YggdrasilBlackRock_NoctilucentFluoriteLump_Platform_glow.Value; + + spriteBatch.Draw(tex, new Vector2(i * 16, j * 16) - Main.screenPosition + zero, new Rectangle(tile.TileFrameX, tile.TileFrameY, 16, 16), new Color(1f, 1f, 1f, 0), 0, new Vector2(0), 1, SpriteEffects.None, 0); + + base.PostDraw(i, j, spriteBatch); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/YggdrasilBlackRock_NoctilucentFluoriteLump_Platform.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/YggdrasilBlackRock_NoctilucentFluoriteLump_Platform.png new file mode 100644 index 000000000..09818dcc5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/YggdrasilBlackRock_NoctilucentFluoriteLump_Platform.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/YggdrasilBlackRock_NoctilucentFluoriteLump_Platform_glow.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/YggdrasilBlackRock_NoctilucentFluoriteLump_Platform_glow.png new file mode 100644 index 000000000..7b6d54707 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/DeathJadeLake/YggdrasilBlackRock_NoctilucentFluoriteLump_Platform_glow.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thick.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thick.cs new file mode 100644 index 000000000..6d8524eda --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thick.cs @@ -0,0 +1,408 @@ +using Everglow.Commons.Physics.MassSpringSystem; +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Items.Tools; +using Spine; +using Terraria.GameContent.Drawing; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.ForestRainVines; + +public class ForestRainVineTile_Thick : HangingTile +{ + public override void InitHanging() + { + MaxWireStyle = 1; + CanGrasp = true; + + RopeUnitMass = 3f; + HangingItemMass = 250f; + Elasticity = 200f; + UnitLength = 16f; + } + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + if (j >= 20) + { + Tile tileUp = Main.tile[i, j - 1]; + if (tileUp.Slope != SlopeType.Solid) + { + tileUp.Slope = SlopeType.Solid; + } + } + return base.TileFrame(i, j, ref resetFrame, ref noBreak); + } + + public override void DrawCable(Rope rope, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing, Color color = default) + { + if (!TileDrawing.IsVisible(Main.tile[pos])) + { + return; + } + + var tile = Main.tile[pos]; + ushort type = tile.TileType; + int paint = Main.tile[pos].TileColor; + string originalPath = @Texture; + string[] pathSegments = originalPath.Split("/"); + string trimmedTexturePath = Path.Combine(pathSegments.Skip(1).ToArray()); + Texture2D tex = PaintedTextureSystem.TryGetPaintedTexture(trimmedTexturePath, type, 1, paint, tileDrawing); + tex ??= (Texture2D)ModContent.Request(Texture); + + var masses = rope.Masses; + for (int i = 0; i < masses.Length; i++) + { + Mass thisMass = masses[i]; + int totalPushTime = 80; + float pushForcePerFrame = 1.26f; + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f), 1, 1)) + { + windCycle = tileDrawing.GetWindCycle((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f), tileDrawing._sunflowerWindCounter); + } + + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f), 1, 1, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + windCycle += highestWindGridPushComplex; + if (!Main.gamePaused) + { + if (i < masses.Length - 1) + { + rope.ApplyForceSpecial(i, new Vector2(windCycle / 4.0f, 0.4f * thisMass.Value)); + } + else + { + rope.ApplyForceSpecial(i, new Vector2(windCycle * 10.0f, 0.4f * thisMass.Value)); + } + } + + // 支æŒå‘光涂料 + Color tileLight; + if (color != default) + { + tileLight = color; + } + else + { + tileLight = Lighting.GetColor((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f)); + } + + Vector2 toNextMass; + if (i < masses.Length - 1) + { + Mass nextMass = masses[i + 1]; + toNextMass = nextMass.Position - thisMass.Position; + } + else + { + Mass passedMass = masses[i - 1]; + toNextMass = thisMass.Position - passedMass.Position; + } + Vector2 drawPos = thisMass.Position - Main.screenPosition; + DrawRopeUnit(spriteBatch, tex, drawPos, pos, rope, i, toNextMass.ToRotation() - MathHelper.PiOver2, tileLight); + if (HangingTileUpdateSystem.WinchAdjustingPlayerTimers.Keys.Contains(pos)) + { + float value = HangingTileUpdateSystem.WinchAdjustingPlayerTimers[pos] / AdjustingVisualTimeMax; + Color drawColor = Color.Lerp(Color.White, new Color(0.2f, 0.7f, 0.4f, 0), 1 - value) * value; + DrawRopeUnit(spriteBatch, ModAsset.ForestRainVineTile_Thick_Shape.Value, drawPos, pos, rope, i, toNextMass.ToRotation() - MathHelper.PiOver2, drawColor); + } + } + } + + public override void DrawWinch(int i, int j, SpriteBatch spriteBatch) + { + Color lightColor = Lighting.GetColor(i, j); + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + Texture2D tex = (Texture2D)ModContent.Request(Texture); + Rectangle frame = new Rectangle(0, 0, 50, 24); + spriteBatch.Draw(tex, new Vector2(i, j).ToWorldCoordinates() - Main.screenPosition + zero + new Vector2(0, -12), frame, lightColor, 0, new Vector2(frame.Width * 0.5f, 0), 1, SpriteEffects.None, 0); + if (HangingTileUpdateSystem.WinchAdjustingPlayerTimers.Keys.Contains(new Point(i, j))) + { + tex = ModAsset.ForestRainVineTile_Thick_Shape.Value; + float value = HangingTileUpdateSystem.WinchAdjustingPlayerTimers[new Point(i, j)] / AdjustingVisualTimeMax; + Color drawColor = Color.Lerp(Color.White, new Color(0.2f, 0.7f, 0.4f, 0), 1 - value) * value; + spriteBatch.Draw(tex, new Vector2(i, j).ToWorldCoordinates() - Main.screenPosition + zero + new Vector2(0, -12), frame, drawColor, 0, new Vector2(frame.Width * 0.5f, 0), 1, SpriteEffects.None, 0); + } + } + + public override void DrawRopeUnit(SpriteBatch spriteBatch, Texture2D texture, Vector2 drawPos, Point tilePos, Rope rope, int index, float rotation, Color tileLight) + { + var masses = rope.Masses; + Rectangle frame; + Vector2 offset = new Vector2(0, 0); + drawPos += offset; + if (index <= masses.Length - 6) + { + if (!masses[Math.Min(index + 1, masses.Length - 1)].IsStatic) + { + frame = new Rectangle(0, 16 + TileUtils.GetFixedRandomNumber(index + 60, tilePos.X, 4) * 20, 50, 20); + spriteBatch.Draw(texture, drawPos, frame, tileLight, rotation, frame.Size() * 0.5f, 1f, SpriteEffects.None, 0); + } + } + else + { + int contraryIndex = masses.Length - index; + frame = new Rectangle(0, 100 + (6 - contraryIndex) * 20, 50, 20); + spriteBatch.Draw(texture, drawPos, frame, tileLight, rotation, frame.Size() * 0.5f, 1f, SpriteEffects.None, 0); + } + } + + public override void OnAdjustmentStart(Point fixPoint, Player player) + { + // æ£€æŸ¥æ˜¯å¦æ‰‹æŒè—¤æ›¼ä¿®ç†é­”æ– + if (player.HeldItem?.type == ModContent.ItemType()) + { + // 直接调用法æ–的开始调整方法 + (player.HeldItem.ModItem as VineRepairWand)?.StartAdjustment(player, fixPoint); + } + } + + public override void OnAdjustmentUpdate(Point fixPoint, Player player, int deltaLength) + { + // æ£€æŸ¥æ˜¯å¦æ‰‹æŒè—¤æ›¼ä¿®ç†é­”æ– + if (player.HeldItem?.type == ModContent.ItemType()) + { + // 直接调用法æ–的更新调整方法 + (player.HeldItem.ModItem as VineRepairWand)?.UpdateAdjustment(player, fixPoint, deltaLength); + } + else + { + // å¦‚æžœæ²¡æœ‰æ‰‹æŒæ³•æ–,结æŸè°ƒæ•´ + OnAdjustmentEnd(fixPoint, player); + } + base.OnAdjustmentUpdate(fixPoint, player, deltaLength); + } + + public override void OnAdjustmentEnd(Point fixPoint, Player player) + { + // 直接调用法æ–的结æŸè°ƒæ•´æ–¹æ³• + if (player.HeldItem?.type == ModContent.ItemType()) + { + (player.HeldItem.ModItem as VineRepairWand)?.EndAdjustment(); + } + else + { + // å³ä½¿æ²¡æœ‰æ‰‹æŒæ³•æ–,也å°è¯•结æŸè°ƒæ•´ + var wand = ModContent.GetInstance(); + wand.EndAdjustment(); + } + } + + /// + /// 当手æŒè—¤æ›¼ä¿®ç†é­”æ–æ—¶å…许调整长度 + /// + /// + /// + /// + public override bool IsCanRightClick(int i, int j) + { + Player player = Main.LocalPlayer; + return player.HeldItem != null && player.HeldItem.type == ModContent.ItemType(); + } + + #region 按钮é‡ç»˜ + public override void DrawDefaultPanel(HangingTileAdjustingHelper hangingSystem, Player player, Color color, ref Queue drawStacks) + { + drawStacks = new Queue(); + + // 背景改为淡绿色åŠé€æ˜Žï¼ˆä¿æŒçˆ¶ç±»é¢æ¿ç»“构) + // DrawBackgroundPanel(hangingSystem, new Color(0.8f, 1f, 0.8f, 0.5f), ref drawStacks); + float maxCos = 0; + int maxK = 0; + Vector2 rotCenter = hangingSystem.FixPoint.ToWorldCoordinates(); + + // 完全ä¿ç•™çˆ¶ç±»çš„æ—‹è½¬è®¡ç®—é€»è¾‘ï¼Œä¸æ·»åŠ æ‘†åŠ¨åç§» + Vector2 cut = new Vector2(1, 0).RotatedBy(hangingSystem.HandleRotation + MathHelper.Pi); + + // ä¿ç•™çˆ¶ç±»çš„æ ¡å‡†å°¾è¿¹è®¡ç®—逻辑 + for (int k = -10; k < 10; k++) + { + Vector2 cut2 = new Vector2(0, -1).RotatedBy(k / 20f * MathHelper.TwoPi); + float cosValue = Vector2.Dot(cut, cut2); + if (cosValue > maxCos) + { + maxCos = cosValue; + maxK = k; + } + } + + // 绘制校准尾迹(仅替æ¢ä¸ºç»¿è‰²ä¸»é¢˜ï¼‰ + // 基础色改为绿色系,ä¿ç•™åŽŸæœ‰é€æ˜Žåº¦é€»è¾‘ + Color baseGreen = new Color(0.3f, 0.8f, 0.4f); // 主绿色 + Color newDrawColor = Color.Lerp(baseGreen, color, 0.2f); // 轻微èžåˆåŽŸè‰²è°ƒ + Color outerRingColor = Color.Lerp(newDrawColor, new Color(0.3f, 0.24f, 0.16f), 0.6f); + + float nowFrameY = hangingSystem.StartFrameY60 / 60f + hangingSystem.HandleRotation * 2; + + // 警告色改为绿红色æ¸å˜ï¼ˆä¿æŒåŽŸæœ‰è­¦å‘Šé€»è¾‘ï¼‰ + if (nowFrameY < 5) + { + newDrawColor = Color.Lerp(newDrawColor, new Color(0.9f, 0.3f, 0.3f, 0.8f), (5 - nowFrameY) / 4f); + outerRingColor = Color.Lerp(outerRingColor, new Color(0.9f, 0.2f, 0.2f, 0.8f), (5 - nowFrameY) / 4f); + } + if (nowFrameY > MaxCableLength - 5) + { + newDrawColor = Color.Lerp(newDrawColor, new Color(0.9f, 0.3f, 0.3f, 0.8f), (nowFrameY - (MaxCableLength - 5)) / 4f); + outerRingColor = Color.Lerp(outerRingColor, new Color(0.9f, 0.2f, 0.2f, 0.8f), (nowFrameY - (MaxCableLength - 5)) / 4f); + } + + // 完全ä¿ç•™çˆ¶ç±»çš„逿˜Žåº¦è®¡ç®—逻辑 + float tK = 12f; + if (hangingSystem.TimeToKill > 0) + { + tK = hangingSystem.TimeToKill; + } + float fade = Math.Min(hangingSystem.Timer, tK) / 12f; + + // 边界颜色替æ¢ä¸ºæ·±ç»¿è‰²ï¼ˆä¿æŒçˆ¶ç±»ç»˜åˆ¶é€»è¾‘) + DrawBound(hangingSystem, new Color(0.2f, 0.6f, 0.3f), player, ref drawStacks); + + // æ–¹å‘çŽ¯ä¿æŒçˆ¶ç±»çš„稳定角度,仅替æ¢ä¸ºç»¿è‰² + DrawDirectionRing(hangingSystem, outerRingColor, + hangingSystem.HandleRotation - MathHelper.PiOver2, // 移除所有摆动å移,与父类一致 + ref drawStacks); + + // 绘制线æ¡ï¼ˆä¿æŒçˆ¶ç±»çš„长度ã€ç²—细和角度逻辑,仅改颜色) + for (int k = -10; k < 10; k++) + { + Vector2 cut2 = new Vector2(0, -1).RotatedBy(k / 20f * MathHelper.TwoPi); + float cosValue = Vector2.Dot(cut, cut2); + + if (k == maxK) + { + // ä¿ç•™é»‘色轮廓,确ä¿ä¸Žçˆ¶ç±»é£Žæ ¼ä¸€è‡´ + DrawLine_Black( + hangingSystem, + rotCenter + cut2 * (4 * hangingSystem.PanelRange - 12), + rotCenter + cut2 * (4 * hangingSystem.PanelRange + 64), + 16, ref drawStacks); + + // ä¸»çº¿æ¡æ›¿æ¢ä¸ºç»¿è‰² + DrawLine( + rotCenter + cut2 * (4 * hangingSystem.PanelRange - 12), + rotCenter + cut2 * (4 * hangingSystem.PanelRange + 64), + 16, newDrawColor * fade, 1f, ref drawStacks); + } + else + { + // å‰¯çº¿æ¡æ›¿æ¢ä¸ºç»¿è‰² + DrawLine( + rotCenter + cut2 * 4 * hangingSystem.PanelRange, + rotCenter + cut2 * (4 * hangingSystem.PanelRange + 48), + 12, newDrawColor * fade, cosValue, ref drawStacks); + } + } + + // Draw the weapon which player holding. + Texture2D tex = ModAsset.VineRepairWand.Value; + Texture2D tex_glow = ModAsset.VineRepairWand_glow.Value; + Texture2D tex_bloom = ModAsset.VineRepairWand_bloom.Value; + Texture2D star = Commons.ModAsset.StarSlash.Value; + Vector2 toCenter = rotCenter - player.Center; + float rot = toCenter.ToRotationSafe() + MathHelper.PiOver4; + if (toCenter.X > 1) + { + player.direction = 1; + } + if (toCenter.X < -1) + { + player.direction = -1; + } + + Ins.Batch.Draw(tex, player.Center, null, Lighting.GetColor(player.Center.ToTileCoordinates()), rot, new Vector2(0, 34), 1f, SpriteEffects.None); + Ins.Batch.Draw(tex_glow, player.Center, null, Color.White, rot, new Vector2(0, 34), 1f, SpriteEffects.None); + Ins.Batch.Draw(tex_bloom, player.Center, null, new Color(1f, 1f, 1f, 0), rot, new Vector2(0, 80), 1f, SpriteEffects.None); + Ins.Batch.Draw(star, player.Center + new Vector2(28, -28).RotatedBy(rot), null, new Color(0.02f, 0.08f, 0.04f, 0f), MathHelper.PiOver2, star.Size() * 0.5f, 1f, SpriteEffects.None); + } + + public override void DrawLine(Vector2 pos1, Vector2 pos2, float width, Color color, float highlight, ref Queue drawStacks) + { + if (drawStacks == null) + { + drawStacks = new Queue(); + } + Vector2 normal = Utils.SafeNormalize(pos1 - pos2, Vector2.zeroVector).RotatedBy(MathHelper.PiOver2) * width / 2f; + List bars = new List() + { + new Vertex2D(pos1 + normal, color, new Vector3(0, 0, 0)), + new Vertex2D(pos2 + normal, color, new Vector3(1, 0, 0)), + new Vertex2D(pos1 - normal, color, new Vector3(0, 1, 0)), + + new Vertex2D(pos1 - normal, color, new Vector3(0, 1, 0)), + new Vertex2D(pos2 + normal, color, new Vector3(1, 0, 0)), + new Vertex2D(pos2 - normal, color, new Vector3(1, 1, 0)), + }; + drawStacks.Enqueue(new DrawStack(ModAsset.ForestRainVine_Cut.Value, bars, PrimitiveType.TriangleList)); + if (highlight > 0) + { + Color bloomColor = color * highlight; + bloomColor.A = 0; + bars = new List() + { + new Vertex2D(pos1 + normal, bloomColor, new Vector3(0, 0, 0)), + new Vertex2D(pos2 + normal, bloomColor, new Vector3(1, 0, 0)), + new Vertex2D(pos1 - normal, bloomColor, new Vector3(0, 1, 0)), + + new Vertex2D(pos1 - normal, bloomColor, new Vector3(0, 1, 0)), + new Vertex2D(pos2 + normal, bloomColor, new Vector3(1, 0, 0)), + new Vertex2D(pos2 - normal, bloomColor, new Vector3(1, 1, 0)), + }; + drawStacks.Enqueue(new DrawStack(ModAsset.ForestRainVine_Cut_Bloom.Value, bars, PrimitiveType.TriangleList)); + } + } + + public override void DrawLine_Black(HangingTileAdjustingHelper hangingSystem, Vector2 pos1, Vector2 pos2, float width, ref Queue drawStacks) + { + if (drawStacks == null) + { + drawStacks = new Queue(); + } + Vector2 normal = Utils.SafeNormalize(pos1 - pos2, Vector2.zeroVector).RotatedBy(MathHelper.PiOver2) * width / 2f; + Color bloomColor = Color.White; + float tK = 12f; + if (hangingSystem.TimeToKill > 0) + { + tK = hangingSystem.TimeToKill; + } + float fade = Math.Min(hangingSystem.Timer, tK) / 12f; + bloomColor *= fade; + List bars = new List() + { + new Vertex2D(pos1 + normal, bloomColor, new Vector3(0, 0, 0)), + new Vertex2D(pos2 + normal, bloomColor, new Vector3(1, 0, 0)), + new Vertex2D(pos1 - normal, bloomColor, new Vector3(0, 1, 0)), + + new Vertex2D(pos1 - normal, bloomColor, new Vector3(0, 1, 0)), + new Vertex2D(pos2 + normal, bloomColor, new Vector3(1, 0, 0)), + new Vertex2D(pos2 - normal, bloomColor, new Vector3(1, 1, 0)), + }; + drawStacks.Enqueue(new DrawStack(ModAsset.ForestRainVine_Cut_Bloom_black.Value, bars, PrimitiveType.TriangleList)); + } + + public override void DrawDirectionRing(HangingTileAdjustingHelper hangingSystem, Color color, float rotation, ref Queue drawStacks) + { + if (drawStacks == null) + { + drawStacks = new Queue(); + } + color.A = 0; + Vector2 pos = hangingSystem.FixPoint.ToWorldCoordinates(); + List bars = new List(); + for (int k = 0; k <= 60; k++) + { + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 64).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), Color.White, new Vector3(k / 20f, 0, 0)); + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 0).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), Color.White, new Vector3(k / 20f, 1, 0)); + } + drawStacks.Enqueue(new DrawStack(ModAsset.ForestRainVine_Matrix_black.Value, bars, PrimitiveType.TriangleStrip)); + bars = new List(); + for (int k = 0; k <= 60; k++) + { + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 64).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), color, new Vector3(k / 20f, 0, 0)); + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 0).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), color, new Vector3(k / 20f, 1, 0)); + } + drawStacks.Enqueue(new DrawStack(ModAsset.ForestRainVine_Matrix.Value, bars, PrimitiveType.TriangleStrip)); + } + #endregion +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thick.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thick.png new file mode 100644 index 000000000..1055ae63d Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thick.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thick_Bloom.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thick_Bloom.png new file mode 100644 index 000000000..c40233672 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thick_Bloom.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thick_Shape.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thick_Shape.png new file mode 100644 index 000000000..1ecd0ec4a Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thick_Shape.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thin.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thin.cs new file mode 100644 index 000000000..578b912f1 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thin.cs @@ -0,0 +1,403 @@ +using Everglow.Commons.Physics.MassSpringSystem; +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Items.Tools; +using Terraria.GameContent.Drawing; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.ForestRainVines; + +public class ForestRainVineTile_Thin : HangingTile +{ + public override void InitHanging() + { + MaxWireStyle = 1; + CanGrasp = true; + + RopeUnitMass = 3f; + HangingItemMass = 250f; + Elasticity = 200f; + UnitLength = 6f; + MaxCableLength = 120; + } + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + if (j >= 20) + { + Tile tileUp = Main.tile[i, j - 1]; + if (tileUp.Slope != SlopeType.Solid) + { + tileUp.Slope = SlopeType.Solid; + } + } + return base.TileFrame(i, j, ref resetFrame, ref noBreak); + } + + public override void DrawCable(Rope rope, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing, Color color = default) + { + if (!TileDrawing.IsVisible(Main.tile[pos])) + { + return; + } + + var tile = Main.tile[pos]; + ushort type = tile.TileType; + int paint = Main.tile[pos].TileColor; + string originalPath = @Texture; + string[] pathSegments = originalPath.Split("/"); + string trimmedTexturePath = Path.Combine(pathSegments.Skip(1).ToArray()); + Texture2D tex = PaintedTextureSystem.TryGetPaintedTexture(trimmedTexturePath, type, 1, paint, tileDrawing); + tex ??= (Texture2D)ModContent.Request(Texture); + + var masses = rope.Masses; + for (int i = 0; i < masses.Length; i++) + { + Mass thisMass = masses[i]; + int totalPushTime = 80; + float pushForcePerFrame = 1.26f; + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f), 1, 1)) + { + windCycle = tileDrawing.GetWindCycle((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f), tileDrawing._sunflowerWindCounter); + } + + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f), 1, 1, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + windCycle += highestWindGridPushComplex; + if (!Main.gamePaused) + { + if (i < masses.Length - 1) + { + rope.ApplyForceSpecial(i, new Vector2(windCycle / 4.0f, 0.4f * thisMass.Value)); + } + else + { + rope.ApplyForceSpecial(i, new Vector2(windCycle * 10.0f, 0.4f * thisMass.Value)); + } + } + + // 支æŒå‘光涂料 + Color tileLight; + if (color != default) + { + tileLight = color; + } + else + { + tileLight = Lighting.GetColor((int)((thisMass.Position.X - 8) / 16f), (int)((thisMass.Position.Y - 8) / 16f)); + } + + Vector2 toNextMass; + if (i < masses.Length - 1) + { + Mass nextMass = masses[i + 1]; + toNextMass = nextMass.Position - thisMass.Position; + } + else + { + Mass passedMass = masses[i - 1]; + toNextMass = thisMass.Position - passedMass.Position; + } + Vector2 drawPos = thisMass.Position - Main.screenPosition; + DrawRopeUnit(spriteBatch, tex, drawPos, pos, rope, i, toNextMass.ToRotation() - MathHelper.PiOver2, tileLight); + if (HangingTileUpdateSystem.WinchAdjustingPlayerTimers.Keys.Contains(pos)) + { + float value = HangingTileUpdateSystem.WinchAdjustingPlayerTimers[pos] / AdjustingVisualTimeMax; + Color drawColor = Color.Lerp(Color.White, new Color(0.2f, 0.7f, 0.4f, 0), 1 - value) * value; + DrawRopeUnit(spriteBatch, ModAsset.ForestRainVineTile_Thin_Shape.Value, drawPos, pos, rope, i, toNextMass.ToRotation() - MathHelper.PiOver2, drawColor); + } + } + } + + public override void DrawWinch(int i, int j, SpriteBatch spriteBatch) + { + Color lightColor = Lighting.GetColor(i, j); + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + Texture2D tex = (Texture2D)ModContent.Request(Texture); + Rectangle frame = new Rectangle(0, 0, 16, 16); + spriteBatch.Draw(tex, new Vector2(i, j) * 16 - Main.screenPosition + zero, frame, lightColor, 0, Vector2.zeroVector, 1, SpriteEffects.None, 0); + if (HangingTileUpdateSystem.WinchAdjustingPlayerTimers.Keys.Contains(new Point(i, j))) + { + tex = ModAsset.ForestRainVineTile_Thin_Shape.Value; + float value = HangingTileUpdateSystem.WinchAdjustingPlayerTimers[new Point(i, j)] / AdjustingVisualTimeMax; + Color drawColor = Color.Lerp(Color.White, new Color(0.2f, 0.7f, 0.4f, 0), 1 - value) * value; + spriteBatch.Draw(tex, new Vector2(i, j).ToWorldCoordinates() - Main.screenPosition + zero + new Vector2(0, -12), frame, drawColor, 0, new Vector2(frame.Width * 0.5f, 0), 1, SpriteEffects.None, 0); + } + } + + public override void DrawRopeUnit(SpriteBatch spriteBatch, Texture2D texture, Vector2 drawPos, Point tilePos, Rope rope, int index, float rotation, Color tileLight) + { + var masses = rope.Masses; + Rectangle frame; + Vector2 offset = new Vector2(0, 0); + drawPos += offset; + int randomByPos = tilePos.X; + if (index <= masses.Length - 10) + { + frame = new Rectangle(0, 8 + (index + randomByPos) % 18 * 8, 16, 8); + spriteBatch.Draw(texture, drawPos, frame, tileLight, rotation, frame.Size() * 0.5f, 1f, SpriteEffects.None, 0); + } + else + { + int contraryIndex = masses.Length - index; + frame = new Rectangle(0, 152 + (10 - contraryIndex) * 8, 16, 8); + spriteBatch.Draw(texture, drawPos, frame, tileLight, rotation, frame.Size() * 0.5f, 1f, SpriteEffects.None, 0); + } + } + + public override void OnAdjustmentStart(Point fixPoint, Player player) + { + // æ£€æŸ¥æ˜¯å¦æ‰‹æŒè—¤æ›¼ä¿®ç†é­”æ– + if (player.HeldItem?.type == ModContent.ItemType()) + { + // 直接调用法æ–的开始调整方法 + (player.HeldItem.ModItem as VineRepairWand)?.StartAdjustment(player, fixPoint); + } + } + + public override void OnAdjustmentUpdate(Point fixPoint, Player player, int deltaLength) + { + // æ£€æŸ¥æ˜¯å¦æ‰‹æŒè—¤æ›¼ä¿®ç†é­”æ– + if (player.HeldItem?.type == ModContent.ItemType()) + { + // 直接调用法æ–的更新调整方法 + (player.HeldItem.ModItem as VineRepairWand)?.UpdateAdjustment(player, fixPoint, deltaLength); + } + else + { + // å¦‚æžœæ²¡æœ‰æ‰‹æŒæ³•æ–,结æŸè°ƒæ•´ + OnAdjustmentEnd(fixPoint, player); + } + base.OnAdjustmentUpdate(fixPoint, player, deltaLength); + } + + public override void OnAdjustmentEnd(Point fixPoint, Player player) + { + // 直接调用法æ–的结æŸè°ƒæ•´æ–¹æ³• + if (player.HeldItem?.type == ModContent.ItemType()) + { + (player.HeldItem.ModItem as VineRepairWand)?.EndAdjustment(); + } + else + { + // å³ä½¿æ²¡æœ‰æ‰‹æŒæ³•æ–,也å°è¯•结æŸè°ƒæ•´ + var wand = ModContent.GetInstance(); + wand.EndAdjustment(); + } + } + + /// + /// 当手æŒè—¤æ›¼ä¿®ç†é­”æ–æ—¶å…许调整长度 + /// + /// + /// + /// + public override bool IsCanRightClick(int i, int j) + { + Player player = Main.LocalPlayer; + return player.HeldItem != null && player.HeldItem.type == ModContent.ItemType(); + } + + #region 按钮é‡ç»˜ + public override void DrawDefaultPanel(HangingTileAdjustingHelper hangingSystem, Player player, Color color, ref Queue drawStacks) + { + drawStacks = new Queue(); + + // 背景改为淡绿色åŠé€æ˜Žï¼ˆä¿æŒçˆ¶ç±»é¢æ¿ç»“构) + // DrawBackgroundPanel(hangingSystem, new Color(0.8f, 1f, 0.8f, 0.5f), ref drawStacks); + float maxCos = 0; + int maxK = 0; + Vector2 rotCenter = hangingSystem.FixPoint.ToWorldCoordinates(); + + // 完全ä¿ç•™çˆ¶ç±»çš„æ—‹è½¬è®¡ç®—é€»è¾‘ï¼Œä¸æ·»åŠ æ‘†åŠ¨åç§» + Vector2 cut = new Vector2(1, 0).RotatedBy(hangingSystem.HandleRotation + MathHelper.Pi); + + // ä¿ç•™çˆ¶ç±»çš„æ ¡å‡†å°¾è¿¹è®¡ç®—逻辑 + for (int k = -10; k < 10; k++) + { + Vector2 cut2 = new Vector2(0, -1).RotatedBy(k / 20f * MathHelper.TwoPi); + float cosValue = Vector2.Dot(cut, cut2); + if (cosValue > maxCos) + { + maxCos = cosValue; + maxK = k; + } + } + + // 绘制校准尾迹(仅替æ¢ä¸ºç»¿è‰²ä¸»é¢˜ï¼‰ + // 基础色改为绿色系,ä¿ç•™åŽŸæœ‰é€æ˜Žåº¦é€»è¾‘ + Color baseGreen = new Color(0.3f, 0.8f, 0.4f); // 主绿色 + Color newDrawColor = Color.Lerp(baseGreen, color, 0.2f); // 轻微èžåˆåŽŸè‰²è°ƒ + Color outerRingColor = Color.Lerp(newDrawColor, new Color(0.3f, 0.24f, 0.16f), 0.6f); + + float nowFrameY = hangingSystem.StartFrameY60 / 60f + hangingSystem.HandleRotation * 2; + + // 警告色改为绿红色æ¸å˜ï¼ˆä¿æŒåŽŸæœ‰è­¦å‘Šé€»è¾‘ï¼‰ + if (nowFrameY < 5) + { + newDrawColor = Color.Lerp(newDrawColor, new Color(0.9f, 0.3f, 0.3f, 0.8f), (5 - nowFrameY) / 4f); + outerRingColor = Color.Lerp(outerRingColor, new Color(0.9f, 0.2f, 0.2f, 0.8f), (5 - nowFrameY) / 4f); + } + if (nowFrameY > MaxCableLength - 5) + { + newDrawColor = Color.Lerp(newDrawColor, new Color(0.9f, 0.3f, 0.3f, 0.8f), (nowFrameY - (MaxCableLength - 5)) / 4f); + outerRingColor = Color.Lerp(outerRingColor, new Color(0.9f, 0.2f, 0.2f, 0.8f), (nowFrameY - (MaxCableLength - 5)) / 4f); + } + + // 完全ä¿ç•™çˆ¶ç±»çš„逿˜Žåº¦è®¡ç®—逻辑 + float tK = 12f; + if (hangingSystem.TimeToKill > 0) + { + tK = hangingSystem.TimeToKill; + } + float fade = Math.Min(hangingSystem.Timer, tK) / 12f; + + // 边界颜色替æ¢ä¸ºæ·±ç»¿è‰²ï¼ˆä¿æŒçˆ¶ç±»ç»˜åˆ¶é€»è¾‘) + DrawBound(hangingSystem, new Color(0.2f, 0.6f, 0.3f), player, ref drawStacks); + + // æ–¹å‘çŽ¯ä¿æŒçˆ¶ç±»çš„稳定角度,仅替æ¢ä¸ºç»¿è‰² + DrawDirectionRing(hangingSystem, outerRingColor, + hangingSystem.HandleRotation - MathHelper.PiOver2, // 移除所有摆动å移,与父类一致 + ref drawStacks); + + // 绘制线æ¡ï¼ˆä¿æŒçˆ¶ç±»çš„长度ã€ç²—细和角度逻辑,仅改颜色) + for (int k = -10; k < 10; k++) + { + Vector2 cut2 = new Vector2(0, -1).RotatedBy(k / 20f * MathHelper.TwoPi); + float cosValue = Vector2.Dot(cut, cut2); + + if (k == maxK) + { + // ä¿ç•™é»‘色轮廓,确ä¿ä¸Žçˆ¶ç±»é£Žæ ¼ä¸€è‡´ + DrawLine_Black( + hangingSystem, + rotCenter + cut2 * (4 * hangingSystem.PanelRange - 12), + rotCenter + cut2 * (4 * hangingSystem.PanelRange + 32), + 16, ref drawStacks); + + // ä¸»çº¿æ¡æ›¿æ¢ä¸ºç»¿è‰² + DrawLine( + rotCenter + cut2 * (4 * hangingSystem.PanelRange - 12), + rotCenter + cut2 * (4 * hangingSystem.PanelRange + 32), + 16, newDrawColor * fade, 1f, ref drawStacks); + } + else + { + // å‰¯çº¿æ¡æ›¿æ¢ä¸ºç»¿è‰² + DrawLine( + rotCenter + cut2 * 4 * hangingSystem.PanelRange, + rotCenter + cut2 * (4 * hangingSystem.PanelRange + 24), + 12, newDrawColor * fade, cosValue, ref drawStacks); + } + } + + // Draw the weapon which player holding. + Texture2D tex = ModAsset.VineRepairWand.Value; + Texture2D tex_glow = ModAsset.VineRepairWand_glow.Value; + Texture2D tex_bloom = ModAsset.VineRepairWand_bloom.Value; + Vector2 toCenter = rotCenter - player.Center; + float rot = toCenter.ToRotationSafe() + MathHelper.PiOver4; + if (toCenter.X > 1) + { + player.direction = 1; + } + if (toCenter.X < -1) + { + player.direction = -1; + } + Ins.Batch.Draw(tex, player.Center, null, Lighting.GetColor(player.Center.ToTileCoordinates()), rot, new Vector2(0, 34), 1f, SpriteEffects.None); + Ins.Batch.Draw(tex_glow, player.Center, null, Color.White, rot, new Vector2(0, 34), 1f, SpriteEffects.None); + Ins.Batch.Draw(tex_bloom, player.Center, null, new Color(1f, 1f, 1f, 0), rot, new Vector2(0, 80), 1f, SpriteEffects.None); + } + + public override void DrawLine(Vector2 pos1, Vector2 pos2, float width, Color color, float highlight, ref Queue drawStacks) + { + if (drawStacks == null) + { + drawStacks = new Queue(); + } + Vector2 normal = Utils.SafeNormalize(pos1 - pos2, Vector2.zeroVector).RotatedBy(MathHelper.PiOver2) * width / 2f; + List bars = new List() + { + new Vertex2D(pos1 + normal, color, new Vector3(0, 0, 0)), + new Vertex2D(pos2 + normal, color, new Vector3(1, 0, 0)), + new Vertex2D(pos1 - normal, color, new Vector3(0, 1, 0)), + + new Vertex2D(pos1 - normal, color, new Vector3(0, 1, 0)), + new Vertex2D(pos2 + normal, color, new Vector3(1, 0, 0)), + new Vertex2D(pos2 - normal, color, new Vector3(1, 1, 0)), + }; + drawStacks.Enqueue(new DrawStack(ModAsset.ForestRainVine_Cut.Value, bars, PrimitiveType.TriangleList)); + if (highlight > 0) + { + Color bloomColor = color * highlight; + bloomColor.A = 0; + bars = new List() + { + new Vertex2D(pos1 + normal, bloomColor, new Vector3(0, 0, 0)), + new Vertex2D(pos2 + normal, bloomColor, new Vector3(1, 0, 0)), + new Vertex2D(pos1 - normal, bloomColor, new Vector3(0, 1, 0)), + + new Vertex2D(pos1 - normal, bloomColor, new Vector3(0, 1, 0)), + new Vertex2D(pos2 + normal, bloomColor, new Vector3(1, 0, 0)), + new Vertex2D(pos2 - normal, bloomColor, new Vector3(1, 1, 0)), + }; + drawStacks.Enqueue(new DrawStack(ModAsset.ForestRainVine_Cut_Bloom.Value, bars, PrimitiveType.TriangleList)); + } + } + + public override void DrawLine_Black(HangingTileAdjustingHelper hangingSystem, Vector2 pos1, Vector2 pos2, float width, ref Queue drawStacks) + { + if (drawStacks == null) + { + drawStacks = new Queue(); + } + Vector2 normal = Utils.SafeNormalize(pos1 - pos2, Vector2.zeroVector).RotatedBy(MathHelper.PiOver2) * width / 2f; + Color bloomColor = Color.White; + float tK = 12f; + if (hangingSystem.TimeToKill > 0) + { + tK = hangingSystem.TimeToKill; + } + float fade = Math.Min(hangingSystem.Timer, tK) / 12f; + bloomColor *= fade; + List bars = new List() + { + new Vertex2D(pos1 + normal, bloomColor, new Vector3(0, 0, 0)), + new Vertex2D(pos2 + normal, bloomColor, new Vector3(1, 0, 0)), + new Vertex2D(pos1 - normal, bloomColor, new Vector3(0, 1, 0)), + + new Vertex2D(pos1 - normal, bloomColor, new Vector3(0, 1, 0)), + new Vertex2D(pos2 + normal, bloomColor, new Vector3(1, 0, 0)), + new Vertex2D(pos2 - normal, bloomColor, new Vector3(1, 1, 0)), + }; + drawStacks.Enqueue(new DrawStack(ModAsset.ForestRainVine_Cut_Bloom_black.Value, bars, PrimitiveType.TriangleList)); + } + + public override void DrawDirectionRing(HangingTileAdjustingHelper hangingSystem, Color color, float rotation, ref Queue drawStacks) + { + if (drawStacks == null) + { + drawStacks = new Queue(); + } + color.A = 0; + Vector2 pos = hangingSystem.FixPoint.ToWorldCoordinates(); + List bars = new List(); + for (int k = 0; k <= 60; k++) + { + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 36).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), Color.White, new Vector3(k / 20f, 0, 0)); + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 0).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), Color.White, new Vector3(k / 20f, 1, 0)); + } + drawStacks.Enqueue(new DrawStack(ModAsset.ForestRainVine_Matrix_black.Value, bars, PrimitiveType.TriangleStrip)); + bars = new List(); + for (int k = 0; k <= 60; k++) + { + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 36).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), color, new Vector3(k / 20f, 0, 0)); + bars.Add(pos + new Vector2(0, hangingSystem.PanelRange * 0).RotatedBy(k / 60f * MathHelper.TwoPi + rotation), color, new Vector3(k / 20f, 1, 0)); + } + drawStacks.Enqueue(new DrawStack(ModAsset.ForestRainVine_Matrix.Value, bars, PrimitiveType.TriangleStrip)); + } + #endregion +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thin.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thin.png new file mode 100644 index 000000000..c43b6b144 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thin.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thin_Bloom.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thin_Bloom.png new file mode 100644 index 000000000..900ff50c7 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thin_Bloom.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thin_Shape.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thin_Shape.png new file mode 100644 index 000000000..a1e79152e Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVineTile_Thin_Shape.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Cut.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Cut.png new file mode 100644 index 000000000..dd943edef Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Cut.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Cut_Bloom.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Cut_Bloom.png new file mode 100644 index 000000000..1b1fc64a4 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Cut_Bloom.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Cut_Bloom_black.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Cut_Bloom_black.png new file mode 100644 index 000000000..caf47008c Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Cut_Bloom_black.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Cut_black.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Cut_black.png new file mode 100644 index 000000000..85fae804b Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Cut_black.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Matrix.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Matrix.png new file mode 100644 index 000000000..5f25f3682 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Matrix.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Matrix_black.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Matrix_black.png new file mode 100644 index 000000000..744efe4a5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/ForestRainVines/ForestRainVine_Matrix_black.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/BlackAwningBoatSign.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/BlackAwningBoatSign.cs new file mode 100644 index 000000000..3f47580d6 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/BlackAwningBoatSign.cs @@ -0,0 +1,104 @@ +using Everglow.Commons.CustomTiles; +using Everglow.Yggdrasil.KelpCurtain.CustomTiles; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +public class BlackAwningBoatSign : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3); + TileObjectData.newTile.Height = 3; + TileObjectData.newTile.Width = 3; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 16, + 18, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(131, 158, 154)); + } + + public override bool RightClick(int i, int j) + { + var tile = Main.tile[i, j]; + float offset_x = -tile.TileFrameX / 18f * 16f - 16; + if (tile.TileFrameX > 36) + { + offset_x = (108 - tile.TileFrameX) / 18f * 16f + 16; + } + float offset_y = -tile.TileFrameY / 18f * 16f; + Vector2 summonPos = new Vector2(i, j) * 16f + new Vector2(offset_x, offset_y); + int x = (int)(summonPos.X / 16); + int y = (int)(summonPos.Y / 16); + var checkWaterTile = Main.tile[x, y]; + float waterLine = 0; + if (checkWaterTile.LiquidAmount <= 0) + { + for (int h = 0; h < 40; h++) + { + Collision.GetWaterLine(x, y + h, out waterLine); + if (waterLine != 0) + { + summonPos.Y = waterLine; + break; + } + } + } + else + { + for (int h = 0; h < 40; h++) + { + Collision.GetWaterLine(x, y - h, out waterLine); + if (waterLine != 0) + { + summonPos.Y = waterLine; + break; + } + } + } + + summonPos -= new Vector2(46, 20); + ColliderManager.Instance.Add(summonPos); + for (int l = 0; l < 16; l++) + { + int type; + switch (Main.rand.Next(3)) + { + case 0: + type = GoreID.ChimneySmoke1; + break; + case 1: + type = GoreID.ChimneySmoke2; + break; + case 2: + type = GoreID.ChimneySmoke3; + break; + default: + type = GoreID.ChimneySmoke1; + break; + } + + var gore = Gore.NewGorePerfect(summonPos + new Vector2(Main.rand.NextFloat(92), Main.rand.NextFloat(20)) - new Vector2(17, 18), new Vector2(0, Main.rand.NextFloat(1f)).RotatedByRandom(MathHelper.TwoPi), type); + gore.timeLeft = Main.rand.Next(60, 120); + } + return base.RightClick(i, j); + } + + public override bool CanExplode(int i, int j) => false; + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + noBreak = true; + return base.TileFrame(i, j, ref resetFrame, ref noBreak); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/BlackAwningBoatSign.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/BlackAwningBoatSign.png new file mode 100644 index 000000000..72a40c95b Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/BlackAwningBoatSign.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo.cs new file mode 100644 index 000000000..7eb858417 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo.cs @@ -0,0 +1,468 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.Items.Placeables; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Terraria; +using Terraria.GameContent.Drawing; +using Terraria.ModLoader.IO; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +public class IsleBamboo : ModTile, ITileFluentlyDrawn +{ + public const int MaxLength = 60; + + public override void PostSetDefaults() + { + Main.tileFrameImportant[Type] = false; + Main.tileNoAttach[Type] = true; + Main.tileCut[Type] = false; + Main.tileLavaDeath[Type] = true; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 1; + TileObjectData.newTile.Width = 1; + TileObjectData.newTile.CoordinateWidth = 16; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + + AddMapEntry(new Color(55, 91, 40)); + HitSound = SoundID.Grass; + } + + public override IEnumerable GetItemDrops(int i, int j) + { + yield return new Item(ModContent.ItemType()); + } + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + Tile bottomTile = TileUtils.SafeGetTile(i, j + 1); + Tile tile = Main.tile[i, j]; + if (tile.HasTile && tile.TileType == Type) + { + if (!bottomTile.HasTile || (bottomTile.TileType != Type && !Main.tileSolid[bottomTile.type] && !Main.tileSolidTop[bottomTile.type])) + { + int deltaY = 0; + while (true) + { + Tile topTile = TileUtils.SafeGetTile(i, j - deltaY); + if (topTile.HasTile && topTile.TileType == Type && j - deltaY > 0) + { + WorldGen.KillTile(i, j - deltaY, false, false, true); + } + else + { + break; + } + deltaY++; + } + } + } + return base.TileFrame(i, j, ref resetFrame, ref noBreak); + } + + public override bool CreateDust(int i, int j, ref int type) + { + for (int k = 0; k < 2; k++) + { + Vector2 pos = new Point(i, j).ToWorldCoordinates(); + var d = Dust.NewDustDirect(pos - new Vector2(20, 40) + new Vector2(4), 40, 50, type); + d.noGravity = true; + } + return false; + } + + public override void RandomUpdate(int i, int j) + { + var tile = Main.tile[i, j]; + var tile2 = Main.tile[i, j - 1]; + + if (tile2.TileType != tile.TileType && !tile2.HasTile) + { + int length = 0; + int maxLengthHere = MaxLength - (TileUtils.GetFixedRandomNumber(tile) % 10); + while (TileUtils.SafeGetTile(i, j + length).TileType == tile.TileType) + { + length++; + if (length >= maxLengthHere + 1) + { + break; + } + } + if (length <= maxLengthHere) + { + tile2.TileType = Type; + tile2.HasTile = true; + } + } + bool canGenerateDust = true; + for (int y = 0; y < 10; y++) + { + if (TileUtils.SafeGetTile(i, j + y).type != Type) + { + canGenerateDust = false; + break; + } + } + if (canGenerateDust) + { + var leaf = new BambooLeaf + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = new Vector2(i, j).ToWorldCoordinates() + new Vector2(0, Main.rand.NextFloat()).RotatedByRandom(MathHelper.TwoPi), + MaxTime = 3600, + Scale = Main.rand.NextFloat(0.5f, 0.7f), + Frame = Main.rand.Next(8), + FlipAngle = Main.rand.NextFloat(MathHelper.TwoPi), + FlipSpeed = Main.rand.NextFloat(-0.4f, 0.4f), + ai = new float[] { Main.rand.NextFloat(1f, 8f), -1 }, + }; + Ins.VFXManager.Add(leaf); + } + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + if (Main.tile[i, j + 1].TileType != Type) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + } + else if (j == (Main.screenPosition + new Vector2(0, Main.screenHeight / Main.GameViewMatrix.Zoom.Y + Main.offScreenRange + 160)).ToTileCoordinates().Y) + { + for (int y = 1; y < MaxLength; y++) + { + Tile stepDown = TileUtils.SafeGetTile(i, j + y); + if (stepDown.TileType != Type) + { + TileFluentDrawManager.AddFluentPoint(this, i, j + y - 1); + break; + } + } + } + return false; + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + DrawBamboo(pos, pos.ToWorldCoordinates() - screenPosition, spriteBatch, tileDrawing); + } + + /// + /// Draw a piece of lotus + /// + private void DrawBamboo(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + var lastOffset = new Vector2(0, 12); + int height = 0; + float lastRot = 0; + for (int j = 0; j < MaxLength; j++) + { + height++; + if (tilePos.Y - j < 21) + { + break; + } + var tile = Main.tile[tilePos + new Point(0, -j)]; + if (!(tile.TileType == Type && tile.HasTile)) + { + break; + } + } + float natureBendValue = (TileUtils.GetFixedRandomNumber(tilePos.X, tilePos.Y) % 10) - 4.5f; + natureBendValue += MathF.Sin((float)(Main.time * 0.03f + (TileUtils.GetFixedRandomNumber(tilePos.X, tilePos.Y) % 10) / 9f * MathHelper.PiOver2)) * Math.Clamp(Main.windSpeedCurrent, 0, 1); + if (height < 20) + { + natureBendValue *= 0; + } + else if (height < 30) + { + natureBendValue *= (height - 20) / 10f; + } + Texture2D tex = ModAsset.IsleBamboo.Value; + List bamboo_top = new List(); + for (int j = 0; j < MaxLength; j++) + { + if (tilePos.Y - j < 21) + { + return; + } + var tile = Main.tile[tilePos + new Point(0, -j)]; + if (!(tile.TileType == Type && tile.HasTile)) + { + break; + } + + int lastTileDis = 0; + int maxLastTileDis = 24; + for (int k = 1; k < maxLastTileDis; k++) + { + var tileUp = Main.tile[tilePos + new Point(0, -j - k)]; + if (!(tileUp.TileType == Type && tileUp.HasTile)) + { + lastTileDis = k; + break; + } + } + ushort type = tile.TileType; + int jointStyle = 4 - (j + TileUtils.GetFixedRandomNumber_SingleSeed(tilePos.X)) % 5; + var frame = new Rectangle(3 + 12 * jointStyle, 116, 10, 18); + if (lastTileDis > 0) + { + if (lastTileDis < 20) + { + frame.Y -= 20; + } + if (lastTileDis < 16) + { + frame.Y -= 20; + } + } + + // 回声涂料 + if (!TileDrawing.IsVisible(tile)) + { + continue; + } + + int paint = Main.tile[tilePos].TileColor; + tex = PaintedTextureSystem.TryGetPaintedTexture(ModAsset.IsleBamboo_Path, type, 1, paint, tileDrawing); + tex ??= ModAsset.IsleBamboo.Value; + + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(tilePos.X, tilePos.Y - j, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(tilePos.X, tilePos.Y - j, tileDrawing._sunflowerWindCounter) * 0.25f; + } + + int totalPushTime = 140; + float pushForcePerFrame = 0.96f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X, tilePos.Y - j, 1, 1, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + windCycle += highestWindGridPushComplex * 0.25f; + float rotation = windCycle * 0.01f + natureBendValue / 540f; + if (lastTileDis > 0) + { + rotation *= MathF.Pow(maxLastTileDis - lastTileDis, 2) / 6f; + } + float addRot = rotation - lastRot; + if (Math.Abs(rotation) > MathHelper.PiOver2 * 0.8) + { + float rotDecay = MathHelper.PiOver2 * 0.8f - Math.Abs(rotation); + addRot *= MathF.Pow(10, rotDecay); + } + rotation = lastRot + addRot; + + // rotation -= lastOffset.X / (22f + j * 3f); + // rotation += MathF.Sin(j / (float)height * MathHelper.Pi) * MathF.Sin(tilePos.X * 2 + tilePos.Y - j * 0.45f + (float)Main.time / 20f) * 0.15f; + // rotation += MathF.Sin(j / (float)height * MathHelper.Pi) * MathF.Sin(tilePos.X * 2 + tilePos.Y + (float)Main.time / 20f) * 6f / (height + 25); + var tileLight = Lighting.GetColor(tilePos + new Point(0, -j)); + + // 支æŒå‘光涂料 + tileDrawing.DrawAnimatedTile_AdjustForVisionChangers(tilePos.X, tilePos.Y - j, tile, type, 0, 0, ref tileLight, tileDrawing._rand.NextBool(4)); + tileLight = tileDrawing.DrawTiles_GetLightOverride(tilePos.X, tilePos.Y - j, tile, type, 0, 0, tileLight); + + var origin = new Vector2(5, 18); + + var drawPos = drawCenterPos + lastOffset; + var tileSpriteEffect = SpriteEffects.None; + if (j > 1) + { + if (lastTileDis <= 0 || lastTileDis > 11) + { + spriteBatch.Draw(tex, drawPos, frame, tileLight, rotation, origin, 1f, tileSpriteEffect, 0f); + } + } + else + { + if (j == 0) + { + int value = TileUtils.GetFixedRandomNumber(tile); + frame = new Rectangle(18 * (value % 3), 34 * (value % 2), 18, 34); + origin = new Vector2(08, 34); + spriteBatch.Draw(tex, drawPos, frame, tileLight, rotation, origin, 1f, tileSpriteEffect, 0f); + } + } + + // Leaves in low joints + if (lastTileDis <= 0) + { + if (j > 4 && jointStyle is 0 or 2) + { + Vector2 jointOffset = new Vector2(0, -14).RotatedBy(rotation); + if (jointStyle == 2) + { + jointOffset = new Vector2(0, -6).RotatedBy(rotation); + } + var leftLeafFrame = new Rectangle(6, 138, 38, 30); + var rightLeafFrame = new Rectangle(48, 136, 46, 30); + Vector2 leaf_drawPos = jointOffset + drawPos; + float sub_rot_Left = GetRotationLeaf(tileDrawing, tilePos.X - 1, tilePos.Y - j, rotation); + float sub_rot_Right = GetRotationLeaf(tileDrawing, tilePos.X + 1, tilePos.Y - j, rotation); + switch (TileUtils.GetFixedRandomNumber(tile) % 10) + { + case 0: // Left0 + spriteBatch.Draw(tex, leaf_drawPos, leftLeafFrame, tileLight, sub_rot_Left, new Vector2(38, 9), 1f, tileSpriteEffect, 0f); + break; + case 1: // Right0 + spriteBatch.Draw(tex, leaf_drawPos, rightLeafFrame, tileLight, sub_rot_Right, new Vector2(0, 9), 1f, tileSpriteEffect, 0f); + break; + case 2: // Left0, Right0 + spriteBatch.Draw(tex, leaf_drawPos, leftLeafFrame, tileLight, sub_rot_Left, new Vector2(38, 9), 1f, tileSpriteEffect, 0f); + + spriteBatch.Draw(tex, leaf_drawPos, rightLeafFrame, tileLight, sub_rot_Right, new Vector2(0, 9), 1f, tileSpriteEffect, 0f); + break; + case 3: // Left1, Right0 + leftLeafFrame = new Rectangle(8, 172, 40, 24); + spriteBatch.Draw(tex, leaf_drawPos, leftLeafFrame, tileLight, sub_rot_Left, new Vector2(40, 5), 1f, tileSpriteEffect, 0f); + + spriteBatch.Draw(tex, leaf_drawPos, rightLeafFrame, tileLight, sub_rot_Right, new Vector2(0, 9), 1f, tileSpriteEffect, 0f); + break; + case 4: // Left1 + leftLeafFrame = new Rectangle(8, 172, 40, 24); + spriteBatch.Draw(tex, leaf_drawPos, leftLeafFrame, tileLight, sub_rot_Left, new Vector2(40, 5), 1f, tileSpriteEffect, 0f); + break; + case 5: // Left1, Right1 + leftLeafFrame = new Rectangle(8, 172, 40, 24); + spriteBatch.Draw(tex, leaf_drawPos, leftLeafFrame, tileLight, sub_rot_Left, new Vector2(40, 5), 1f, tileSpriteEffect, 0f); + + rightLeafFrame = new Rectangle(58, 170, 34, 24); + spriteBatch.Draw(tex, leaf_drawPos, rightLeafFrame, tileLight, sub_rot_Right, new Vector2(0, 7), 1f, tileSpriteEffect, 0f); + break; + case 7: // Right1 + rightLeafFrame = new Rectangle(58, 170, 34, 24); + spriteBatch.Draw(tex, leaf_drawPos, rightLeafFrame, tileLight, sub_rot_Right, new Vector2(0, 7), 1f, tileSpriteEffect, 0f); + break; + case 8: // Left0, Right1 + spriteBatch.Draw(tex, leaf_drawPos, leftLeafFrame, tileLight, sub_rot_Left, new Vector2(38, 9), 1f, tileSpriteEffect, 0f); + + rightLeafFrame = new Rectangle(58, 170, 34, 24); + spriteBatch.Draw(tex, leaf_drawPos, rightLeafFrame, tileLight, sub_rot_Right, new Vector2(0, 7), 1f, tileSpriteEffect, 0f); + break; + default: + break; + } + } + } + + // Leaves in medium-low joints + else if (lastTileDis is < 24 and > 18) + { + if (j > 4 && jointStyle is 0 or 2) + { + Vector2 jointOffset = new Vector2(0, -14).RotatedBy(rotation); + if (jointStyle == 2) + { + jointOffset = new Vector2(0, -6).RotatedBy(rotation); + } + var leafFrame = new Rectangle(276, 184, 130, 54); + Vector2 leaf_drawPos = jointOffset + drawPos; + float sub_rot = GetRotationLeaf(tileDrawing, tilePos.X, tilePos.Y - j, rotation); + switch (TileUtils.GetFixedRandomNumber(tile) % 2) + { + case 0: + spriteBatch.Draw(tex, leaf_drawPos, leafFrame, tileLight, sub_rot, new Vector2(70, 24), 1f, tileSpriteEffect, 0f); + break; + case 1: + spriteBatch.Draw(tex, leaf_drawPos, leafFrame, tileLight, sub_rot, new Vector2(70, 24), 1f, SpriteEffects.FlipHorizontally, 0f); + break; + } + } + } + + // Leaves in medium joints + else if (lastTileDis is <= 18 and > 11) + { + if (j > 4 && jointStyle is 0 or 2) + { + Vector2 jointOffset = new Vector2(0, -14).RotatedBy(rotation); + if (jointStyle == 2) + { + jointOffset = new Vector2(0, -6).RotatedBy(rotation); + } + var leafFrame = new Rectangle(274, 4, 144, 50); + Vector2 anchorPos = new Vector2(72, 18); + Vector2 leaf_drawPos = jointOffset + drawPos; + float sub_rot = GetRotationLeaf_LargeLeaves(tileDrawing, tilePos.X, tilePos.Y - j, rotation); + switch (TileUtils.GetFixedRandomNumber(tile) % 3) + { + case 0: + break; + case 1: + leafFrame = new Rectangle(264, 58, 160, 54); + anchorPos = new Vector2(82, 18); + break; + case 2: + leafFrame = new Rectangle(278, 112, 156, 62); + anchorPos = new Vector2(68, 18); + break; + default: + break; + } + var leafFrame_front = leafFrame; + leafFrame_front.X -= 172; + SpriteEffects spriteEffects = SpriteEffects.None; + if (TileUtils.GetFixedRandomNumber(tile) % 2 == 0) + { + spriteEffects = SpriteEffects.FlipHorizontally; + } + spriteBatch.Draw(tex, leaf_drawPos, leafFrame, tileLight, sub_rot, anchorPos, 1f, spriteEffects, 0f); + spriteBatch.Draw(tex, leaf_drawPos, leafFrame_front, tileLight, sub_rot, anchorPos, 1f, spriteEffects, 0f); + } + } + + // Leaves in high joints + if (lastTileDis is > 0 and <= 12) + { + Rectangle frame_top = new Rectangle(440, 0, 108, 188); + Vector2 posLeft = drawPos + new Vector2(-54, 0).RotatedBy(rotation); + Vector2 posRight = drawPos + new Vector2(54, 0).RotatedBy(rotation); + float coordY = (lastTileDis - 1) / 11f * frame_top.Height / tex.Height; + float coordX1 = 548f / tex.Width; + float coordX2 = 440f / tex.Width; + if (TileUtils.GetFixedRandomNumber(tilePos) % 2 == 1) + { + (coordX2, coordX1) = (coordX1, coordX2); + } + bamboo_top.Add(posRight, Lighting.GetColor((posRight + Main.screenPosition).ToTileCoordinates()), new Vector3(coordX2, coordY, 0)); + bamboo_top.Add(posLeft, Lighting.GetColor((posLeft + Main.screenPosition).ToTileCoordinates()), new Vector3(coordX1, coordY, 0)); + } + + lastOffset += new Vector2(0, -16).RotatedBy(rotation); + lastRot = rotation; + } + if (bamboo_top.Count > 2) + { + spriteBatch.GraphicsDevice.Textures[0] = tex; + spriteBatch.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bamboo_top.ToArray(), 0, bamboo_top.Count - 2); + } + } + + public float GetRotationLeaf(TileDrawing tileDrawing, int x, int y, float rotation) + { + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(x, y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(x, y, tileDrawing._sunflowerWindCounter); + } + float sub_highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(x, y, 1, 1, 140, 0.96f, 3, swapLoopDir: true); + float sub_windCycle = windCycle + sub_highestWindGridPushComplex * 1.5f; + float sub_rot = rotation + sub_windCycle * 0.25f; + return sub_rot; + } + + public float GetRotationLeaf_LargeLeaves(TileDrawing tileDrawing, int x, int y, float rotation) + { + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(x, y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(x, y, tileDrawing._sunflowerWindCounter); + } + float sub_highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(x, y, 1, 1, 140, 0.96f, 3, swapLoopDir: true); + float sub_windCycle = windCycle + sub_highestWindGridPushComplex * 1.5f; + float sub_rot = rotation + sub_windCycle * 0.05f; + return sub_rot; + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo.png new file mode 100644 index 000000000..a88b59d7c Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo_H.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo_H.cs new file mode 100644 index 000000000..891052a81 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo_H.cs @@ -0,0 +1,20 @@ +using Everglow.Yggdrasil.KelpCurtain.Dusts; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +public class IsleBamboo_H : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileSolid[Type] = true; + Main.tileMergeDirt[Type] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[ModContent.TileType()][Type] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[ModContent.TileType()][Type] = true; + Main.tileNoSunLight[Type] = true; + Main.tileBlockLight[Type] = true; + DustType = ModContent.DustType(); + AddMapEntry(new Color(124, 103, 82)); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo_H.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo_H.png new file mode 100644 index 000000000..61eba2eaf Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo_H.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo_V.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo_V.cs new file mode 100644 index 000000000..24ecf7e65 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo_V.cs @@ -0,0 +1,18 @@ +using Everglow.Yggdrasil.KelpCurtain.Dusts; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +public class IsleBamboo_V : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileSolid[Type] = true; + Main.tileMergeDirt[Type] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[ModContent.TileType()][Type] = true; + Main.tileNoSunLight[Type] = true; + Main.tileBlockLight[Type] = true; + DustType = ModContent.DustType(); + AddMapEntry(new Color(124, 103, 82)); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo_V.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo_V.png new file mode 100644 index 000000000..1b5f7cecb Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleBamboo_V.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleOfBloom_CaveRay.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleOfBloom_CaveRay.cs new file mode 100644 index 000000000..e2231fa10 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleOfBloom_CaveRay.cs @@ -0,0 +1,53 @@ +using Everglow.Commons.TileHelper; +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.KelpCurtain.Background; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using MonoMod.Core.Platforms; +using Terraria.DataStructures; +using Terraria.GameContent.Drawing; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +public class IsleOfBloom_CaveRay : ModTile, ISceneTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileWaterDeath[Type] = false; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 1; + TileObjectData.newTile.Width = 1; + TileObjectData.newTile.AnchorBottom = AnchorData.Empty; + TileObjectData.newTile.AnchorWall = true; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + TileObjectData.addTile(Type); + AddMapEntry(new Color(36, 56, 23)); + } + + public override void NearbyEffects(int i, int j, bool closer) + { + base.NearbyEffects(i, j, closer); + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + return false; + } + + public void AddScene(int i, int j) + { + IsleOfBloom_CaveRay_VFX ray = new IsleOfBloom_CaveRay_VFX(); + ray.Active = true; + ray.Visible = true; + ray.OriginTilePos = new Point(i, j); + ray.Position = new Point(i, j).ToWorldCoordinates(); + ray.OriginTileType = Type; + Ins.VFXManager.Add(ray); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleOfBloom_CaveRay.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleOfBloom_CaveRay.png new file mode 100644 index 000000000..b7521fb2a Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleOfBloom_CaveRay.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleOfBloom_CaveRay_VFX.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleOfBloom_CaveRay_VFX.cs new file mode 100644 index 000000000..979c72340 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IsleOfBloom_CaveRay_VFX.cs @@ -0,0 +1,55 @@ +using Everglow.Commons.VFX.Scene; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +[Pipeline(typeof(WCSPipeline_PointWrap))] +public class IsleOfBloom_CaveRay_VFX : TileVFX +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; + + public override void OnSpawn() + { + Texture = Commons.ModAsset.Noise_flame_2.Value; + MaxDiatanceOutOfScreen = 3000; + } + + public override void Update() + { + base.Update(); + } + + public override void Draw() + { + Vector2 center = OriginTilePos.ToWorldCoordinates(8, 8) + new Vector2(0, 320); + Color color = new Color(0.4f, 0.4f, 0.6f, 0) * 0.1f; + float timeValue = Main.GlobalTimeWrappedHourly * 0.05f; + List bars = new List(); + for (int dy = -30; dy <= 30; dy++) + { + float fade = MathF.Cos(dy / 30f * MathF.PI) * 0.5f + 0.5f; + Vector2 drawPos = center + new Vector2(0, dy * 16); + Lighting.AddLight(drawPos, new Vector3(0.1f, 0.1f, 0.15f)); + bars.Add(drawPos + new Vector2(-32, 0), color * fade, new Vector3(0.3f, timeValue, 0)); + bars.Add(drawPos + new Vector2(32, 0), color * fade, new Vector3(0.7f, timeValue, 0)); + } + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleStrip); + bars = new List(); + for (int dy = -30; dy <= 30; dy++) + { + float fade = MathF.Cos(dy / 30f * MathF.PI) * 0.5f + 0.5f; + Vector2 drawPos = center + new Vector2(0, dy * 16); + bars.Add(drawPos + new Vector2(-64, 0), color * 0, new Vector3(-0.1f, timeValue, 0)); + bars.Add(drawPos + new Vector2(-32, 0), color * fade, new Vector3(0.3f, timeValue, 0)); + } + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleStrip); + bars = new List(); + for (int dy = -30; dy <= 30; dy++) + { + float fade = MathF.Cos(dy / 30f * MathF.PI) * 0.5f + 0.5f; + Vector2 drawPos = center + new Vector2(0, dy * 16); + bars.Add(drawPos + new Vector2(64, 0), color * 0, new Vector3(1.1f, timeValue, 0)); + bars.Add(drawPos + new Vector2(32, 0), color * fade, new Vector3(0.7f, timeValue, 0)); + } + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleStrip); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_large.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_large.cs new file mode 100644 index 000000000..df88e6a93 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_large.cs @@ -0,0 +1,230 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Microsoft.Build.Tasks; +using Terraria.GameContent.Drawing; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +public class IslePeachTree_large : ModTile, ITileFluentlyDrawn +{ + public const int MaxLength = 6; + + public override void PostSetDefaults() + { + Main.tileFrameImportant[Type] = false; + Main.tileNoAttach[Type] = true; + Main.tileCut[Type] = false; + Main.tileLavaDeath[Type] = true; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 1; + TileObjectData.newTile.Width = 1; + TileObjectData.newTile.CoordinateWidth = 16; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + + AddMapEntry(new Color(137, 99, 99)); + HitSound = SoundID.Dig; + } + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + Tile bottomTile = TileUtils.SafeGetTile(i, j + 1); + Tile tile = Main.tile[i, j]; + if (tile.HasTile && tile.TileType == Type) + { + if (!bottomTile.HasTile || (bottomTile.TileType != Type && !Main.tileSolid[bottomTile.type] && !Main.tileSolidTop[bottomTile.type])) + { + int deltaY = 0; + while (true) + { + Tile topTile = TileUtils.SafeGetTile(i, j - deltaY); + if (topTile.HasTile && topTile.TileType == Type && j - deltaY > 0) + { + WorldGen.KillTile(i, j - deltaY, false, false, true); + } + else + { + break; + } + deltaY++; + } + } + } + return base.TileFrame(i, j, ref resetFrame, ref noBreak); + } + + public override bool CreateDust(int i, int j, ref int type) + { + for (int k = 0; k < 2; k++) + { + Vector2 pos = new Point(i, j).ToWorldCoordinates(); + var d = Dust.NewDustDirect(pos - new Vector2(20, 40) + new Vector2(4), 40, 50, type); + d.noGravity = true; + } + return false; + } + + public override void RandomUpdate(int i, int j) + { + var tile = Main.tile[i, j]; + var tile2 = Main.tile[i, j - 1]; + + if (tile2.TileType != tile.TileType && !tile2.HasTile) + { + int length = 0; + int maxLengthHere = MaxLength - TileUtils.GetFixedRandomNumber(tile) % 3; + while (TileUtils.SafeGetTile(i, j + length).TileType == Type) + { + length++; + if (length >= maxLengthHere + 1) + { + break; + } + } + if (length <= maxLengthHere) + { + tile2.TileType = Type; + tile2.HasTile = true; + } + } + + int topY = j; + for (int y = 0; y < 12; y++) + { + if (TileUtils.SafeGetTile(i, j - y).TileType != Type) + { + topY = j - y + 1; + break; + } + } + var petal = new PeachBlossom + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = new Vector2(i, topY).ToWorldCoordinates() + new Vector2(0, Main.rand.NextFloat()).RotatedByRandom(MathHelper.TwoPi) * 120 + new Vector2(0, -60), + MaxTime = 3600, + Scale = Main.rand.NextFloat(1f, 1.5f), + Frame = Main.rand.Next(10), + ai = new float[] { Main.rand.NextFloat(1f, 8f), -1 }, + }; + Ins.VFXManager.Add(petal); + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + return false; + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + DrawPeachTree(pos, pos.ToWorldCoordinates() - screenPosition, spriteBatch, tileDrawing); + } + + /// + /// Draw a piece of peach blossom + /// + private void DrawPeachTree(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + int toBottom = 0; + int toTop = 0; + var tile = TileUtils.SafeGetTile(tilePos); + for (int j = 1; j < MaxLength; j++) + { + toBottom = j; + var checkTile = TileUtils.SafeGetTile(tilePos.X, tilePos.Y + j); + if (checkTile.type != Type) + { + break; + } + } + for (int j = 1; j < MaxLength; j++) + { + toTop = j; + var checkTile = TileUtils.SafeGetTile(tilePos.X, tilePos.Y - j); + if (checkTile.type != Type) + { + break; + } + } + Texture2D tex = ModAsset.IslePeachTree_large.Value; + + // 回声涂料 + if (!TileDrawing.IsVisible(tile)) + { + return; + } + + int paint = Main.tile[tilePos].TileColor; + tex = PaintedTextureSystem.TryGetPaintedTexture(ModAsset.IslePeachTree_large_Path, Type, 1, paint, tileDrawing); + tex ??= ModAsset.IslePeachTree_large.Value; + + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(tilePos.X, tilePos.Y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(tilePos.X, tilePos.Y, tileDrawing._sunflowerWindCounter) * 0.25f; + } + + int totalPushTime = 140; + float pushForcePerFrame = 0.96f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X, tilePos.Y, 1, 1, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + int styleTop = TileUtils.GetFixedRandomNumber(tilePos, 2); + if (toTop == 1) + { + highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X - 3, tilePos.Y - 7, 7, 7, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + } + windCycle += highestWindGridPushComplex * 0.25f; + float rotation = windCycle * 0.1f; + if (windCycle > 0.17f && toTop == 1) + { + if (!Main.gamePaused && Main.rand.NextBool(2)) + { + var petal = new PeachBlossom + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = tilePos.ToWorldCoordinates() + new Vector2(0, Main.rand.NextFloat()).RotatedByRandom(MathHelper.TwoPi) * 120 + new Vector2(0, -60), + MaxTime = 3600, + Scale = Main.rand.NextFloat(1f, 1.5f), + Frame = Main.rand.Next(10), + ai = new float[] { Main.rand.NextFloat(1f, 8f), -1 }, + }; + if (styleTop == 1) + { + petal.Position = tilePos.ToWorldCoordinates() + new Vector2(0, Main.rand.NextFloat()).RotatedByRandom(MathHelper.TwoPi) * new Vector2(1, 0.5f) * 240 + new Vector2(0, -80); + } + Ins.VFXManager.Add(petal); + } + } + + var tileLight = Lighting.GetColor(tilePos); + + // 支æŒå‘光涂料 + tileDrawing.DrawAnimatedTile_AdjustForVisionChangers(tilePos.X, tilePos.Y, tile, Type, 0, 0, ref tileLight, tileDrawing._rand.NextBool(4)); + tileLight = tileDrawing.DrawTiles_GetLightOverride(tilePos.X, tilePos.Y, tile, Type, 0, 0, tileLight); + + if (toTop == 1) + { + var frame = new Rectangle(184, 6, 1022, 726); + var origin = new Vector2(505, 726); + var drawPos = drawCenterPos; + var tileSpriteEffect = SpriteEffects.None; + spriteBatch.Draw(tex, drawPos, frame, tileLight, rotation, origin, 1f, tileSpriteEffect, 0f); + } + if (toTop > 1) + { + int style = TileUtils.GetFixedRandomNumber(tile) % 1; + var frame = new Rectangle(2, 636 + 18 * style, 38, 16); + var origin = new Vector2(19, 16); + + var drawPos = drawCenterPos; + var tileSpriteEffect = SpriteEffects.None; + spriteBatch.Draw(tex, drawPos, frame, tileLight, rotation, origin, 1f, tileSpriteEffect, 0f); + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_large.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_large.png new file mode 100644 index 000000000..aa7208bc5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_large.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_large_Highlight.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_large_Highlight.png new file mode 100644 index 000000000..52cac79df Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_large_Highlight.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_medium.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_medium.cs new file mode 100644 index 000000000..0e8205dca --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_medium.cs @@ -0,0 +1,245 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Terraria.GameContent.Drawing; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +public class IslePeachTree_medium : ModTile, ITileFluentlyDrawn +{ + public const int MaxLength = 6; + + public override void PostSetDefaults() + { + Main.tileFrameImportant[Type] = false; + Main.tileNoAttach[Type] = true; + Main.tileCut[Type] = false; + Main.tileLavaDeath[Type] = true; + Main.tileAxe[Type] = true; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 1; + TileObjectData.newTile.Width = 1; + TileObjectData.newTile.CoordinateWidth = 16; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + + AddMapEntry(new Color(205, 101, 147)); + HitSound = SoundID.Dig; + } + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + Tile bottomTile = TileUtils.SafeGetTile(i, j + 1); + Tile tile = Main.tile[i, j]; + if (tile.HasTile && tile.TileType == Type) + { + if (!bottomTile.HasTile || (bottomTile.TileType != Type && !Main.tileSolid[bottomTile.type] && !Main.tileSolidTop[bottomTile.type])) + { + int deltaY = 0; + while (true) + { + Tile topTile = TileUtils.SafeGetTile(i, j - deltaY); + if (topTile.HasTile && topTile.TileType == Type && j - deltaY > 0) + { + WorldGen.KillTile(i, j - deltaY, false, false, true); + } + else + { + break; + } + deltaY++; + } + } + } + return base.TileFrame(i, j, ref resetFrame, ref noBreak); + } + + public override bool CreateDust(int i, int j, ref int type) + { + for (int k = 0; k < 2; k++) + { + Vector2 pos = new Point(i, j).ToWorldCoordinates(); + var d = Dust.NewDustDirect(pos - new Vector2(20, 40) + new Vector2(4), 40, 50, type); + d.noGravity = true; + } + return false; + } + + public override void RandomUpdate(int i, int j) + { + var tile = Main.tile[i, j]; + var tile2 = Main.tile[i, j - 1]; + + if (tile2.TileType != tile.TileType && !tile2.HasTile) + { + int length = 0; + int maxLengthHere = MaxLength - TileUtils.GetFixedRandomNumber(tile) % 3; + while (TileUtils.SafeGetTile(i, j + length).TileType == Type) + { + length++; + if (length >= maxLengthHere + 1) + { + break; + } + } + if (length <= maxLengthHere) + { + tile2.TileType = Type; + tile2.HasTile = true; + } + } + + int topY = j; + for (int y = 0; y < 12; y++) + { + if (TileUtils.SafeGetTile(i, j - y).TileType != Type) + { + topY = j - y + 1; + break; + } + } + var petal = new PeachBlossom + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = new Vector2(i, topY).ToWorldCoordinates() + new Vector2(0, Main.rand.NextFloat()).RotatedByRandom(MathHelper.TwoPi) * 120 + new Vector2(0, -60), + MaxTime = 3600, + Scale = Main.rand.NextFloat(1f, 1.5f), + Frame = Main.rand.Next(10), + ai = new float[] { Main.rand.NextFloat(1f, 8f), -1 }, + }; + Ins.VFXManager.Add(petal); + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + return false; + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + DrawPeachTree(pos, pos.ToWorldCoordinates() - screenPosition, spriteBatch, tileDrawing); + } + + /// + /// Draw a piece of peach blossom + /// + private void DrawPeachTree(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + int toBottom = 0; + int toTop = 0; + var tile = TileUtils.SafeGetTile(tilePos); + for (int j = 1; j < MaxLength; j++) + { + toBottom = j; + var checkTile = TileUtils.SafeGetTile(tilePos.X, tilePos.Y + j); + if (checkTile.type != Type) + { + break; + } + } + for (int j = 1; j < MaxLength; j++) + { + toTop = j; + var checkTile = TileUtils.SafeGetTile(tilePos.X, tilePos.Y - j); + if (checkTile.type != Type) + { + break; + } + } + Texture2D tex = ModAsset.IslePeachTree_medium.Value; + + // 回声涂料 + if (!TileDrawing.IsVisible(tile)) + { + return; + } + + int paint = Main.tile[tilePos].TileColor; + tex = PaintedTextureSystem.TryGetPaintedTexture(ModAsset.IslePeachTree_medium_Path, Type, 1, paint, tileDrawing); + tex ??= ModAsset.IslePeachTree_medium.Value; + + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(tilePos.X, tilePos.Y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(tilePos.X, tilePos.Y, tileDrawing._sunflowerWindCounter) * 0.25f; + } + + int totalPushTime = 140; + float pushForcePerFrame = 0.96f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X, tilePos.Y, 1, 1, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + int styleTop = TileUtils.GetFixedRandomNumber_SingleSeed(tilePos.X, 2); + if (toTop == 1) + { + highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X - 3, tilePos.Y - 7, 7, 7, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + } + windCycle += highestWindGridPushComplex * 0.25f; + float rotation = windCycle * 0.1f; + if (!Main.gamePaused) + { + if (windCycle > 0.1f && toTop == 1) + { + if (Main.rand.NextBool(2)) + { + var petal = new PeachBlossom + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = tilePos.ToWorldCoordinates() + new Vector2(0, Main.rand.NextFloat()).RotatedByRandom(MathHelper.TwoPi) * new Vector2(1, 0.5f) * 150 + new Vector2(0, -80), + MaxTime = 3600, + Scale = Main.rand.NextFloat(0.8f, 1.2f), + Frame = Main.rand.Next(10), + ai = new float[] { Main.rand.NextFloat(1f, 8f), -1 }, + }; + if (styleTop == 1) + { + petal.Position = tilePos.ToWorldCoordinates() + new Vector2(0, Main.rand.NextFloat()).RotatedByRandom(MathHelper.TwoPi) * 100 + new Vector2(0, -100); + } + Ins.VFXManager.Add(petal); + } + } + } + + var tileLight = Lighting.GetColor(tilePos); + + // 支æŒå‘光涂料 + tileDrawing.DrawAnimatedTile_AdjustForVisionChangers(tilePos.X, tilePos.Y, tile, Type, 0, 0, ref tileLight, tileDrawing._rand.NextBool(4)); + tileLight = tileDrawing.DrawTiles_GetLightOverride(tilePos.X, tilePos.Y, tile, Type, 0, 0, tileLight); + + if (toTop == 1) + { + var frame = new Rectangle(14, 4, 340, 212); + var origin = new Vector2(170, 224); + switch (styleTop) + { + case 0: + frame = new Rectangle(14, 4, 340, 212); + origin = new Vector2(167, 212); + break; + case 1: + frame = new Rectangle(370, 38, 240, 220); + origin = new Vector2(114, 220); + break; + } + TileUtils.VertexDraw_Grid(drawCenterPos + new Vector2(0, 2), frame, origin, tex, spriteBatch, rotation); + } + if (toTop > 1 && toBottom > 1) + { + int style = TileUtils.GetFixedRandomNumber(tile) % 8; + var frame = new Rectangle(0, 236 + 18 * style, 34, 16); + var origin = new Vector2(15, 16); + TileUtils.VertexDraw_4_Corner(drawCenterPos, frame, origin, tex, spriteBatch, rotation); + } + if (toBottom == 1) + { + var frame = new Rectangle(50, 340, 38, 40); + var origin = new Vector2(19, 32); + TileUtils.VertexDraw_Grid(drawCenterPos + new Vector2(0, 12), frame, origin, tex, spriteBatch, rotation); + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_medium.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_medium.png new file mode 100644 index 000000000..00acf566f Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_medium.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_side.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_side.cs new file mode 100644 index 000000000..5f65cde14 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_side.cs @@ -0,0 +1,178 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.GameContent.Drawing; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +public class IslePeachTree_side : ModTile, ITileFluentlyDrawn, ITileOffsetOverScreenDrawn +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileLighted[Type] = true; + Main.tileSolid[Type] = false; + Main.tileNoFail[Type] = true; + Main.tileAxe[Type] = true; + + DustType = ModContent.DustType(); + + // Placement - Standard Chandelier Setup Below + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 1; + TileObjectData.newTile.Width = 10; + TileObjectData.newTile.CoordinateHeights = new int[] { 16, }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.DrawYOffset = 0; + TileObjectData.newTile.StyleMultiplier = 2; + TileObjectData.newTile.AnchorBottom = AnchorData.Empty; // Clear out existing bottom anchor inherited from Style1x1 temporarily so that we don't have to set it to empty in each of the alternates. + + var SolidOrSolidSideAnchor1TilesLong = new AnchorData(AnchorType.SolidTile | AnchorType.SolidSide, 1, 0); + + TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile); + TileObjectData.newAlternate.Origin = new Point16(0, 1); + TileObjectData.newAlternate.AnchorLeft = SolidOrSolidSideAnchor1TilesLong; + TileObjectData.newAlternate.Style = 1; + TileObjectData.addAlternate(1); + + TileObjectData.newTile.Origin = new Point16(4, 1); + TileObjectData.newTile.AnchorRight = SolidOrSolidSideAnchor1TilesLong; + TileObjectData.addTile(Type); + AnimationFrameHeight = 18; + AddMapEntry(new Color(205, 101, 147)); + HitSound = SoundID.Dig; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = fail ? 1 : 3; + } + + public override void RandomUpdate(int i, int j) + { + var petal = new PeachBlossom + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = new Vector2(i, j).ToWorldCoordinates() + new Vector2(0, Main.rand.NextFloat()).RotatedByRandom(MathHelper.TwoPi) * 120 + new Vector2(0, -60), + MaxTime = 3600, + Scale = Main.rand.NextFloat(1f, 1.5f), + Frame = Main.rand.Next(10), + ai = new float[] { Main.rand.NextFloat(1f, 8f), -1 }, + }; + Ins.VFXManager.Add(petal); + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + if (!ITileOffsetOverScreenDrawn.SpecialTilePositon.Contains(new Point(i, j))) + { + ITileOffsetOverScreenDrawn.SpecialTilePositon.Add(new Point(i, j)); + } + Tile tile = TileUtils.SafeGetTile(i, j); + if (tile.TileFrameX is 162 or 180) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + } + return false; + } + + public override void DrawEffects(int i, int j, SpriteBatch spriteBatch, ref TileDrawInfo drawData) + { + // Tile tile = TileUtils.SafeGetTile(i, j); + // if (tile.TileFrameX is 72 or 90) + // { + // TileFluentDrawManager.AddFluentPoint(this, i, j); + // } + base.DrawEffects(i, j, spriteBatch, ref drawData); + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + DrawPeachTree(pos, pos.ToWorldCoordinates() - screenPosition, spriteBatch, tileDrawing); + } + + /// + /// Draw a piece of peach blossom + /// + private void DrawPeachTree(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + var tile = TileUtils.SafeGetTile(tilePos); + Texture2D tex = ModAsset.IslePeachTree_side_tree.Value; + + // 回声涂料 + if (!TileDrawing.IsVisible(tile)) + { + return; + } + + int paint = Main.tile[tilePos].TileColor; + tex = PaintedTextureSystem.TryGetPaintedTexture(ModAsset.IslePeachTree_side_tree_Path, Type, 1, paint, tileDrawing); + tex ??= ModAsset.IslePeachTree_side_tree.Value; + + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(tilePos.X, tilePos.Y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(tilePos.X, tilePos.Y, tileDrawing._sunflowerWindCounter) * 0.25f; + } + + int totalPushTime = 140; + float pushForcePerFrame = 0.96f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X - 20, tilePos.Y - 10, 20, 10, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + if (tile.TileFrameX == 180) + { + highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X, tilePos.Y - 10, 20, 10, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + } + windCycle += highestWindGridPushComplex * 0.25f; + float rotation = windCycle * 0.1f; + if (!Main.gamePaused) + { + if (windCycle > 0.1f) + { + if (Main.rand.NextBool(2)) + { + var petal = new PeachBlossom + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = tilePos.ToWorldCoordinates() + new Vector2(0, Main.rand.NextFloat()).RotatedByRandom(MathHelper.TwoPi) * new Vector2(1, 0.1f) * 120 + new Vector2(-100, -80), + MaxTime = 3600, + Scale = Main.rand.NextFloat(0.8f, 1.2f), + Frame = Main.rand.Next(10), + ai = new float[] { Main.rand.NextFloat(1f, 8f), -1 }, + }; + if (tile.TileFrameX == 180) + { + petal.Position = tilePos.ToWorldCoordinates() + new Vector2(0, Main.rand.NextFloat()).RotatedByRandom(MathHelper.TwoPi) * new Vector2(1, 0.1f) * 120 + new Vector2(100, -80); + } + Ins.VFXManager.Add(petal); + } + } + } + + var tileLight = Lighting.GetColor(tilePos); + + // 支æŒå‘光涂料 + tileDrawing.DrawAnimatedTile_AdjustForVisionChangers(tilePos.X, tilePos.Y, tile, Type, 0, 0, ref tileLight, tileDrawing._rand.NextBool(4)); + tileLight = tileDrawing.DrawTiles_GetLightOverride(tilePos.X, tilePos.Y, tile, Type, 0, 0, tileLight); + + var frame = new Rectangle(0, 0, 412, 200); + var origin = new Vector2(390, 179); + if (tile.TileFrameX == 180) + { + frame = new Rectangle(416, 0, 412, 200); + origin = new Vector2(21, 179); + } + + TileUtils.VertexDraw_Grid(drawCenterPos, frame, origin, tex, spriteBatch, rotation); + } + + int ITileOffsetOverScreenDrawn.TileOffsetScreenRange() => 480; +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_side.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_side.png new file mode 100644 index 000000000..f64000f36 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_side.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_side_tree.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_side_tree.png new file mode 100644 index 000000000..d7572e057 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_side_tree.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_small.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_small.cs new file mode 100644 index 000000000..77410f7e0 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_small.cs @@ -0,0 +1,150 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Terraria.GameContent.Drawing; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +public class IslePeachTree_small : ModTile, ITileFluentlyDrawn +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + Main.tileAxe[Type] = true; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 2; + TileObjectData.newTile.Width = 1; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 18, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(205, 101, 147)); + HitSound = SoundID.Dig; + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + Tile tile = TileUtils.SafeGetTile(i, j); + if (tile.TileFrameY == 18) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + } + return false; + } + + public override void RandomUpdate(int i, int j) + { + var petal = new PeachBlossom + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = new Vector2(i, j).ToWorldCoordinates() + new Vector2(0, Main.rand.NextFloat()).RotatedByRandom(MathHelper.TwoPi) * 120 + new Vector2(0, -60), + MaxTime = 3600, + Scale = Main.rand.NextFloat(1f, 1.5f), + Frame = Main.rand.Next(10), + ai = new float[] { Main.rand.NextFloat(1f, 8f), -1 }, + }; + Ins.VFXManager.Add(petal); + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + DrawPeachTree(pos, pos.ToWorldCoordinates() - screenPosition, spriteBatch, tileDrawing); + } + + /// + /// Draw a piece of peach blossom + /// + private void DrawPeachTree(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + var tile = TileUtils.SafeGetTile(tilePos); + Texture2D tex; + + // 回声涂料 + if (!TileDrawing.IsVisible(tile)) + { + return; + } + + int paint = Main.tile[tilePos].TileColor; + tex = PaintedTextureSystem.TryGetPaintedTexture(ModAsset.IslePeachTree_small_tree_Path, Type, 1, paint, tileDrawing); + tex ??= ModAsset.IslePeachTree_small_tree.Value; + + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(tilePos.X, tilePos.Y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(tilePos.X, tilePos.Y, tileDrawing._sunflowerWindCounter) * 0.25f; + } + + int totalPushTime = 140; + float pushForcePerFrame = 0.96f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X - 3, tilePos.Y - 8, 7, 7, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + windCycle += highestWindGridPushComplex * 0.25f; + float rotation = windCycle * 0.2f; + + var tileLight = Lighting.GetColor(tilePos); + + // 支æŒå‘光涂料 + tileDrawing.DrawAnimatedTile_AdjustForVisionChangers(tilePos.X, tilePos.Y, tile, Type, 0, 0, ref tileLight, tileDrawing._rand.NextBool(4)); + tileLight = tileDrawing.DrawTiles_GetLightOverride(tilePos.X, tilePos.Y, tile, Type, 0, 0, tileLight); + + var frame = new Rectangle(0, 26, 182, 142); + var origin = new Vector2(88, 140); + var offset = new Vector2(0, 12); + var tileBelow = TileUtils.SafeGetTile(tilePos + new Point(0, 1)); + if (tileBelow.IsHalfBlock) + { + offset.Y += 8; + } + if (!Main.gamePaused) + { + if (windCycle > 0.1f) + { + if (Main.rand.NextBool(8)) + { + var petal = new PeachBlossom + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = tilePos.ToWorldCoordinates() + new Vector2(0, Main.rand.NextFloat()).RotatedByRandom(MathHelper.TwoPi) * 75 + new Vector2(0, -80), + MaxTime = 3600, + Scale = Main.rand.NextFloat(0.8f, 1.2f), + Frame = Main.rand.Next(10), + ai = new float[] { Main.rand.NextFloat(1f, 8f), -1 }, + }; + Ins.VFXManager.Add(petal); + } + } + } + switch (TileUtils.GetFixedRandomNumber(tilePos, 4)) + { + case 0: + break; + case 1: + frame = new Rectangle(182, 10, 156, 158); + origin = new Vector2(92, 156); + break; + case 2: + frame = new Rectangle(406, 56, 96, 122); + origin = new Vector2(45, 111); + break; + case 3: + frame = new Rectangle(576, 30, 122, 138); + origin = new Vector2(49, 138); + break; + } + + TileUtils.VertexDraw_Grid(drawCenterPos + offset, frame, origin, tex, spriteBatch, rotation); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_small.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_small.png new file mode 100644 index 000000000..6bfe44606 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_small.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_small_tree.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_small_tree.png new file mode 100644 index 000000000..351406b9e Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_small_tree.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_large.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_large.cs new file mode 100644 index 000000000..fcf8acfac --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_large.cs @@ -0,0 +1,148 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Terraria; +using Terraria.DataStructures; +using Terraria.GameContent.Drawing; +using Terraria.ModLoader.IO; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +public class IslePeachTree_wall_large : ModTile, ITileFluentlyDrawn +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + Main.tileAxe[Type] = true; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 1; + TileObjectData.newTile.Width = 1; + TileObjectData.newTile.AnchorBottom = AnchorData.Empty; + TileObjectData.newTile.AnchorWall = true; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(205, 101, 147)); + HitSound = SoundID.Dig; + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + return false; + } + + public override void RandomUpdate(int i, int j) + { + var petal = new PeachBlossom + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = new Vector2(i, j).ToWorldCoordinates() + new Vector2(0, Main.rand.NextFloat()).RotatedByRandom(MathHelper.TwoPi) * 120 + new Vector2(0, -60), + MaxTime = 3600, + Scale = Main.rand.NextFloat(1f, 1.5f), + Frame = Main.rand.Next(10), + ai = new float[] { Main.rand.NextFloat(1f, 8f), -1 }, + }; + Ins.VFXManager.Add(petal); + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + DrawPeachTree(pos, pos.ToWorldCoordinates() - screenPosition, spriteBatch, tileDrawing); + } + + /// + /// Draw a piece of peach blossom + /// + private void DrawPeachTree(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + var tile = TileUtils.SafeGetTile(tilePos); + Texture2D tex; + + // 回声涂料 + if (!TileDrawing.IsVisible(tile)) + { + return; + } + + int paint = Main.tile[tilePos].TileColor; + tex = PaintedTextureSystem.TryGetPaintedTexture(ModAsset.IslePeachTree_wall_large_Path, Type, 1, paint, tileDrawing); + tex ??= ModAsset.IslePeachTree_wall_large.Value; + + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(tilePos.X, tilePos.Y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(tilePos.X, tilePos.Y, tileDrawing._sunflowerWindCounter) * 0.25f; + } + + int totalPushTime = 140; + float pushForcePerFrame = 0.96f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X - 8, tilePos.Y - 8, 17, 5, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + windCycle += highestWindGridPushComplex * 0.25f; + float rotation = windCycle * 0.2f; + + var tileLight = Lighting.GetColor(tilePos); + + // 支æŒå‘光涂料 + tileDrawing.DrawAnimatedTile_AdjustForVisionChangers(tilePos.X, tilePos.Y, tile, Type, 0, 0, ref tileLight, tileDrawing._rand.NextBool(4)); + tileLight = tileDrawing.DrawTiles_GetLightOverride(tilePos.X, tilePos.Y, tile, Type, 0, 0, tileLight); + + var frame = new Rectangle(0, 26, 182, 142); + var origin = new Vector2(88, 140); + var offset = new Vector2(0, 12); + var tileBelow = TileUtils.SafeGetTile(tilePos + new Point(0, 1)); + if (tileBelow.IsHalfBlock) + { + offset.Y += 8; + } + switch (TileUtils.GetFixedRandomNumber(tilePos, 2)) + { + case 0: + frame = new Rectangle(18, 28, 278, 96); + origin = new Vector2(151, 86); + break; + case 1: + frame = new Rectangle(312, 12, 302, 110); + origin = new Vector2(192, 83); + break; + } + if (rotation > 0.02f) + { + GenerateDust(tilePos.X, tilePos.Y, origin, frame); + } + + TileUtils.VertexDraw_Grid(drawCenterPos + offset, frame, origin, tex, spriteBatch, rotation); + } + + public void GenerateDust(int i, int j, Vector2 origin, Rectangle frame) + { + if (!Main.gamePaused) + { + if (Main.rand.NextBool(8)) + { + Point tilePos = new Point(i, j); + int style = TileUtils.GetFixedRandomNumber(tilePos, 2); + var petal = new PeachBlossom + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = tilePos.ToWorldCoordinates(), + MaxTime = 3600, + Scale = Main.rand.NextFloat(0.8f, 1.2f), + Frame = Main.rand.Next(10), + ai = new float[] { Main.rand.NextFloat(1f, 8f), -1 }, + }; + petal.Position += new Vector2(Main.rand.NextFloat(frame.Width), Main.rand.NextFloat(frame.Height * 0.3f) + frame.Height * 0.3f) - origin; + Ins.VFXManager.Add(petal); + } + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_large.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_large.png new file mode 100644 index 000000000..427be1b27 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_large.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_medium.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_medium.cs new file mode 100644 index 000000000..4b0948b1e --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_medium.cs @@ -0,0 +1,144 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Terraria.DataStructures; +using Terraria.GameContent.Drawing; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +public class IslePeachTree_wall_medium : ModTile, ITileFluentlyDrawn +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + Main.tileAxe[Type] = true; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 1; + TileObjectData.newTile.Width = 1; + TileObjectData.newTile.AnchorBottom = AnchorData.Empty; + TileObjectData.newTile.AnchorWall = true; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(205, 101, 147)); + HitSound = SoundID.Dig; + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + return false; + } + + public override void RandomUpdate(int i, int j) + { + var petal = new PeachBlossom + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = new Vector2(i, j).ToWorldCoordinates() + new Vector2(0, Main.rand.NextFloat()).RotatedByRandom(MathHelper.TwoPi) * 120 + new Vector2(0, -60), + MaxTime = 3600, + Scale = Main.rand.NextFloat(1f, 1.5f), + Frame = Main.rand.Next(10), + ai = new float[] { Main.rand.NextFloat(1f, 8f), -1 }, + }; + Ins.VFXManager.Add(petal); + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + DrawPeachTree(pos, pos.ToWorldCoordinates() - screenPosition, spriteBatch, tileDrawing); + } + + /// + /// Draw a piece of peach blossom + /// + private void DrawPeachTree(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + var tile = TileUtils.SafeGetTile(tilePos); + Texture2D tex; + + // 回声涂料 + if (!TileDrawing.IsVisible(tile)) + { + return; + } + + int paint = Main.tile[tilePos].TileColor; + tex = PaintedTextureSystem.TryGetPaintedTexture(ModAsset.IslePeachTree_wall_medium_Path, Type, 1, paint, tileDrawing); + tex ??= ModAsset.IslePeachTree_wall_medium.Value; + + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(tilePos.X, tilePos.Y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(tilePos.X, tilePos.Y, tileDrawing._sunflowerWindCounter) * 0.25f; + } + + int totalPushTime = 140; + float pushForcePerFrame = 0.96f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X - 4, tilePos.Y - 1, 8, 3, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + windCycle += highestWindGridPushComplex * 0.25f; + float rotation = windCycle * 0.2f; + + var tileLight = Lighting.GetColor(tilePos); + + // 支æŒå‘光涂料 + tileDrawing.DrawAnimatedTile_AdjustForVisionChangers(tilePos.X, tilePos.Y, tile, Type, 0, 0, ref tileLight, tileDrawing._rand.NextBool(4)); + tileLight = tileDrawing.DrawTiles_GetLightOverride(tilePos.X, tilePos.Y, tile, Type, 0, 0, tileLight); + + var frame = new Rectangle(0, 26, 182, 142); + var origin = new Vector2(88, 140); + var offset = new Vector2(0, 12); + var tileBelow = TileUtils.SafeGetTile(tilePos + new Point(0, 1)); + if (tileBelow.IsHalfBlock) + { + offset.Y += 8; + } + switch (TileUtils.GetFixedRandomNumber(tilePos, 2)) + { + case 0: + frame = new Rectangle(12, 6, 138, 46); + origin = new Vector2(91, 36); + break; + case 1: + frame = new Rectangle(166, 12, 130, 40); + origin = new Vector2(68, 34); + break; + } + if (rotation > 0.02f) + { + GenerateDust(tilePos.X, tilePos.Y, origin, frame); + } + TileUtils.VertexDraw_Grid(drawCenterPos + offset, frame, origin, tex, spriteBatch, rotation); + } + public void GenerateDust(int i, int j, Vector2 origin, Rectangle frame) + { + if (!Main.gamePaused) + { + if (Main.rand.NextBool(12)) + { + Point tilePos = new Point(i, j); + int style = TileUtils.GetFixedRandomNumber(tilePos, 2); + var petal = new PeachBlossom + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = tilePos.ToWorldCoordinates(), + MaxTime = 3600, + Scale = Main.rand.NextFloat(0.8f, 1.2f), + Frame = Main.rand.Next(10), + ai = new float[] { Main.rand.NextFloat(1f, 8f), -1 }, + }; + petal.Position += new Vector2(Main.rand.NextFloat(frame.Width), Main.rand.NextFloat(frame.Height * 0.3f) + frame.Height * 0.3f) - origin; + Ins.VFXManager.Add(petal); + } + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_medium.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_medium.png new file mode 100644 index 000000000..8da9b3679 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_medium.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_small.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_small.cs new file mode 100644 index 000000000..7ed8a2ec5 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_small.cs @@ -0,0 +1,149 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Everglow.Yggdrasil.KelpCurtain.VFXs; +using Terraria.DataStructures; +using Terraria.GameContent.Drawing; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +public class IslePeachTree_wall_small : ModTile, ITileFluentlyDrawn +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileWaterDeath[Type] = false; + Main.tileAxe[Type] = true; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 1; + TileObjectData.newTile.Width = 1; + TileObjectData.newTile.AnchorBottom = AnchorData.Empty; + TileObjectData.newTile.AnchorWall = true; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = true; + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + AddMapEntry(new Color(205, 101, 147)); + HitSound = SoundID.Dig; + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + return false; + } + + public override void RandomUpdate(int i, int j) + { + var petal = new PeachBlossom + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = new Vector2(i, j).ToWorldCoordinates() + new Vector2(0, Main.rand.NextFloat()).RotatedByRandom(MathHelper.TwoPi) * 120 + new Vector2(0, -60), + MaxTime = 3600, + Scale = Main.rand.NextFloat(1f, 1.5f), + Frame = Main.rand.Next(10), + ai = new float[] { Main.rand.NextFloat(1f, 8f), -1 }, + }; + Ins.VFXManager.Add(petal); + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + DrawPeachTree(pos, pos.ToWorldCoordinates() - screenPosition, spriteBatch, tileDrawing); + } + + /// + /// Draw a piece of peach blossom + /// + private void DrawPeachTree(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + var tile = TileUtils.SafeGetTile(tilePos); + Texture2D tex; + + // 回声涂料 + if (!TileDrawing.IsVisible(tile)) + { + return; + } + + int paint = Main.tile[tilePos].TileColor; + tex = PaintedTextureSystem.TryGetPaintedTexture(ModAsset.IslePeachTree_wall_small_Path, Type, 1, paint, tileDrawing); + tex ??= ModAsset.IslePeachTree_wall_small.Value; + + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(tilePos.X, tilePos.Y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(tilePos.X, tilePos.Y, tileDrawing._sunflowerWindCounter) * 0.25f; + } + + int totalPushTime = 140; + float pushForcePerFrame = 0.96f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X - 2, tilePos.Y - 1, 5, 2, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + windCycle += highestWindGridPushComplex * 0.25f; + float rotation = windCycle * 0.2f; + + var tileLight = Lighting.GetColor(tilePos); + + // 支æŒå‘光涂料 + tileDrawing.DrawAnimatedTile_AdjustForVisionChangers(tilePos.X, tilePos.Y, tile, Type, 0, 0, ref tileLight, tileDrawing._rand.NextBool(4)); + tileLight = tileDrawing.DrawTiles_GetLightOverride(tilePos.X, tilePos.Y, tile, Type, 0, 0, tileLight); + + var frame = new Rectangle(0, 26, 182, 142); + var origin = new Vector2(88, 140); + var offset = new Vector2(0, 12); + var tileBelow = TileUtils.SafeGetTile(tilePos + new Point(0, 1)); + if (tileBelow.IsHalfBlock) + { + offset.Y += 8; + } + switch (TileUtils.GetFixedRandomNumber(tilePos, 3)) + { + case 0: + frame = new Rectangle(8, 12, 88, 36); + origin = new Vector2(53, 30); + break; + case 1: + frame = new Rectangle(112, 4, 98, 52); + origin = new Vector2(64, 42); + break; + case 2: + frame = new Rectangle(218, 14, 84, 38); + origin = new Vector2(61, 36); + break; + } + if (rotation > 0.02f) + { + GenerateDust(tilePos.X, tilePos.Y, origin, frame); + } + TileUtils.VertexDraw_Grid(drawCenterPos + offset, frame, origin, tex, spriteBatch, rotation); + } + + public void GenerateDust(int i, int j, Vector2 origin, Rectangle frame) + { + if (!Main.gamePaused) + { + if (Main.rand.NextBool(12)) + { + Point tilePos = new Point(i, j); + int style = TileUtils.GetFixedRandomNumber(tilePos, 2); + var petal = new PeachBlossom + { + Velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2), + Active = true, + Visible = true, + Position = tilePos.ToWorldCoordinates(), + MaxTime = 3600, + Scale = Main.rand.NextFloat(0.8f, 1.2f), + Frame = Main.rand.Next(10), + ai = new float[] { Main.rand.NextFloat(1f, 8f), -1 }, + }; + petal.Position += new Vector2(Main.rand.NextFloat(frame.Width), Main.rand.NextFloat(frame.Height * 0.3f) + frame.Height * 0.3f) - origin; + Ins.VFXManager.Add(petal); + } + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_small.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_small.png new file mode 100644 index 000000000..15e4a889b Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/IslePeachTree_wall_small.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/MossyDockWood.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/MossyDockWood.cs new file mode 100644 index 000000000..a18b7b7b9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/MossyDockWood.cs @@ -0,0 +1,38 @@ +using Everglow.Yggdrasil.KelpCurtain.Dusts; + +namespace Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; + +public class MossyDockWood : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileSolid[Type] = true; + Main.tileMergeDirt[Type] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[ModContent.TileType()][Type] = true; + Main.tileNoSunLight[Type] = true; + Main.tileBlockLight[Type] = true; + DustType = ModContent.DustType(); + AddMapEntry(new Color(109, 67, 55)); + } + + public override bool CanExplode(int i, int j) + { + var tileTop = Main.tile[i, j - 1]; + if (tileTop.HasTile && tileTop.TileType == ModContent.TileType()) + { + return false; + } + return base.CanExplode(i, j); + } + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + var tileTop = Main.tile[i, j - 1]; + if (tileTop.HasTile && tileTop.TileType == ModContent.TileType()) + { + noBreak = true; + } + return base.TileFrame(i, j, ref resetFrame, ref noBreak); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/MossyDockWood.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/MossyDockWood.png new file mode 100644 index 000000000..aac4e0ae5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/MossyDockWood.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/peach.pdn b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/peach.pdn new file mode 100644 index 000000000..1c43ebff2 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/IsleOfBloom/peach.pdn differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss.cs index a1e1f6697..94b7eb7c8 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss.cs @@ -1,8 +1,11 @@ +using Everglow.Commons.DataStructures; +using Everglow.Commons.TileHelper; using Everglow.Yggdrasil.KelpCurtain.Dusts; +using Terraria.GameContent.Drawing; namespace Everglow.Yggdrasil.KelpCurtain.Tiles; -public class KelpMoss : ModTile +public class KelpMoss : ModTile, ITileFluentlyDrawn { public override void PostSetDefaults() { @@ -13,15 +16,17 @@ public override void PostSetDefaults() Main.tileCut[Type] = true; AddMapEntry(new Color(36, 86, 19)); HitSound = SoundID.Grass; - } + public override void PlaceInWorld(int i, int j, Item item) { } + public override IEnumerable GetItemDrops(int i, int j) { yield break; } + public override void RandomUpdate(int i, int j) { int deltaY = 0; @@ -44,16 +49,21 @@ public override void RandomUpdate(int i, int j) { tileBelow.TileType = Type; tileBelow.HasTile = true; + // 与原版一致,漆与涂料继承 tileBelow.CopyPaintAndCoating(Main.tile[i, j]); + // frameè°ƒæ•´ä¸Žè”æœºåŒæ­¥ WorldGen.SquareTileFrame(i, j + 1); if (Main.netMode is NetmodeID.Server) + { NetMessage.SendTileSquare(-1, i, j + 1); + } } } base.RandomUpdate(i, j); } + public override void KillTile(int i, int j, ref bool fail, ref bool effectOnly, ref bool noItem) { base.KillTile(i, j, ref fail, ref effectOnly, ref noItem); @@ -61,18 +71,123 @@ public override void KillTile(int i, int j, ref bool fail, ref bool effectOnly, public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) { - Main.instance.TilesRenderer.CrawlToTopOfVineAndAddSpecialPoint(j, i); + if (Main.tile[i, j - 1].TileType != Type) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + } return false; } - public override void SetDrawPositions(int i, int j, ref int width, ref int offsetY, ref int height, ref short tileFrameX, ref short tileFrameY) + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) { - offsetY = -2; + DrawAlgae(pos, pos.ToWorldCoordinates() - screenPosition, spriteBatch, tileDrawing); } - public override void SetSpriteEffects(int i, int j, ref SpriteEffects spriteEffects) + /// + /// Vanilla function. + /// + /// + /// + /// + /// + /// + private void DrawAlgae(Point tilePos, Vector2 drawCenterPos, SpriteBatch spriteBatch, TileDrawing tileDrawing) { - if (i % 2 == 0) - spriteEffects = SpriteEffects.FlipHorizontally; + int maxCount = 40; + Vector2 lastSegmentPos = drawCenterPos - new Vector2(0, 24); + float lastRot = 0; + int xStyle = TileUtils.GetFixedRandomNumber_SingleSeed(tilePos.X, 3); + Rectangle lastFrame = new Rectangle(xStyle * 34, 0, 32, 16); + bool tail = false; + Texture2D dropTex = ModAsset.KelpMoss.Value; + float displacement = 0; + for (int t = 0; t < maxCount; t++) + { + var tile = TileUtils.SafeGetTile(tilePos + new Point(0, t)); + if (tile.TileType != Type) + { + break; + } + int paint = tile.TileColor; + Texture2D tex = PaintedTextureSystem.TryGetPaintedTexture(ModAsset.KelpMoss_Path, Type, 1, paint, tileDrawing); + tex ??= ModAsset.KelpMoss.Value; + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(tilePos.X, tilePos.Y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(tilePos.X, tilePos.Y + t, tileDrawing._sunflowerWindCounter); + } + + int totalPushTime = 140; + float pushForcePerFrame = 0.96f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(tilePos.X, tilePos.Y + t, 1, 1, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + windCycle += highestWindGridPushComplex; + float rotation = -windCycle * 0.21f + displacement * 0.015f; + var tileLight = Lighting.GetColor(tilePos + new Point(0, t)); + tileDrawing.DrawAnimatedTile_AdjustForVisionChangers(tilePos.X, tilePos.Y - t, tile, Type, 0, 0, ref tileLight, tileDrawing._rand.NextBool(4)); + tileLight = tileDrawing.DrawTiles_GetLightOverride(tilePos.X, tilePos.Y - t, tile, Type, 0, 0, tileLight); + var origin = new Vector2(16, 0); + spriteBatch.Draw(tex, lastSegmentPos, lastFrame, tileLight, rotation, origin, 1f, SpriteEffects.None, 0); + lastRot = rotation; + Vector2 bone = new Vector2(0, 16).RotatedBy(lastRot); + lastSegmentPos += bone; + displacement += bone.X; + var tileBelow4 = TileUtils.SafeGetTile(tilePos + new Point(0, t + 4)); + if ((!tileBelow4.HasTile || tileBelow4.TileType != Type) && !tail) + { + lastFrame.Y = 136; + for (int j = 1; j <= 3; j++) + { + var tileBelow_j = TileUtils.SafeGetTile(tilePos + new Point(0, t + j)); + if (!tileBelow_j.HasTile || tileBelow_j.TileType != Type) + { + lastFrame.Y += (4 - j) * 16; + break; + } + } + tail = true; + } + if (tail) + { + lastFrame.Y += 16; + } + else + { + if (lastFrame.Y % 34 == 0) + { + lastFrame.Y += 16; + } + else + { + lastFrame.Y = TileUtils.GetFixedRandomNumber(t + tilePos.Y, tilePos.X, 3) * 34 + 34; + } + } + } + Vector2 dropOffset = new Vector2(0); + switch (xStyle) + { + case 0: + dropOffset = new Vector2(3, 0); + break; + case 1: + dropOffset = new Vector2(1, 0); + break; + case 2: + dropOffset = new Vector2(-1, 0); + break; + } + + Vector2 worldPos_drop = lastSegmentPos + Main.screenPosition + dropOffset.RotatedBy(lastRot); + float dropValue = (TileUtils.GetFixedRandomNumber(tilePos, 600) + (int)Main.time) % 600 - 300; + if (dropValue < 0) + { + dropValue = 0; + } + if (dropValue == 299 && !Main.gamePaused) + { + Dust.NewDustPerfect(worldPos_drop, ModContent.DustType(), Vector2.zeroVector); + } + dropValue *= 2.5f / 600f; + var dropLight = Lighting.GetColor(worldPos_drop.ToTileCoordinates()) * dropValue; + spriteBatch.Draw(dropTex, lastSegmentPos + dropOffset.RotatedBy(lastRot), new Rectangle(0, 206, 2, 2), dropLight, 0, new Vector2(1), 1f, SpriteEffects.None, 0); } } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss.png index 5f541f606..62d6499a6 100644 Binary files a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss.png and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss_large.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss_large.cs index e16406388..8ae3fd141 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss_large.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss_large.cs @@ -3,11 +3,12 @@ namespace Everglow.Yggdrasil.KelpCurtain.Tiles; -public class KelpMoss_large_fore : ForegroundVFX +public class KelpMoss_large_fore : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; public override void OnSpawn() { - texture = ModAsset.KelpMoss_large.Value; + Texture = ModAsset.KelpMoss_large.Value; } public override void Update() @@ -20,13 +21,13 @@ public override void Update() { if (i >= wigglerOmegas.Count) { - wigglerOmegas.Add(MathF.Sin(position.X + position.Y + i * 0.4f + (float)Main.time * 0.05f) * 0.03f); + wigglerOmegas.Add(MathF.Sin(Position.X + Position.Y + i * 0.4f + (float)Main.time * 0.05f) * 0.03f); } else { wigglerRotations[i] += wigglerOmegas[i]; wigglerOmegas[i] *= 0.9f; - wigglerOmegas[i] += MathF.Sin(position.X + position.Y + i * 0.4f + (float)Main.time * 0.05f) * 0.0005f - Main.windSpeedCurrent * 0.001f / wigglerRotations.Count; + wigglerOmegas[i] += MathF.Sin(Position.X + Position.Y + i * 0.4f + (float)Main.time * 0.05f) * 0.0005f - Main.windSpeedCurrent * 0.001f / wigglerRotations.Count; wigglerRotations[i] = wigglerRotations[i] * 0.9f + startRotation * MathF.Pow(0.7f, i) * 0.1f; } } @@ -46,9 +47,9 @@ private static Color GetPosLight(Vector2 worldCoord) public override void Draw() { - Vector2 pos0 = position + unit.RotatedBy(startRotation + MathHelper.PiOver2) * scale; - Vector2 pos1 = position - unit.RotatedBy(startRotation + MathHelper.PiOver2) * scale; - Vector2 centerPos = position; + Vector2 pos0 = Position + unit.RotatedBy(startRotation + MathHelper.PiOver2) * scale; + Vector2 pos1 = Position - unit.RotatedBy(startRotation + MathHelper.PiOver2) * scale; + Vector2 centerPos = Position; List bars = new List() { new Vertex2D(pos0, GetPosLight(pos0), new Vector3(0, 0, 1)), @@ -68,6 +69,6 @@ public override void Draw() Vector2 pos5 = centerPos - unit.RotatedBy(MathHelper.PiOver2) * scale; bars.Add(pos4, GetPosLight(pos4), new Vector3(0, 1, 0)); bars.Add(pos5, GetPosLight(pos5), new Vector3(1, 1, 0)); - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleStrip); } } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss_large_tile.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss_large_tile.cs index 415d720b4..7636cc188 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss_large_tile.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/KelpMoss_large_tile.cs @@ -21,14 +21,14 @@ public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) } public void AddScene(int i, int j) { - KelpMoss_large_fore kelp = new KelpMoss_large_fore { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = ModContent.TileType() }; + KelpMoss_large_fore kelp = new KelpMoss_large_fore { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = ModContent.TileType() }; kelp.startRotation = GetNeighborTileRotation(new Vector2(i * 16, j * 16)); for (int x = 0; x < Main.rand.Next(4, 125); x++) { kelp.wigglerRotations.Add(kelp.startRotation * MathF.Pow(0.7f, x)); } kelp.scale = Main.rand.NextFloat(45f, 80f); - kelp.position -= new Vector2(0, 12).RotatedBy(kelp.startRotation) - new Vector2(8); + kelp.Position -= new Vector2(0, 12).RotatedBy(kelp.startRotation) - new Vector2(8); Ins.VFXManager.Add(kelp); } private static float GetNeighborTileRotation(Vector2 worldCoord) diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/SucculentHerb_type0.png b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/SucculentHerb_type0.png index f54dcecdb..3e19beea5 100644 Binary files a/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/SucculentHerb_type0.png and b/Sources/Modules/Yggdrasil/KelpCurtain/Tiles/SucculentHerb_type0.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Branch.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Branch.cs new file mode 100644 index 000000000..eaf24424a --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Branch.cs @@ -0,0 +1,67 @@ +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +[Pipeline(typeof(WCSPipeline))] +public class ActivatedDogStaff_Branch : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawProjectiles; + + public Projectile ParentEneity; + public Vector2 Position; + public Vector2 Velocity; + public float[] ai; + public float Timer; + public float MaxTime; + public float Scale; + public float MaxScale; + public float Rotation; + public float Fade = 1f; + public int Frame = 0; + + public override void Update() + { + Timer++; + if (Timer > MaxTime) + { + Active = false; + } + if (MaxTime - Timer < 10) + { + Fade *= 0.9f; + } + + Vector2 toTarget = ParentEneity.Center - Position; + float distanceValue = toTarget.Length(); + float power = 25f / (distanceValue + 1f); + float vortexEyeRadius = ParentEneity.timeLeft; + if (ParentEneity.active == false || (ParentEneity.Center - Position).Length() > 100) + { + vortexEyeRadius = 1; + } + float deviate = vortexEyeRadius / (distanceValue + 1f) * MathHelper.PiOver2; + Vector2 acclerate = toTarget.NormalizeSafe().RotatedBy(deviate) * power; + Velocity *= 0.9f; + Velocity += acclerate; + + Position += Velocity; + Rotation += MathF.Sin(ai[0]) * 0.05f; + } + + public override void Draw() + { + float frameCount = 5; + float frameY = Frame; + Vector2 toCorner = new Vector2(0, Scale).RotatedBy(Rotation); + Color drawColor = Lighting.GetColor(Position.ToTileCoordinates()) * Fade; + var bars = new List() + { + new Vertex2D(Position + toCorner, drawColor, new Vector3(0, frameY / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 0.5), drawColor, new Vector3(1, frameY / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 1.5), drawColor, new Vector3(0, (frameY + 1) / frameCount, 0)), + + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 1.5), drawColor, new Vector3(0, (frameY + 1) / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 0.5), drawColor, new Vector3(1, frameY / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 1), drawColor, new Vector3(1, (frameY + 1) / frameCount, 0)), + }; + Ins.Batch.Draw(ModAsset.ActivatedDogStaff_Branch.Value, bars, PrimitiveType.TriangleList); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Branch.png b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Branch.png new file mode 100644 index 000000000..067b2e759 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Branch.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Branch_physical.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Branch_physical.cs new file mode 100644 index 000000000..2032e0a43 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Branch_physical.cs @@ -0,0 +1,57 @@ +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +[Pipeline(typeof(WCSPipeline))] +public class ActivatedDogStaff_Branch_physical : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawProjectiles; + + public Vector2 Position; + public Vector2 Velocity; + public float[] ai; + public float Timer; + public float MaxTime; + public float Scale; + public float MaxScale; + public float Rotation; + public float Fade = 1f; + public int Frame = 0; + + public override void Update() + { + Timer++; + if (Timer > MaxTime) + { + Active = false; + } + if (MaxTime - Timer < 10) + { + Fade *= 0.9f; + } + + Vector2 acclerate = new Vector2(0, 0.3f); + Velocity *= 0.98f; + Velocity += acclerate; + + Position += Velocity; + Rotation += MathF.Sin(ai[0]) * 0.05f; + } + + public override void Draw() + { + float frameCount = 5; + float frameY = Frame; + Vector2 toCorner = new Vector2(0, Scale).RotatedBy(Rotation); + Color drawColor = Lighting.GetColor(Position.ToTileCoordinates()) * Fade; + var bars = new List() + { + new Vertex2D(Position + toCorner, drawColor, new Vector3(0, frameY / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 0.5), drawColor, new Vector3(1, frameY / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 1.5), drawColor, new Vector3(0, (frameY + 1) / frameCount, 0)), + + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 1.5), drawColor, new Vector3(0, (frameY + 1) / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 0.5), drawColor, new Vector3(1, frameY / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 1), drawColor, new Vector3(1, (frameY + 1) / frameCount, 0)), + }; + Ins.Batch.Draw(ModAsset.ActivatedDogStaff_Branch.Value, bars, PrimitiveType.TriangleList); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Leaf.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Leaf.cs new file mode 100644 index 000000000..8167561ff --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Leaf.cs @@ -0,0 +1,77 @@ +using Terraria.Map; + +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +[Pipeline(typeof(WCSPipeline))] +public class ActivatedDogStaff_Leaf : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawProjectiles; + + public Projectile ParentEneity; + public Vector2 Position; + public Vector2 Velocity; + public float[] ai; + public float Timer; + public float MaxTime; + public float Scale; + public float Rotation; + public float Fade = 1f; + + public override void Update() + { + Timer++; + if (Timer > MaxTime) + { + Active = false; + } + if (MaxTime - Timer < 10) + { + Fade *= 0.9f; + } + if (ai[1] < 0) + { + Velocity *= 0.9f; + Velocity.Y += 0.10f; + } + if (ParentEneity is null) + { + return; + } + + Vector2 toTarget = ParentEneity.Center - Position; + float distanceValue = toTarget.Length(); + float power = 25f / (distanceValue + 1f); + float vortexEyeRadius = ParentEneity.timeLeft; + if (ParentEneity.active == false || (ParentEneity.Center - Position).Length() > 100) + { + vortexEyeRadius = 1; + } + float deviate = vortexEyeRadius / (distanceValue + 1f) * MathHelper.PiOver2; + Vector2 acclerate = toTarget.NormalizeSafe().RotatedBy(deviate) * power; + Velocity *= 0.9f; + Velocity += acclerate; + + Position += Velocity; + Rotation += MathF.Sin(ai[0]) * 0.05f; + } + + public override void Draw() + { + float timeValue = (float)(Main.time * 0.24 + ai[0]); + float frameCount = 8; + float frameY = (int)timeValue % frameCount; + Vector2 toCorner = new Vector2(0, Scale).RotatedBy(Rotation); + Color drawColor = Lighting.GetColor(Position.ToTileCoordinates()) * Fade; + var bars = new List() + { + new Vertex2D(Position + toCorner, drawColor, new Vector3(0, frameY / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 0.5), drawColor, new Vector3(1, frameY / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 1.5), drawColor, new Vector3(0, (frameY + 1) / frameCount, 0)), + + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 1.5), drawColor, new Vector3(0, (frameY + 1) / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 0.5), drawColor, new Vector3(1, frameY / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 1), drawColor, new Vector3(1, (frameY + 1) / frameCount, 0)), + }; + Ins.Batch.Draw(ModAsset.ActivatedDogStaff_Leaf.Value, bars, PrimitiveType.TriangleList); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Leaf.png b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Leaf.png new file mode 100644 index 000000000..281b301d1 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Leaf.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Leaf_physical.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Leaf_physical.cs new file mode 100644 index 000000000..e21efb6ae --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_Leaf_physical.cs @@ -0,0 +1,63 @@ +using Terraria.Map; + +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +[Pipeline(typeof(WCSPipeline))] +public class ActivatedDogStaff_Leaf_physical : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawProjectiles; + + public Vector2 Position; + public Vector2 Velocity; + public float[] ai; + public float Timer; + public float MaxTime; + public float Scale; + public float Rotation; + public float Fade = 1f; + + public override void Update() + { + Timer++; + if (Timer > MaxTime) + { + Active = false; + } + if (MaxTime - Timer < 10) + { + Fade *= 0.9f; + } + if (ai[1] < 0) + { + Velocity *= 0.9f; + Velocity.Y += 0.10f; + } + + Vector2 acclerate = new Vector2(Main.windSpeedCurrent * 0.05f, 0.1f); + Velocity *= 0.95f; + Velocity += acclerate; + + Position += Velocity; + Rotation += MathF.Sin(ai[0]) * 0.05f; + } + + public override void Draw() + { + float timeValue = (float)(Main.time * 0.24 + ai[0]); + float frameCount = 8; + float frameY = (int)timeValue % frameCount; + Vector2 toCorner = new Vector2(0, Scale).RotatedBy(Rotation); + Color drawColor = Lighting.GetColor(Position.ToTileCoordinates()) * Fade; + var bars = new List() + { + new Vertex2D(Position + toCorner, drawColor, new Vector3(0, frameY / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 0.5), drawColor, new Vector3(1, frameY / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 1.5), drawColor, new Vector3(0, (frameY + 1) / frameCount, 0)), + + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 1.5), drawColor, new Vector3(0, (frameY + 1) / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 0.5), drawColor, new Vector3(1, frameY / frameCount, 0)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 1), drawColor, new Vector3(1, (frameY + 1) / frameCount, 0)), + }; + Ins.Batch.Draw(ModAsset.ActivatedDogStaff_Leaf.Value, bars, PrimitiveType.TriangleList); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_green_Dust_Trail.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_green_Dust_Trail.cs new file mode 100644 index 000000000..1cc46b957 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/ActivatedDogStaff_green_Dust_Trail.cs @@ -0,0 +1,75 @@ +using Everglow.Commons.Graphics; + +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +[Pipeline(typeof(WCSPipeline))] +public class ActivatedDogStaff_green_Dust_Trail : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawDusts; + + public Vector2 position; + public Vector2 velocity; + public float[] ai; + public float timer; + public float maxTime; + public float scale; + public float rotation; + public Queue trails = new Queue(); + + public override void Update() + { + if (position.X <= 320 || position.X >= Main.maxTilesX * 16 - 320) + { + timer = maxTime; + Active = false; + return; + } + if (position.Y <= 320 || position.Y >= Main.maxTilesY * 16 - 320) + { + timer = maxTime; + Active = false; + return; + } + trails.Enqueue(position); + if (trails.Count > 40) + { + trails.Dequeue(); + } + velocity += new Vector2(0, 0.2f); + position += velocity; + velocity *= 0.95f; + scale *= 0.96f; + timer++; + if (timer > maxTime) + { + Active = false; + } + } + + public override void Draw() + { + GradientColor gradientColor = new GradientColor(); + gradientColor.colorList.Add((new Color(89, 255, 122, 0), 0)); + gradientColor.colorList.Add((new Color(6, 132, 0, 0), 0.2f)); + gradientColor.colorList.Add((new Color(0, 0, 0, 0), 1)); + + var toCorner = new Vector2(0, scale); + var bars = new List(); + for (int i = 0; i < trails.Count; i++) + { + Color drawColor = gradientColor.GetColor((1 - i / (float)trails.Count) + timer / maxTime); + Vector2 pos = trails.ToArray()[i]; + float size = i / (float)trails.Count; + bars.Add(pos + toCorner.RotatedBy(Math.PI * 1 + rotation) * size, drawColor, new Vector3(1, 0, 0)); + bars.Add(pos + toCorner.RotatedBy(Math.PI * 0.5 + rotation) * size, drawColor, new Vector3(0, 0, 0)); + bars.Add(pos + toCorner.RotatedBy(Math.PI * 0 + rotation) * size, drawColor, new Vector3(0, 1, 0)); + + bars.Add(pos + toCorner.RotatedBy(Math.PI * -0.5 + rotation) * size, drawColor, new Vector3(1, 1, 0)); + bars.Add(pos + toCorner.RotatedBy(Math.PI * 0 + rotation) * size, drawColor, new Vector3(0, 1, 0)); + bars.Add(pos + toCorner.RotatedBy(Math.PI * 1 + rotation) * size, drawColor, new Vector3(1, 0, 0)); + } + Ins.Batch.Draw(ModAsset.BloodFlame_noise.Value, bars, PrimitiveType.TriangleList); + Color lightColor = gradientColor.GetColor(timer / maxTime); + Lighting.AddLight(position, new Vector3(lightColor.R, lightColor.G, lightColor.B) / 255f * scale * 0.1f); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/BambooLeaf.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/BambooLeaf.cs new file mode 100644 index 000000000..2349b0d22 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/BambooLeaf.cs @@ -0,0 +1,66 @@ +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +[Pipeline(typeof(WCSPipeline))] +public class BambooLeaf : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawProjectiles; + + public Vector2 Position; + public Vector2 Velocity; + public float[] ai; + public float Timer; + public float MaxTime; + public float Scale; + public float Rotation; + public float FlipAngle; + public float FlipSpeed; + public float Fade = 1f; + public int Frame; + + public override void Update() + { + Timer++; + if (Timer > MaxTime) + { + Active = false; + } + if (MaxTime - Timer < 60) + { + Fade = (MaxTime - Timer) / 60f; + } + Velocity *= 0.9f; + Velocity += new Vector2(Main.windSpeedCurrent * 0.3f, 0.1f); + Velocity = Velocity.RotatedBy(MathF.Sin((float)Main.time * 0.03f + ai[0]) * 0.05f); + if (Collision.IsWorldPointSolid(Position)) + { + Rotation = 0; + Velocity *= 0; + if (MaxTime - Timer > 60) + { + Timer = MaxTime - 60; + } + } + else if (TileUtils.SafeGetTile(Position.ToTileCoordinates()).LiquidAmount > 0) + { + Rotation = 0; + Velocity *= 0; + Position.Y = Position.ToTileCoordinates().ToWorldCoordinates().Y + TileUtils.SafeGetTile(Position.ToTileCoordinates()).LiquidAmount / 255f; + if (MaxTime - Timer > 60) + { + Timer = MaxTime - 60; + } + } + else + { + Position += Velocity; + } + Rotation = MathF.Sin(ai[0]) * 0.5f; + FlipAngle += FlipSpeed; + } + + public override void Draw() + { + Rectangle frame = new Rectangle(0, Frame * 8, 28, 8); + Ins.Batch.Draw(ModAsset.BambooLeaf.Value, Position, frame, Lighting.GetColor(Position.ToTileCoordinates()) * Fade, Rotation, frame.Size() * 0.5f, new Vector2(1, MathF.Cos(FlipAngle)) * Scale, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/BambooLeaf.png b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/BambooLeaf.png new file mode 100644 index 000000000..ba3a263a8 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/BambooLeaf.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/BarnacleTissueDust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/BarnacleTissueDust.cs new file mode 100644 index 000000000..f1641ce09 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/BarnacleTissueDust.cs @@ -0,0 +1,76 @@ +using Spine; + +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +[Pipeline(typeof(WCSPipeline))] +public class BarnacleTissueDust : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawDusts; + + public Vector2 position; + public Vector2 velocity; + public float[] ai; + public float timer; + public float maxTime; + public float scale; + public float rotation; + public Queue trails = new Queue(); + + public override void Update() + { + if (position.X <= 320 || position.X >= Main.maxTilesX * 16 - 320) + { + timer = maxTime; + Active = false; + return; + } + if (position.Y <= 320 || position.Y >= Main.maxTilesY * 16 - 320) + { + timer = maxTime; + Active = false; + return; + } + trails.Enqueue(position); + if (trails.Count > 6) + { + trails.Dequeue(); + } + position += velocity; + velocity *= 0.95f; + scale *= 0.96f; + timer++; + if (timer > maxTime) + { + Active = false; + } + Lighting.AddLight(position, scale * 0.016f, scale * 0.0004f, scale * 0.008f); + } + + public override void Draw() + { + var lightColor = new Color(1f, 0.18f, 0.12f, 0f); + float timeValue = (float)Main.time * 0.07f + ai[1]; + var bars = new List(); + if (trails.Count <= 2) + { + bars.Add(position, Color.Transparent, new Vector3(timeValue, 0, 0)); + bars.Add(position, Color.Transparent, new Vector3(timeValue, 1, 0)); + bars.Add(position, Color.Transparent, new Vector3(timeValue, 0, 0)); + bars.Add(position, Color.Transparent, new Vector3(timeValue, 1, 0)); + } + else + { + for (int i = 0; i < trails.Count - 1; i++) + { + Vector2 pos = trails.ToArray()[i]; + Vector2 dir = pos - trails.ToArray()[i + 1]; + dir = dir.NormalizeSafe(); + float size = i / (float)trails.Count; + bars.Add(pos + dir.RotatedBy(MathHelper.PiOver2) * scale, lightColor * size, new Vector3(i / 12f + timeValue, 0, 0)); + bars.Add(pos + dir.RotatedBy(-MathHelper.PiOver2) * scale, lightColor * size, new Vector3(i / 12f + timeValue, 1, 0)); + } + } + Ins.Batch.Draw(ModAsset.BarnacleTissueDust.Value, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(ModAsset.BarnacleTissueDust.Value, bars, PrimitiveType.TriangleStrip); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/BarnacleTissueDust.png b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/BarnacleTissueDust.png new file mode 100644 index 000000000..3f927ba5e Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/BarnacleTissueDust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/DevilHeart_Spark_II.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/DevilHeart_Spark_II.cs index 02c233e03..feeb468fd 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/DevilHeart_Spark_II.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/DevilHeart_Spark_II.cs @@ -18,6 +18,17 @@ public class DevilHeart_Spark_II : Visual public GradientColor dHSparkColor = new(); + public void FillGradientColor() + { + dHSparkColor.colorList.Add((new Color(191, 241, 255, 250), 0)); + dHSparkColor.colorList.Add((new Color(221, 155, 255, 250), 0.08f)); + dHSparkColor.colorList.Add((new Color(225, 68, 223, 250), 0.18f)); + dHSparkColor.colorList.Add((new Color(155, 0, 130, 250), 0.24f)); + dHSparkColor.colorList.Add((new Color(25, 0, 230, 150), 0.44f)); + dHSparkColor.colorList.Add((new Color(5, 0, 160, 150), 0.64f)); + dHSparkColor.colorList.Add((new Color(24, 24, 24, 50), 1)); + } + public override void Update() { trails.Enqueue(position); @@ -39,13 +50,7 @@ public override void Update() } if (dHSparkColor.colorList.Count <= 0) { - dHSparkColor.colorList.Add((new Color(191, 241, 255, 250), 0)); - dHSparkColor.colorList.Add((new Color(221, 155, 255, 250), 0.08f)); - dHSparkColor.colorList.Add((new Color(225, 68, 223, 250), 0.18f)); - dHSparkColor.colorList.Add((new Color(155, 0, 130, 250), 0.24f)); - dHSparkColor.colorList.Add((new Color(25, 0, 230, 150), 0.44f)); - dHSparkColor.colorList.Add((new Color(5, 0, 160, 150), 0.64f)); - dHSparkColor.colorList.Add((new Color(24, 24, 24, 50), 1)); + FillGradientColor(); } float timeLeftValue = timer / maxTime; var lightColor = new Color(221, 155, 255, 250); @@ -60,13 +65,7 @@ public override void Draw() { if (dHSparkColor.colorList.Count <= 0) { - dHSparkColor.colorList.Add((new Color(191, 241, 255, 250), 0)); - dHSparkColor.colorList.Add((new Color(221, 155, 255, 250), 0.08f)); - dHSparkColor.colorList.Add((new Color(225, 68, 223, 250), 0.18f)); - dHSparkColor.colorList.Add((new Color(155, 0, 130, 250), 0.24f)); - dHSparkColor.colorList.Add((new Color(25, 0, 230, 150), 0.44f)); - dHSparkColor.colorList.Add((new Color(5, 0, 160, 150), 0.64f)); - dHSparkColor.colorList.Add((new Color(24, 24, 24, 50), 1)); + FillGradientColor(); } var toCorner = new Vector2(0, scale); var bars = new List(); diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/EmptyWaterStaff_BubbleBreak.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/EmptyWaterStaff_BubbleBreak.cs new file mode 100644 index 000000000..6d5053974 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/EmptyWaterStaff_BubbleBreak.cs @@ -0,0 +1,69 @@ +using Everglow.Commons.Graphics; + +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +[Pipeline(typeof(WCSPipeline))] +public class EmptyWaterStaff_BubbleBreak : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawDusts; + + public Vector2 position; + public Vector2 velocity; + public float[] ai; + public float timer; + public float maxTime; + public float scale; + public float rotation; + public Queue trails = new Queue(); + + public override void Update() + { + if (position.X <= 320 || position.X >= Main.maxTilesX * 16 - 320) + { + timer = maxTime; + Active = false; + return; + } + if (position.Y <= 320 || position.Y >= Main.maxTilesY * 16 - 320) + { + timer = maxTime; + Active = false; + return; + } + trails.Enqueue(position); + if (trails.Count > 40) + { + trails.Dequeue(); + } + velocity += new Vector2(0, 0.02f); + position += velocity; + velocity *= 0.8f; + scale *= 0.96f; + timer++; + if (timer > maxTime) + { + Active = false; + } + } + + public override void Draw() + { + var toCorner = new Vector2(0, scale); + var bars = new List(); + Color drawColor = new Color(204, 238, 255); + drawColor = Lighting.GetColor(position.ToTileCoordinates(), drawColor); + for (int i = 0; i < trails.Count; i++) + { + Vector2 pos = trails.ToArray()[i]; + float size = i / (float)trails.Count; + bars.Add(pos + toCorner.RotatedBy(Math.PI * 1 + rotation) * size, drawColor * size, new Vector3(1, 0, 0)); + bars.Add(pos + toCorner.RotatedBy(Math.PI * 0.5 + rotation) * size, drawColor * size, new Vector3(0, 0, 0)); + bars.Add(pos + toCorner.RotatedBy(Math.PI * 0 + rotation) * size, drawColor * size, new Vector3(0, 1, 0)); + + bars.Add(pos + toCorner.RotatedBy(Math.PI * -0.5 + rotation) * size, drawColor * size, new Vector3(1, 1, 0)); + bars.Add(pos + toCorner.RotatedBy(Math.PI * 0 + rotation) * size, drawColor * size, new Vector3(0, 1, 0)); + bars.Add(pos + toCorner.RotatedBy(Math.PI * 1 + rotation) * size, drawColor * size, new Vector3(1, 0, 0)); + } + Ins.Batch.Draw(ModAsset.BloodFlame_noise.Value, bars, PrimitiveType.TriangleList); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/LightningDust_Trail.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/LightningDust_Trail.cs new file mode 100644 index 000000000..bcae3bb5b --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/LightningDust_Trail.cs @@ -0,0 +1,78 @@ +using Everglow.Commons.Graphics; + +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +[Pipeline(typeof(WCSPipeline))] +public class LightningDust_Trail : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawDusts; + + public Vector2 position; + public Vector2 velocity; + public float[] ai; + public float timer; + public float maxTime; + public float scale; + public float rotation; + public Queue trails = new Queue(); + + public override void Update() + { + if (position.X <= 320 || position.X >= Main.maxTilesX * 16 - 320) + { + timer = maxTime; + Active = false; + return; + } + if (position.Y <= 320 || position.Y >= Main.maxTilesY * 16 - 320) + { + timer = maxTime; + Active = false; + return; + } + trails.Enqueue(position); + if (trails.Count > 40) + { + trails.Dequeue(); + } + velocity += new Vector2(0, 0.2f); + position += velocity; + velocity *= 0.95f; + scale *= 0.96f; + timer++; + if (timer > maxTime) + { + Active = false; + } + } + + public override void Draw() + { + GradientColor gradientColor = new GradientColor(); + gradientColor.colorList.Add((new Color(1f, 1f, 1f, 0), 0)); + gradientColor.colorList.Add((new Color(140, 232, 255, 0), 0.2f)); + gradientColor.colorList.Add((new Color(252, 170, 255, 0), 0.4f)); + gradientColor.colorList.Add((new Color(255, 166, 114, 0), 0.6f)); + gradientColor.colorList.Add((new Color(255, 84, 81, 0), 0.8f)); + gradientColor.colorList.Add((new Color(0, 0, 0, 0), 1)); + + var toCorner = new Vector2(0, scale); + var bars = new List(); + for (int i = 0; i < trails.Count; i++) + { + Color drawColor = gradientColor.GetColor((1 - i / (float)trails.Count) + timer / maxTime); + Vector2 pos = trails.ToArray()[i]; + float size = i / (float)trails.Count; + bars.Add(pos + toCorner.RotatedBy(Math.PI * 1 + rotation) * size, drawColor * size, new Vector3(1, 0, 0)); + bars.Add(pos + toCorner.RotatedBy(Math.PI * 0.5 + rotation) * size, drawColor * size, new Vector3(0, 0, 0)); + bars.Add(pos + toCorner.RotatedBy(Math.PI * 0 + rotation) * size, drawColor * size, new Vector3(0, 1, 0)); + + bars.Add(pos + toCorner.RotatedBy(Math.PI * -0.5 + rotation) * size, drawColor * size, new Vector3(1, 1, 0)); + bars.Add(pos + toCorner.RotatedBy(Math.PI * 0 + rotation) * size, drawColor * size, new Vector3(0, 1, 0)); + bars.Add(pos + toCorner.RotatedBy(Math.PI * 1 + rotation) * size, drawColor * size, new Vector3(1, 0, 0)); + } + Ins.Batch.Draw(ModAsset.BloodFlame_noise.Value, bars, PrimitiveType.TriangleList); + Color lightColor = gradientColor.GetColor(timer / maxTime); + Lighting.AddLight(position, new Vector3(lightColor.R, lightColor.G, lightColor.B) / 255f * scale * 0.1f); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/PeachBlossom.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/PeachBlossom.cs new file mode 100644 index 000000000..cb063892d --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/PeachBlossom.cs @@ -0,0 +1,71 @@ +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +[Pipeline(typeof(WCSPipeline))] +public class PeachBlossom : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawProjectiles; + + public Vector2 Position; + public Vector2 Velocity; + public float[] ai; + public float Timer; + public float MaxTime; + public float Scale; + public float Rotation; + public float Fade = 1f; + public int Frame; + + public override void Update() + { + Timer++; + if (Timer > MaxTime) + { + Active = false; + } + if (MaxTime - Timer < 60) + { + Fade = (MaxTime - Timer) / 60f; + } + Velocity *= 0.9f; + Velocity += new Vector2(Main.windSpeedCurrent * 0.3f, 0.1f); + Velocity = Velocity.RotatedBy(MathF.Sin((float)Main.time * 0.03f + ai[0]) * 0.05f); + if (Collision.IsWorldPointSolid(Position)) + { + Rotation = 0; + Velocity *= 0; + if (MaxTime - Timer > 60) + { + Timer = MaxTime - 60; + } + } + else if (TileUtils.SafeGetTile(Position.ToTileCoordinates()).LiquidAmount > 0) + { + Rotation = 0; + Velocity *= 0; + Position.Y = Position.ToTileCoordinates().ToWorldCoordinates().Y + TileUtils.SafeGetTile(Position.ToTileCoordinates()).LiquidAmount / 255f; + if (MaxTime - Timer > 60) + { + Timer = MaxTime - 60; + } + } + else + { + Position += Velocity; + } + if (Timer % 5 == 0 && Velocity.Length() > 0.1f) + { + Frame++; + if (Frame >= 10) + { + Frame = 0; + } + } + Rotation = MathF.Sin(ai[0]) * 0.5f; + } + + public override void Draw() + { + Rectangle frame = new Rectangle(0, Frame * 12, 12, 12); + Ins.Batch.Draw(ModAsset.PeachBlossom.Value, Position, frame, Lighting.GetColor(Position.ToTileCoordinates()) * Fade, Rotation, frame.Size() * 0.5f, Scale, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/PeachBlossom.png b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/PeachBlossom.png new file mode 100644 index 000000000..15318efec Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/PeachBlossom.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgaeDust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgaeDust.cs new file mode 100644 index 000000000..6284ffbca --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgaeDust.cs @@ -0,0 +1,70 @@ +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +[Pipeline(typeof(ColorDissolvePipeline))] +public class RedAlgaeDust : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawProjectiles; + + public Vector2 Position; + public Vector2 Velocity; + public float[] ai; + public float Timer; + public float MaxTime; + public float Scale; + public float MaxScale; + public float Rotation; + public float Fade = 1f; + public int Frame = 0; + + public override void Update() + { + Timer++; + if (Timer > MaxTime) + { + Active = false; + } + if (MaxTime - Timer < 60) + { + Fade = (MaxTime - Timer) / 60f; + } + if (Timer < 10) + { + Scale = Timer / 10f * MaxScale; + } + else + { + Scale = MaxScale; + } + Position += Velocity; + Velocity = Velocity.RotatedBy(ai[0]); + ai[0] *= 0.96f; + Velocity *= 0.98f; + if (ai.Length >= 2) + { + Rotation += ai[1]; + } + else + { + Rotation += 0.05f; + } + } + + public override void Draw() + { + float frameCount = 4; + float frameY = Frame; + Vector2 toCorner = new Vector2(0, Scale * 38).RotatedBy(Rotation); + Color drawColor = Lighting.GetColor(Position.ToTileCoordinates()); + var bars = new List() + { + new Vertex2D(Position + toCorner, drawColor, new Vector3(0, frameY / frameCount, Fade)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 0.5), drawColor, new Vector3(1, frameY / frameCount, Fade)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 1.5), drawColor, new Vector3(0, (frameY + 1) / frameCount, Fade)), + + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 1.5), drawColor, new Vector3(0, (frameY + 1) / frameCount, Fade)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 0.5), drawColor, new Vector3(1, frameY / frameCount, Fade)), + new Vertex2D(Position + toCorner.RotatedBy(Math.PI * 1), drawColor, new Vector3(1, (frameY + 1) / frameCount, Fade)), + }; + Ins.Batch.Draw(ModAsset.RedAlgaeDust.Value, bars, PrimitiveType.TriangleList); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgaeDust.png b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgaeDust.png new file mode 100644 index 000000000..ce3765ae8 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgaeDust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgaeHitStar.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgaeHitStar.cs new file mode 100644 index 000000000..a9c73be5b --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgaeHitStar.cs @@ -0,0 +1,39 @@ +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +[Pipeline(typeof(WCSPipeline))] +public class RedAlgaeHitStar : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawProjectiles; + + public Vector2 Position; + public float Timer; + public float MaxTime; + public float Scale; + + public override void Update() + { + Timer++; + if (Timer > MaxTime) + { + Active = false; + } + float value = Timer / MaxTime; + Vector3 color = Vector3.Lerp(new Vector3(1f, 0.9f, 0.8f), new Vector3(0.7f, 0.1f, 0.2f), MathF.Pow(value, 0.5f)); + Lighting.AddLight(Position, color * (1 - value) * Scale * 3); + } + + public override void Draw() + { + Texture2D star = Commons.ModAsset.StarSlash.Value; + float value = Timer / MaxTime; + Color color = new Color(1f, 0.9f, 0.8f, 0); + if (value > 0.5f) + { + color = new Color(0.7f, 0.1f, 0.2f, 0); + } + Ins.Batch.Draw(star, Position, null, color * 0.5f, 0, star.Size() * 0.5f, new Vector2(1f, 1 - value) * Scale, SpriteEffects.None); + Ins.Batch.Draw(star, Position, null, color * 0.5f, MathHelper.PiOver2, star.Size() * 0.5f, new Vector2(1f, 1 - value) * Scale, SpriteEffects.None); + Ins.Batch.Draw(star, Position, null, color * 0.25f, MathHelper.PiOver4, star.Size() * 0.5f, new Vector2(1f, 1 - value) * Scale * 0.5f, SpriteEffects.None); + Ins.Batch.Draw(star, Position, null, color * 0.25f, -MathHelper.PiOver4, star.Size() * 0.5f, new Vector2(1f, 1 - value) * Scale * 0.5f, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_GasRing.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_GasRing.cs new file mode 100644 index 000000000..bb85c1d0c --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_GasRing.cs @@ -0,0 +1,78 @@ +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +[Pipeline(typeof(WCSPipeline_PointWrap))] +public class RedAlgae_GasRing : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawProjectiles; + + public Vector2 Position; + public float Timer; + public float MaxTime; + public float Scale; + public float Fade; + + public override void Update() + { + if (Timer < 1) + { + Fade = 1; + } + Timer++; + if (Timer > MaxTime) + { + Active = false; + } + if (MaxTime - Timer < 60) + { + Fade *= 0.95f; + } + } + + public override void Draw() + { + float radius = Scale * 10 * MathF.Pow(Timer / MaxTime, 0.5f); + Texture2D tex = Commons.ModAsset.Noise_spiderNet.Value; + Texture2D tex_dark = Commons.ModAsset.Noise_spiderNet_dark.Value; + List bars = new List(); + List bars_out = new List(); + List bars_dark = new List(); + List bars_out_dark = new List(); + for (int k = 0; k <= 30; k++) + { + float value = k / 30f; + Vector2 ringPos = new Vector2(0, radius).RotatedBy(value * MathHelper.TwoPi) + Position; + Vector2 ringPos2 = new Vector2(0, radius + 40).RotatedBy(value * MathHelper.TwoPi) + Position; + Vector2 ringPos3 = new Vector2(0, radius + 80).RotatedBy(value * MathHelper.TwoPi) + Position; + AddVertex(bars, ringPos, new Vector2(value * 3, 0), 0); + AddVertex(bars, ringPos2, new Vector2(value * 3, 0.5f)); + + AddVertex(bars_out, ringPos2, new Vector2(value * 3, 0.5f)); + AddVertex(bars_out, ringPos3, new Vector2(value * 3, 1f), 0); + + AddVertexDark(bars_dark, ringPos, new Vector2(value * 3, 0), 0); + AddVertexDark(bars_dark, ringPos2, new Vector2(value * 3, 0.5f)); + + AddVertexDark(bars_out_dark, ringPos2, new Vector2(value * 3, 0.5f)); + AddVertexDark(bars_out_dark, ringPos3, new Vector2(value * 3, 1f), 0); + } + Ins.Batch.Draw(tex_dark, bars_dark, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(tex_dark, bars_out_dark, PrimitiveType.TriangleStrip); + + Ins.Batch.Draw(tex, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(tex, bars_out, PrimitiveType.TriangleStrip); + } + + public void AddVertex(List bars, Vector2 worldPos, Vector2 coord, float colorFade = 1f) + { + float timeValue = Timer / 60f; + Color color = Lighting.GetColor(worldPos.ToTileCoordinates(), new Color(0.7f, 0.1f, 0.4f, 0f)) * colorFade * Fade * Fade; + color.A = 0; + bars.Add(worldPos, color, new Vector3(coord.X, coord.Y + timeValue, 0)); + } + + public void AddVertexDark(List bars, Vector2 worldPos, Vector2 coord, float colorFade = 1f) + { + float timeValue = Timer / 60f; + bars.Add(worldPos, Color.White * colorFade * Fade, new Vector3(coord.X, coord.Y + timeValue, 0)); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Small_Dust.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Small_Dust.cs new file mode 100644 index 000000000..b88a8184f --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Small_Dust.cs @@ -0,0 +1,45 @@ +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +[Pipeline(typeof(WCSPipeline))] +public class RedAlgae_Small_Dust : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawProjectiles; + + public Vector2 Position; + public Vector2 Velocity; + public float[] ai; + public float Timer; + public float MaxTime; + public float Scale; + public float Rotation; + public int Frame; + + public override void Update() + { + Timer++; + if (Timer > MaxTime) + { + Active = false; + } + if (MaxTime - Timer < 60) + { + Scale *= 0.95f; + } + if (ai.Length > 0) + { + Velocity *= ai[0]; + } + else + { + Velocity *= 0.99f; + } + Position += Velocity; + Rotation += 0.05f; + } + + public override void Draw() + { + Rectangle frame = new Rectangle(0, Frame * 12, 12, 12); + Ins.Batch.Draw(ModAsset.RedAlgae_Small_Dust.Value, Position, frame, Lighting.GetColor(Position.ToTileCoordinates()), Rotation, frame.Size() * 0.5f, Scale, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Small_Dust.png b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Small_Dust.png new file mode 100644 index 000000000..6d9031329 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Small_Dust.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Small_Dust_SpinAroundEntity.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Small_Dust_SpinAroundEntity.cs new file mode 100644 index 000000000..0e07dc7b8 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Small_Dust_SpinAroundEntity.cs @@ -0,0 +1,60 @@ +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +/// +/// ai[0] = distance to parent entity
+/// ai[1] = initial angle
+///
+[Pipeline(typeof(WCSPipeline))] +public class RedAlgae_Small_Dust_SpinAroundEntity : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawProjectiles; + + public Projectile ParentEntity; + public Vector2 Position; + public Vector2 Velocity; + public float[] ai; + public float Timer; + public float MaxTime; + public float Scale; + public float MaxScale; + public float Rotation; + public int Frame; + + public override void Update() + { + if (ParentEntity is null) + { + Velocity *= 0.99f; + Position += Velocity; + } + else + { + ai[1] -= 4f / ai[0]; + Vector2 oldPos = Position; + Position = ParentEntity.Center + new Vector2(0, ai[0]).RotatedBy(ai[1]); + Velocity = Position - oldPos; + ai[0] *= 0.99f; + } + Timer++; + if (Timer > MaxTime) + { + Active = false; + return; + } + if (MaxTime - Timer < 60) + { + Scale *= 0.95f; + } + if (Timer <= 10) + { + Scale = MaxScale * Timer / 10f; + } + Rotation += 0.05f; + } + + public override void Draw() + { + Rectangle frame = new Rectangle(0, Frame * 12, 12, 12); + Ins.Batch.Draw(ModAsset.RedAlgae_Small_Dust.Value, Position, frame, Lighting.GetColor(Position.ToTileCoordinates()), Rotation, frame.Size() * 0.5f, Scale, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Spark.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Spark.cs new file mode 100644 index 000000000..9d457b8b2 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Spark.cs @@ -0,0 +1,45 @@ +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +[Pipeline(typeof(WCSPipeline), typeof(BloomPipeline))] +public class RedAlgae_Spark : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawProjectiles; + + public Vector2 Position; + public Vector2 Velocity; + public float[] ai; + public float Timer; + public float MaxTime; + public float Scale; + public float Rotation; + + public override void Update() + { + Timer++; + if (Timer > MaxTime) + { + Active = false; + } + if (MaxTime - Timer < 60) + { + Scale *= 0.95f; + } + if (ai.Length > 0) + { + Velocity *= ai[0]; + } + else + { + Velocity *= 0.99f; + } + Position += Velocity; + Rotation += 0.05f; + Lighting.AddLight(Position, new Vector3(0.5f, 0.45f, 0.4f) * Scale); + } + + public override void Draw() + { + Texture2D tex = ModAsset.RedAlgae_Spark.Value; + Ins.Batch.Draw(tex, Position, null, Lighting.GetColor(Position.ToTileCoordinates()), Rotation, tex.Size() * 0.5f, Scale, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Spark.png b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Spark.png new file mode 100644 index 000000000..d6df48514 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Spark.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Spark_SpinAroundEntity.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Spark_SpinAroundEntity.cs new file mode 100644 index 000000000..ac4c460b5 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/RedAlgae_Spark_SpinAroundEntity.cs @@ -0,0 +1,60 @@ +namespace Everglow.Yggdrasil.KelpCurtain.VFXs; + +/// +/// ai[0] = distance to parent entity
+/// ai[1] = initial angle
+///
+[Pipeline(typeof(WCSPipeline), typeof(BloomPipeline))] +public class RedAlgae_Spark_SpinAroundEntity : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawProjectiles; + + public Projectile ParentEntity; + public Vector2 Position; + public Vector2 Velocity; + public float[] ai; + public float Timer; + public float MaxTime; + public float Scale; + public float MaxScale; + public float Rotation; + + public override void Update() + { + if (ParentEntity is null) + { + Velocity *= 0.99f; + Position += Velocity; + } + else + { + ai[1] -= 4f / ai[0]; + Vector2 oldPos = Position; + Position = ParentEntity.Center + new Vector2(0, ai[0]).RotatedBy(ai[1]); + Velocity = Position - oldPos; + ai[0] *= 0.99f; + } + Timer++; + if (Timer > MaxTime) + { + Active = false; + return; + } + if (MaxTime - Timer < 60) + { + Scale *= 0.95f; + } + if (Timer <= 10) + { + Scale = MaxScale * Timer / 10f; + } + Rotation += 0.05f; + Lighting.AddLight(Position, new Vector3(0.5f, 0.45f, 0.4f) * Scale); + } + + public override void Draw() + { + Rectangle frame = new Rectangle(0, 0, 4, 4); + Ins.Batch.Draw(ModAsset.RedAlgae_Spark.Value, Position, frame, new Color(1f, 1f, 1f, 1f), Rotation, frame.Size() * 0.5f, Scale, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/VampireMat/ScreenScaringEffect.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/VampireMat/ScreenScaringEffect.cs new file mode 100644 index 000000000..7c1f6c39e --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/VampireMat/ScreenScaringEffect.cs @@ -0,0 +1,48 @@ +namespace Everglow.Yggdrasil.KelpCurtain.VFXs.VampireMat; + +[Pipeline(typeof(ScreenScaringEffectPipeline))] +public class ScreenScaringEffect : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PreDrawFilter; + + public int Timer; + public int MaxTime; + + public override void Update() + { + Timer++; + if (Timer >= MaxTime) + { + Active = false; + return; + } + } + + public override void Draw() + { + float timeValue = MaxTime - Timer; + float fade = timeValue / MaxTime; + for (int i = 0; i < 5; i++) + { + for (int j = 0; j < 2; j++) + { + Vector2 offset = new Vector2(MathF.Sin(Main.GlobalTimeWrappedHourly * 2.4f) * MathF.Pow(timeValue, 0.5f) * 2, 0); + Color drawColor = new Color(0.8f, 0f, 0f, 0) * fade; + if (j == 1) + { + drawColor = new Color(0f, 0.4f, 0f, 0) * fade; + offset.X *= -1; + } + List bars = new List(); + bars.Add(offset + new Vector2(0, 0), drawColor, new Vector3(0, 0, 0)); + bars.Add(offset + new Vector2(Main.screenWidth, 0), drawColor, new Vector3(1, 0, 0)); + bars.Add(offset + new Vector2(0, Main.screenHeight), drawColor, new Vector3(0, 1, 0)); + bars.Add(offset + new Vector2(Main.screenWidth, Main.screenHeight), drawColor, new Vector3(1, 1, 0)); + if (bars.Count == 4) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, 2); + } + } + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/VampireMat/ScreenScaringEffectPipeline.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/VampireMat/ScreenScaringEffectPipeline.cs new file mode 100644 index 000000000..43ad03eaa --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/VampireMat/ScreenScaringEffectPipeline.cs @@ -0,0 +1,86 @@ +using Everglow.Commons.Interfaces; + +namespace Everglow.Yggdrasil.KelpCurtain.VFXs.VampireMat; + +public class ScreenScaringEffectPipeline : Pipeline +{ + private RenderTarget2D screenTextureAsset; // å射区域 + + public override void Load() + { + Ins.MainThread.AddTask(() => + { + AllocateRenderTarget(new Vector2(Main.screenWidth, Main.screenHeight)); + }); + Ins.HookManager.AddHook(CodeLayer.ResolutionChanged, (Vector2 size) => + { + screenTextureAsset?.Dispose(); + AllocateRenderTarget(size); + }, "Realloc RenderTarget"); + effect = ModAsset.ScreenScaringShader; + } + + private void AllocateRenderTarget(Vector2 size) + { + var gd = Main.instance.GraphicsDevice; + screenTextureAsset = new RenderTarget2D(gd, (int)size.X, (int)size.Y, false, gd.PresentationParameters.BackBufferFormat, DepthFormat.None); + } + + public override void BeginRender() + { + var graphicsDevice = Main.graphics.GraphicsDevice; + var spriteBatch = Main.spriteBatch; + + graphicsDevice.SetRenderTarget(Main.screenTargetSwap); + + // ä¿å­˜åŽŸå±å¹• + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.PointClamp, DepthStencilState.Default, + RasterizerState.CullNone); + spriteBatch.Draw(Main.screenTarget, Vector2.Zero, Color.White); + spriteBatch.End(); + + graphicsDevice.SetRenderTarget(screenTextureAsset); + + // 以å¦ä¸€ç§æ–¹æ³•绘制ä¿å­˜ä¸‹æ¥çš„å±å¹• + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.PointClamp, DepthStencilState.Default, + RasterizerState.CullNone, null, Matrix.Invert(Main.GameViewMatrix.TransformationMatrix)); + spriteBatch.Draw(Main.screenTargetSwap, Vector2.Zero, Color.White); + spriteBatch.End(); + + graphicsDevice.SetRenderTarget(Main.screenTarget); + + // 绘制原å±å¹• + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.PointClamp, DepthStencilState.Default, + RasterizerState.CullNone); + spriteBatch.Draw(Main.screenTargetSwap, Vector2.Zero, Color.White); + spriteBatch.End(); + + spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.None, + RasterizerState.CullNone); + + effect.Value.Parameters["uTransform"].SetValue( + Matrix.CreateTranslation(new Vector3(0, 0, 0)) * + Main.GameViewMatrix.TransformationMatrix * + Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1)); + effect.Value.CurrentTechnique.Passes[0].Apply(); + + Main.graphics.GraphicsDevice.Textures[0] = screenTextureAsset; + Main.graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp; + } + + public override void Render(IEnumerable visuals) + { + BeginRender(); + foreach (var visual in visuals) + { + visual.Draw(); + } + EndRender(); + } + + public override void EndRender() + { + var spriteBatch = Main.spriteBatch; + spriteBatch.End(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/VampireMat/ScreenScaringShader.fx b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/VampireMat/ScreenScaringShader.fx new file mode 100644 index 000000000..6ce738523 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/VampireMat/ScreenScaringShader.fx @@ -0,0 +1,41 @@ +sampler2D uImage : register(s0); + +float4x4 uTransform; + +struct VSInput +{ + float2 Pos : POSITION0; + float4 Color : COLOR0; + float3 Texcoord : TEXCOORD0; +}; + +struct PSInput +{ + float4 Pos : SV_POSITION; + float4 Color : COLOR0; + float3 Texcoord : TEXCOORD0; +}; + +PSInput VertexShaderFunction(VSInput input) +{ + PSInput output; + output.Color = input.Color; + output.Texcoord = input.Texcoord; + output.Pos = mul(float4(input.Pos, 0, 1), uTransform); + return output; +} + +float4 PixelShaderFunction(PSInput input) : COLOR0 +{ + float disToCenter = length(float2(0.5, 0.5) - input.Texcoord.xy); + return tex2D(uImage, input.Texcoord.xy) * input.Color * disToCenter; +} + +technique Technique1 +{ + pass Test + { + VertexShader = compile vs_3_0 VertexShaderFunction(); + PixelShader = compile ps_3_0 PixelShaderFunction(); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/VampireMat/VampireMatStickScreen.cs b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/VampireMat/VampireMatStickScreen.cs new file mode 100644 index 000000000..da77caa71 --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/VampireMat/VampireMatStickScreen.cs @@ -0,0 +1,157 @@ +namespace Everglow.Yggdrasil.KelpCurtain.VFXs.VampireMat; + +[Pipeline(typeof(WCSPipeline))] +public class VampireMatStickScreen : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawDusts; + + public Player Owner; + public NPC ParentNPC; + public float Timer; + public float MaxTime; + public float FinishTime = -1; + public float Duration = 0; + + public override void Update() + { + Timer++; + if (Timer > MaxTime) + { + Active = false; + return; + } + if (ParentNPC is null || !ParentNPC.active || ParentNPC.type != ModContent.NPCType()) + { + Active = false; + return; + } + var vMat = ParentNPC.ModNPC as NPCs.VampireMat.VampireMat; + if (MaxTime - Timer > 30 && (vMat.TotalDamageIntakeWhenStickPlayer >= 100 || !vMat.StickPlayer)) + { + Timer = MaxTime - 30; + } + if (Timer < 30) + { + Duration = (1 - MathF.Cos(Timer / 30f * MathHelper.Pi * 1.2f)) * 0.5f; + } + else if (MaxTime - Timer < 30) + { + Duration = (1 - MathF.Cos((MaxTime - Timer) / 30f * MathHelper.Pi * 1.2f)) * 0.5f; + } + else + { + if (vMat.HitTimer > 0) + { + Duration = 1 - vMat.HitTimer / 60f; + } + Duration = Duration * 0.9f + 0.1f; + } + } + + public override void Draw() + { + if (ParentNPC is null || !ParentNPC.active || ParentNPC.type != ModContent.NPCType()) + { + Active = false; + return; + } + var vMat = ParentNPC.ModNPC as NPCs.VampireMat.VampireMat; + + List bars = []; + if (Owner is null || Main.LocalPlayer != Owner) + { + Ins.Batch.Draw(Main.LocalPlayer.Hitbox, Color.Transparent); + return; + } + for (int k = 0; k < 60; k++) + { + AddATentacle(bars, k / 60f * MathHelper.TwoPi); + } + Ins.Batch.Draw(ModAsset.VampireMatStickScreen.Value, bars, PrimitiveType.TriangleStrip); + + List ring = []; + SpriteBatchUtils.AddVerticesForCircleRing(ring, Owner.Center, 300, 30, new Color(0.5f, 0.5f, 0.5f, 0.5f) * Duration, 0.5f, 0.5f); + Ins.Batch.Draw(Commons.ModAsset.TileBlock.Value, ring, PrimitiveType.TriangleStrip); + + List ring2 = []; + SpriteBatchUtils.AddVerticesForCircleRing(ring2, Owner.Center, 324, 12, new Color(0.5f, 0.5f, 0.5f, 0.5f) * Duration, 0.5f, 0.5f); + Ins.Batch.Draw(Commons.ModAsset.TileBlock.Value, ring2, PrimitiveType.TriangleStrip); + + List ring_duration = []; + int maxValue = vMat.TotalDamageIntakeWhenStickPlayer; + if (!vMat.StickPlayer) + { + maxValue = 100; + } + var durationColor = Color.White * 0.75f; + var timeColor = Color.Lerp(Color.Yellow, Color.White, 0.75f) * 0.75f; + if (MaxTime - Timer < 30) + { + if (vMat.FailToEscapeStickTimer > 0) + { + durationColor = Color.Red; + timeColor = Color.Red; + } + else + { + if (FinishTime == -1) + { + FinishTime = Timer; + } + } + maxValue = 100; + } + durationColor *= Duration; + timeColor *= Duration; + for (int k = 0; k <= maxValue; k++) + { + float rot = k / 100f * MathHelper.TwoPi; + ring_duration.Add(Owner.Center + new Vector2(0, -315).RotatedBy(rot), durationColor, new Vector3(0, 0, 0)); + ring_duration.Add(Owner.Center + new Vector2(0, -285).RotatedBy(rot), durationColor, new Vector3(0, 0, 0)); + } + Ins.Batch.Draw(Commons.ModAsset.TileBlock.Value, ring_duration, PrimitiveType.TriangleStrip); + + List ring2_duration = []; + int ring2_time = (int)Timer; + if (FinishTime != -1) + { + ring2_time = (int)FinishTime; + } + if (ring2_time > 120) + { + ring2_time = 120; + } + for (int k = 0; k <= ring2_time; k++) + { + float rot = k / 120f * MathHelper.TwoPi; + ring2_duration.Add(Owner.Center + new Vector2(0, -330).RotatedBy(rot), timeColor, new Vector3(0, 0, 0)); + ring2_duration.Add(Owner.Center + new Vector2(0, -318).RotatedBy(rot), timeColor, new Vector3(0, 0, 0)); + } + Ins.Batch.Draw(Commons.ModAsset.TileBlock.Value, ring2_duration, PrimitiveType.TriangleStrip); + } + + public void AddATentacle(List bars, float direction) + { + if (Owner is null) + { + return; + } + Vector2 tantecle_dir = new Vector2(Main.screenWidth, Main.screenHeight).RotatedBy(direction) * 0.5f; + Vector2 tantecle_pos = Owner.Center + tantecle_dir; + Vector2 tantecle_unit = tantecle_dir.SafeNormalize(Vector2.Zero) * 18f; + float randomOffset = TileUtils.GetFixedRandomNumber_SingleSeed((int)(direction * 610), 200) / 200f; + tantecle_unit *= 1f + MathF.Sin(randomOffset * MathHelper.TwoPi) * 0.25f; + Vector2 tantecle_normal = tantecle_unit.RotatedBy(MathHelper.PiOver2); + int length = (int)(Duration * 90f); + for (int k = 0; k < length; k++) + { + tantecle_pos -= tantecle_unit; + Vector2 unitPos = tantecle_pos + tantecle_normal * MathF.Sin((float)Main.time * 0.03f + k * 0.14f + randomOffset * MathHelper.TwoPi); + float width = 0.6f + (length - k) * 0.05f; + float valueX = k + 60 - length; + valueX /= 60f; + bars.Add(unitPos + tantecle_normal * width, new Color(0, 0, 0, 1f), new Vector3(valueX, 0, 0)); + bars.Add(unitPos - tantecle_normal * width, new Color(0, 0, 0, 1f), new Vector3(valueX, 1, 0)); + } + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/VampireMat/VampireMatStickScreen.png b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/VampireMat/VampireMatStickScreen.png new file mode 100644 index 000000000..0540a0d57 Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/VFXs/VampireMat/VampireMatStickScreen.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Walls/IsleBamboo_Wall.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Walls/IsleBamboo_Wall.cs new file mode 100644 index 000000000..e23e59b6a --- /dev/null +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Walls/IsleBamboo_Wall.cs @@ -0,0 +1,14 @@ +using Everglow.Yggdrasil.KelpCurtain.Dusts; + +namespace Everglow.Yggdrasil.KelpCurtain.Walls; + +public class IsleBamboo_Wall : ModWall +{ + public override void SetStaticDefaults() + { + Main.wallHouse[Type] = true; + DustType = DustType = ModContent.DustType(); + + AddMapEntry(new Color(75, 52, 23)); + } +} diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Walls/IsleBamboo_Wall.png b/Sources/Modules/Yggdrasil/KelpCurtain/Walls/IsleBamboo_Wall.png new file mode 100644 index 000000000..b99d30cca Binary files /dev/null and b/Sources/Modules/Yggdrasil/KelpCurtain/Walls/IsleBamboo_Wall.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Walls/OldMossWall.png b/Sources/Modules/Yggdrasil/KelpCurtain/Walls/OldMossWall.png index b2abbd1c6..687d64e34 100644 Binary files a/Sources/Modules/Yggdrasil/KelpCurtain/Walls/OldMossWall.png and b/Sources/Modules/Yggdrasil/KelpCurtain/Walls/OldMossWall.png differ diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Walls/SharpBarnacleWall.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Walls/SharpBarnacleWall.cs index 354a5524c..899768bb3 100644 --- a/Sources/Modules/Yggdrasil/KelpCurtain/Walls/SharpBarnacleWall.cs +++ b/Sources/Modules/Yggdrasil/KelpCurtain/Walls/SharpBarnacleWall.cs @@ -14,15 +14,28 @@ public override void SetStaticDefaults() public override void PostDraw(int i, int j, SpriteBatch spriteBatch) { - Tile tile = Main.tile[i, j]; - if (j % 2 == 0 && tile.WallFrameY < 180) - { - tile.WallFrameY += 180; - } - if (j % 2 == 1 && tile.WallFrameY >= 180) + //Tile tile = Main.tile[i, j]; + //if (j % 2 == 0 && tile.WallFrameY < 180) + //{ + // tile.WallFrameY += 180; + //} + //if (j % 2 == 1 && tile.WallFrameY >= 180) + //{ + // tile.WallFrameY -= 180; + //} + base.PostDraw(i, j, spriteBatch); + } + + public override bool WallFrame(int i, int j, bool randomizeFrame, ref int style, ref int frameNumber) + { + if (randomizeFrame) { - tile.WallFrameY -= 180; + // Here we make the chance of WallFrameNumber 0 very rare, just for visual variety: https://i.imgur.com/9Irak3p.png + if (frameNumber == 0 && WorldGen.genRand.NextBool(3, 4)) + { + frameNumber = WorldGen.genRand.Next(1, 3); + } } - base.PostDraw(i, j, spriteBatch); + return base.WallFrame(i, j, randomizeFrame, ref style, ref frameNumber); } } diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Walls/SharpBarnacleWall.png b/Sources/Modules/Yggdrasil/KelpCurtain/Walls/SharpBarnacleWall.png index 4d5524e33..b3ff64baf 100644 Binary files a/Sources/Modules/Yggdrasil/KelpCurtain/Walls/SharpBarnacleWall.png and b/Sources/Modules/Yggdrasil/KelpCurtain/Walls/SharpBarnacleWall.png differ diff --git a/Sources/Modules/Yggdrasil/Netcode/PermanentBoostPacket.cs b/Sources/Modules/Yggdrasil/Netcode/PermanentBoostPacket.cs index a11c2c7e1..bdd3cac58 100644 --- a/Sources/Modules/Yggdrasil/Netcode/PermanentBoostPacket.cs +++ b/Sources/Modules/Yggdrasil/Netcode/PermanentBoostPacket.cs @@ -38,8 +38,6 @@ public void Handle(IPacket packet, int whoAmI) mp.ConsumedJadeGlazeFruit = packetData.consumedJadeGlazeFruit; mp.ConsumedLampBorerHoney = packetData.consumedLampBorerHoney; mp.ConsumedSquamousCore = packetData.consumedSquamousCore; - - // Console.WriteLine($"{packetData.consumedAntiHeavenSicknessPill} {packetData.consumedJadeGlazeFruit} {packetData.consumedLampBorerHoney} {packetData.consumedSquamousCore}"); } } } diff --git a/Sources/Modules/Yggdrasil/Netcode/VampireMatHitPacket.cs b/Sources/Modules/Yggdrasil/Netcode/VampireMatHitPacket.cs new file mode 100644 index 000000000..78623338c --- /dev/null +++ b/Sources/Modules/Yggdrasil/Netcode/VampireMatHitPacket.cs @@ -0,0 +1,38 @@ +using Everglow.Commons.Netcode.Abstracts; +using Everglow.Yggdrasil.KelpCurtain.NPCs.VampireMat; + +namespace Everglow.Yggdrasil.Netcode; + +public class VampireMatHitPacket : IPacket +{ + private int damage; + + public VampireMatHitPacket() + { + } + + public VampireMatHitPacket(int damage) + { + this.damage = damage; + } + + public void Receive(BinaryReader reader, int whoAmI) + { + damage = reader.ReadInt32(); + } + + public void Send(BinaryWriter writer) + { + writer.Write(damage); + } + + [HandlePacket(typeof(VampireMatHitPacket))] + public class VampireMatHitPacketHandler : IPacketHandler + { + public void Handle(IPacket packet, int whoAmI) + { + var packetData = (VampireMatHitPacket)packet; + VampireMat.VampireHitHealEffect(Main.player[whoAmI], packetData.damage); + } + } +} diff --git a/Sources/Modules/Yggdrasil/WorldGeneration/KelpCurtainGeneration.cs b/Sources/Modules/Yggdrasil/WorldGeneration/KelpCurtainGeneration.cs index fe1814e8a..bc7a5d792 100644 --- a/Sources/Modules/Yggdrasil/WorldGeneration/KelpCurtainGeneration.cs +++ b/Sources/Modules/Yggdrasil/WorldGeneration/KelpCurtainGeneration.cs @@ -1,16 +1,43 @@ using Everglow.Yggdrasil.Common.Tiles; +using Everglow.Yggdrasil.Common.Walls; using Everglow.Yggdrasil.KelpCurtain; +using Everglow.Yggdrasil.KelpCurtain.Biomes; +using Everglow.Yggdrasil.KelpCurtain.Items.Accessories; +using Everglow.Yggdrasil.KelpCurtain.Items.Materials; +using Everglow.Yggdrasil.KelpCurtain.Items.Weapons; using Everglow.Yggdrasil.KelpCurtain.Tiles; using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake; +using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.IRProbe; +using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.LightningMechanism; +using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.UnderwaterGuillotine; +using Everglow.Yggdrasil.KelpCurtain.Tiles.DeathJadeLake.WaterDeliveryHoles; using Everglow.Yggdrasil.KelpCurtain.Tiles.GeyserAirBuds; +using Everglow.Yggdrasil.KelpCurtain.Tiles.IsleOfBloom; using Everglow.Yggdrasil.KelpCurtain.Walls; using Everglow.Yggdrasil.YggdrasilTown.Tiles; +using Terraria.ObjectData; +using static Everglow.Commons.Utilities.TileUtils; using static Everglow.Yggdrasil.WorldGeneration.YggdrasilWorldGeneration; namespace Everglow.Yggdrasil.WorldGeneration; public class KelpCurtainGeneration { + /// + /// Tile coord. + /// + public static int MazeUnderLake_TopY = -1; + + public static int MazeUnderLake_YggdrasilBlackChestShrineCount = 0; + + public static List WaterDeliveryHoleTiles = new List(); + + public static List MazeUnderLake_YggdrasilBlackRockChestContents = new List(); + + public static int UnderwaterTreasury_Bottom_Room_center_Y; + + public static Vector2 VampireMatCaveCenter; + public static void BuildKelpCurtain() { Initialize(); @@ -28,10 +55,18 @@ public static void BuildKelpCurtain() BuildMossyCavesLow(); BuildMossyCavesHigh(); GreenTundra(); - ScarletGarden(); + + // ScarletGarden(); + IsleOfBloomBaseLand(); MazeUnderLake(); DragonPond(); + IsleOfBloom(); + UnderwaterTreasury(); + VampireMatCave(); + + DeathJadeLakeBiome.GetLiquidSurfaceY(); + // IsleOfBloom(); // BuildRainValley(); } @@ -40,6 +75,13 @@ public static void BuildKelpCurtain() ///
public static void Initialize() { + WaterDeliveryHoleTiles = new List(); + WaterDeliveryHoleTiles.Add(ModContent.TileType()); + WaterDeliveryHoleTiles.Add(ModContent.TileType()); + WaterDeliveryHoleTiles.Add(ModContent.TileType()); + WaterDeliveryHoleTiles.Add(ModContent.TileType()); + WaterDeliveryHoleTiles.Add(ModContent.TileType()); + WaterDeliveryHoleTiles.Add(ModContent.TileType()); } /// @@ -53,7 +95,7 @@ public static void BuildDeathJadeLake() while (startY < (int)(Main.maxTilesY * 0.9f)) { startY++; - Tile tile = TileUtils.SafeGetTile(startX, startY); + Tile tile = SafeGetTile(startX, startY); if (tile.HasTile) { startY -= 20; @@ -63,29 +105,26 @@ public static void BuildDeathJadeLake() int randY = GenRand.Next(512); int randX = GenRand.Next(512); int bankWidth = GenRand.Next(220, 240); - int peakHeight = 0; // 记录一个连续的高度 + int peakHeight = 0; // Lakeshore for (int step = 0; step < bankWidth; step++) { - int height = (int)(step * step / 270f + PerlinPixelB[(step + randX) % 512, randY] / 30f) - 24; - for (int deltaY = 0; deltaY < step; deltaY++) + int height = (int)(step * step / 270f + GetPerlinPixelB((step + randX) % 512, randY) * 256f / 30f) - 24; + int x = startX + step; + int y = startY - height; + int count = 0; + while (!SafeGetTile(x, y).HasTile) { - int x = startX + step; - int y = startY - height; - int count = 0; - while (!TileUtils.SafeGetTile(x, y).HasTile) + Tile tile = SafeGetTile(x, y); + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + count++; + if (count > 300) { - Tile tile = TileUtils.SafeGetTile(x, y); - tile.TileType = (ushort)ModContent.TileType(); - tile.HasTile = true; - count++; - if (count > 300) - { - break; - } - y++; + break; } + y++; } if (height > peakHeight) { @@ -134,9 +173,9 @@ public static void BuildDeathJadeLake() type = ModContent.TileType(); wallType = ModContent.WallType(); } - if (!TileUtils.SafeGetTile(x, y).HasTile && stoneValue >= 0) + if (!SafeGetTile(x, y).HasTile && stoneValue >= 0) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.TileType = (ushort)type; tile.HasTile = true; tile.WallType = (ushort)wallType; @@ -150,12 +189,12 @@ public static void BuildDeathJadeLake() randX = GenRand.Next(512); for (int step = 0; step < 30; step++) { - int thick = (int)((30 - step) * (30 - step) / 26d + PerlinPixelB[(step + randX) % 512, randY] / 30f); + int thick = (int)((30 - step) * (30 - step) / 26d + GetPerlinPixelB((step + randX) % 512, randY) * 256f / 30f); for (int deltaY = 0; deltaY < thick; deltaY++) { int x = lakePeakX + step; int y = startY - peakHeight + deltaY; - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; } @@ -166,7 +205,7 @@ public static void BuildDeathJadeLake() { int y = startY - peakHeight + 7; int count = 0; - while (!TileUtils.SafeGetTile(x, y).HasTile) + while (!SafeGetTile(x, y).HasTile) { count++; if (count > 300) @@ -175,13 +214,36 @@ public static void BuildDeathJadeLake() } if (x > KelpCurtainBiome.FindClosestStratumBoundPointX(y)) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.LiquidType = LiquidID.Water; tile.LiquidAmount = 255; } y++; } } + + // Mossy Dock + int liquidSurfaceY = startY - peakHeight + 7; + Point dockTail = new Point((int)(Main.maxTilesX * 0.5f), liquidSurfaceY - 3); + dockTail.X += CheckSpaceRight(dockTail); + PlaceRectangleAreaOfBlock(dockTail.X - 18, dockTail.Y, dockTail.X + 2, dockTail.Y, ModContent.TileType(), (int)TileUtils.TileChangeState.NoTile); + PlaceRectangleAreaOfBlock(dockTail.X - 19, dockTail.Y - 1, dockTail.X + 2, dockTail.Y - 1, ModContent.TileType(), (int)TileUtils.TileChangeState.NoTile); + PlaceFrameImportantTilesAbove(dockTail.X - 19, dockTail.Y - 1, 3, 3, ModContent.TileType()); + int stumpY = dockTail.Y - 2; + int stumpX = dockTail.X - 16; + for (int dx = 0; dx < 10; dx++) + { + var tile = SafeGetTile(stumpX + dx * 3, stumpY); + if (!tile.HasTile) + { + tile.TileType = TileID.WoodenBeam; + tile.HasTile = true; + } + if (dx % 4 == 0) + { + PlaceTileListTowardDownUntilCollide(new Point(stumpX + dx * 3, stumpY + 3), TileID.WoodenBeam); + } + } } /// @@ -218,13 +280,13 @@ public static void BuildTunnelTo2ndStratum() checkPos.Y += deltaY - 2; for (int x = (int)(checkPos.X - 4); x <= (int)(checkPos.X + 5); x++) { - var tile = TileUtils.SafeGetTile(x, (int)(checkPos.Y + 2)); + var tile = SafeGetTile(x, (int)(checkPos.Y + 2)); tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; } // Place Geyser Air Buds. - TileUtils.PlaceFrameImportantTiles((int)checkPos.X, (int)checkPos.Y, 2, 2, ModContent.TileType()); + PlaceFrameImportantTiles((int)checkPos.X, (int)checkPos.Y, 2, 2, ModContent.TileType()); for (int t = 1; t < 16; t++) { Vector2 addPos = new Vector2((t % 2 - 0.5f) * 30 + 10 + Main.rand.NextFloat(-3, 3), -t * 24 + 10); @@ -235,14 +297,14 @@ public static void BuildTunnelTo2ndStratum() topPos.Y += deltaYTop - 2; for (int x = (int)(topPos.X - 1); x <= (int)(topPos.X + 2); x++) { - var tile = TileUtils.SafeGetTile(x, (int)(topPos.Y + 2)); + var tile = SafeGetTile(x, (int)(topPos.Y + 2)); tile.ClearEverything(); - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; tile.Slope = SlopeType.Solid; } - TileUtils.PlaceFrameImportantTiles((int)topPos.X, (int)topPos.Y, 2, 2, ModContent.TileType()); + PlaceFrameImportantTiles((int)topPos.X, (int)topPos.Y, 2, 2, ModContent.TileType()); } } @@ -252,7 +314,7 @@ public static Point FindSquamousShellTopLeft() { for (int y = (int)(Main.maxTilesY * 0.89f); y <= (int)(Main.maxTilesY * 0.96f); y++) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); if (tile.TileType == ModContent.TileType()) { return new Point(x - tile.TileFrameX / 18, y - tile.TileFrameY / 18); @@ -311,8 +373,8 @@ public static void BuildMossyCavesHigh() float lerpValue = (float)(Main.maxTilesY * 0.88 - y) / 63f; decayValue = (float)Utils.Lerp(decayValue, 0.6f, lerpValue); } - var tile = TileUtils.SafeGetTile(x, y); - if (!tile.HasTile && tile.wall == 0) + var tile = SafeGetTile(x, y); + if (!tile.HasTile && tile.WallType == WallID.None) { if (decayValue is > 0.2f and < 1f) { @@ -354,8 +416,8 @@ public static void BuildMossyCavesHigh() { decayValue += (y - Main.maxTilesY * 0.88f) / 80f; } - var tile = TileUtils.SafeGetTile(x, y); - if (!tile.HasTile && tile.wall == 0) + var tile = SafeGetTile(x, y); + if (!tile.HasTile && tile.WallType == WallID.None) { if (decayValue is > 0.2f and < 1f) { @@ -438,7 +500,7 @@ public static void DigGreenTundraTunnel(int x, int y, float width, Vector2 veloc CircleTile(checkPos, width, -1, true); checkPos += vel; vel = vel.RotatedBy((GetPerlinPixelR(checkPos.X, checkPos.Y) - 60f / 255f) * 0.06f); - if (!TileUtils.SafeGetTile(checkPos + vel.NormalizeSafe() * (width + 2)).HasTile && t < maxStep - 5 && t > 20) + if (!SafeGetTile(checkPos + vel.NormalizeSafe() * (width + 2)).HasTile && t < maxStep - 5 && t > 20) { maxStep = t + 4; } @@ -460,7 +522,7 @@ public static void BuildRainValley() while (startY < (int)(Main.maxTilesY * 0.89f)) { startY++; - Tile tile = TileUtils.SafeGetTile(Main.maxTilesX / 2, startY); + Tile tile = SafeGetTile(Main.maxTilesX / 2, startY); if (tile.HasTile) { break; @@ -471,10 +533,10 @@ public static void BuildRainValley() { for (int x = Main.maxTilesX / 2; x <= Main.maxTilesX - 20; x++) { - int dense = PerlinPixelB[(x / 4 + randX) % 512, (y + randY) % 512]; + int dense = (int)(GetPerlinPixelB(x / 4 + randX, y + randY) * 256); if (dense > 160) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; } @@ -482,271 +544,3439 @@ public static void BuildRainValley() } } + #region IsleOfBloom + /// - /// 绯红花园 + /// å¤­åŽæ´² /// - public static void ScarletGarden() + public static void IsleOfBloom() { - int lakeSurfaceY = (int)(Main.maxTilesY * 0.88); - int lakeCenterX = (int)(Main.maxTilesX * 0.4); - lakeSurfaceY += CheckWaterSurfaceDown(lakeCenterX, lakeSurfaceY); - int xBoundLeft = (int)(Main.maxTilesX * 0.22f); - int xBoundRight = (int)(Main.maxTilesX * 0.4f); - for (int x = xBoundLeft; x < xBoundRight; x++) + int startY = (int)(Main.maxTilesY * 0.88f); + startY += CheckSpaceDown((int)(Main.maxTilesX * 0.31f), startY) - 20; + Point tilePos = new Point((int)(Main.maxTilesX * 0.31f), startY); + List area = + [ + tilePos + new Point(-130, 0), + tilePos + new Point(130, 0), + tilePos + new Point(150, 120), + tilePos + new Point(-150, 120), + ]; + area = GetPolygonAreaOfTilePos(area); + foreach (var pos in area) { - int lakeBottomY = (int)(Main.maxTilesY * 0.88); - lakeBottomY += CheckSpaceDown(lakeCenterX, lakeBottomY); - float xLength = xBoundRight - xBoundLeft; - float height = (MathF.Sin((x - xBoundLeft) / xLength * MathHelper.TwoPi - MathHelper.PiOver2) + 1) * 465f; - float heightMax = lakeBottomY - lakeSurfaceY + GetPerlinPixeG(x, 15) * 16; - height = MathF.Min(heightMax, height); - for (int y = 0; y < height; y++) + var checkPoint = pos; + var tile = SafeGetTile(checkPoint); + if (!tile.HasTile || tile.TileType != ModContent.TileType()) + { + continue; + } + if (pos.Y - tilePos.Y > 105 + GetLargeSmokeTexturePixelB(pos.X * 3, pos.Y * 3) * 15f) + { + continue; + } + tile.LiquidAmount = 0; + float value0 = GetPerlinPixelG(pos.X, pos.Y) * 12; + if (pos.Y - tilePos.Y < 20 + value0) + { + tile.TileType = (ushort)ModContent.TileType(); + } + else + { + tile.TileType = (ushort)ModContent.TileType(); + } + float value1 = GetPerlinPixelR(pos.X, pos.Y); + float value2 = GetPerlinPixelR(pos.Y, pos.X); + if (pos.Y - tilePos.Y > value1 * 3 + value0) { - var tile = TileUtils.SafeGetTile(x, lakeBottomY - y); - tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; } - } - } - - /// - /// 水下迷宫 - /// - public static void MazeUnderLake() - { - int lakeSurfaceY = (int)(Main.maxTilesY * 0.88); - int lakeCenterX = (int)(Main.maxTilesX * 0.4); - lakeSurfaceY += CheckWaterSurfaceDown(lakeCenterX, lakeSurfaceY); - int xBoundLeft = (int)(Main.maxTilesX * 0.34f); - int xBoundRight = (int)(Main.maxTilesX * 0.64f); - lakeCenterX = (int)(Main.maxTilesX * 0.5); - int lakeBottomYHalfX = (int)(Main.maxTilesY * 0.88); - lakeBottomYHalfX += CheckSpaceDown(lakeCenterX, lakeBottomYHalfX); - float halfHeight = (lakeBottomYHalfX - lakeSurfaceY) * 0.6f; - - // Random seed Points - int seedCount = 120; - Point size = new Point((int)(Main.maxTilesX * 0.3f), (int)(halfHeight / 0.6f)); - List<(int X, int Y)> seeds = MazeUnderLake_GenerateRandomSeeds(size, seedCount); - - for (int x = xBoundLeft; x < xBoundRight; x++) - { - halfHeight = (lakeBottomYHalfX - lakeSurfaceY) * 0.6f; - halfHeight += GetPerlinPixeG(x, 60) * 16f; - float thick = 10 + GetPerlinPixelB(x + 32, 140) * 8f; - if (x >= xBoundRight - 30) + else { - float valueH = MathF.Pow((30 + x - xBoundRight) / 6f, 2); - halfHeight += valueH; - thick += valueH; + tile.HasTile = false; } - for (int y = 0; y < halfHeight; y++) + if (pos.Y - tilePos.Y > value2 * 3 + value0 + 16) { - float value = 0; - if (y >= halfHeight - thick) + if (pos.Y - tilePos.Y > value2 * 4 + value0 * 1.2f + 24) { - value += (thick - (halfHeight - y)) / (float)thick; + tile.WallType = (ushort)ModContent.WallType(); } - - // Exist a projection. SeedMap is not TileMap. - var tile = TileUtils.SafeGetTile(x, lakeBottomYHalfX - y); - if (MazeUnderLake_IsEdgePoint(x - xBoundLeft + 15, y + 30, seeds) || value >= 0.2f) + else { - if (!tile.HasTile) - { - tile.TileType = (ushort)ModContent.TileType(); - tile.HasTile = true; - } + tile.WallType = (ushort)ModContent.WallType(); } } } - float middleSeedPosX = (xBoundRight - xBoundLeft) / 2f; - float minDis = 200; - Vector2 centerSeed = Vector2.zeroVector; - foreach (var seed in seeds) + + // Middle Cave Shaft + for (int y = -10; y <= 70; y += 2) + { + float radius = (60 - y) / 3f; + radius = MathF.Max(radius, 10) * 1.4f; + PlaceCircleAreaOfBlockWithRandomNoise(tilePos + new Point(0, y), radius, ModContent.TileType(), 3, (int)TileChangeState.HasTile); + PlaceCircleAreaOfBlockWithRandomNoise(tilePos + new Point(0, y), radius - 3, -1, 3, (int)TileChangeState.Forceful); + PlaceCircleAreaOfWallWithRandomNoise(tilePos + new Point(0, y), radius - 1, ModContent.WallType(), 3, (int)TileChangeState.HasWall); + } + + // Cave Visual Effects + int wallStart = -51; + for (int y = -10; y < 200; y++) { - Vector2 check = new Vector2(seed.X, seed.Y); - Vector2 toCenter = check - new Vector2(middleSeedPosX, 60); - if (toCenter.Length() < minDis) + var tile = SafeGetTile(tilePos + new Point(0, y)); + if (tile.WallType > WallID.None && wallStart == -51) { - minDis = toCenter.Length(); - centerSeed = check; + wallStart = y; + break; } } - CircleTile(new Vector2(xBoundLeft + centerSeed.X, lakeBottomYHalfX - centerSeed.Y), 10, ModContent.TileType()); - } + var rayTile = SafeGetTile(tilePos + new Point(0, wallStart + 5)); + rayTile.WallType = (ushort)ModContent.WallType(); + rayTile.TileType = (ushort)ModContent.TileType(); + rayTile.HasTile = true; - /// - /// 龙潭 - /// - public static void DragonPond() - { - int sandLayerTopY = (int)(Main.maxTilesY * 0.893f); - int sandLayerBottomY = (int)(Main.maxTilesY * 0.9f); - int leftX = (int)(Main.maxTilesX * 0.08f); - int RightX = (int)(Main.maxTilesX * 0.26f); - for (int x = leftX; x <= RightX; x++) + // SubFloor Cave + List Cave0_Bound = new List(); + List Cave0 = new List(); + int cave0Y = 75; + int caveHeight = 200; + YggdrasilWorld.KelpCurtain_IsleOfBloom_CaveCenter = tilePos + new Point(0, cave0Y); + for (int x = -130; x <= 130; x++) { - float xDuration = Math.Abs((x - leftX) / (float)(RightX - leftX)); - float deltaY = Main.maxTilesY * 0.003f * MathF.Pow(xDuration, 0.5f); - sandLayerTopY = (int)(Main.maxTilesY * 0.893f + deltaY); - for (int y = sandLayerBottomY; y >= sandLayerTopY; y--) + float height = 130 - MathF.Abs(x); + height = Math.Clamp(height, 0, caveHeight + 96); + float value2 = GetPerlinPixelR(x * 2, cave0Y) * 64; + height += value2; + Cave0_Bound.Add(new Vector2(x * 16, cave0Y * 16 - height)); + height -= 64; + height = Math.Clamp(height, 0, caveHeight); + value2 = GetPerlinPixelB(x * 2 + 260, cave0Y + 40) * 64; + height += value2; + if (Math.Abs(x) < 120) { - Tile tile = TileUtils.SafeGetTile(x, y); - if (!tile.HasTile) - { - tile.TileType = (ushort)ModContent.TileType(); - tile.HasTile = true; - } - if (y > sandLayerTopY + 3) - { - tile.wall = (ushort)ModContent.WallType(); - } + Cave0.Add(new Vector2(x * 16, cave0Y * 16 - height)); } } - sandLayerTopY = (int)(Main.maxTilesY * 0.893f); - SmoothTile(leftX, sandLayerTopY, RightX, sandLayerBottomY); - for (int x = leftX; x <= RightX; x++) + for (int x = 130; x >= -130; x--) { - for (int y = sandLayerTopY - 10; y < sandLayerBottomY; y++) + float height = 130 - MathF.Abs(x); + height = Math.Clamp(height, 0, caveHeight + 96); + float value2 = GetPerlinPixelB(x * 2, cave0Y + 30) * 64; + height += value2; + Cave0_Bound.Add(new Vector2(x * 16, cave0Y * 16 + height)); + height -= 64; + height = Math.Clamp(height, 0, caveHeight); + value2 = GetPerlinPixelB(x * 2 + 260, cave0Y + 70) * 64; + height += value2; + if (Math.Abs(x) < 120) { - Tile tile = TileUtils.SafeGetTile(x, y); - if (tile.HasTile) + Cave0.Add(new Vector2(x * 16, cave0Y * 16 + height)); + } + } + PlacePolygonAreaOfBlockWithOffset(Cave0_Bound, tilePos.ToWorldCoordinates(), ModContent.TileType(), (int)TileChangeState.HasTile); + PlacePolygonBoundOfBlock(Cave0_Bound, ModContent.TileType(), 64, (int)TileChangeState.HasTile); + PlacePolygonAreaOfBlockWithOffset(Cave0, tilePos.ToWorldCoordinates(), -1, (int)TileChangeState.Forceful); + SmoothTile_XXYY(tilePos.X - 150, tilePos.Y - 60, tilePos.X + 150, tilePos.Y + 150); + List caveTiles = GetPolygonAreaOfTilePos(Cave0_Bound); + IsleOfBloom_CaveKelpMoss(caveTiles); + + // Bamboo + IsleOfBloom_PlantBamboo(tilePos); + + // Side peach + for (int y = -3; y <= 40; y += 2) + { + if (GenRand.NextBool(4)) + { + int checkX = 0; + int direction = -1; + if (GenRand.NextBool()) { - if (GenRand.NextBool(2) && tile.Slope == SlopeType.Solid) + direction = 1; + } + for (int x = 0; x < 23; x++) + { + var tile = SafeGetTile(tilePos.X + x * direction, tilePos.Y + y); + checkX = (x - 1) * direction; + if (tile.HasTile) { - for (int algeaY = 0; algeaY < 90; algeaY++) + break; + } + } + if (MathF.Abs(checkX) < 21) + { + if (direction == -1) + { + if (CheckSpaceRight(tilePos.X + checkX, tilePos.Y + y) > 11) { - if (Main.rand.Next(90) < algeaY) - { - break; - } - Tile algea = TileUtils.SafeGetTile(x, y - algeaY - 1); - if (!algea.HasTile) - { - algea.TileType = (ushort)ModContent.TileType(); - algea.HasTile = true; - } + PlaceFrameImportantTiles(tilePos.X + checkX, tilePos.Y + y, 10, 1, ModContent.TileType(), 180); + IsleOfBloom_FillBlockHorizontally(tilePos + new Point(checkX - 1, y), true); + } + } + else + { + if (CheckSpaceLeft(tilePos.X + checkX, tilePos.Y + y) > 11) + { + PlaceFrameImportantTiles(tilePos.X + checkX - 10, tilePos.Y + y, 10, 1, ModContent.TileType(), 0); + IsleOfBloom_FillBlockHorizontally(tilePos + new Point(checkX, y), false); } } break; } } } - } - /// - /// 水下å®åº“ - /// - public static void UnderwaterTreasury() - { + // Peach + IsleOfBloom_PlantPeachTree_Surface(tilePos); + + // Small Peach + IsleOfBloom_PlantSmallPeachTree_Surface(tilePos); + + // Wall Peach + IsleOfBloom_PlantPeachTree_ShaftWall(tilePos); + + // Left wing and cave + IsleOfBloom_LeftWingAndCave(); + IsleOfBloom_PlantBamboo_LeftWing(tilePos); + + // Float Stone Island + IsleOfBloom_FloatStoneIsland(tilePos); } - /// - /// Build a mossy cave(horizental cave, long and flat), with moss side, radius at lease = 10. - /// - /// - /// - /// - /// - public static void DigAMossyCaveLow(int i, int j, float height, float radius) + public static void IsleOfBloomBaseLand() { - Tile firstCheck = TileUtils.SafeGetTile(i, j); - if (!firstCheck.HasTile || EmbeddingDepth(i, j, 10) < 10) + int lakeSurfaceY = (int)(Main.maxTilesY * 0.88); + int lakeCenterX = (int)(Main.maxTilesX * 0.4); + lakeSurfaceY += CheckWaterSurfaceDown(lakeCenterX, lakeSurfaceY); + int xBoundLeft = (int)(Main.maxTilesX * 0.22f); + int xBoundRight = (int)(Main.maxTilesX * 0.4f); + for (int x = xBoundLeft; x < xBoundRight; x++) { - return; + int lakeBottomY = (int)(Main.maxTilesY * 0.88); + lakeBottomY += CheckSpaceDown(lakeCenterX, lakeBottomY); + float xLength = xBoundRight - xBoundLeft; + float height = (MathF.Sin((x - xBoundLeft) / xLength * MathHelper.TwoPi - MathHelper.PiOver2) + 1) * 465f; + float heightMax = lakeBottomY - lakeSurfaceY + GetPerlinPixelG(x, 15) * 16 + 32; + height = MathF.Min(heightMax, height); + for (int y = 0; y < height; y++) + { + var tile = SafeGetTile(x, lakeBottomY - y); + tile.TileType = (ushort)ModContent.TileType(); + if (y < height - 5) + { + tile.wall = (ushort)ModContent.WallType(); + } + tile.HasTile = true; + } } - float hValue = 1f; + } - // Right Cave - int maxStepRight = (int)(radius + 3); - for (int step = 0; step < maxStepRight; step++) + public static void IsleOfBloom_PlantPeachTree_ShaftWall(Point tilePos) + { + List peachPos = new List(); + for (int t = 0; t < 999; t++) { - if (step > maxStepRight - 13) - { - hValue = (maxStepRight - 3 - step) / 10f; - } - int x = i + step; - if (maxStepRight == (int)(radius + 3)) + int x = GenRand.Next(-30, 31); + int y = GenRand.Next(-10, 101); + bool valid = true; + foreach (var pos in peachPos) { - int xCheck = x + 13; - float hCheck = 1f; - if (step + 13 > maxStepRight - 10) + if (new Vector2(x - pos.X, y - pos.Y).Length() < 7) { - hCheck = (maxStepRight - step - 13) / 10f; + valid = false; + break; } - for (int h = (int)(-height * hCheck); h <= height * hCheck; h++) + } + if (valid) + { + var checkPoint = tilePos + new Point(x, y); + var tile = SafeGetTile(checkPoint); + float toSidePeach = ToNearestTypeOfTile(tilePos.X + x, tilePos.Y + y, ModContent.TileType(), 5).Length(); + if (tile.WallType == ModContent.WallType() && !tile.HasTile && toSidePeach > 80) { - int y = j + h; - Tile tile = TileUtils.SafeGetTile(xCheck, y); - if (!tile.HasTile) + if (toSidePeach < 130) + { + Main.NewText(toSidePeach); + } + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + peachPos.Add(new Vector2(x, y)); + if (peachPos.Count > 10) { - maxStepRight = step + 13; break; } } } - for (int h = (int)(-height * hValue - 3); h <= height * hValue + 3; h++) + } + + for (int t = 0; t < 999; t++) + { + int x = GenRand.Next(-30, 31); + int y = GenRand.Next(-10, 101); + bool valid = true; + foreach (var pos in peachPos) { - int y = j + h; - Tile tile = TileUtils.SafeGetTile(x, y); - if (MathF.Abs(h) < height * hValue) + if (new Vector2(x - pos.X, y - pos.Y).Length() < 4) { - tile.wall = (ushort)ModContent.WallType(); - tile.HasTile = false; + valid = false; + break; } - else + } + if (valid) + { + var checkPoint = tilePos + new Point(x, y); + var tile = SafeGetTile(checkPoint); + float toSidePeach = ToNearestTypeOfTile(tilePos.X + x, tilePos.Y + y, ModContent.TileType(), 5).Length(); + if (tile.WallType == ModContent.WallType() && !tile.HasTile && toSidePeach > 80) { + if (toSidePeach < 130) + { + Main.NewText(toSidePeach); + } + tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; - tile.TileType = (ushort)ModContent.TileType(); - tile.wall = (ushort)ModContent.WallType(); + peachPos.Add(new Vector2(x, y)); + if (peachPos.Count > 22) + { + break; + } } } } - hValue = 1f; - // Left Cave - int maxStepLeft = (int)(radius + 3); - for (int step = 0; step < maxStepLeft + 3; step++) + for (int t = 0; t < 999; t++) { - if (step > maxStepLeft - 13) - { - hValue = (maxStepLeft - 3 - step) / 10f; - } - int x = i - step; - if (maxStepLeft == (int)(radius + 3)) + int x = GenRand.Next(-30, 31); + int y = GenRand.Next(-10, 101); + bool valid = true; + foreach (var pos in peachPos) { - int xCheck = x - 13; - float hCheck = 1f; - if (step + 13 > maxStepLeft - 10) + if (new Vector2(x - pos.X, y - pos.Y).Length() < 3) { - hCheck = (maxStepLeft - step - 13) / 10f; + valid = false; + break; } - for (int h = (int)(-height * hCheck); h <= height * hCheck; h++) + } + if (valid) + { + var checkPoint = tilePos + new Point(x, y); + var tile = SafeGetTile(checkPoint); + float toSidePeach = ToNearestTypeOfTile(tilePos.X + x, tilePos.Y + y, ModContent.TileType(), 5).Length(); + if (tile.WallType == ModContent.WallType() && !tile.HasTile && toSidePeach > 80) { - int y = j + h; - Tile tile = TileUtils.SafeGetTile(xCheck, y); - if (!tile.HasTile) + if (toSidePeach < 130) + { + Main.NewText(toSidePeach); + } + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + peachPos.Add(new Vector2(x, y)); + if (peachPos.Count > 40) { - maxStepLeft = step + 13; break; } } } - for (int h = (int)(-height * hValue - 3); h <= height * hValue + 3; h++) + } + } + + public static void IsleOfBloom_PlantPeachTree_Surface(Point tilePos) + { + List peachPosX = new List(); + for (int t = 0; t < 999; t++) + { + int x = GenRand.Next(-30, 31); + bool valid = true; + if (Math.Abs(x) < 15) { - int y = j + h; - Tile tile = TileUtils.SafeGetTile(x, y); + valid = false; + } + foreach (var oldX in peachPosX) + { + if (Math.Abs(x - oldX) < 7) + { + valid = false; + break; + } + } + if (valid) + { + int surfaceY = 0; + bool safe = false; + for (int y = 0; y <= 30; y++) + { + var checkPoint = tilePos + new Point(x, y); + var tile = SafeGetTile(checkPoint); + if (IsTileSolid(tile)) + { + surfaceY = y - 1; + safe = true; + break; + } + } + if (safe) + { + float value2 = GetFixedRandomNumber(x, surfaceY, 4); + for (int j = -1; j <= 1 + value2; j++) + { + var checkPoint = tilePos + new Point(x, surfaceY - j); + var tile = SafeGetTile(checkPoint); + if (j >= 0) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + } + else + { + IsleOfBloom_FillBlockBelow(checkPoint); + } + } + peachPosX.Add(x); + if (peachPosX.Count > 2) + { + break; + } + } + } + } + } + + public static void IsleOfBloom_PlantSmallPeachTree_Surface(Point tilePos) + { + List peachPosX = new List(); + for (int t = 0; t < 999; t++) + { + int x = GenRand.Next(-60, 61); + bool valid = true; + foreach (var oldX in peachPosX) + { + if (Math.Abs(x - oldX) < 3) + { + valid = false; + break; + } + } + if (MathF.Abs(x) < 20) + { + valid = false; + } + + if (valid) + { + int surfaceY = 0; + bool safe = false; + for (int y = 0; y <= 50; y++) + { + var checkPoint = tilePos + new Point(x, y); + var tile = SafeGetTile(checkPoint); + surfaceY = y; + float toSidePeach = ToNearestTypeOfTile(tilePos.X + x, tilePos.Y + y, ModContent.TileType(), 3).Length(); + if (tile.HasTile && tile.TileType == ModContent.TileType() && toSidePeach > 48) + { + safe = true; + break; + } + } + if (safe) + { + PlaceFrameImportantTilesAbove(tilePos.X + x, tilePos.Y + surfaceY, 1, 2, ModContent.TileType()); + IsleOfBloom_FillBlockBelow(tilePos + new Point(x, surfaceY)); + peachPosX.Add(x); + if (peachPosX.Count > 5) + { + break; + } + } + } + } + } + + public static void IsleOfBloom_LeftWingAndCave() + { + Point p0 = new Point(Main.maxTilesX / 2, (int)(Main.maxTilesY * 0.8857143f)); + p0.Y += CheckWaterSurfaceDown(p0.X, p0.Y) - 20; + int waterSurface = p0.Y + 20; + IsleOfBloom_RightSideDock(waterSurface); + int maze_TopY = waterSurface + 45; + p0.X += -CheckSpaceLeft(p0.X, p0.Y) + 30; + Point startP0 = p0; + List leftWing = new List(); + leftWing.Add(p0); + for (int t = 1; t <= 10; t++) + { + Point p1 = p0 + new Point(t * 10, (int)(GetLargeSmokeTexturePixelG(t * 4f + p0.X, p0.Y) * 26f) - 13); + leftWing.Add(p1); + if (t == 10) + { + p0 = p1; + } + else + { + GenerateStalactite(p1.ToVector2() + new Vector2(GenRand.NextFloat(-3, 3), 0), GenRand.NextFloat(3, 6), GenRand.NextFloat(8, 24), ModContent.TileType()); + if (GenRand.NextBool()) + { + GenerateStalactite(p1.ToVector2() + new Vector2(5 + GenRand.NextFloat(-3, 3), 0), GenRand.NextFloat(3, 6), GenRand.NextFloat(8, 24), ModContent.TileType()); + } + } + } + int rightBoundBottom = p0.X; + p0 += new Point(16, -16); + leftWing.Add(p0); + for (int t = 0; t <= 6; t++) + { + Point p1 = p0 + new Point(-t * 10, (int)(GetLargeSmokeTexturePixelG(t * 4f + p0.X, p0.Y) * 12f) - 6); + if (t > 3) + { + int value = t - 3; + p1.Y -= value * value * 3; + } + leftWing.Add(p1); + if (t == 6) + { + p0 = p1; + } + } + p0 += new Point(100, -100); + Point rightPeak = p0; + leftWing.Add(p0); + p0 += new Point(-180, 110); + Point leftTail = p0; + leftWing.Add(p0); + for (int t = 1; t <= 20; t++) + { + Point wallPosLerp = PointLerp(p0, startP0, t / 20f); + wallPosLerp.X += (int)(GetLargeSmokeTexturePixelB(t * 3, waterSurface) * 22 - 11); + leftWing.Add(wallPosLerp); + } + PlacePolygonAreaOfBlock(leftWing, ModContent.TileType()); + List wingTiles = GetPolygonAreaOfTilePos(leftWing); + foreach (var pos in wingTiles) + { + Vector2 line0 = rightPeak.ToVector2(); + Vector2 line1 = leftTail.ToVector2(); + float distance = MathUtils.PointToLineDistance(line0, line1, pos.ToVector2()); + float value0 = 10f / (distance + 1f); + value0 = MathF.Pow(value0, 0.5f); + float value1 = GetCellPixel(pos.X * 4, pos.Y * 4) * 10f; + value1 *= value1 / 5f; + if (value0 < 1f) + { + value1 *= value0; + } + if (value0 + value1 > 6f) + { + var tile = SafeGetTile(pos); + if (tile.HasTile && tile.TileType == ModContent.TileType()) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.WallType = (ushort)ModContent.WallType(); + } + } + } + + Point wall_p0 = p0 + new Point(-16, 16); + List leftWing_Wall = new List(); + leftWing_Wall.Add(wall_p0); + wall_p0.X += 8; + wall_p0.Y = maze_TopY; + leftWing_Wall.Add(wall_p0); + wall_p0.X += 130; + leftWing_Wall.Add(wall_p0); + Point wall_Right_destination = new Point(rightBoundBottom, waterSurface - 20); + for (int t = 0; t <= 20; t++) + { + Point wallPosLerp = PointLerp(wall_p0, wall_Right_destination, t / 20f); + wallPosLerp.X += (int)(GetLargeSmokeTexturePixelB(t, waterSurface) * 22 - 11); + leftWing_Wall.Add(wallPosLerp); + + // Arrive at the right entrance of the cave. + if (t == 20) + { + wall_p0 = wallPosLerp; + } + } + wall_p0 -= new Point(65, 65); + leftWing_Wall.Add(wall_p0); + PlacePolygonAreaOfWall(leftWing_Wall, ModContent.WallType(), (int)TileChangeState.NoWall); + for (int t = 0; t < 5; t++) + { + IsleOfBloom_SoilPlatform(new Point(leftTail.X + t * 20, leftTail.Y - 20 - t * 20), 55); + } + } + + public static void IsleOfBloom_SoilPlatform(Point tilePos, float maxLength) + { + tilePos.X += CheckSpaceRight(tilePos) - 3; + int minusY = 0; + for (int dx = 0; dx < maxLength; dx++) + { + if (GenRand.NextBool(3)) + { + minusY += 1; + } + var pos = tilePos + new Point(-dx, minusY); + if (maxLength - dx <= 1) + { + tilePos = pos; + } + int height = CheckSpaceDown(pos); + if (height < 36) + { + for (int dy = 0; dy < height; dy++) + { + var tile = SafeGetTile(pos + new Point(0, dy)); + if (!tile.HasTile) + { + if (dy > GetPerlinPixelG(pos.X, dy) * 5) + { + if (dy > GetPerlinPixelR(pos.X, dy + 5) * 5 + 10) + { + tile.TileType = (ushort)ModContent.TileType(); + } + else + { + tile.TileType = (ushort)ModContent.TileType(); + } + tile.HasTile = true; + } + if (dy > GetPerlinPixelR(pos.X, dy) * 5 + 3) + { + if (dy > GetPerlinPixelB(pos.X, dy + 5) * 5 + 13) + { + tile.WallType = (ushort)ModContent.WallType(); + } + else + { + tile.WallType = (ushort)ModContent.WallType(); + } + tile.HasTile = true; + } + } + else + { + break; + } + } + } + else + { + tilePos = pos; + break; + } + } + PlaceCircleAreaOfBlockWithRandomNoise(tilePos + new Point(0, 18), 12, ModContent.TileType(), 10, (int)TileChangeState.NoTile); + PlaceCircleAreaOfWallWithRandomNoise(tilePos + new Point(0, 18), 9, (ushort)ModContent.WallType(), 10, (int)TileChangeState.NoTile); + PlaceCircleAreaOfBlockWithRandomNoise(tilePos + new Point(0, 18), 18, ModContent.TileType(), 10, (int)TileChangeState.NoTile); + PlaceCircleAreaOfWallWithRandomNoise(tilePos + new Point(0, 18), 15, (ushort)ModContent.WallType(), 10, (int)TileChangeState.NoTile); + } + + public static void IsleOfBloom_PlantBamboo(Point tilePos) + { + List bambooPosX = new List(); + for (int t = 0; t < 999; t++) + { + int x = GenRand.Next(-110, 111); + if (MathF.Abs(x) > 30) + { + bool valid = true; + foreach (var oldX in bambooPosX) + { + if (Math.Abs(x - oldX) < 3) + { + valid = false; + break; + } + } + if (valid) + { + int surfaceY = 0; + for (int y = 0; y <= 40; y++) + { + var checkPoint = tilePos + new Point(x, y); + var tile = SafeGetTile(checkPoint); + if (tile.HasTile) + { + surfaceY = y - 1; + break; + } + } + if (surfaceY <= 39) + { + float value2 = GetFixedRandomNumber(x, surfaceY, 12); + for (int j = -1; j <= 27 + value2; j++) + { + var checkPoint = tilePos + new Point(x, surfaceY - j); + var tile = SafeGetTile(checkPoint); + if (j >= 0) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + } + else + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + tile.IsHalfBlock = false; + tile.Slope = SlopeType.Solid; + } + } + bambooPosX.Add(x); + if (bambooPosX.Count > 36) + { + break; + } + } + } + } + } + } + + public static void IsleOfBloom_PlantBamboo_LeftWing(Point tilePos) + { + tilePos += new Point(90, -140); + List bambooPosX = new List(); + for (int t = 0; t < 999; t++) + { + int x = GenRand.Next(0, 190); + if (MathF.Abs(x) > 30) + { + bool valid = true; + foreach (var oldX in bambooPosX) + { + if (Math.Abs(x - oldX) < 3) + { + valid = false; + break; + } + } + if (valid) + { + int surfaceY = CheckSpaceDown(tilePos + new Point(x, 0)) - 1; + + float value2 = GetFixedRandomNumber(x, surfaceY, 12); + for (int j = -1; j <= 27 + value2; j++) + { + var checkPoint = tilePos + new Point(x, surfaceY - j); + var tile = SafeGetTile(checkPoint); + if (j >= 0) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + } + else + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + tile.IsHalfBlock = false; + tile.Slope = SlopeType.Solid; + } + } + bambooPosX.Add(x); + if (bambooPosX.Count > 36) + { + break; + } + } + } + } + } + + public static void IsleOfBloom_FillBlockBelow(Point pos) + { + for (int x = -1; x <= 1; x++) + { + for (int y = 0; y < 100; y++) + { + var tile = SafeGetTile(pos.X + x, pos.Y + y); + if (!tile.HasTile || (tile.HasTile && (tile.IsHalfBlock || tile.Slope != SlopeType.Solid))) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + tile.IsHalfBlock = false; + tile.Slope = SlopeType.Solid; + } + else + { + break; + } + } + } + } + + public static void IsleOfBloom_FillBlockHorizontally(Point pos, bool towardLeft) + { + int dir = 1; + if (towardLeft) + { + dir = -1; + } + for (int y = -1; y <= 1; y++) + { + for (int x = 0; x < 100; x++) + { + var tile = SafeGetTile(pos.X + x * dir, pos.Y + y); + if (!tile.HasTile || (tile.HasTile && (tile.IsHalfBlock || tile.Slope != SlopeType.Solid))) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + tile.IsHalfBlock = false; + tile.Slope = SlopeType.Solid; + } + else + { + break; + } + } + } + } + + public static void IsleOfBloom_RightSideDock(int waterSurfaceY) + { + int liquidSurfaceY = waterSurfaceY; + Point dockTail = new Point((int)(Main.maxTilesX * 0.5f), liquidSurfaceY - 3); + dockTail.X -= CheckSpaceLeft(dockTail); + PlaceRectangleAreaOfBlock(dockTail.X + 28, dockTail.Y, dockTail.X - 2, dockTail.Y, ModContent.TileType(), (int)TileUtils.TileChangeState.NoTile); + PlaceRectangleAreaOfBlock(dockTail.X + 29, dockTail.Y - 1, dockTail.X - 2, dockTail.Y - 1, ModContent.TileType(), (int)TileUtils.TileChangeState.NoTile); + PlaceFrameImportantTilesAbove(dockTail.X + 27, dockTail.Y - 1, 3, 3, ModContent.TileType(), 54); + int stumpY = dockTail.Y - 2; + int stumpX = dockTail.X + 26; + for (int dx = 0; dx < 10; dx++) + { + var tile = SafeGetTile(stumpX - dx * 3, stumpY); + if (!tile.HasTile) + { + tile.TileType = TileID.WoodenBeam; + tile.HasTile = true; + } + if (dx % 4 == 0) + { + PlaceTileListTowardDownUntilCollide(new Point(stumpX - dx * 3, stumpY + 3), TileID.WoodenBeam); + } + } + } + + public static void IsleOfBloom_FloatStoneIsland(Point tilePos) + { + int count = 0; + for (int t = 0; t < 999; t++) + { + var checkPos = tilePos + new Point(GenRand.Next(-160, 161), GenRand.Next(-110, -10)); + Point nearest = FindNearestTileWithin100Range(checkPos); + float distance = PointDistance(checkPos, nearest); + float radius = GenRand.NextFloat(7, 24); + if (distance < radius + 12) + { + continue; + } + List tiles = GetCircleAreaOfTilePosWithRandomNoise(checkPos, radius, 6); + if (tiles.Count <= 0) + { + continue; + } + Point centroid = GetCentroid(tiles); + List bambooX = new List(); + foreach (var pos in tiles) + { + var tile = SafeGetTile(pos); + if (pos.Y < centroid.Y - GetLargeSmokeTexturePixelR(pos.X * 8, pos.Y * 8) * 12) + { + tile.TileType = (ushort)ModContent.TileType(); + } + else + { + tile.TileType = (ushort)ModContent.TileType(); + } + tile.HasTile = true; + var tileAbove = SafeGetTile(pos + new Point(0, -1)); + if (tileAbove.HasTile && tileAbove.TileType == ModContent.TileType()) + { + for (int j = 1; j < 999; j++) + { + var tile_above_above = SafeGetTile(pos.X, pos.Y - j); + if (tile_above_above.HasTile && tile_above_above.TileType == ModContent.TileType()) + { + tile_above_above.HasTile = false; + } + else + { + break; + } + } + } + if (GenRand.NextBool(4)) + { + if (!tileAbove.HasTile) + { + bool safe = true; + foreach (var b_x in bambooX) + { + if (Math.Abs(pos.X - b_x) < 3) + { + safe = false; + break; + } + } + if (safe) + { + int maxHeight = CheckSpaceUp(pos + new Point(0, -1)); + maxHeight = Math.Min(maxHeight, GenRand.Next(24, 40)); + for (int j = 0; j < maxHeight; j++) + { + var bambooTile = SafeGetTile(pos + new Point(0, -1) + new Point(0, -j)); + bambooTile.TileType = (ushort)ModContent.TileType(); + bambooTile.HasTile = true; + } + bambooX.Add(pos.X); + } + } + } + } + List walls = GetCircleAreaOfTilePosWithRandomNoise(checkPos, radius - 2); + foreach (var pos in walls) + { + var tile = SafeGetTile(pos); + if (tile.TileType == ModContent.TileType()) + { + tile.WallType = (ushort)ModContent.WallType(); + } + if (tile.TileType == ModContent.TileType()) + { + tile.WallType = (ushort)ModContent.WallType(); + } + } + count++; + if (count >= 10) + { + break; + } + } + } + + public static void IsleOfBloom_CaveKelpMoss(List tiles) + { + foreach (var pos in tiles) + { + var tile = SafeGetTile(pos); + if (GenRand.NextBool(2)) + { + var tile_below = SafeGetTile(pos + new Point(0, 1)); + if (tile.HasTile && tile.TileType == ModContent.TileType() && !tile_below.HasTile) + { + tile.Slope = SlopeType.Solid; + tile.IsHalfBlock = false; + var length = CheckSpaceDown(pos + new Point(0, 1)); + length = Math.Min(length, GenRand.Next(5, 15)); + for (int j = 0; j < length; j++) + { + var tile_kelp = SafeGetTile(pos + new Point(0, 1) + new Point(0, j)); + tile_kelp.TileType = (ushort)ModContent.TileType(); + tile_kelp.HasTile = true; + } + } + } + if (tile.WallType != ModContent.WallType()) + { + if (GetPerlinPixelR(pos.X, pos.Y) > 0.8f) + { + tile.WallType = (ushort)ModContent.WallType(); + } + else + { + tile.WallType = WallID.None; + } + } + } + } + + #endregion + + #region MazeUnderLake + + /// + /// 水下迷宫 + /// + public static void MazeUnderLake() + { + int lakeSurfaceY = (int)(Main.maxTilesY * 0.88); + int lakeCenterX = (int)(Main.maxTilesX * 0.4); + lakeSurfaceY += CheckWaterSurfaceDown(lakeCenterX, lakeSurfaceY); + int xBoundLeft = (int)(Main.maxTilesX * 0.34f); + int xBoundRight = (int)(Main.maxTilesX * 0.64f); + lakeCenterX = (int)(Main.maxTilesX * 0.5); + int lakeBottomYHalfX = (int)(Main.maxTilesY * 0.88); + lakeBottomYHalfX += CheckSpaceDown(lakeCenterX, lakeBottomYHalfX); + int yBoundTop = lakeSurfaceY + 45; + MazeUnderLake_TopY = yBoundTop; + int yBoundBottom = lakeBottomYHalfX + 15; + MazeUnderLake_YggdrasilBlackChestShrineCount = 0; + MazeUnderLake_YggdrasilBlackRockChestContents = new List(); + + // We need a bound of Yggdrasil Black Rock. + List MazeBoundPolygon = new List(); + int distance_Center_Left = CheckSpaceLeft(lakeCenterX, yBoundTop); + int distance_Center_Right = CheckSpaceRight(lakeCenterX, yBoundTop); + MazeBoundPolygon.Add(new Vector2(lakeCenterX - distance_Center_Left, yBoundTop) * 16); + for (int dx = lakeCenterX - distance_Center_Left + 5; dx < lakeCenterX + distance_Center_Right; dx += 10) + { + int depthOfLake = CheckSpaceDown(dx, yBoundTop); + MazeBoundPolygon.Add(new Vector2(dx, yBoundTop + depthOfLake) * 16); + } + MazeBoundPolygon.Add(new Vector2(lakeCenterX + distance_Center_Right, yBoundTop) * 16); + PlacePolygonBoundOfBlock(MazeBoundPolygon, ModContent.TileType(), 40, (int)TileChangeState.Forceful); + PlacePolygonBoundOfWall(MazeBoundPolygon, ModContent.WallType(), 40, (int)TileChangeState.Forceful); + + // Random seed Points + List seeds = GenerateRandomSeeds(xBoundLeft - 30, xBoundRight + 30, yBoundTop - 30, yBoundBottom + 30, 180, 25); + for (int x = xBoundLeft; x < xBoundRight; x++) + { + for (int y = yBoundTop; y < yBoundBottom; y++) + { + // Exist a projection. SeedMap is not TileMap. + var tile = SafeGetTile(x, y); + if (!tile.HasTile) + { + if (MazeUnderLake_IsEdgePoint(x, y, seeds)) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + } + if (MazeUnderLake_IsEdgePoint(x, y, seeds, 1.8f)) + { + tile.WallType = (ushort)ModContent.WallType(); + } + } + } + } + + for (int x = xBoundLeft; x < xBoundRight; x++) + { + for (int y = yBoundTop - 10; y <= yBoundTop + 10; y++) + { + int value = y - yBoundTop; + var tile = SafeGetTile(x, y); + if (!tile.HasTile) + { + if (value > -GetPerlinPixelG(x, y) * 4f - 4f && value < GetPerlinPixelR(x, y) * 4f + 4f) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + if (value > -GetPerlinPixelG(x, y) * 4f - 3f && value < GetPerlinPixelR(x, y) * 4f + 3f) + { + tile.WallType = (ushort)ModContent.WallType(); + } + } + } + } + } + Dictionary> holes = new Dictionary>(); + Point mediumSeedPos = default; + float minDisToCenter = new Vector2(xBoundRight - xBoundLeft, yBoundBottom - yBoundTop).Length(); + float min_seeds_Y = float.MaxValue; + float max_seeds_Y = 0; + float avg_seeds_Y = 0; + + // Connect seeds with holes, and connect seeds with each other. + foreach (var pos in seeds) + { + avg_seeds_Y += pos.Y; + min_seeds_Y = Math.Min(min_seeds_Y, pos.Y); + max_seeds_Y = Math.Max(max_seeds_Y, pos.Y); + float boundRange = 8; + Vector2 center = new Vector2(xBoundLeft + xBoundRight, yBoundTop + yBoundBottom) * 0.5f; + float toCenterDis = new Vector2(pos.X - center.X, pos.Y - center.Y).Length(); + if (toCenterDis < minDisToCenter) + { + minDisToCenter = toCenterDis; + mediumSeedPos = pos; + } + if (pos.X >= xBoundLeft + boundRange && pos.X <= xBoundRight - boundRange && pos.Y <= yBoundBottom - boundRange && pos.Y >= yBoundTop + boundRange && !SafeGetTile(pos).HasTile) + { + MazeUnderLake_AddNewConnection(pos, holes, seeds); + } + } + avg_seeds_Y /= seeds.Count; + if (mediumSeedPos != default) + { + int maxStep = 10; + for (int t = 0; t < maxStep; t++) + { + List connectedWithMediumSeeds = MazeUnderLake_GetAllConnectedPoints(holes, seeds, new List(), mediumSeedPos, 0); + foreach (var pos in connectedWithMediumSeeds) + { + bool noTileWithin5x5 = true; + for (int dx = -2; dx <= 2; dx++) + { + for (int dy = -2; dy <= 2; dy++) + { + Tile surroundTile = SafeGetTile(pos.X + dx, pos.Y + dy); + if (surroundTile.HasTile) + { + noTileWithin5x5 = false; + break; + } + } + if (!noTileWithin5x5) + { + break; + } + } + if (noTileWithin5x5) + { + MazeUnderLake_AddNewConnectionWithMediumNet(pos, holes, seeds, connectedWithMediumSeeds); + } + } + } + } + + // Fill remaining gaps during generation. This step is important to avoid too many small holes in the maze. + foreach (var pos in seeds) + { + bool inTheArea = MathUtils.IsPointInPolygon(MazeBoundPolygon, pos.ToWorldCoordinates()); + if (!inTheArea) + { + continue; + } + bool flag0 = holes.ContainsKey(pos); + if (flag0) + { + continue; + } + bool canFill = true; + foreach (var des in seeds) + { + bool flag2 = holes.ContainsKey(des) && holes[des].Contains(pos); + if (flag2) + { + canFill = false; + break; + } + } + if (canFill) + { + List cellArea = BFSContinueEmpty(pos, false, 1024); + foreach (var cell_pos in cellArea) + { + MazeUnderLake_FillYggdrasilBlackRock(cell_pos.X, cell_pos.Y); + } + } + } + for (int x = xBoundLeft; x < xBoundRight; x += 5) + { + for (int y = yBoundTop; y <= yBoundBottom; y += 5) + { + List cellArea = BFSContinueEmpty(new Point(x, y), false, 25); + if (cellArea.Count < 25 && cellArea.Count > 0) + { + foreach (var pos in cellArea) + { + MazeUnderLake_FillYggdrasilBlackRock(pos.X, pos.Y); + } + } + } + } + + // Build rooms based on seeds. + foreach (var pos in seeds) + { + bool inTheArea = MathUtils.IsPointInPolygon(MazeBoundPolygon, pos.ToWorldCoordinates()); + if (!inTheArea) + { + continue; + } + + List tiles = BFSContinueEmpty(pos, false, 1536, WaterDeliveryHoleTiles); + if (pos.Y <= avg_seeds_Y) + { + if (GenRand.NextBool(5)) + { + MazeUnderLake_RedAlgaeRoom(tiles); + } + else + { + MazeUnderLake_BuildDesolateRoom(tiles); + } + } + else + { + if (GenRand.NextBool(4)) + { + MazeUnderLake_RedAlgaeRoom(tiles); + } + else + { + if (pos.Y <= avg_seeds_Y * 0.75f + max_seeds_Y * 0.25f + GenRand.NextFloat(-120, 120)) + { + MazeUnderLake_BuildSpongeRoom(tiles); + } + else + { + MazeUnderLake_BuildFluorescentHydraRoom(tiles); + } + } + } + } + + // Entrance of the maze. This is an important part for players to find the maze and get into it. + float xMiddle = xBoundLeft + xBoundRight; + xMiddle /= 2; + int successCount = 0; + List successedX = new List(); + for (int k = 0; k < 999; k++) + { + bool success = false; + float randomX = GenRand.NextFloat(-120, 120); + float checkX = xMiddle + randomX; + float avg_x = -1; + Point checkPos = new Vector2(checkX, yBoundTop + 11).ToPoint(); + List checkRoom = BFSContinueEmpty(checkPos, false, 1536, WaterDeliveryHoleTiles); + if (checkRoom.Count > 300 && checkRoom.Count < 1536) + { + foreach (var pos in checkRoom) + { + var tile = SafeGetTile(pos); + if (WaterDeliveryHoleTiles.Contains(tile.TileType)) + { + success = true; + } + avg_x += pos.X; + } + } + if (success) + { + avg_x /= checkRoom.Count; + bool canBuildEntrance = true; + foreach (var x in successedX) + { + if (Math.Abs(avg_x - x) < 24) + { + canBuildEntrance = false; + break; + } + } + if (canBuildEntrance) + { + int surfaceY = yBoundTop - 20; + surfaceY += CheckSpaceDown((int)avg_x, surfaceY); + Vector2 entranceCenter = new Vector2(avg_x, surfaceY + 2) * 16; + float tilt = GenRand.NextFloat(-0.8f, 0.8f); + Vector2 top_Vertex = new Vector2(0, -320).RotatedBy(tilt) + entranceCenter; + Vector2 left_Vertex = new Vector2(-720, 0) + entranceCenter; + Vector2 right_Vertex = new Vector2(720, 0) + entranceCenter; + List curve_polygon = new List(); + curve_polygon.Add(left_Vertex); + for (int m = 0; m < 20; m++) + { + float value = m / 20f; + Vector2 lerpPos = Vector2.Lerp(left_Vertex, top_Vertex, value); + lerpPos = Vector2.Lerp(lerpPos, entranceCenter, MathF.Sin(value * MathHelper.Pi) * 0.5f); + curve_polygon.Add(lerpPos); + } + curve_polygon.Add(top_Vertex); + for (int m = 0; m < 20; m++) + { + float value = m / 20f; + Vector2 lerpPos = Vector2.Lerp(top_Vertex, right_Vertex, value); + lerpPos = Vector2.Lerp(lerpPos, entranceCenter, MathF.Sin(value * MathHelper.Pi) * 0.5f); + curve_polygon.Add(lerpPos); + } + curve_polygon.Add(right_Vertex); + PlacePolygonAreaOfBlock(curve_polygon, ModContent.TileType(), (int)TileChangeState.NoWall); + for (int m = 0; m < curve_polygon.Count; m++) + { + var pos = curve_polygon[m]; + pos.Y = pos.Y * 0.9f + entranceCenter.Y * 0.1f; + curve_polygon[m] = pos; + } + PlacePolygonAreaOfWall(curve_polygon, ModContent.WallType(), (int)TileChangeState.Forceful); + Vector2 des = Vector2.Lerp(top_Vertex, entranceCenter, 1.7f); + PlaceLineBlock(des, Vector2.Lerp(top_Vertex, entranceCenter, -0.2f), 48, -1, (int)TileChangeState.Forceful); + + Vector2 entranceVertice_RoomSide = Vector2.Lerp(top_Vertex, entranceCenter, 0.4f); + Point des_point = des.ToTileCoordinates(); + float roomLeft = des_point.X - CheckSpaceLeft(des_point.X, des_point.Y); + roomLeft *= 16; + roomLeft += 8; + float roomRight = des_point.X + CheckSpaceRight(des_point.X, des_point.Y); + roomRight *= 16; + roomRight += 8; + + // Main.NewText(CheckSpaceLeft(des_point.X, des_point.Y) + CheckSpaceRight(des_point.X, des_point.Y)); + List killTile_polygon = new List(); + killTile_polygon.Add(new Vector2(roomLeft, des.Y)); + for (int m = 0; m < 20; m++) + { + float value = m / 20f; + Vector2 lerpPos = Vector2.Lerp(new Vector2(roomLeft, des.Y), entranceVertice_RoomSide, value); + lerpPos = Vector2.Lerp(lerpPos, entranceCenter, MathF.Sin(value * MathHelper.Pi) * 0.5f); + killTile_polygon.Add(lerpPos); + } + killTile_polygon.Add(entranceVertice_RoomSide); + for (int m = 0; m < 20; m++) + { + float value = m / 20f; + Vector2 lerpPos = Vector2.Lerp(entranceVertice_RoomSide, new Vector2(roomRight, des.Y), value); + lerpPos = Vector2.Lerp(lerpPos, entranceCenter, MathF.Sin(value * MathHelper.Pi) * 0.5f); + killTile_polygon.Add(lerpPos); + } + killTile_polygon.Add(new Vector2(roomRight, des.Y)); + PlacePolygonAreaOfBlock(killTile_polygon, -1, (int)TileChangeState.SolidBlock); + + successCount++; + successedX.Add((int)avg_x); + } + } + if (successCount > 3) + { + break; + } + } + + // Fill remaining gaps at the bottom of the maze. + for (int x = xBoundLeft; x < xBoundRight; x += 4) + { + for (int y = (int)(avg_seeds_Y * 0.5f + max_seeds_Y * 0.5f); y <= max_seeds_Y; y += 4) + { + var tile = SafeGetTile(x, y); + if (!tile.HasTile) + { + List emptySpace = BFSContinueEmpty(new Point(x, y), false, 3072, WaterDeliveryHoleTiles); + bool shouldFill = true; + foreach (var pos in emptySpace) + { + var checkHole = SafeGetTile(pos); + if (WaterDeliveryHoleTiles.Contains(checkHole.TileType)) + { + shouldFill = false; + break; + } + } + if (shouldFill) + { + foreach (var pos in emptySpace) + { + var checkTile = SafeGetTile(pos); + checkTile.TileType = (ushort)ModContent.TileType(); + checkTile.wall = (ushort)ModContent.WallType(); + checkTile.HasTile = true; + } + } + } + } + List noSolidMazeTile = new List(WaterDeliveryHoleTiles); + noSolidMazeTile.Add(ModContent.TileType()); + noSolidMazeTile.Add(ModContent.TileType()); + noSolidMazeTile.Add(ModContent.TileType()); + noSolidMazeTile.Add(ModContent.TileType()); + noSolidMazeTile.Add(ModContent.TileType()); + noSolidMazeTile.Add(ModContent.TileType()); + noSolidMazeTile.Add(ModContent.TileType()); + noSolidMazeTile.Add(ModContent.TileType()); + noSolidMazeTile.Add(ModContent.TileType()); + noSolidMazeTile.Add(ModContent.TileType()); + noSolidMazeTile.Add(ModContent.TileType()); + noSolidMazeTile.Add(ModContent.TileType()); + noSolidMazeTile.Add(ModContent.TileType()); + noSolidMazeTile.Add(ModContent.TileType()); + noSolidMazeTile.Add(ModContent.TileType()); + noSolidMazeTile.Add(ModContent.TileType()); + for (int y = (int)avg_seeds_Y; y <= max_seeds_Y; y += 4) + { + var tile = SafeGetTile(x, y); + if (tile.WallType == WallID.None) + { + List emptySpace = BFSContinueEmpty(new Point(x, y), false, 3072, noSolidMazeTile); + foreach (var pos in emptySpace) + { + var checkTile = SafeGetTile(pos); + if (checkTile.wall == 0 && pos.Y > avg_seeds_Y + GetPerlinPixelG(pos.X, pos.Y) * 30) + { + checkTile.wall = (ushort)ModContent.WallType(); + } + } + } + } + } + + // Cover the top of the maze with DecaySandSoil. + for (int x = xBoundLeft; x < xBoundRight; x++) + { + int topCheckY = yBoundTop - 20; + var tile = SafeGetTile(x, topCheckY); + if (!IsTileSolid(tile)) + { + topCheckY += CheckSpaceDown(x, topCheckY); + } + else + { + for (int dy = 1; dy < 100; dy++) + { + var checkTile = SafeGetTile(x, topCheckY + dy); + if (!IsTileSolid(checkTile)) + { + topCheckY += dy; + break; + } + } + } + float shrink = 1f; + if (topCheckY > yBoundTop) + { + shrink = (yBoundTop + 10 - topCheckY) / 10f; + shrink = Math.Clamp(shrink, 0f, 1f); + } + int topSandY = topCheckY - (int)(7 - (GetPerlinPixelR(x, yBoundTop) * 5) * shrink); + for (int y = topSandY; y <= topCheckY + 2; y++) + { + var sandTile = SafeGetTile(x, y); + if (y > topSandY) + { + if (!IsTileSolid(sandTile)) + { + if (y < topCheckY) + { + sandTile.TileType = (ushort)ModContent.TileType(); + sandTile.HasTile = true; + if (y > topSandY + 1) + { + sandTile.wall = (ushort)ModContent.WallType(); + } + } + } + } + else + { + if (GenRand.NextBool(4)) + { + int height = GenRand.Next(4, 30); + for (int dy = 0; dy < height; dy++) + { + var algaeTile = SafeGetTile(x, y - dy); + if (!IsTileSolid(algaeTile) && algaeTile.LiquidAmount > 254) + { + algaeTile.TileType = (ushort)ModContent.TileType(); + algaeTile.HasTile = true; + } + else + { + break; + } + } + } + } + } + } + SmoothTile_XXYY(xBoundLeft - 10, yBoundTop - 40, xBoundRight + 10, yBoundTop); + } + + public static void MazeUnderLake_BuildSpongeRoom(List tiles) + { + int maxY = 0; + foreach (var pos in tiles) + { + maxY = Math.Max(maxY, pos.Y); + } + foreach (var pos in tiles) + { + Tile tile = SafeGetTile(pos); + if (pos.Y > maxY - 7 + GetPerlinPixelB(pos.X, pos.Y) && !tile.HasTile) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + PlaceWallAround(pos, (ushort)ModContent.WallType(), true, false); + } + } + foreach (var pos in tiles) + { + Tile tile = SafeGetTile(pos); + if (GetPerlinPixelB(pos.X, pos.Y * 4) > 0.55f && !tile.HasTile) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.WallType = (ushort)ModContent.WallType(); + tile.HasTile = true; + } + } + MazeUnderLake_ClearChannel(tiles); + foreach (var pos in tiles) + { + if (GenRand.NextBool(7)) + { + Tile tile = SafeGetTile(pos); + Tile tile_top = SafeGetTile(pos + new Point(0, -1)); + if (tile.HasTile && !tile_top.HasTile && Collision.IsWorldPointSolid(pos.ToWorldCoordinates())) + { + tile_top.TileType = (ushort)ModContent.TileType(); + tile_top.TileFrameY = 0; + tile_top.TileFrameX = (short)(GenRand.Next(12) * 30); + tile_top.HasTile = true; + } + } + } + foreach (var pos in tiles) + { + Tile tile = SafeGetTile(pos); + if (GetPerlinPixelR(pos.X, pos.Y * 4) > 0.2f && tile.WallType == WallID.None) + { + tile.WallType = (ushort)ModContent.WallType(); + } + } + SmoothTile_List(tiles); + } + + public static void MazeUnderLake_BuildFluorescentHydraRoom(List tiles) + { + int maxY = 0; + foreach (var pos in tiles) + { + maxY = Math.Max(maxY, pos.Y); + } + foreach (var pos in tiles) + { + Tile tile = SafeGetTile(pos); + if (pos.Y > maxY - 7 + GetPerlinPixelB(pos.X, pos.Y) && !tile.HasTile) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + PlaceWallAround(pos, (ushort)ModContent.WallType(), true, false); + } + } + MazeUnderLake_ClearChannel(tiles); + List towardUp_Mud = new List(); + List towardUp_Solid = new List(); + foreach (var pos in tiles) + { + var tile = SafeGetTile(pos); + var tile_up = SafeGetTile(pos.X, pos.Y - 1); + if (tile.HasTile && tile.TileType == ModContent.TileType() && !tile_up.HasTile && !towardUp_Mud.Contains(pos)) + { + towardUp_Mud.Add(pos); + } + if (tile.HasTile && Collision.IsWorldPointSolid(pos.ToWorldCoordinates()) && !tile_up.HasTile && !towardUp_Solid.Contains(pos)) + { + towardUp_Solid.Add(pos); + } + } + List treePosX = new List(); + foreach (var pos in towardUp_Mud) + { + int distanceToTop = CheckSpaceUp(pos.X, pos.Y - 1); + distanceToTop = Math.Min(distanceToTop, 12); + if (GenRand.NextBool(4) && distanceToTop > 4) + { + bool safeToPlace = true; + foreach (var x in treePosX) + { + if (Math.Abs(x - pos.X) <= 4) + { + safeToPlace = false; + break; + } + } + if (safeToPlace) + { + treePosX.Add(pos.X); + int height = GenRand.Next(4, distanceToTop); + for (int j = 1; j <= height; j++) + { + var f_tree = SafeGetTile(pos.X, pos.Y - j); + f_tree.TileType = (ushort)ModContent.TileType(); + f_tree.HasTile = true; + } + } + } + } + foreach (var pos in tiles) + { + Tile tile = SafeGetTile(pos); + if (tile.WallType == WallID.None) + { + tile.WallType = (ushort)ModContent.WallType(); + } + if (GenRand.NextBool(12) && !tile.HasTile) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + } + } + foreach (var pos in towardUp_Solid) + { + if (GenRand.NextBool(3)) + { + if (CanPlaceMultiAtTopTowardsUpRight(pos.X, pos.Y, 3, 3)) + { + PlaceFrameImportantTilesAbove(pos.X, pos.Y, 3, 3, ModContent.TileType(), 54 * GenRand.Next(4)); + } + } + } + foreach (var pos in towardUp_Solid) + { + Tile tile = SafeGetTile(pos + new Point(0, -1)); + if (GenRand.NextBool(12) && !tile.HasTile) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.TileFrameX = (short)(GenRand.Next(6) * 28); + tile.HasTile = true; + } + } + } + + public static void MazeUnderLake_BuildDesolateRoom(List tiles) + { + int maxY = 0; + foreach (var pos in tiles) + { + maxY = Math.Max(maxY, pos.Y); + } + Vector2 center = default; + foreach (var pos in tiles) + { + center += pos.ToVector2(); + Tile tile = SafeGetTile(pos); + if (pos.Y > maxY - 7 + GetPerlinPixelB(pos.X, pos.Y) && !tile.HasTile) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + PlaceWallAround(pos, (ushort)ModContent.WallType(), true, false); + } + } + center *= 1f / tiles.Count; + MazeUnderLake_ClearChannel(tiles); + + if (MazeUnderLake_YggdrasilBlackChestShrineCount < 8) + { + if (MazeUnderLake_BuildChestShrine(center.ToPoint())) + { + MazeUnderLake_YggdrasilBlackChestShrineCount++; + } + else if (MazeUnderLake_BuildChestShrine(center.ToPoint() + new Point(0, -1))) + { + MazeUnderLake_YggdrasilBlackChestShrineCount++; + } + else if (MazeUnderLake_BuildChestShrine(center.ToPoint() + new Point(0, 1))) + { + MazeUnderLake_YggdrasilBlackChestShrineCount++; + } + } + + List towardUp_Mud = new List(); + foreach (var pos in tiles) + { + var tile = SafeGetTile(pos); + var tile_up = SafeGetTile(pos.X, pos.Y - 1); + if (tile.HasTile && tile.TileType == ModContent.TileType() && !tile_up.HasTile && !towardUp_Mud.Contains(pos)) + { + towardUp_Mud.Add(pos); + } + } + foreach (var pos in towardUp_Mud) + { + int distanceToTop = CheckSpaceUp(pos.X, pos.Y - 1); + if (GenRand.NextBool(4) && distanceToTop > 1) + { + ushort algaeType = (ushort)ModContent.TileType(); + int height = GenRand.Next(1, distanceToTop); + for (int j = 1; j <= height; j++) + { + var algeeTile = SafeGetTile(pos.X, pos.Y - j); + algeeTile.TileType = algaeType; + algeeTile.HasTile = true; + } + } + if (GenRand.NextBool(8) && distanceToTop > 1) + { + ushort algaeType = (ushort)ModContent.TileType(); + int height = GenRand.Next(1, distanceToTop); + for (int j = 1; j <= height; j++) + { + var algeeTile = SafeGetTile(pos.X, pos.Y - j); + algeeTile.TileType = algaeType; + algeeTile.HasTile = true; + } + } + } + foreach (var pos in towardUp_Mud) + { + if (GenRand.NextBool(8)) + { + if (CanPlaceMultiAtTopTowardsUpRight(pos.X, pos.Y, 3, 2)) + { + switch (GenRand.Next(2)) + { + case 0: + PlaceFrameImportantTilesAbove(pos.X, pos.Y, 3, 2, ModContent.TileType(), 54 * GenRand.Next(4)); + break; + case 1: + PlaceFrameImportantTilesAbove(pos.X, pos.Y, 3, 2, ModContent.TileType(), 54 * GenRand.Next(6)); + break; + } + } + } + } + foreach (var pos in towardUp_Mud) + { + if (GenRand.NextBool(3)) + { + if (CanPlaceMultiAtTopTowardsUpRight(pos.X, pos.Y, 2, 2)) + { + switch (GenRand.Next(3)) + { + case 0: + PlaceFrameImportantTilesAbove(pos.X, pos.Y, 2, 2, ModContent.TileType(), 36 * GenRand.Next(4)); + break; + case 1: + PlaceFrameImportantTilesAbove(pos.X, pos.Y, 2, 2, ModContent.TileType(), 36 * GenRand.Next(4)); + break; + case 2: + PlaceFrameImportantTilesAbove(pos.X, pos.Y, 2, 2, ModContent.TileType(), 36 * GenRand.Next(6)); + break; + } + } + } + } + foreach (var pos in towardUp_Mud) + { + if (GenRand.NextBool(8)) + { + if (CanPlaceMultiAtTopTowardsUpRight(pos.X, pos.Y, 1, 2)) + { + PlaceFrameImportantTilesAbove(pos.X, pos.Y, 1, 2, ModContent.TileType(), 18 * GenRand.Next(3)); + } + } + } + } + + public static void MazeUnderLake_RedAlgaeRoom(List tiles) + { + int maxY = 0; + foreach (var pos in tiles) + { + maxY = Math.Max(maxY, pos.Y); + } + foreach (var pos in tiles) + { + Tile tile = SafeGetTile(pos); + if (pos.Y > maxY - 7 + GetPerlinPixelB(pos.X, pos.Y) && !tile.HasTile) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + PlaceWallAround(pos, (ushort)ModContent.WallType(), true, false); + } + } + MazeUnderLake_ClearChannel(tiles); + + List towardUp_Mud = new List(); + foreach (var pos in tiles) + { + var tile = SafeGetTile(pos); + var tile_up = SafeGetTile(pos.X, pos.Y - 1); + if (tile.HasTile && tile.TileType == ModContent.TileType() && !tile_up.HasTile && !towardUp_Mud.Contains(pos)) + { + towardUp_Mud.Add(pos); + } + } + float avg_mud_x = -1; + foreach (var pos in towardUp_Mud) + { + avg_mud_x += pos.X; + } + avg_mud_x /= towardUp_Mud.Count; + float closestToAvg = towardUp_Mud.Count; + Point targetForCenterPlant = default; + if (avg_mud_x != -1) + { + foreach (var pos in towardUp_Mud) + { + float disToAvg = Math.Abs(pos.X - avg_mud_x); + if (disToAvg < closestToAvg) + { + closestToAvg = disToAvg; + targetForCenterPlant = pos; + } + } + } + if (targetForCenterPlant != default) + { + int distanceToTop = CheckSpaceUp(targetForCenterPlant.X, targetForCenterPlant.Y - 1); + int height = distanceToTop / 2; + for (int j = 1; j <= height; j++) + { + var algeeTile = SafeGetTile(targetForCenterPlant.X, targetForCenterPlant.Y - j); + algeeTile.TileType = (ushort)ModContent.TileType(); + if (j == height) + { + algeeTile.TileType = (ushort)ModContent.TileType(); + } + algeeTile.HasTile = true; + } + } + foreach (var pos in towardUp_Mud) + { + int distanceToTop = CheckSpaceUp(pos.X, pos.Y - 1); + if (GenRand.NextBool(4) && distanceToTop > 1) + { + int height = GenRand.Next(1, distanceToTop); + for (int j = 1; j <= height; j++) + { + var algeeTile = SafeGetTile(pos.X, pos.Y - j); + algeeTile.TileType = (ushort)ModContent.TileType(); + algeeTile.HasTile = true; + } + } + } + + List side_tiles = new List(); + foreach (var pos in tiles) + { + var tile = SafeGetTile(pos); + var pos_up = new Point(pos.X, pos.Y - 1); + var pos_down = new Point(pos.X, pos.Y + 1); + var pos_left = new Point(pos.X - 1, pos.Y); + var pos_right = new Point(pos.X + 1, pos.Y); + bool flag = !tiles.Contains(pos_up) || !tiles.Contains(pos_down) || !tiles.Contains(pos_left) || !tiles.Contains(pos_right); + if (tile.HasTile && flag) + { + bool flag1 = !side_tiles.Contains(pos_up) || !side_tiles.Contains(pos_down) || !side_tiles.Contains(pos_left) || !side_tiles.Contains(pos_right); + if (flag1) + { + side_tiles.AddRange(BFSSurface(pos)); + } + } + } + side_tiles = side_tiles.Distinct().ToList(); + foreach (var pos in side_tiles) + { + var tile = SafeGetTile(pos); + if (tile.TileType != ModContent.TileType() && tile.TileType != ModContent.TileType()) + { + continue; + } + var tile_up = SafeGetTile(pos.X, pos.Y - 1); + var tile_down = SafeGetTile(pos.X, pos.Y + 1); + var tile_left = SafeGetTile(pos.X - 1, pos.Y); + var tile_right = SafeGetTile(pos.X + 1, pos.Y); + if (!GenRand.NextBool(3)) + { + if (!tile_up.HasTile) + { + tile_up.TileType = (ushort)ModContent.TileType(); + tile_up.HasTile = true; + } + } + if (!GenRand.NextBool(3)) + { + if (!tile_down.HasTile) + { + tile_down.TileType = (ushort)ModContent.TileType(); + tile_down.HasTile = true; + } + } + if (!GenRand.NextBool(3)) + { + if (!tile_left.HasTile) + { + tile_left.TileType = (ushort)ModContent.TileType(); + tile_left.HasTile = true; + } + } + if (!GenRand.NextBool(8)) + { + if (!tile_right.HasTile) + { + tile_right.TileType = (ushort)ModContent.TileType(); + tile_right.HasTile = true; + } + } + } + foreach (var pos in tiles) + { + if (GetPerlinPixelR(pos.X * 3, pos.Y * 3) > 0.3f) + { + var tile = SafeGetTile(pos); + tile.WallType = (ushort)ModContent.WallType(); + if (GenRand.NextBool(5) && !tile.HasTile) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + } + } + } + } + + public static void MazeUnderLake_ClearChannel(List tiles) + { + foreach (var pos in tiles) + { + Tile tile = SafeGetTile(pos); + if (WaterDeliveryHoleTiles.Contains(tile.TileType)) + { + if (tile == MazeUnderLake_WaterDeliveryHole_GetCenterTile(pos.X, pos.Y)) + { + int dir = MazeUnderLake_WaterDeliveryHole_GetDirection(tile); + Vector2 checkTilePos = tile.Center(); + Vector2 normal = new Vector2(8, 0).RotatedBy(MathHelper.PiOver4 * dir); + checkTilePos += normal * 5; + List shouldClearTilePos = new List(); + for (int k = 0; k < 32; k++) + { + checkTilePos += normal; + shouldClearTilePos.Add(checkTilePos); + if (SafeGetTile(checkTilePos.ToTileCoordinates()).TileType != ModContent.TileType()) + { + shouldClearTilePos.Add(checkTilePos + normal); + shouldClearTilePos.Add(checkTilePos + normal * 2); + shouldClearTilePos.Add(checkTilePos + normal * 3); + break; + } + } + foreach (var corePos in shouldClearTilePos) + { + KillCircleAreaOfBlockWithRandomNoiseInCertainTypeOfTile(corePos.ToTileCoordinates(), 3, new List { ModContent.TileType(), ModContent.TileType(), ModContent.TileType(), ModContent.TileType(), ModContent.TileType() }, -1, 0); + KillCircleAreaOfWallWithRandomNoiseInCertainType(corePos.ToTileCoordinates(), 4, new List { ModContent.WallType() }, -1, 0); + } + } + } + } + } + + public static int MazeUnderLake_WaterDeliveryHole_GetDirection(Tile tile) + { + int targetType = tile.TileType; + int dir = -1; + int style = TileObjectData.GetTileStyle(tile); + if (targetType == ModContent.TileType()) + { + if (style == 0) + { + dir = 6; + } + else + { + dir = 2; + } + } + if (targetType == ModContent.TileType()) + { + if (style == 0) + { + dir = 4; + } + else + { + dir = 0; + } + } + if (targetType == ModContent.TileType()) + { + dir = 1; + } + if (targetType == ModContent.TileType()) + { + dir = 3; + } + if (targetType == ModContent.TileType()) + { + dir = 5; + } + if (targetType == ModContent.TileType()) + { + dir = 7; + } + return dir; + } + + public static Tile MazeUnderLake_WaterDeliveryHole_GetCenterTile(int i, int j) + { + Tile tile = SafeGetTile(i, j); + int currentOffsetX = 0; + int currentOffsetY = 0; + bool fail = true; + if (tile.TileType == ModContent.TileType()) + { + currentOffsetX = -tile.TileFrameX / 18 + 1; + if (tile.TileFrameX >= 36) + { + currentOffsetX = -(tile.TileFrameX % 36) / 18; + } + currentOffsetY = -tile.TileFrameY / 18 + 2; + fail = false; + } + else if (tile.TileType == ModContent.TileType()) + { + currentOffsetX = -(tile.TileFrameX % 90) / 18 + 2; + currentOffsetY = -tile.TileFrameY / 18 + 1; + fail = false; + } + else if (WaterDeliveryHoleTiles.Contains(tile.TileType)) + { + int currentStyle = TileObjectData.GetTileStyle(tile); + TileObjectData currentObjectData = TileObjectData.GetTileData(tile.TileType, currentStyle); + currentOffsetX = -(tile.TileFrameX / 18 - currentStyle * currentObjectData.Width) + currentObjectData.Origin.X; + currentOffsetY = -tile.TileFrameY / 18 + currentObjectData.Origin.Y; + fail = false; + } + if (fail) + { + Main.NewText("Fail to access target", Color.Red); + } + return SafeGetTile(i + currentOffsetX, j + currentOffsetY); + } + + public static void MazeUnderLake_AddNewConnectionWithMediumNet(Point pos, Dictionary> holes, List seeds, List mediumNet, int count = 1) + { + int connectedCount = 0; + if (holes.ContainsKey(pos)) + { + connectedCount += holes[pos].Count; + } + List closeSeeds = new List(); + foreach (var otherPos in seeds) + { + if (otherPos != pos) + { + float dis = Vector2.Distance(new Vector2(pos.X, pos.Y), new Vector2(otherPos.X, otherPos.Y)); + Point des = otherPos; + bool flag1 = holes.ContainsKey(pos) && holes[pos].Contains(des); + bool flag2 = holes.ContainsKey(des) && holes[des].Contains(pos); + bool flag3 = mediumNet.Contains(des); + bool flag4 = des.Y < MazeUnderLake_TopY + 5; + bool flag5 = BFSContinueEmpty(des, false, 10).Count < 10; + bool flag6 = BFSContinueEmpty(pos, false, 10).Count < 10; + if (dis < 50 && !flag1 && !flag2 && !flag3 && !flag4 && !flag5 && !flag6) + { + closeSeeds.Add(des); + } + if (flag2) + { + connectedCount++; + } + } + } + if (connectedCount >= 3) + { + return; + } + List connectedSeeds = new List(); + if (holes.ContainsKey(pos)) + { + connectedSeeds = holes[pos]; + } + for (int k = 0; k < count; k++) + { + if (closeSeeds.Count <= 0) + { + break; + } + int index = GenRand.Next(closeSeeds.Count); + MazeUnderLake_ConnectDeliveryHole(pos.ToWorldCoordinates(), closeSeeds[index].ToWorldCoordinates()); + connectedSeeds.Add(closeSeeds[index]); + closeSeeds.RemoveAt(index); + } + if (holes.ContainsKey(pos)) + { + holes[pos] = connectedSeeds; + } + else + { + holes.Add(pos, connectedSeeds); + } + } + + public static void MazeUnderLake_AddNewConnection(Point pos, Dictionary> holes, List seeds, int count = 1) + { + List closeSeeds = new List(); + foreach (var otherPos in seeds) + { + if (otherPos != pos) + { + float dis = Vector2.Distance(new Vector2(pos.X, pos.Y), new Vector2(otherPos.X, otherPos.Y)); + Point des = otherPos; + bool flag1 = holes.ContainsKey(pos) && holes[pos].Contains(des); + bool flag2 = holes.ContainsKey(des) && holes[des].Contains(pos); + bool flag4 = des.Y < MazeUnderLake_TopY + 5; + bool flag5 = BFSContinueEmpty(des, false, 10).Count < 10; + bool flag6 = BFSContinueEmpty(pos, false, 10).Count < 10; + if (dis < 33 && !flag1 && !flag2 && !flag4 && !flag5 && !flag6) + { + closeSeeds.Add(des); + } + } + } + List connectedSeeds = new List(); + if (holes.ContainsKey(pos)) + { + connectedSeeds = holes[pos]; + } + for (int k = 0; k < count; k++) + { + if (closeSeeds.Count <= 0) + { + break; + } + int index = GenRand.Next(closeSeeds.Count); + MazeUnderLake_ConnectDeliveryHole(pos.ToWorldCoordinates(), closeSeeds[index].ToWorldCoordinates()); + connectedSeeds.Add(closeSeeds[index]); + closeSeeds.RemoveAt(index); + } + if (holes.ContainsKey(pos)) + { + holes[pos] = connectedSeeds; + } + else + { + holes.Add(pos, connectedSeeds); + } + } + + public static List MazeUnderLake_GetAllConnectedPoints(Dictionary> connectMap, List seedMap, List checkedList, Point checkPos, int step) + { + List result = checkedList; + if (step > 8) + { + return result; + } + List newPoint = new List(); + if (connectMap.ContainsKey(checkPos)) + { + List subSeed = connectMap[checkPos]; + foreach (var sub in subSeed) + { + if (!result.Contains(sub) && !newPoint.Contains(sub)) + { + newPoint.Add(sub); + } + } + } + foreach (var parentPos in connectMap.Keys) + { + if (connectMap[parentPos].Contains(checkPos)) + { + if (!result.Contains(parentPos) && !newPoint.Contains(parentPos)) + { + newPoint.Add(parentPos); + } + } + } + result.AddRange(newPoint); + foreach (var point in newPoint) + { + List subNewPoint = MazeUnderLake_GetAllConnectedPoints(connectMap, seedMap, result, point, step + 1); + foreach (var pos in subNewPoint) + { + if (!result.Contains(pos)) + { + result.Add(pos); + } + } + } + return result; + } + + public static void MazeUnderLake_ConnectDeliveryHole(Vector2 pos0, Vector2 pos1) + { + if (pos0 == pos1) + { + return; + } + Vector2 dir = (pos1 - pos0).SafeNormalize(Vector2.Zero); + float rot = dir.ToRotation(); + + int style = -1; + if (MathF.Abs(rot) <= MathHelper.Pi * 1f / 8f) + { + style = 0; + } + else if (rot <= MathHelper.Pi * 3f / 8f && rot > MathHelper.Pi * 1f / 8f) + { + style = 1; + } + else if (rot <= MathHelper.Pi * 5f / 8f && rot > MathHelper.Pi * 3f / 8f) + { + style = 2; + } + else if (rot <= MathHelper.Pi * 7f / 8f && rot > MathHelper.Pi * 5f / 8f) + { + style = 3; + } + else if (MathF.Abs(rot) >= MathHelper.Pi * 7f / 8f) + { + style = 4; + } + else if (rot >= -MathHelper.Pi * 7f / 8f && rot < -MathHelper.Pi * 5f / 8f) + { + style = 5; + } + else if (rot >= -MathHelper.Pi * 5f / 8f && rot < -MathHelper.Pi * 3f / 8f) + { + style = 6; + } + else if (rot >= -MathHelper.Pi * 3f / 8f && rot < -MathHelper.Pi * 1f / 8f) + { + style = 7; + } + Vector2 checkPos = pos0; + int penetrateState = 0; + + Point origin0 = default; + Point origin1 = default; + int penetrate1Count = 0; + for (int t = 0; t < 400; t++) + { + if (t % 2 == 0) + { + checkPos.X += dir.X * 4f; + } + else + { + checkPos.Y += dir.Y * 4f; + } + Point tilePos = checkPos.ToTileCoordinates(); + if (penetrateState == 0) + { + if (MazeUnderLake_SpecialCollisionWithDeliveryHoleStyle(checkPos, style)) + { + penetrateState = 1; + origin0 = tilePos; + } + } + + if (penetrateState == 1) + { // Second delivery hole. + penetrate1Count++; + if (!MazeUnderLake_SpecialCollisionWithDeliveryHoleStyle(checkPos, style) && penetrate1Count >= 16) + { + origin1 = tilePos; + break; + } + } + } + if (origin0 != default && origin1 != default) + { + WaterDeliveryHole_TopLeft waterDeliveryHole_TopLeft = TileLoader.GetTile(ModContent.TileType()) as WaterDeliveryHole_TopLeft; + WaterDeliveryHole_BottomRight waterDeliveryHole_BottomRight = TileLoader.GetTile(ModContent.TileType()) as WaterDeliveryHole_BottomRight; + WaterDeliveryHole_TopRight waterDeliveryHole_TopRight = TileLoader.GetTile(ModContent.TileType()) as WaterDeliveryHole_TopRight; + WaterDeliveryHole_BottomLeft waterDeliveryHole_BottomLeft = TileLoader.GetTile(ModContent.TileType()) as WaterDeliveryHole_BottomLeft; + switch (style) + { + case 0: + PlaceFrameImportantTiles(origin0.X - 1, origin0.Y - 2, 2, 5, (ushort)ModContent.TileType(), 0, 0); + PlaceRectangleAreaOfBlock_XYWH(origin0.X + 1, origin0.Y - 2, 1, 5, ModContent.TileType()); + PlaceFrameImportantTiles(origin1.X, origin1.Y - 2, 2, 5, (ushort)ModContent.TileType(), 36, 0); + PlaceRectangleAreaOfBlock_XYWH(origin1.X - 1, origin1.Y - 2, 1, 5, ModContent.TileType()); + break; + case 1: + MazeUnderLake_CheckSuitableForSlopeHole(ref origin0, 3); + waterDeliveryHole_TopLeft.PlaceAtTileObjectDataOrigin(origin0.X, origin0.Y); + MazeUnderLake_CheckSuitableForSlopeHole(ref origin1, 1); + waterDeliveryHole_BottomRight.PlaceAtTileObjectDataOrigin(origin1.X, origin1.Y); + break; + case 2: + PlaceFrameImportantTiles(origin0.X - 2, origin0.Y - 1, 5, 2, (ushort)ModContent.TileType(), 0, 0); + PlaceRectangleAreaOfBlock_XYWH(origin0.X - 2, origin0.Y + 1, 5, 1, ModContent.TileType()); + PlaceFrameImportantTiles(origin1.X - 2, origin1.Y, 5, 2, (ushort)ModContent.TileType(), 90, 0); + PlaceRectangleAreaOfBlock_XYWH(origin1.X - 2, origin1.Y - 1, 5, 1, ModContent.TileType()); + break; + case 3: + MazeUnderLake_CheckSuitableForSlopeHole(ref origin0, 0); + waterDeliveryHole_TopRight.PlaceAtTileObjectDataOrigin(origin0.X, origin0.Y); + MazeUnderLake_CheckSuitableForSlopeHole(ref origin1, 2); + waterDeliveryHole_BottomLeft.PlaceAtTileObjectDataOrigin(origin1.X, origin1.Y); + break; + case 4: + PlaceFrameImportantTiles(origin0.X, origin0.Y - 2, 2, 5, (ushort)ModContent.TileType(), 36, 0); + PlaceRectangleAreaOfBlock_XYWH(origin0.X - 1, origin0.Y - 2, 1, 5, ModContent.TileType()); + PlaceFrameImportantTiles(origin1.X - 1, origin1.Y - 2, 2, 5, (ushort)ModContent.TileType(), 0, 0); + PlaceRectangleAreaOfBlock_XYWH(origin1.X + 1, origin1.Y - 2, 1, 5, ModContent.TileType()); + break; + case 5: + MazeUnderLake_CheckSuitableForSlopeHole(ref origin0, 1); + waterDeliveryHole_BottomRight.PlaceAtTileObjectDataOrigin(origin0.X, origin0.Y); + MazeUnderLake_CheckSuitableForSlopeHole(ref origin1, 3); + waterDeliveryHole_TopLeft.PlaceAtTileObjectDataOrigin(origin1.X, origin1.Y); + break; + case 6: + PlaceFrameImportantTiles(origin0.X - 2, origin0.Y, 5, 2, (ushort)ModContent.TileType(), 90, 0); + PlaceRectangleAreaOfBlock_XYWH(origin0.X - 2, origin0.Y - 1, 5, 1, ModContent.TileType()); + PlaceFrameImportantTiles(origin1.X - 2, origin1.Y - 1, 5, 2, (ushort)ModContent.TileType(), 0, 0); + PlaceRectangleAreaOfBlock_XYWH(origin1.X - 2, origin1.Y + 1, 5, 1, ModContent.TileType()); + break; + case 7: + MazeUnderLake_CheckSuitableForSlopeHole(ref origin0, 2); + waterDeliveryHole_BottomLeft.PlaceAtTileObjectDataOrigin(origin0.X, origin0.Y); + MazeUnderLake_CheckSuitableForSlopeHole(ref origin1, 0); + waterDeliveryHole_TopRight.PlaceAtTileObjectDataOrigin(origin1.X, origin1.Y); + break; + } + List polygon = + [ + origin0.ToWorldCoordinates() + new Vector2(0, -48).RotatedBy(MathHelper.PiOver4 * style), + origin1.ToWorldCoordinates() + new Vector2(0, -48).RotatedBy(MathHelper.PiOver4 * style), + origin1.ToWorldCoordinates() + new Vector2(0, 48).RotatedBy(MathHelper.PiOver4 * style), + origin0.ToWorldCoordinates() + new Vector2(0, 48).RotatedBy(MathHelper.PiOver4 * style), + ]; + PlacePolygonAreaOfBlock(polygon, ModContent.TileType(), (int)TileChangeState.NoTile); + } + } + + /// + /// Check whether the position is suitable for placing a slope hole. + /// + /// + /// 0: TopRight 1: BottomRight 2: BottomLeft 3: TopLeft + /// A suitable point for placement. + public static void MazeUnderLake_CheckSuitableForSlopeHole(ref Point oldPoint, int slopeType) + { + switch (slopeType) + { + case 0: + for (int c = 0; c < 2; c++) + { + if (SafeGetTile(oldPoint.X - 1, oldPoint.Y).HasTile || SafeGetTile(oldPoint.X, oldPoint.Y + 1).HasTile) + { + if (c % 2 == 0) + { + oldPoint.X += 1; + } + else + { + oldPoint.Y -= 1; + } + } + } + break; + case 1: + for (int c = 0; c < 2; c++) + { + if (SafeGetTile(oldPoint.X - 1, oldPoint.Y).HasTile || SafeGetTile(oldPoint.X, oldPoint.Y - 1).HasTile) + { + if (c % 2 == 0) + { + oldPoint.X += 1; + } + else + { + oldPoint.Y += 1; + } + } + } + break; + case 2: + for (int c = 0; c < 2; c++) + { + if (SafeGetTile(oldPoint.X + 1, oldPoint.Y).HasTile || SafeGetTile(oldPoint.X, oldPoint.Y - 1).HasTile) + { + if (c % 2 == 0) + { + oldPoint.X -= 1; + } + else + { + oldPoint.Y += 1; + } + } + } + break; + case 3: + for (int c = 0; c < 2; c++) + { + if (SafeGetTile(oldPoint.X + 1, oldPoint.Y).HasTile || SafeGetTile(oldPoint.X, oldPoint.Y + 1).HasTile) + { + if (c % 2 == 0) + { + oldPoint.X -= 1; + } + else + { + oldPoint.Y -= 1; + } + } + } + break; + } + } + + public static bool MazeUnderLake_SpecialCollisionWithDeliveryHoleStyle(Vector2 checkPos, int style) + { + switch (style) + { + case 0: + if (Collision.SolidCollision(checkPos - new Vector2(8, 40), 16, 80)) + { + return true; + } + break; + case 1: + if (Collision.SolidCollision(checkPos - new Vector2(8), 16, 16) || Collision.SolidCollision(checkPos - new Vector2(8) + new Vector2(32, -32), 16, 16) || Collision.SolidCollision(checkPos - new Vector2(8) + new Vector2(-32, 32), 16, 16)) + { + return true; + } + break; + case 2: + if (Collision.SolidCollision(checkPos - new Vector2(40, 8), 80, 16)) + { + return true; + } + break; + case 3: + if (Collision.SolidCollision(checkPos - new Vector2(8), 16, 16) || Collision.SolidCollision(checkPos - new Vector2(8) + new Vector2(-32, -32), 16, 16) || Collision.SolidCollision(checkPos - new Vector2(8) + new Vector2(32, 32), 16, 16)) + { + return true; + } + break; + case 4: + if (Collision.SolidCollision(checkPos - new Vector2(8, 40), 16, 80)) + { + return true; + } + break; + case 5: + if (Collision.SolidCollision(checkPos - new Vector2(8), 16, 16) || Collision.SolidCollision(checkPos - new Vector2(8) + new Vector2(32, -32), 16, 16) || Collision.SolidCollision(checkPos - new Vector2(8) + new Vector2(-32, 32), 16, 16)) + { + return true; + } + break; + case 6: + if (Collision.SolidCollision(checkPos - new Vector2(40, 8), 80, 16)) + { + return true; + } + break; + case 7: + if (Collision.SolidCollision(checkPos - new Vector2(8), 16, 16) || Collision.SolidCollision(checkPos - new Vector2(8) + new Vector2(-32, -32), 16, 16) || Collision.SolidCollision(checkPos - new Vector2(8) + new Vector2(32, 32), 16, 16)) + { + return true; + } + break; + } + return false; + } + + public static void MazeUnderLake_FillYggdrasilBlackRock(int i, int j) + { + Tile tile = SafeGetTile(i, j); + if (!tile.HasTile) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + } + } + + public static bool MazeUnderLake_BuildChestShrine(Point pos) + { + Point tilePos = pos; + Point buildPos = pos; + int dir = 1; + if (GenRand.NextBool()) + { + dir = -1; + } + int space = CheckSpaceLeft(tilePos.X, tilePos.Y); + if (dir == -1) + { + space = CheckSpaceRight(tilePos.X, tilePos.Y); + } + buildPos.X -= space * dir; + Tile safeCheck = SafeGetTile(buildPos.X - dir, buildPos.Y); + if (safeCheck.TileType != ModContent.TileType()) + { + return false; + } + int randomAddPosX = GenRand.Next(0, 4); + buildPos.X += randomAddPosX * dir; + if (dir == 1) + { + if (GetUniformTile(buildPos.X, buildPos.Y - 9, 10, 10) == -1) + { + QuickBuild(buildPos.X, buildPos.Y - 9, ModAsset.MazeUnderLake_ChestRoom_withLamps10x10_Path, false); + MazeUnderLake_PlaceYggdrasilBlackRockUntilHitTile(buildPos + new Point(0 + 2, 1)); + MazeUnderLake_PlaceYggdrasilBlackRockUntilHitTile(buildPos + new Point(0 + 7, 1)); + PlaceRectangleAreaOfLiquid_XYWH(buildPos.X, buildPos.Y - 9, 10, 10, LiquidID.Water); + PlaceLineBlock(buildPos, buildPos + new Point(-randomAddPosX, 0), 1, ModContent.TileType()); + FillChestXYWH(buildPos.X, buildPos.Y - 9, 10, 10, MazeUnderLake_GetRandomChestContents()); + return true; + } + } + else + { + if (GetUniformTile(buildPos.X - 10, buildPos.Y - 9, 10, 10) == -1) + { + QuickBuild(buildPos.X - 10, buildPos.Y - 9, ModAsset.MazeUnderLake_ChestRoom_withLamps10x10_Path, false); + MazeUnderLake_PlaceYggdrasilBlackRockUntilHitTile(buildPos + new Point(-10 + 2, 1)); + MazeUnderLake_PlaceYggdrasilBlackRockUntilHitTile(buildPos + new Point(-10 + 7, 1)); + PlaceRectangleAreaOfLiquid_XYWH(buildPos.X - 10, buildPos.Y - 9, 10, 10, LiquidID.Water); + PlaceLineBlock(buildPos, buildPos + new Point(randomAddPosX, 0), 1, ModContent.TileType()); + FillChestXYWH(buildPos.X - 10, buildPos.Y - 9, 10, 10, MazeUnderLake_GetRandomChestContents()); + return true; + } + } + return false; + } + + public static void MazeUnderLake_PlaceYggdrasilBlackRockUntilHitTile(Point pos) + { + for (int dy = 0; dy < 100; dy++) + { + var checkPos = pos + new Point(0, dy); + var checkTile = SafeGetTile(checkPos); + if (Main.tileSolid[checkTile.TileType] && checkTile.HasTile) + { + break; + } + checkTile.wall = (ushort)ModContent.WallType(); + } + } + + public static List MazeUnderLake_GetRandomChestContents() + { + List chestContents = new List(); + int maxTypes = 6; + int index = GenRand.Next(maxTypes); + int timeTried = 0; + if (MazeUnderLake_YggdrasilBlackChestShrineCount < maxTypes) + { + while (MazeUnderLake_YggdrasilBlackRockChestContents.Contains(index)) + { + timeTried++; + index = GenRand.Next(maxTypes); + if (timeTried > 10) + { + break; + } + } + } + + MazeUnderLake_YggdrasilBlackRockChestContents.Add(index); + switch (index) + { + case 0: + chestContents.Add(new Item(setDefaultsToType: ModContent.ItemType(), 1)); + break; + case 1: + chestContents.Add(new Item(setDefaultsToType: ModContent.ItemType(), 1)); + break; + case 2: + chestContents.Add(new Item(setDefaultsToType: ModContent.ItemType(), 1)); + break; + case 3: + chestContents.Add(new Item(setDefaultsToType: ModContent.ItemType(), 1)); + break; + case 4: + chestContents.Add(new Item(setDefaultsToType: ModContent.ItemType(), 1)); + break; + case 5: + chestContents.Add(new Item(setDefaultsToType: ModContent.ItemType(), 1)); + break; + } + chestContents.AddRange(NormalChestContents_KelpCurtain()); + return chestContents; + } + + /// + /// True if the point is close to multiple seeds, which means it's likely to be at the edge of the Voronoi cell and suitable for placing delivery holes. + /// + /// + /// + /// + /// + /// + public static bool MazeUnderLake_IsEdgePoint(int x, int y, List seeds, float edgeThreshold = 2.5f) + { + // 计算到所有ç§å­ç‚¹çš„è·ç¦»å¹³æ–¹ï¼ˆé¿å…开方è¿ç®—,æé«˜æ•ˆçŽ‡ï¼‰ + List<(int SeedIndex, long DistanceSquared)> distances = new List<(int, long)>(); + + for (int i = 0; i < seeds.Count; i++) + { + long dx = x - seeds[i].X; + long dy = y - seeds[i].Y; + long distSq = dx * dx + dy * dy; // è·ç¦»å¹³æ–¹ + distances.Add((i, distSq)); + } + + // 排åºèŽ·å–æœ€è¿‘的两个ç§å­ç‚¹ + distances.Sort((a, b) => a.DistanceSquared.CompareTo(b.DistanceSquared)); + + // 如果最近两个ç§å­ç‚¹çš„è·ç¦»å·®å°äºŽé˜ˆå€¼ï¼Œåˆ™è§†ä¸ºè¾¹ç¼˜ + // 阈值å¯è°ƒæ•´ï¼šå€¼è¶Šå°è¾¹ç¼˜è¶Šç»†ï¼Œå€¼è¶Šå¤§è¾¹ç¼˜è¶Šç²— + double minDist = Math.Sqrt(distances[0].DistanceSquared); + double secondMinDist = Math.Sqrt(distances[1].DistanceSquared); + + return (secondMinDist - minDist) < edgeThreshold; + } + + #endregion + + /// + /// 龙潭 + /// + public static void DragonPond() + { + int sandLayerTopY = (int)(Main.maxTilesY * 0.893f); + int sandLayerBottomY = (int)(Main.maxTilesY * 0.9f); + int leftX = (int)(Main.maxTilesX * 0.08f); + int RightX = (int)(Main.maxTilesX * 0.26f); + for (int x = leftX; x <= RightX; x++) + { + float xDuration = Math.Abs((x - leftX) / (float)(RightX - leftX)); + float deltaY = Main.maxTilesY * 0.003f * MathF.Pow(xDuration, 0.5f); + sandLayerTopY = (int)(Main.maxTilesY * 0.893f + deltaY); + for (int y = sandLayerBottomY; y >= sandLayerTopY; y--) + { + Tile tile = SafeGetTile(x, y); + if (!tile.HasTile) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + } + if (y > sandLayerTopY + 3) + { + tile.WallType = (ushort)ModContent.WallType(); + } + } + } + sandLayerTopY = (int)(Main.maxTilesY * 0.893f); + SmoothTile_XXYY(leftX, sandLayerTopY, RightX, sandLayerBottomY); + for (int x = leftX; x <= RightX; x++) + { + for (int y = sandLayerTopY - 10; y < sandLayerBottomY; y++) + { + Tile tile = SafeGetTile(x, y); + if (tile.HasTile) + { + if (GenRand.NextBool(2) && tile.Slope == SlopeType.Solid) + { + for (int algeaY = 0; algeaY < 90; algeaY++) + { + if (Main.rand.Next(90) < algeaY) + { + break; + } + Tile algea = SafeGetTile(x, y - algeaY - 1); + if (!algea.HasTile) + { + algea.TileType = (ushort)ModContent.TileType(); + algea.HasTile = true; + } + } + } + break; + } + } + } + } + + /// + /// 水下å®åº“ + /// + public static void UnderwaterTreasury() + { + int center_x = (int)(Main.maxTilesX * 0.32f); + int center_y = (int)(Main.maxTilesY * 0.895f); + for (int dy = 0; dy < 1000; dy++) + { + var tile = SafeGetTile(center_x, center_y + dy); + if (tile.HasTile && tile.TileType == ModContent.TileType()) + { + center_y += dy - 14; + break; + } + } + UnderwaterTreasury_Bottom_Room_center_Y = center_y; + UnderwaterTreasury_GenerateUnderWaterDungeon(center_x, center_y); + } + + public static void UnderwaterTreasury_GenerateUnderWaterDungeon(int i, int j) + { + int cellHeight = 22; + int cellWidth = 34; + int cellDistance = 80; + int tunnelHeight = 16; + for (int xRoom = 0; xRoom < 1; xRoom++) + { + int centerX = i - xRoom * cellDistance; + int centerY = j; + UnderwaterTreasury_BrickRoom(centerX, centerY, cellWidth, cellHeight); + + // Trigger of the trap #0 + Point irPos = new Point(i - xRoom * cellDistance - cellWidth + 9, j); + Tile irProbeTile = SafeGetTile(irPos); + irProbeTile.TileType = (ushort)ModContent.TileType(); + irProbeTile.TileFrameX = 36; + irProbeTile.HasTile = true; + + // Trap #0 + Point underwaterGuillotinePos = new Point(i - xRoom * cellDistance - 4, j - cellHeight + 9); + UnderwaterGuillotine underwaterGuillotine = TileLoader.GetTile(ModContent.TileType()) as UnderwaterGuillotine; + if (underwaterGuillotine is not null) + { + underwaterGuillotine.PlaceOriginAtTopLeft(underwaterGuillotinePos.X, underwaterGuillotinePos.Y); + } + + // Wire #0 + ConnectWire(underwaterGuillotinePos, irPos); + + // trigger #1 + irPos = new Point(i - xRoom * cellDistance - 12, j - cellHeight + 9); + irProbeTile = SafeGetTile(irPos); + irProbeTile.TileType = (ushort)ModContent.TileType(); + irProbeTile.TileFrameX = 18; + irProbeTile.HasTile = true; + + // Trap #1 + underwaterGuillotinePos = new Point(i - xRoom * cellDistance - 22, j - cellHeight + 9); + if (underwaterGuillotine is not null) + { + underwaterGuillotine.PlaceOriginAtTopLeft(underwaterGuillotinePos.X, underwaterGuillotinePos.Y); + } + + // Wire #1 + ConnectWire(underwaterGuillotinePos, irPos, false, true); + + // trigger #2 + irPos = new Point(i - xRoom * cellDistance + 12, j - cellHeight + 9); + irProbeTile = SafeGetTile(irPos); + irProbeTile.TileType = (ushort)ModContent.TileType(); + irProbeTile.TileFrameX = 18; + irProbeTile.HasTile = true; + + // Trap #2 + underwaterGuillotinePos = new Point(i - xRoom * cellDistance + 15, j - cellHeight + 9); + if (underwaterGuillotine is not null) + { + underwaterGuillotine.PlaceOriginAtTopLeft(underwaterGuillotinePos.X, underwaterGuillotinePos.Y); + } + + // Wire #2 + ConnectWire(underwaterGuillotinePos, irPos, false, false, true); + + // Lightings + for (int t = 0; t < 4; t++) + { + int moveX = 6; + int moveY = 6; + switch (t) + { + case 0: + moveX = 6; + moveY = 6; + break; + case 1: + moveX = 20; + moveY = 7; + break; + case 2: + moveX = 11; + moveY = 8; + break; + case 3: + moveX = 7; + moveY = 11; + break; + } + int thick = 8; + int lampY = centerY - cellHeight + thick + moveY; + int lampX0 = centerX - cellWidth + thick + moveX; + int lampX1 = centerX + cellWidth - thick - moveX; + Tile lamp0 = SafeGetTile(lampX0, lampY); + Tile lamp1 = SafeGetTile(lampX1, lampY); + lamp0.TileType = (ushort)ModContent.TileType(); + lamp0.HasTile = true; + + lamp1.TileType = (ushort)ModContent.TileType(); + lamp1.HasTile = true; + } + } + for (int xRoom = 0; xRoom < 1; xRoom++) + { + if (xRoom < 1) + { + int y = j + (cellHeight - tunnelHeight / 2) - 3; + UnderwaterTreasury_ConnectWaterErodedBrickTunnel(i - xRoom * cellDistance - (cellWidth - 7), y, i - xRoom * cellDistance - cellDistance + (cellWidth - 7), y, tunnelHeight); + Tile lamp0 = SafeGetTile(i - xRoom * cellDistance - (cellWidth - 7) - 0, y); + lamp0.TileType = (ushort)ModContent.TileType(); + lamp0.HasTile = true; + } + } + UnderwaterTreasury_BrickRoom(i - 1 * cellDistance - 20, j - 90, cellWidth + 30, cellHeight); + int checkXRoom2 = i - 1 * cellDistance - 20 - (cellWidth + 10); + int checkYRoom2 = j - 95; + for (int k = 0; k < 30; k++) + { + int checkX = checkXRoom2 + k * 15; + int checkY = checkYRoom2 + (k % 2 == 0 ? 3 : 0); + Tile lamp = SafeGetTile(checkX, checkY); + if ((!lamp.HasTile || lamp.TileType != ModContent.TileType()) && lamp.wall == ModContent.WallType()) + { + lamp.TileType = (ushort)ModContent.TileType(); + lamp.HasTile = true; + } + else + { + break; + } + } + + UnderwaterTreasury_ConnectWaterErodedBrickTunnel_Serrated(new Point(i - 1 * cellDistance - 40, j - 64), new Point(i - 38, j + 9), 12, 8); + } + + public static void UnderwaterTreasury_BrickRoom(int centerX, int centerY, int halfWidth, int halfHeight) + { + int thick = 8; + + // Main structure + for (int x = centerX - halfWidth; x <= centerX + halfWidth; x++) + { + for (int y = centerY - halfHeight; y <= centerY + halfHeight; y++) + { + Tile tile = SafeGetTile(x, y); + int boundValue = halfWidth - Math.Abs(x - centerX); + int boundValue2 = halfHeight - Math.Abs(y - centerY); + boundValue = Math.Min(boundValue, boundValue2); + if (boundValue <= thick) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + } + if (boundValue > thick) + { + tile.HasTile = false; + if (boundValue > 1) + { + tile.WallType = (ushort)ModContent.WallType(); + tile.liquid = (byte)LiquidID.Water; + tile.LiquidAmount = 255; + } + } + } + } + + // Alga + for (int algaX = 0; algaX < halfWidth * 2; algaX++) + { + int height = WorldGen.genRand.Next(-12, 18); + if (height > 0) + { + Tile algaBottom = SafeGetTile(centerX - halfWidth + algaX, centerY + halfHeight - thick); + if (algaBottom.HasTile) + { + for (int algaY = 0; algaY < height; algaY++) + { + Tile algaTile = SafeGetTile(centerX - halfWidth + algaX, centerY + halfHeight - thick - algaY - 1); + if (algaTile.HasTile) + { + break; + } + else + { + algaTile.TileType = (ushort)ModContent.TileType(); + algaTile.HasTile = true; + } + } + } + } + } + + // Drain(bubbles for breathe) + Point outlet = new Point(centerX - 2, centerY); + PlaceFrameImportantTiles(outlet.X, outlet.Y, 4, 4, ModContent.TileType()); + } + + /// + /// Create a tunnel with water-erodeed brick side between 2 points. + /// + /// + /// + /// + public static void UnderwaterTreasury_ConnectWaterErodedBrickTunnel(Point p0, Point p1, float width) + { + UnderwaterTreasury_ConnectWaterErodedBrickTunnel(p0.X, p0.Y, p1.X, p1.Y, width); + } + + /// + /// Create a tunnel with water-erodeed brick side between 2 points. + /// + /// + /// + /// + /// + /// + public static void UnderwaterTreasury_ConnectWaterErodedBrickTunnel(int x0, int y0, int x1, int y1, float width) + { + int sideThick = 6; + int maxStep = (int)(new Vector2(x1, y1) - new Vector2(x0, y0)).Length(); + Vector2 dir = Vector2.Normalize(new Vector2(x1, y1) - new Vector2(x0, y0)); + Vector2 checkPoint = new Vector2(x0, y0); + float halfWidth = width / 2f; + for (int s = 0; s < maxStep; s++) + { + checkPoint += dir; + for (int x = (int)(-halfWidth); x <= halfWidth; x++) + { + for (int y = (int)(-halfWidth); y <= halfWidth; y++) + { + Vector2 checkDir = new Vector2(x, y); + bool shouldKill = false; + if (checkDir.Length() < 3f) + { + shouldKill = true; + } + else + { + Vector2 normalCheckDir = checkDir.NormalizeSafe(); + if (MathF.Abs(Vector2.Dot(normalCheckDir, dir)) <= 0.15f) + { + shouldKill = true; + } + } + if (shouldKill) + { + Tile tile = SafeGetTile((int)(x + checkPoint.X), (int)(y + checkPoint.Y)); + float distance = checkDir.Length(); + if (distance < halfWidth - (sideThick - 1)) + { + tile.HasTile = false; + tile.WallType = (ushort)ModContent.WallType(); + tile.liquid = (byte)LiquidID.Water; + tile.LiquidAmount = 255; + } + if (distance >= halfWidth - (sideThick - 1)) + { + tile.HasTile = true; + tile.TileType = (ushort)ModContent.TileType(); + if (distance < halfWidth) + { + tile.WallType = (ushort)ModContent.WallType(); + } + } + } + } + } + } + } + + /// + /// Create a tunnel with water-erodeed brick side between 2 points.Traversing altitute by creating a zigzag path. + /// + /// + /// + /// + /// + /// + public static void UnderwaterTreasury_ConnectWaterErodedBrickTunnel_Serrated(int x0, int y0, int x1, int y1, float width, float sideThick) + { + UnderwaterTreasury_ConnectWaterErodedBrickTunnel_Serrated(new Point(x0, y0), new Point(x1, y1), width, sideThick); + } + + /// + /// Create a tunnel with water-erodeed brick side between 2 points.Traversing altitute by creating a zigzag path. + /// + /// + /// + /// + /// + /// + public static void UnderwaterTreasury_ConnectWaterErodedBrickTunnel_Serrated(Point point0, Point point1, float width, float sideThick) + { + // Calculate the shape + float centerThick = width - sideThick; + int distanceY = Math.Abs((point1 - point0).Y); + Point check = point0; + int dirY = 1; + if (point1.Y < point0.Y) + { + dirY = -1; + } + int jaggedX = 0; + int jaggedDir = (int)((WorldGen.genRand.Next(2) - 0.5f) * 2); + + // Calclate the trail + List trailPos = new List(); + List inflectionPoint = new List(); + List lumpLampPoint = new List(); + List breathePoint = new List(); + List platformPoint = new List(); + for (int y = 0; y < distanceY; y++) + { + trailPos.Add(check + new Point(jaggedX, 0)); + check.Y += dirY; + jaggedX += jaggedDir * 3; + if (Math.Abs(jaggedX) > 24 && jaggedX * jaggedDir > 0) + { + jaggedDir *= -1; + inflectionPoint.Add(y); + lumpLampPoint.Add(y); + platformPoint.Add(y); + breathePoint.Add(y - 8); + } + } + check += new Point(jaggedX, 0); + int dirX = 1; + if (point1.X < check.X) + { + dirX = -1; + } + int distanceX = Math.Abs((point1 - check).X); + for (int x = 0; x <= distanceX; x++) + { + trailPos.Add(check); + check.X += dirX; + if (x % 24 == 16) + { + lumpLampPoint.Add(trailPos.Count); + } + if (x == 3) + { + breathePoint.Add(trailPos.Count); + } + } + + // Build the Exterior + for (int s = 0; s < trailPos.Count; s++) + { + PlaceSquareAreaOfBlock(trailPos[s], (int)width, ModContent.TileType()); + PlaceSquareAreaOfWall(trailPos[s], (int)width - 1, ModContent.WallType()); + } + + // Build the inner Tunnel + for (int s = 0; s < trailPos.Count; s++) + { + PlaceSquareAreaOfBlock(trailPos[s], (int)centerThick, -1); + PlaceSquareAreaOfLiquid(trailPos[s], (int)width - 1, LiquidID.Water); + } + + // Traps + for (int s = 0; s < trailPos.Count; s++) + { + // Lightning Mechanism + if (inflectionPoint.Contains(s)) + { + Point point = trailPos[s]; + Tile checkLeft = SafeGetTile(point + new Point(-8, 3)); + Tile checkRight = SafeGetTile(point + new Point(8, 3)); + Point probePos = point + new Point(0, -7); + if (checkLeft.HasTile) + { + PlaceFrameImportantTiles(point.X - 7, point.Y + 3, 5, 3, ModContent.TileType(), 90); + probePos += new Point(7, 0); + ConnectWire(probePos, new Point(point.X - 3, point.Y + 4)); + } + if (checkRight.HasTile) + { + PlaceFrameImportantTiles(point.X + 3, point.Y + 3, 5, 3, ModContent.TileType()); + probePos += new Point(-7, 0); + ConnectWire(probePos, new Point(point.X + 3, point.Y + 4)); + } + Tile irProbe = SafeGetTile(probePos); + Tile irProbeTop = SafeGetTile(probePos + new Point(0, -1)); + if (!irProbe.HasTile && irProbeTop.HasTile) + { + irProbe.TileType = (ushort)ModContent.TileType(); + irProbe.HasTile = true; + irProbe.TileFrameX = 18; + } + } + + // Lamps + if (lumpLampPoint.Contains(s)) + { + Point point = trailPos[s] + new Point(0, -1); + Tile tile = SafeGetTile(point); + if (!tile.HasTile) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + } + } + + // Drain ourlets + if (breathePoint.Contains(s)) + { + Point point = trailPos[s] + new Point(-2, 1); + PlaceFrameImportantTiles(point.X, point.Y, 4, 4, ModContent.TileType()); + } + + // Platforms + if (platformPoint.Contains(s)) + { + Point point = trailPos[s] + new Point(0, 1); + Tile checkLeft = SafeGetTile(point + new Point(-8, 2)); + Tile checkRight = SafeGetTile(point + new Point(8, 2)); + if (checkLeft.HasTile) + { + int length = CheckSpaceLeft(point.X, point.Y); + for (int x = 1; x <= 3; x++) + { + Point pointCheck = point + new Point(-length, 0) + new Point(x, 0); + WorldGen.PlaceTile(pointCheck.X, pointCheck.Y, TileID.Platforms, false, true, -1, 9); + } + Point pointChest = point + new Point(-length, 0) + new Point(1, -1); + + // TODO:Enable this. + // WorldGenMisc.PlaceChest(pointChest.X, pointChest.Y, ModContent.TileType(), new List(), 0); + length = CheckSpaceRight(point.X, point.Y); + for (int j = 0; j < 10; j++) + { + point = trailPos[s] + new Point(0, 1 + 2 * j); + for (int x = 1; x <= 2; x++) + { + Point pointCheck = point + new Point(length, 0) + new Point(-x, 0); + if (SafeGetTile(pointCheck).HasTile) + { + j = 20; + break; + } + WorldGen.PlaceTile(pointCheck.X, pointCheck.Y, TileID.Platforms, false, false, -1, 9); + } + } + } + if (checkRight.HasTile) + { + int length = CheckSpaceRight(point.X, point.Y); + for (int x = 1; x <= 3; x++) + { + Point pointCheck = point + new Point(length, 0) + new Point(-x, 0); + WorldGen.PlaceTile(pointCheck.X, pointCheck.Y, TileID.Platforms, false, true, -1, 9); + } + Point pointChest = point + new Point(length, 0) + new Point(-2, -1); + + // TODO:Enable this. + // WorldGenMisc.PlaceChest(pointChest.X, pointChest.Y, ModContent.TileType(), new List(), 0); + length = CheckSpaceLeft(point.X, point.Y); + for (int j = 0; j < 10; j++) + { + point = trailPos[s] + new Point(0, 1 + 2 * j); + for (int x = 1; x <= 2; x++) + { + Point pointCheck = point + new Point(-length, 0) + new Point(x, 0); + if (SafeGetTile(pointCheck).HasTile) + { + j = 20; + break; + } + WorldGen.PlaceTile(pointCheck.X, pointCheck.Y, TileID.Platforms, false, true, -1, 9); + } + } + } + } + } + int overLength = 15; + if (dirX < 0) + { + KillRectangleAreaOfTile(trailPos[^1].X - (int)width - overLength, trailPos[^1].Y - (int)centerThick, trailPos[^1].X, trailPos[^1].Y + (int)centerThick); + PlaceRectangleAreaOfWall(trailPos[^1].X - (int)width - overLength, trailPos[^1].Y - (int)centerThick, trailPos[^1].X, trailPos[^1].Y + (int)centerThick, ModContent.WallType()); + PlaceRectangleAreaOfLiquid(trailPos[^1].X - (int)width - overLength, trailPos[^1].Y - (int)centerThick, trailPos[^1].X, trailPos[^1].Y + (int)centerThick, LiquidID.Water); + } + else + { + KillRectangleAreaOfTile(trailPos[^1].X, trailPos[^1].Y - (int)centerThick, trailPos[^1].X + (int)width + overLength, trailPos[^1].Y + (int)centerThick); + PlaceRectangleAreaOfWall(trailPos[^1].X, trailPos[^1].Y - (int)centerThick, trailPos[^1].X + (int)width + overLength, trailPos[^1].Y + (int)centerThick, ModContent.WallType()); + PlaceRectangleAreaOfLiquid(trailPos[^1].X, trailPos[^1].Y - (int)centerThick, trailPos[^1].X + (int)width + overLength, trailPos[^1].Y + (int)centerThick, LiquidID.Water); + } + KillRectangleAreaOfTile(trailPos[0].X - (int)centerThick, trailPos[0].Y - (int)width, trailPos[0].X + (int)centerThick, trailPos[0].Y); + PlaceRectangleAreaOfWall(trailPos[0].X - (int)centerThick, trailPos[0].Y - (int)width, trailPos[0].X + (int)centerThick, trailPos[0].Y, ModContent.WallType()); + PlaceRectangleAreaOfLiquid(trailPos[0].X - (int)centerThick, trailPos[0].Y - (int)width, trailPos[0].X + (int)centerThick, trailPos[0].Y, LiquidID.Water); + } + + /// + /// The cave of Vampire Mat + /// + public static void VampireMatCave() + { + // Tunnel to the Maze; + int x = (int)(Main.maxTilesX * 0.388f); + int y = (int)(Main.maxTilesY * 0.894f); + Point entrance = new Point(x, y); + List cellRoom = BFSContinueEmpty(entrance, false, 1536, WaterDeliveryHoleTiles); + if (cellRoom.Count < 100) + { + for (int k = 0; k < 100; k++) + { + int dk = GenRand.Next(16) - 8; + Point newEntrance = entrance + new Point(dk + GenRand.Next(-3, 4), dk * 4 + GenRand.Next(-3, 4)); + cellRoom = BFSContinueEmpty(newEntrance, false, 1536, WaterDeliveryHoleTiles); + if (cellRoom.Count >= 100) + { + break; + } + } + } + bool hasDeliveryHole = false; + foreach (var pos in cellRoom) + { + var tile = SafeGetTile(pos); + if (WaterDeliveryHoleTiles.Contains(tile.TileType)) + { + hasDeliveryHole = true; + break; + } + } + Point room_centroid = GetCentroid(cellRoom); + if (!hasDeliveryHole) + { + MazeUnderLake_ConnectDeliveryHole(room_centroid.ToWorldCoordinates(), (room_centroid + new Point(1000, 0)).ToWorldCoordinates()); + } + + // Cave of Vampire Mat. + int cave_x = (int)(Main.maxTilesX * 0.3435f); + int cave_y = (int)(Main.maxTilesY * 0.894f); + Point caveCenter = new Point(cave_x, cave_y); + VampireMatCaveCenter = caveCenter.ToWorldCoordinates(); + List cave = GetCircleAreaOfTilePosWithRandomNoise(caveCenter, 54, 3); + List cave_bound = GetCircleAreaOfTilePosWithRandomNoise(caveCenter, 60, 3); + foreach (var pos in cave_bound) + { + var tile = SafeGetTile(pos); + if (tile.TileType == ModContent.TileType() || tile.TileType == ModContent.TileType()) + { + if (cave.Contains(pos)) + { + ChangeTile(tile, -1, (int)TileChangeState.Forceful); + if ((pos.ToWorldCoordinates() - VampireMatCaveCenter).Length() < 55 * 16) + { + tile.WallType = WallID.None; + } + else + { + tile.WallType = (ushort)ModContent.WallType(); + } + } + else + { + ChangeTile(tile, ModContent.TileType(), (int)TileChangeState.Forceful); + tile.WallType = (ushort)ModContent.WallType(); + } + } + tile.LiquidType = LiquidID.Water; + tile.LiquidAmount = 255; + } + + PlaceLineBlock(caveCenter, room_centroid, 12 * 16, ModContent.TileType(), (int)TileChangeState.SolidBlock); + PlaceLineWall(caveCenter, room_centroid, 12 * 16, ModContent.WallType(), (int)TileChangeState.SolidBlock); + PlaceLineBlock(caveCenter, room_centroid, 8 * 16, -1, (int)TileChangeState.SolidBlock); + + // Board Sign + Point boardSignBottom = room_centroid + new Point(3, 0); + for (int k = 0; k < 60; k++) + { + var tile = SafeGetTile(boardSignBottom); + if (IsTileSolid(boardSignBottom)) + { + break; + } + boardSignBottom.Y += 1; + } + boardSignBottom.Y -= 1; + VampireMatCave_BoardSign vMCBS = TileLoader.GetTile(ModContent.TileType()) as VampireMatCave_BoardSign; + if (vMCBS is not null) + { + vMCBS.PlaceAtTileObjectDataOrigin(boardSignBottom.X, boardSignBottom.Y); + } + + // Hanging Sign + Point hangingSignTop = room_centroid + new Point(-2, 0); + hangingSignTop.Y -= CheckSpaceUp(hangingSignTop); + VampireMatCave_HangingSign vMCHS = TileLoader.GetTile(ModContent.TileType()) as VampireMatCave_HangingSign; + if (vMCHS is not null) + { + vMCHS.PlaceAtTileObjectDataOrigin(hangingSignTop.X, hangingSignTop.Y); + } + + // Barnacle room. + Point barnacle_room_center = new Point((int)(Main.maxTilesX * 0.361f), UnderwaterTreasury_Bottom_Room_center_Y); + Point dungeon_bound = barnacle_room_center; + for (int dx = 0; dx < 300; dx++) + { + var tile = SafeGetTile(dungeon_bound.X, dungeon_bound.Y); + if (tile.HasTile && tile.TileType == ModContent.TileType()) + { + break; + } + dungeon_bound.X--; + } + barnacle_room_center = dungeon_bound; + List barnaclePolygonRoom = new List(); + for (int dx = 0; dx <= 40; dx += 5) + { + barnaclePolygonRoom.Add(barnacle_room_center + new Point(dx, (int)(-14 - 6 * MathF.Sin(dx / 40f * MathHelper.Pi * 1.5f)))); + } + for (int dx = 40; dx >= 0; dx -= 5) + { + barnaclePolygonRoom.Add(barnacle_room_center + new Point(dx, (int)(14 + 6 * MathF.Sin(dx / 40f * MathHelper.Pi * 1.5f)))); + } + PlacePolygonAreaOfBlock(barnaclePolygonRoom, -1, (int)TileChangeState.Forceful); + PlacePolygonBoundOfBlock(barnaclePolygonRoom, ModContent.TileType(), 48, (int)TileChangeState.NoTile); + PlacePolygonAreaOfWall(barnaclePolygonRoom, ModContent.WallType(), (int)TileChangeState.Forceful); + List barnacleRoom = GetPolygonAreaOfTilePos(barnaclePolygonRoom); + foreach (var pos in barnacleRoom) + { + var tile = SafeGetTile(pos); + tile.LiquidType = LiquidID.Water; + tile.LiquidAmount = 255; + } + var gGCBCT = TileLoader.GetTile(ModContent.TileType()) as GiantGhostClawBarnacleCollideTile; + if (gGCBCT != null) + { + gGCBCT.PlaceOriginAtTopLeft(barnacle_room_center.X, barnacle_room_center.Y - 12); + } + + // Tunnel to the cave of Vampire Mat. + List path_to_vampire_cave = new List(); + Vector2 checkPos = (barnacle_room_center + new Point(37, 0)).ToWorldCoordinates(); + Vector2 checkVel = new Vector2(128, 0); + for (int k = 0; k < 40; k++) + { + path_to_vampire_cave.Add(checkPos); + checkPos += checkVel; + Vector2 toTarget = caveCenter.ToWorldCoordinates() - checkPos; + if (toTarget.Length() < 120) + { + break; + } + toTarget = toTarget.NormalizeSafe(); + checkVel = checkVel * 0.92f + toTarget * 128 * 0.08f; + } + PlaceCurveBlock(path_to_vampire_cave, 16 * 16, ModContent.TileType(), (int)TileChangeState.HasTile); + PlaceCurveWall(path_to_vampire_cave, 16 * 16, ModContent.WallType(), (int)TileChangeState.HasTile); + PlaceCurveBlock(path_to_vampire_cave, 12 * 16, -1, (int)TileChangeState.HasTile); + PlaceCurveLiquid(path_to_vampire_cave, 16 * 16, LiquidID.Water, (int)TileChangeState.HasTile); + + // Add DrainOutlet for player breathing. + for (int k = 0; k < 5; k++) + { + Point tilePos = caveCenter + new Vector2(0, -480).RotatedBy(k / 5f * MathHelper.TwoPi).ToTileCoordinates(); + PlaceFrameImportantTilesAtTileObjectDataOrigin(tilePos, ModContent.TileType()); + for (int dx = -3; dx <= 4; dx++) + { + Point platformPos = tilePos + new Point(dx, 4); + var tile = SafeGetTile(platformPos); + tile.TileType = (ushort)ModContent.TileType(); + tile.TileFrameX = 0; + tile.TileFrameY = 0; + tile.HasTile = true; + if (dx == -3) + { + tile.TileFrameX = 36; + tile.TileFrameY = 0; + } + if (dx == 4) + { + tile.TileFrameX = 18; + tile.TileFrameY = 0; + } + } + } + for (int k = 0; k < 21; k++) + { + Point tilePos = caveCenter + new Vector2(0, -808).RotatedBy(k / 21f * MathHelper.TwoPi).ToTileCoordinates(); + var tile = SafeGetTile(tilePos); + if (!tile.HasTile) + { + tile.TileType = (ushort)ModContent.TileType(); + tile.HasTile = true; + } + } + } + + /// + /// Build a mossy cave(horizental cave, long and flat), with moss side, radius at lease = 10. + /// + /// + /// + /// + /// + public static void DigAMossyCaveLow(int i, int j, float height, float radius) + { + Tile firstCheck = SafeGetTile(i, j); + if (!firstCheck.HasTile || EmbeddingDepth(i, j, 10) < 10) + { + return; + } + float hValue = 1f; + + // Right Cave + int maxStepRight = (int)(radius + 3); + for (int step = 0; step < maxStepRight; step++) + { + if (step > maxStepRight - 13) + { + hValue = (maxStepRight - 3 - step) / 10f; + } + int x = i + step; + if (maxStepRight == (int)(radius + 3)) + { + int xCheck = x + 13; + float hCheck = 1f; + if (step + 13 > maxStepRight - 10) + { + hCheck = (maxStepRight - step - 13) / 10f; + } + for (int h = (int)(-height * hCheck); h <= height * hCheck; h++) + { + int y = j + h; + Tile tile = SafeGetTile(xCheck, y); + if (!tile.HasTile) + { + maxStepRight = step + 13; + break; + } + } + } + for (int h = (int)(-height * hValue - 3); h <= height * hValue + 3; h++) + { + int y = j + h; + Tile tile = SafeGetTile(x, y); + if (MathF.Abs(h) < height * hValue) + { + tile.WallType = (ushort)ModContent.WallType(); + tile.HasTile = false; + } + else + { + tile.HasTile = true; + tile.TileType = (ushort)ModContent.TileType(); + tile.WallType = (ushort)ModContent.WallType(); + } + } + } + hValue = 1f; + + // Left Cave + int maxStepLeft = (int)(radius + 3); + for (int step = 0; step < maxStepLeft + 3; step++) + { + if (step > maxStepLeft - 13) + { + hValue = (maxStepLeft - 3 - step) / 10f; + } + int x = i - step; + if (maxStepLeft == (int)(radius + 3)) + { + int xCheck = x - 13; + float hCheck = 1f; + if (step + 13 > maxStepLeft - 10) + { + hCheck = (maxStepLeft - step - 13) / 10f; + } + for (int h = (int)(-height * hCheck); h <= height * hCheck; h++) + { + int y = j + h; + Tile tile = SafeGetTile(xCheck, y); + if (!tile.HasTile) + { + maxStepLeft = step + 13; + break; + } + } + } + for (int h = (int)(-height * hValue - 3); h <= height * hValue + 3; h++) + { + int y = j + h; + Tile tile = SafeGetTile(x, y); if (MathF.Abs(h) < height * hValue) { - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); tile.HasTile = false; } else { tile.HasTile = true; tile.TileType = (ushort)ModContent.TileType(); - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } } } @@ -789,19 +4019,19 @@ public static void ConnectMossyTunnel(int x0, int y0, int x1, int y1, float widt } if (shouldKill) { - Tile tile = TileUtils.SafeGetTile((int)(x + checkPoint.X), (int)(y + checkPoint.Y)); + Tile tile = SafeGetTile((int)(x + checkPoint.X), (int)(y + checkPoint.Y)); if (tile.HasTile) { if (checkDir.Length() < halfWidth - 1) { tile.HasTile = false; - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } else { tile.HasTile = true; tile.TileType = (ushort)ModContent.TileType(); - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } } } @@ -821,56 +4051,6 @@ public static void ConnectMossyTunnel(Point p0, Point p1, float width) ConnectMossyTunnel(p0.X, p0.Y, p1.X, p1.Y, width); } - /// - /// 生æˆéšæœºç§å­ç‚¹ï¼ˆç¡®ä¿åœ¨ç‚¹é˜µèŒƒå›´å†…) - /// - public static List<(int X, int Y)> MazeUnderLake_GenerateRandomSeeds(Point size, int count) - { - List<(int X, int Y)> seeds = new List<(int X, int Y)>(); - for (int j = 0; j < size.Y / 20f; j++) - { - for (int i = 0; i < size.X / 20f; i++) - { - int x = i * 30 + GenRand.Next(-10, 10) + 10; - if (j % 2 == 0) - { - x += 15; - } - int y = (int)(j * 15 * MathF.Sqrt(3)) + GenRand.Next(-10, 10) + 10; - seeds.Add((x, y)); - } - } - return seeds; - } - - /// - /// 判断点是å¦ä¸ºå¤šè¾¹å½¢è¾¹ç¼˜ï¼ˆä¸Žä¸¤ä¸ªç§å­ç‚¹è·ç¦»ç›¸è¿‘) - /// - public static bool MazeUnderLake_IsEdgePoint(int x, int y, List<(int X, int Y)> seeds) - { - // 计算到所有ç§å­ç‚¹çš„è·ç¦»å¹³æ–¹ï¼ˆé¿å…开方è¿ç®—,æé«˜æ•ˆçŽ‡ï¼‰ - List<(int SeedIndex, long DistanceSquared)> distances = new List<(int, long)>(); - - for (int i = 0; i < seeds.Count; i++) - { - long dx = x - seeds[i].X; - long dy = y - seeds[i].Y; - long distSq = dx * dx + dy * dy; // è·ç¦»å¹³æ–¹ - distances.Add((i, distSq)); - } - - // 排åºèŽ·å–æœ€è¿‘的两个ç§å­ç‚¹ - distances.Sort((a, b) => a.DistanceSquared.CompareTo(b.DistanceSquared)); - - // 如果最近两个ç§å­ç‚¹çš„è·ç¦»å·®å°äºŽé˜ˆå€¼ï¼Œåˆ™è§†ä¸ºè¾¹ç¼˜ - // 阈值å¯è°ƒæ•´ï¼šå€¼è¶Šå°è¾¹ç¼˜è¶Šç»†ï¼Œå€¼è¶Šå¤§è¾¹ç¼˜è¶Šç²— - double minDist = Math.Sqrt(distances[0].DistanceSquared); - double secondMinDist = Math.Sqrt(distances[1].DistanceSquared); - double edgeThreshold = 2.5; // 边缘检测阈值 - - return (secondMinDist - minDist) < edgeThreshold; - } - public static int CheckWaterSurfaceDown(int x, int y) { int count = 0; @@ -880,7 +4060,7 @@ public static int CheckWaterSurfaceDown(int x, int y) { return count; } - while (!TileUtils.SafeGetTile(x0, y0).HasTile && TileUtils.SafeGetTile(x0, y0).LiquidAmount <= 0) + while (!SafeGetTile(x0, y0).HasTile && SafeGetTile(x0, y0).LiquidAmount <= 0) { if (y0 > Main.maxTilesY) { @@ -943,7 +4123,7 @@ public static void UnforcablePlaceAreaOfTile(int x0, int y0, int x1, int y1, int { for (int y = y0; y <= y1; y += 1) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); if (!tile.HasTile) { tile.TileType = (ushort)type; @@ -952,4 +4132,47 @@ public static void UnforcablePlaceAreaOfTile(int x0, int y0, int x1, int y1, int } } } + + public static List NormalChestContents_KelpCurtain() + { + List contents = new List(); + + // Gold coin + if (WorldGen.genRand.NextBool(5)) + { + contents.Add(new Item(setDefaultsToType: ItemID.GoldCoin, WorldGen.genRand.Next(3, 7))); + } + + // Potion + int potionType = 1; + switch (WorldGen.genRand.Next(6)) + { + case 0: + potionType = ItemID.WarmthPotion; + break; + case 1: + potionType = ItemID.GillsPotion; + break; + case 2: + potionType = ItemID.WaterWalkingPotion; + break; + case 3: + potionType = ItemID.SpelunkerPotion; + break; + case 4: + potionType = ItemID.MiningPotion; + break; + case 5: + potionType = ItemID.RecallPotion; + break; + } + contents.Add(new Item(setDefaultsToType: potionType, WorldGen.genRand.Next(3, 6))); + + // yggdrasil Amber + if (WorldGen.genRand.NextBool(5)) + { + contents.Add(new Item(setDefaultsToType: ModContent.ItemType(), WorldGen.genRand.Next(5, 15))); + } + return contents; + } } diff --git a/Sources/Modules/Yggdrasil/WorldGeneration/YggdrasilTownGeneration.cs b/Sources/Modules/Yggdrasil/WorldGeneration/YggdrasilTownGeneration.cs index 475fd0cfb..37b2c82c7 100644 --- a/Sources/Modules/Yggdrasil/WorldGeneration/YggdrasilTownGeneration.cs +++ b/Sources/Modules/Yggdrasil/WorldGeneration/YggdrasilTownGeneration.cs @@ -6,9 +6,12 @@ using Everglow.Yggdrasil.YggdrasilTown.Items.Materials; using Everglow.Yggdrasil.YggdrasilTown.Items.Pets; using Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.TwilightForest; +using Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Ores; using Everglow.Yggdrasil.YggdrasilTown.Items.Tools; using Everglow.Yggdrasil.YggdrasilTown.Items.Tools.Developer; using Everglow.Yggdrasil.YggdrasilTown.Items.Weapons; +using Everglow.Yggdrasil.YggdrasilTown.Items.Weapons.TwilightForest; +using Everglow.Yggdrasil.YggdrasilTown.Liquids; using Everglow.Yggdrasil.YggdrasilTown.Tiles; using Everglow.Yggdrasil.YggdrasilTown.Tiles.CyanVine; using Everglow.Yggdrasil.YggdrasilTown.Tiles.LampWood; @@ -16,7 +19,9 @@ using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest; using Everglow.Yggdrasil.YggdrasilTown.Walls; using Everglow.Yggdrasil.YggdrasilTown.Walls.TwilightForest; +using ModLiquidLib.ModLoader; using ReLogic.Utilities; +using static Everglow.Commons.Utilities.TileUtils; using static Everglow.Yggdrasil.WorldGeneration.YggdrasilWorldGeneration; namespace Everglow.Yggdrasil.WorldGeneration; @@ -40,22 +45,25 @@ public static void BuildYggdrasilTown() BuildMidnightBayou(); Main.statusText = "Giant Cavenours Pillars..."; - BuildGiantYggdrasilPosts(); + BuildGiantYggdrasilPosts(); Main.statusText = "Building Twilight Castle..."; - BuildTwilightRelic(); + BuildTwilightRelic(); Main.statusText = "Constructing LampWood Forest Mesa..."; - BuildLampWoodLand(); + BuildLampWoodLand(); Main.statusText = "Planting Twilight Crystal Forest..."; - BuildTwilightLand(); + BuildTwilightLand(); Main.statusText = "Carving the Heavenly Portal..."; BuildHeavenlyPortal(); Main.statusText = "Constructing the Yggdrasil Town Below..."; - BuildTownBelow(); + BuildMainTown(); + + Main.statusText = "Mineralizing..."; + BuildTangledSubmine(); Main.statusText = "Engraving Cage of Challengers..."; BuildStoneCageOfChallenges(); @@ -64,6 +72,7 @@ public static void BuildYggdrasilTown() BuildJellyBallHotbed(); Main.statusText = "Smoothing Yggdrasil Town..."; + SmoothYggdrasilTown(); } @@ -72,6 +81,8 @@ public static void BuildYggdrasilTown() public static Vector2 LifeLampWoodRootPos => new Vector2(Main.maxTilesX - 100, Main.maxTilesY - 560); + public static Point YggdrasilTownTopLeft; + public static List StreetConstructorsSheet; public static List InDoorChineseStyleHangingSheet; public static List TwilightBonusList; @@ -83,56 +94,6 @@ public static void BuildYggdrasilTown() /// public static void Initialize() { - FillPerlinPixel(); - { - // StreetConstructorsSheet = new List() - // { - // new Lamppost(), - // new Bench(), - // new Crate(), - // new ThreeCrate(), - // new FolkHouseofChineseStyle(), - // new FolkHouseofWoodStoneStruture(), - // new FolkHouseofWoodStruture(), - // new TwoStoriedFolkHouse(), - // new SmithyType(), - // }; - // InDoorChineseStyleHangingSheet = new List() - // { - // new BambooChandelier(), - // new CrystalChandelier(), - // new CylinderChandelierGroup(), - // new DynasticChandelier(), - // new EvilChandelier(), - // new GoldenChandelier(), - // new GraniteChandelier(), - // new GreenDungeonChandelier(), - // new HexagonalCeilingChandelier(), - // new MetalChandelier(), - // new PalmChandelier(), - // new RichMahoganyChandelier(), - - // new DiscoBall(), - - // new FireflyBottle(), - // new LavaFlyBottle(), - // new LightningBugBottle(), - // new SoulBottle(), - - // new BambooLantern(), - // new BowlLantern(), - // new ChineseLantern(), - // new DynasticLantern(), - // new FleshLantern(), - // new GlassLantern(), - // new LivingWoodLantern(), - // new MetalLantern(), - // new SpellLantern(), - // new BurningBowl(), - // new PlantBowl(), - // new EmptyAnchoredTop(), - // }; - }// Expired codes. TwilightBonusList = new List { ModContent.ItemType(), @@ -168,7 +129,7 @@ public static void BuildMidnightBayou() { for (int y = center.Y - 60; y < center.Y + radious; y++) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); float color = PerlinPixel2[Math.Clamp((int)(x - center.X + radious * 1.5f) / 3, 0, 1024), Math.Clamp((y - center.Y + radious) / 2, 0, 1024)] / 255f; float distance = new Vector2((x - center.X) * 0.6667f, y - center.Y).Length() / 200f; if (color + distance > 1.5f) @@ -177,7 +138,7 @@ public static void BuildMidnightBayou() tile.HasTile = true; if (color + distance > 1.6f) { - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } } else @@ -186,10 +147,10 @@ public static void BuildMidnightBayou() } if (y > center.Y + 30) { - if (!tile.HasTile) + if (!tile.HasTile && tile.LiquidAmount == 0) { - tile.TileType = (ushort)ModContent.TileType(); - tile.HasTile = true; + tile.LiquidType = LiquidLoader.LiquidType(); + tile.LiquidAmount = byte.MaxValue; } } } @@ -206,25 +167,25 @@ public static void BuildMidnightBayou() KillRectangleAreaOfTile(leftBound, startY - 10, rightBound, startY); // æºæ™¶å¡” - TileUtils.PlaceFrameImportantTiles(1395, startY - 37, 8, 12, ModContent.TileType()); - TileUtils.PlaceFrameImportantTiles(1257, startY, 3, 1, ModContent.TileType(), 0, 18); - TileUtils.PlaceFrameImportantTiles(1253, startY + 7, 7, 1, ModContent.TileType(), 36, 36); + // PlaceFrameImportantTiles(1395, startY - 37, 8, 12, ModContent.TileType()); + PlaceFrameImportantTiles(1257, startY, 3, 1, ModContent.TileType(), 0, 18); + PlaceFrameImportantTiles(1253, startY + 7, 7, 1, ModContent.TileType(), 36, 36); for (int x = leftBound + 5; x < rightBound - 5; x++) { if (x % 20 == 0) { - TileUtils.PlaceFrameImportantTiles(x, startY, 20, 1, ModContent.TileType(), 0, 0); + PlaceFrameImportantTiles(x, startY, 20, 1, ModContent.TileType(), 0, 0); - TileUtils.PlaceFrameImportantTiles(x, startY + 7, 20, 1, ModContent.TileType(), 36, 36); + PlaceFrameImportantTiles(x, startY + 7, 20, 1, ModContent.TileType(), 36, 36); } } - TileUtils.PlaceFrameImportantTiles(1440, startY, 8, 1, ModContent.TileType(), 0, 54); + PlaceFrameImportantTiles(1440, startY, 8, 1, ModContent.TileType(), 0, 54); - TileUtils.PlaceFrameImportantTiles(1440, startY - 3, 4, 3, ModContent.TileType(), 0, 0); + PlaceFrameImportantTiles(1440, startY - 3, 4, 3, ModContent.TileType(), 0, 0); - TileUtils.PlaceFrameImportantTiles(1440, startY + 7, 12, 1, ModContent.TileType(), 36, 36); + PlaceFrameImportantTiles(1440, startY + 7, 12, 1, ModContent.TileType(), 36, 36); - TileUtils.PlaceFrameImportantTiles(1470, startY + 7, 16, 1, ModContent.TileType(), 0, 72); + PlaceFrameImportantTiles(1470, startY + 7, 16, 1, ModContent.TileType(), 0, 72); } /// @@ -273,7 +234,7 @@ public static void BuildGiantYggdrasilPosts() { point += velocity; oldPoints.Add(point); - if (TileUtils.SafeGetTile((int)(point + velocity * 30).X, (int)(point + velocity).Y).HasTile) + if (SafeGetTile((int)(point + velocity * 30).X, (int)(point + velocity).Y).HasTile) { point -= velocity; velocity.X *= -1; @@ -311,14 +272,14 @@ public static void BuildGiantYggdrasilPosts() int x = (int)point.X + dx; int y = (int)point.Y + dy; - float aValue = PerlinPixelB[(x + x0CoordPerlin) % 1024, (y + y0CoordPerlin) % 1024] / 8f; + float aValue = GetLargeSmokeTexturePixelB(x + x0CoordPerlin, y + y0CoordPerlin) * 32f; if (v0.Length() < radious - aValue) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.TileType = (ushort)ModContent.TileType(); if (v0.Length() < radious - aValue - 2) { - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } tile.HasTile = true; } @@ -335,9 +296,9 @@ public static void BuildGiantYggdrasilPosts() int upY = (int)(oldPoints[a].Y - radious); int downY = (int)(oldPoints[a].Y + radious); - // SmoothTile(leftX, upY, rightX, downY); + // SmoothTile_XXYY(leftX, upY, rightX, downY); } - FillLiquid(oldPoints[a] + new Vector2(0, MathF.Sqrt(Main.rand.NextFloat(1))).RotatedByRandom(MathHelper.TwoPi) * radious); + FillLiquid(oldPoints[a] * 16 + new Vector2(0, MathF.Sqrt(Main.rand.NextFloat(16))).RotatedByRandom(MathHelper.TwoPi) * radious); } } } @@ -354,7 +315,7 @@ public static void BuildHeavenlyPortal() { for (int y = center.Y - radious; y < center.Y - 60; y++) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); float color = PerlinPixel2[Math.Clamp((int)(x - center.X + radious * 1.5f) / 3, 0, 1024), Math.Clamp((y - center.Y + radious) / 2, 0, 1024)] / 255f; float distance = new Vector2((x - center.X) * 0.6667f, y - center.Y).Length() / 200f; if (color + distance is > 1.5f and < 2f) @@ -363,7 +324,7 @@ public static void BuildHeavenlyPortal() tile.HasTile = true; if (color + distance > 1.6f) { - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } } else if (color + distance < 1.5f) @@ -379,111 +340,6 @@ public static void BuildHeavenlyPortal() /// public static void BuildAzureGrotto() { - // int startX = AzureGrottoCenterX; - // int bottomY = 11000; - // while (!TileUtils.SafeGetTile(startX, bottomY).HasTile) - // { - // bottomY++; - // if (bottomY > 11900) - // { - // break; - // } - // } - // int height = GenRand.Next(270, 321); - // int maxWidth = GenRand.Next(960, 981); - // int y0CoordPerlin = GenRand.Next(1024); - // int y1CoordPerlin = GenRand.Next(1024); - - // for (int y = -30; y < height; y++) - // { - // float heightValue = y / (float)height; - // int width = (int)(Math.Pow(2, 8 * (heightValue - 0.9)) / 4d * maxWidth) + 25; - // for (int x = -width; x <= width; x++) - // { - // float thickValue = PerlinPixelG[(int)(x * 0.9f + maxWidth * 1f) % 1024, y0CoordPerlin] * 0.2f; - // float thickValueUp = PerlinPixelG[(int)(x * 0.9f + maxWidth * 1f) % 1024, y1CoordPerlin] * 0.08f; - // float mulThickValue = 1; - // if (maxWidth * 0.4377f - Math.Abs(x) < 30) - // { - // mulThickValue = (maxWidth * 0.4377f - Math.Abs(x)) / 60f; - // mulThickValue = MathF.Sin(mulThickValue * MathF.PI); - // } - // thickValue *= mulThickValue; - // thickValue = Math.Max(thickValue, 6); - // thickValueUp *= mulThickValue; - // thickValueUp = Math.Max(thickValueUp, 4); - // if (x <= -width + 8 || x >= width - 8) - // { - // if ((startX - 600) * x > 0) - // { - // int y1 = (int)-thickValueUp; - // while (true) - // { - // y1++; - // if (y1 > bottomY + 500) - // { - // break; - // } - // int finalX = x + startX; - // int finalY = bottomY - y + y1; - // Tile tile = TileUtils.SafeGetTile(finalX, finalY); - // if (!tile.HasTile) - // { - // tile.TileType = (ushort)ModContent.TileType(); - // tile.HasTile = true; - // if ((x <= -width + 12 && x >= -width + 3) || (x >= width - 12 && x <= width - 3)) - // { - // tile.wall = (ushort)ModContent.WallType(); - // } - // if (y1 > 0) - // { - // tile.wall = (ushort)ModContent.WallType(); - // } - // } - // else if (TileUtils.SafeGetTile(finalX, finalY + 5).HasTile) - // { - // for (int y2 = 0; y2 < 6; y2++) - // { - // Tile tile2 = TileUtils.SafeGetTile(finalX, finalY + y2); - // tile2.wall = (ushort)ModContent.WallType(); - // } - // break; - // } - // } - // } - // else - // { - // for (int y1 = (int)-thickValueUp; y1 < thickValue; y1++) - // { - // int finalX = x + startX; - // int finalY = bottomY - y + y1; - // Tile tile = TileUtils.SafeGetTile(finalX, finalY); - // if (!tile.HasTile) - // { - // tile.TileType = (ushort)ModContent.TileType(); - // tile.HasTile = true; - // if ((x <= -width + 12 && x >= -width + 3) || (x >= width - 12 && x <= width - 3)) - // { - // tile.wall = (ushort)ModContent.WallType(); - // } - // if (y1 > 0 && y1 < thickValue - 4) - // { - // tile.wall = (ushort)ModContent.WallType(); - // } - // } - // } - // } - // } - // else - // { - // int finalX = x + startX; - // int finalY = bottomY - y; - // Tile tile = TileUtils.SafeGetTile(finalX, finalY); - // tile.LiquidType = LiquidID.Water; - // tile.LiquidAmount = 255; - // } - // } - // } } /// @@ -491,10 +347,10 @@ public static void BuildAzureGrotto() /// public static void BuildTangledSubmine() { - Minerization(40, Main.maxTilesY - 700, Main.maxTilesX / 2 + 50, Main.maxTilesY - 50); + Minerization(40, Main.maxTilesY - 820, Main.maxTilesX / 2 + 50, Main.maxTilesY - 50); for (int i = 0; i < 200; i++) { - Vector2 pos = new Vector2(Main.rand.Next(40, Main.maxTilesX / 2 + 50), Main.rand.Next(Main.maxTilesY - 700, Main.maxTilesY - 20)); + Point pos = new Point(Main.rand.Next(40, Main.maxTilesX / 2 + 50), Main.rand.Next(Main.maxTilesY - 700, Main.maxTilesY - 20)); FillLiquid(pos); } } @@ -525,21 +381,22 @@ public static void Minerization(int leftX, int upY, int rightX, int downY) { for (int y = upY; y < downY; y++) { - Tile tile = TileUtils.SafeGetTile(x, y); - Tile tileUp = TileUtils.SafeGetTile(x, y - 1); - Tile tileUp1 = TileUtils.SafeGetTile(x - 1, y - 1); - Tile tileUp2 = TileUtils.SafeGetTile(x - 2, y - 1); - Tile tileUp3 = TileUtils.SafeGetTile(x - 3, y - 1); - Tile tileUp4 = TileUtils.SafeGetTile(x - 4, y - 1); - Tile tileLeft1 = TileUtils.SafeGetTile(x - 1, y); - Tile tileLeft2 = TileUtils.SafeGetTile(x - 2, y); - Tile tileLeft3 = TileUtils.SafeGetTile(x - 3, y); - Tile tileLeft4 = TileUtils.SafeGetTile(x - 4, y); + Tile tile = SafeGetTile(x, y); + Tile tileUp = SafeGetTile(x, y - 1); + Tile tileUp1 = SafeGetTile(x - 1, y - 1); + Tile tileUp2 = SafeGetTile(x - 2, y - 1); + Tile tileUp3 = SafeGetTile(x - 3, y - 1); + Tile tileUp4 = SafeGetTile(x - 4, y - 1); + Tile tileMiddleUpUp = SafeGetTile(x - 2, y - 2); + Tile tileLeft1 = SafeGetTile(x - 1, y); + Tile tileLeft2 = SafeGetTile(x - 2, y); + Tile tileLeft3 = SafeGetTile(x - 3, y); + Tile tileLeft4 = SafeGetTile(x - 4, y); if (tile.LiquidAmount > 0 || tileUp.LiquidAmount > 0 || tileUp1.LiquidAmount > 0 || tileUp2.LiquidAmount > 0 || tileUp3.LiquidAmount > 0 || tileUp4.LiquidAmount > 0 || tileLeft1.LiquidAmount > 0 || tileLeft1.LiquidAmount > 0 || tileLeft2.LiquidAmount > 0 || tileLeft3.LiquidAmount > 0 || tileLeft4.LiquidAmount > 0) { continue; } - if (tileLeft1.HasTile && tileLeft2.HasTile && tileLeft3.HasTile && tileLeft4.HasTile && tile.HasTile && !tileUp.HasTile && !tileUp4.HasTile) + if (tileLeft1.HasTile && tileLeft2.HasTile && tileLeft3.HasTile && tileLeft4.HasTile && tile.HasTile && !tileUp.HasTile && !tileUp4.HasTile! && !tileMiddleUpUp.HasTile) { if (tileLeft1.TileType == ModContent.TileType() && tileLeft2.TileType == ModContent.TileType() && tileLeft3.TileType == ModContent.TileType() && tileLeft4.TileType == ModContent.TileType() && tile.TileType == ModContent.TileType()) { @@ -549,7 +406,7 @@ public static void Minerization(int leftX, int upY, int rightX, int downY) } } } - if (tileLeft1.HasTile && tileLeft2.HasTile && tile.HasTile && !tileUp2.HasTile) + if (tileLeft1.HasTile && tileLeft2.HasTile && tile.HasTile && !tileUp2.HasTile && !tileMiddleUpUp.HasTile) { if (tileLeft1.TileType == ModContent.TileType() && tileLeft2.TileType == ModContent.TileType() && tile.TileType == ModContent.TileType()) { @@ -559,7 +416,7 @@ public static void Minerization(int leftX, int upY, int rightX, int downY) } } } - if (tileLeft1.HasTile && tileLeft2.HasTile && tile.HasTile && !tileUp1.HasTile) + if (tileLeft1.HasTile && tileLeft2.HasTile && tile.HasTile && !tileUp1.HasTile && !tileMiddleUpUp.HasTile) { if (tileLeft1.TileType == ModContent.TileType() && tileLeft2.TileType == ModContent.TileType() && tile.TileType == ModContent.TileType()) { @@ -597,11 +454,11 @@ public static void Minerization(int leftX, int upY, int rightX, int downY) { if (GenRand.NextBool(1500)) { - Tile tile = TileUtils.SafeGetTile(x, y); - Tile tileUp = TileUtils.SafeGetTile(x, y - 1); - Tile tileDown = TileUtils.SafeGetTile(x, y + 1); - Tile tileLeft = TileUtils.SafeGetTile(x - 1, y); - Tile tileRight = TileUtils.SafeGetTile(x + 1, y); + Tile tile = SafeGetTile(x, y); + Tile tileUp = SafeGetTile(x, y - 1); + Tile tileDown = SafeGetTile(x, y + 1); + Tile tileLeft = SafeGetTile(x - 1, y); + Tile tileRight = SafeGetTile(x + 1, y); if (tile.HasTile && tile.TileType == ModContent.TileType()) { if (tileUp.LiquidAmount <= 0 && tileDown.LiquidAmount <= 0 && tileLeft.LiquidAmount <= 0 && tileRight.LiquidAmount <= 0) @@ -631,16 +488,16 @@ public static void MinerizationCyanOreCircle(Vector2 center, float range) { if ((center - new Vector2(x, y)).Length() <= range) { - Tile tile = TileUtils.SafeGetTile(x, y); - Tile tileUp = TileUtils.SafeGetTile(x, y - 1); - Tile tileUp1 = TileUtils.SafeGetTile(x - 1, y - 1); - Tile tileUp2 = TileUtils.SafeGetTile(x - 2, y - 1); - Tile tileUp3 = TileUtils.SafeGetTile(x - 3, y - 1); - Tile tileUp4 = TileUtils.SafeGetTile(x - 4, y - 1); - Tile tileLeft1 = TileUtils.SafeGetTile(x - 1, y); - Tile tileLeft2 = TileUtils.SafeGetTile(x - 2, y); - Tile tileLeft3 = TileUtils.SafeGetTile(x - 3, y); - Tile tileLeft4 = TileUtils.SafeGetTile(x - 4, y); + Tile tile = SafeGetTile(x, y); + Tile tileUp = SafeGetTile(x, y - 1); + Tile tileUp1 = SafeGetTile(x - 1, y - 1); + Tile tileUp2 = SafeGetTile(x - 2, y - 1); + Tile tileUp3 = SafeGetTile(x - 3, y - 1); + Tile tileUp4 = SafeGetTile(x - 4, y - 1); + Tile tileLeft1 = SafeGetTile(x - 1, y); + Tile tileLeft2 = SafeGetTile(x - 2, y); + Tile tileLeft3 = SafeGetTile(x - 3, y); + Tile tileLeft4 = SafeGetTile(x - 4, y); if (tile.LiquidAmount > 0 || tileUp.LiquidAmount > 0 || tileUp1.LiquidAmount > 0 || tileUp2.LiquidAmount > 0 || tileUp3.LiquidAmount > 0 || tileUp4.LiquidAmount > 0 || tileLeft1.LiquidAmount > 0 || tileLeft1.LiquidAmount > 0 || tileLeft2.LiquidAmount > 0 || tileLeft3.LiquidAmount > 0 || tileLeft4.LiquidAmount > 0) { continue; @@ -651,7 +508,7 @@ public static void MinerizationCyanOreCircle(Vector2 center, float range) { if (GenRand.NextBool(3)) { - if (TileUtils.CanPlaceMultiAtTopTowardsUpRight(x - 4, y, 5, 3)) + if (CanPlaceMultiAtTopTowardsUpRight(x - 4, y, 5, 3)) { PlaceLargeCyanVineOre(x - 4, y - 3); } @@ -664,7 +521,7 @@ public static void MinerizationCyanOreCircle(Vector2 center, float range) { if (GenRand.NextBool(12)) { - if (TileUtils.CanPlaceMultiAtTopTowardsUpRight(x - 2, y + 1, 4, 3)) + if (CanPlaceMultiAtTopTowardsUpRight(x - 2, y + 1, 4, 3)) { PlaceMiddleCyanVineOre(x - 2, y - 2); } @@ -677,7 +534,7 @@ public static void MinerizationCyanOreCircle(Vector2 center, float range) { if (GenRand.NextBool(12)) { - if (TileUtils.CanPlaceMultiAtTopTowardsUpRight(x - 2, y, 3, 2)) + if (CanPlaceMultiAtTopTowardsUpRight(x - 2, y, 3, 2)) { PlaceSmallCyanVineOre(x - 2, y - 2); } @@ -690,7 +547,7 @@ public static void MinerizationCyanOreCircle(Vector2 center, float range) { if (GenRand.NextBool(6)) { - if (TileUtils.CanPlaceMultiBenethTowardsDownRight(x - 2, y - 1, 3, 2)) + if (CanPlaceMultiBenethTowardsDownRight(x - 2, y - 1, 3, 2)) { PlaceSmallUpCyanVineOre(x - 2, y); } @@ -703,7 +560,7 @@ public static void MinerizationCyanOreCircle(Vector2 center, float range) { if (GenRand.NextBool(3)) { - if (TileUtils.CanPlaceMultiBenethTowardsDownRight(x - 4, y - 1, 5, 3)) + if (CanPlaceMultiBenethTowardsDownRight(x - 4, y - 1, 5, 3)) { PlaceLargeUpCyanVineOre(x - 4, y); } @@ -721,11 +578,11 @@ public static void MinerizationCyanOreCircle(Vector2 center, float range) { if (GenRand.NextBool(3000)) { - Tile tile = TileUtils.SafeGetTile(x, y); - Tile tileUp = TileUtils.SafeGetTile(x, y - 1); - Tile tileDown = TileUtils.SafeGetTile(x, y + 1); - Tile tileLeft = TileUtils.SafeGetTile(x - 1, y); - Tile tileRight = TileUtils.SafeGetTile(x + 1, y); + Tile tile = SafeGetTile(x, y); + Tile tileUp = SafeGetTile(x, y - 1); + Tile tileDown = SafeGetTile(x, y + 1); + Tile tileLeft = SafeGetTile(x - 1, y); + Tile tileRight = SafeGetTile(x + 1, y); if (tile.HasTile && tile.TileType == ModContent.TileType()) { if (tileUp.LiquidAmount <= 0 && tileDown.LiquidAmount <= 0 && tileLeft.LiquidAmount <= 0 && tileRight.LiquidAmount <= 0) @@ -752,7 +609,7 @@ public static void MinerizationCyanOreCircle(Vector2 center, float range) /// public static Vector2D DigTunnelAvoidYggdrasilTown(double x, double y, double xDir, double yDir, int steps, int size, int type, bool wet = false, int wallType = -1) { - Rectangle townArea = new Rectangle(230, Main.maxTilesY - 480, 706, 275); + Rectangle townArea = new Rectangle(230, Main.maxTilesY - 600, 706, 275); int embedTownDepth = 0; double startX = x; double startY = y; @@ -781,7 +638,7 @@ public static Vector2D DigTunnelAvoidYggdrasilTown(double x, double y, double xD return new Vector2D(startX, startY); } } - Tile tile = TileUtils.SafeGetTile(j, k); + Tile tile = SafeGetTile(j, k); if (ChestSafe(j, k)) { if (tile.TileType == type) @@ -793,7 +650,7 @@ public static Vector2D DigTunnelAvoidYggdrasilTown(double x, double y, double xD } if (wallType != -1) { - tile.wall = (ushort)wallType; + tile.WallType = (ushort)wallType; } } else @@ -801,7 +658,7 @@ public static Vector2D DigTunnelAvoidYggdrasilTown(double x, double y, double xD return new Vector2D(startX, startY); } } - Tile tileSafe = TileUtils.SafeGetTile((int)(j + (xVel + xDir) * 3), (int)(k + (yVel + yDir) * 3)); + Tile tileSafe = SafeGetTile((int)(j + (xVel + xDir) * 3), (int)(k + (yVel + yDir) * 3)); if (tile.TileType != type) { return new Vector2D(startX, startY); @@ -867,104 +724,17 @@ public static Vector2D DigTunnelAvoidYggdrasilTown(double x, double y, double xD /// public static void BuildFossilizedMineRoad() { - // int deltaX = 120; - // if (AzureGrottoCenterX > 600) - // { - // deltaX = -120; - // } - // int step = Math.Sign(deltaX); - // int startX = 600 + deltaX; - // int startY = 11632; - // while (TileUtils.SafeGetTile(startX, startY + 1).TileType == TileID.GrayBrick) - // { - // startX += step; - // } - // int lengthX = GenRand.Next(140, 152); - // for (int x0 = 0; x0 < lengthX; x0++) - // { - // KillRectangleAreaOfTile(x0 * step + startX, startY - 17, x0 * step + startX, startY); - // PlaceRectangleAreaOfBlock(x0 * step + startX, startY + 1, x0 * step + startX, startY + 3, TileID.GrayBrick, false); - // } - // int continueEmpty = 0; - // float radius = 5f; - // Vector2 velocity = new Vector2(step, 0); - // Vector2 position = new Vector2(startX + lengthX * step, startY - radius); - // int times = 0; - // int coordY = GenRand.Next(1024); - // int rotatedTimes = 0; - // int noRotatedTimes = 0; - // while (continueEmpty < 15) - // { - // times++; - // velocity = Vector2.Normalize(velocity); - // position += velocity; - // int x = (int)position.X; - // int y = (int)position.Y; - // for (int x0 = -10; x0 <= 10; x0++) - // { - // for (int y0 = -10; y0 <= 10; y0++) - // { - // if (new Vector2(x0, y0).Length() < radius) - // { - // Tile tile = TileUtils.SafeGetTile(x0 + x, y0 + y); - // tile.HasTile = false; - // } - // } - // } - // if (rotatedTimes > 0) - // { - // rotatedTimes--; - // velocity = velocity.RotatedBy(step * Math.PI / 40d); - // noRotatedTimes = 0; - // } - // else - // { - // rotatedTimes = 0; - // Vector2 probePos = position + velocity * 50; - // if ((!TileUtils.SafeGetTile((int)probePos.X, (int)probePos.Y).HasTile && position.Y > 11451) || probePos.X > 1200 || probePos.X < 0) - // { - // rotatedTimes = 40; - // step *= -1; - // continue; - // } - // velocity = velocity.RotatedBy((PerlinPixelG[times % 1024, coordY] - 127.5) * 0.0002); - // velocity.Y -= 0.015f; - // noRotatedTimes++; - // if (noRotatedTimes > Math.Max(80 + 11540 - position.Y, 80)) - // { - // if (GenRand.NextBool(60)) - // { - // rotatedTimes = 40; - // step *= -1; - // } - // } - // velocity.X *= 1.12f; - // } - // Vector2 probePosII = position + velocity * 5; - // if (TileUtils.SafeGetTile((int)probePosII.X, (int)probePosII.Y).TileType != ModContent.TileType() && y < 11451) - // { - // continueEmpty++; - // } - // else - // { - // continueEmpty = 0; - // } - // if (times > 8000) - // { - // break; - // } - // } } /// /// 下天穹镇 /// - public static void BuildTownBelow() + public static void BuildMainTown() { // 圆壳罩ä½å¤©ç©¹é•‡ - Point topLeft = new Point(20, Main.maxTilesY - 680); + Point topLeft = new Point(20, Main.maxTilesY - 800); int length = 1100; - int height = 370; + int height = 490; int x0CoordPerlin = GenRand.Next(1024); int y0CoordPerlin = GenRand.Next(1024); float thick = 30; @@ -979,8 +749,8 @@ public static void BuildTownBelow() for (int j = 0; j < height; j++) { Point pos = new Point(i, j) + topLeft; - Tile tile = TileUtils.SafeGetTile(pos); - float noiseValueUp = PerlinPixelG[(i + x0CoordPerlin) % 1024, (j + y0CoordPerlin) % 1024] / 255f * 0.5f; + Tile tile = SafeGetTile(pos); + float noiseValueUp = GetLargeSmokeTexturePixelG(i + x0CoordPerlin, j + y0CoordPerlin) * 0.5f; // float noiseValueDown = PerlinPixelG[(i + x0CoordPerlin) % 1024, (j + 50 + y0CoordPerlin) % 1024] / 255f * 0.5f; if (ChestSafe(pos.X, pos.Y)) @@ -992,13 +762,8 @@ public static void BuildTownBelow() } if (j > height - value + noiseValueUp * 15 + 3/* && j < height - value + thick + noiseValueDown * 25 - 3*/) { - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } - - // if (j >= height + thick - value + noiseValueDown * 25) - // { - // tile.ClearEverything(); - // } } } } @@ -1011,8 +776,8 @@ public static void BuildTownBelow() for (int j = 0; j < height; j++) { Point pos = new Point(i, j) + topLeft; - Tile tile = TileUtils.SafeGetTile(pos); - float noiseValue = PerlinPixelG[(i + x0CoordPerlin) % 1024, (j + 50 + y0CoordPerlin) % 1024] / 255f * 0.5f; + Tile tile = SafeGetTile(pos); + float noiseValue = GetLargeSmokeTexturePixelG(i + x0CoordPerlin, j + y0CoordPerlin) * 0.5f; if (j >= height - value + noiseValue * 25) { tile.TileType = (ushort)ModContent.TileType(); @@ -1020,172 +785,62 @@ public static void BuildTownBelow() } if (j >= height - value + noiseValue * 25 + 3) { - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } } } - QuickBuild(230, Main.maxTilesY - 480, ModAsset.MapIOs_706x275YggdrasilTown_Path); - BuildTangledSubmine(); - - // fill ebonwood wall as piers below town ground. - // for (int i = 0; i < 501; i += 6) - // { - // for (int j = 0; j < 100; j++) - // { - // int x = 430 + i; - // int y = Main.maxTilesY - 400 + 91 + j; - // Tile tile = TileUtils.SafeGetTile(x, y); - // if (!tile.HasTile && tile.wall <= 0) - // { - // tile.wall = WallID.Ebonwood; - // } - // } - // } + YggdrasilTownTopLeft = new Point(230, Main.maxTilesY - 600); + QuickBuild(YggdrasilTownTopLeft.X, YggdrasilTownTopLeft.Y, ModAsset.YggdrasilTown_New_706x275_Path); - // cable tunnel - int tunnelLeftX = 945; - int tunnelRightX = 1170; - int tunnelLeftY = Main.maxTilesY - 333; - for (int x = tunnelLeftX; x < tunnelRightX; x += 3) + // Railway + for (int t = 0; t <= 120; t++) { - CircleTile(new Vector2(x, tunnelLeftY - (x - tunnelLeftX) * 0.33f), GenRand.NextFloat(12f, 17f), -1, true); + int dx = t * 3; + int x = YggdrasilTownTopLeft.X + 706 + dx; + int y = YggdrasilTownTopLeft.Y + 189; + if (t == 120) + { + y -= 15; + QuickBuild(x, y, ModAsset.OriginalPylonStation231x31_Path); + break; + } + var checkPos = new Point(x + 2, y + 16); + var checkTile = SafeGetTile(checkPos); + if (checkTile.HasTile) + { + if (t % 15 == 14) + { + QuickBuild(x, y, ModAsset.MetroTunnelPiece_WithLamp3x16_Path); + } + else + { + QuickBuild(x, y, ModAsset.MetroTunnelPiece3x16_Path); + } + } + else + { + if (t % 9 == 4) + { + QuickBuild(x, y, ModAsset.MetroBridgePiece_withPier3x15_Path); + for (int dy = 0; dy < 300; dy++) + { + var tile = SafeGetTile(x + 1, y + dy + 15); + if (tile.WallType > WallID.None) + { + break; + } + else + { + ChangeWall(tile, ModContent.WallType(), (int)TileChangeState.Forceful); + } + } + } + else + { + QuickBuild(x, y, ModAsset.MetroBridgePiece3x15_Path); + } + } } - KillRectangleAreaOfTile(1180, Main.maxTilesY - 400, 1240, Main.maxTilesY - 370); - - // first cable joint - // WorldGenMisc.PlaceRope(930, Main.maxTilesY - 326, 1000, Main.maxTilesY - 339, ModContent.TileType()); - // Tile firstJoint = TileUtils.SafeGetTile(1000, Main.maxTilesY - 339); - // firstJoint.TileFrameX = 0; - // for (int j = 1; j < 100; j++) - // { - // Tile tile = TileUtils.SafeGetTile(1000, Main.maxTilesY - 339 + j); - // if (tile.HasTile) - // { - // break; - // } - // else - // { - // tile.TileType = TileID.WoodenBeam; - // tile.HasTile = true; - // } - // } - // for (int j = 1; j < 100; j++) - // { - // Tile tile = TileUtils.SafeGetTile(930, Main.maxTilesY - 326 + j); - // if (tile.HasTile) - // { - // break; - // } - // else - // { - // tile.TileType = TileID.WoodenBeam; - // tile.HasTile = true; - // } - // } - - // Cable car telpher - // int lastPosX = 0; - // int lastPosY = 0; - - // for (int x = tunnelLeftX; x < tunnelRightX; x += 60) - // { - // int y = (int)(tunnelLeftY - (x - tunnelLeftX) * 0.3f) - 6; - // if (lastPosX != 0 && lastPosY != 0) - // { - // WorldGenMisc.PlaceRope(lastPosX, lastPosY, x, y, ModContent.TileType()); - // if (x > tunnelLeftX + 60) - // { - // Tile joint = TileUtils.SafeGetTile(lastPosX, lastPosY); - // joint.TileFrameX = 36; - // } - // for (int j = 1; j < 100; j++) - // { - // Tile tile = TileUtils.SafeGetTile(x, y - j); - // if (tile.HasTile) - // { - // break; - // } - // else - // { - // tile.TileType = TileID.WoodenBeam; - // tile.HasTile = true; - // } - // } - // } - // lastPosX = x; - // lastPosY = y; - // } - - // int telpherY = Main.maxTilesY - 390; - // int tunntelpherLeftX = 1180; - // int tunntelpherRightX = 1360; - // for (int x = tunntelpherLeftX; x < tunntelpherRightX; x += 60) - // { - // int y = telpherY; - // if (x > 1350) - // { - // y += 8; - // } - // if (x == 1240) - // { - // x += 30; - // y -= 16; - // } - // if (lastPosX != 0 && lastPosY != 0) - // { - // WorldGenMisc.PlaceRope(lastPosX, lastPosY, x, y, ModContent.TileType()); - // Tile joint = TileUtils.SafeGetTile(x, y); - // joint.TileFrameX = 0; - // if (x == tunntelpherLeftX) - // { - // joint = TileUtils.SafeGetTile(lastPosX, lastPosY); - // joint.TileFrameX = 36; - // } - // for (int j = 1; j < 100; j++) - // { - // Tile tile = TileUtils.SafeGetTile(x, y + j); - // if (tile.HasTile) - // { - // break; - // } - // else - // { - // tile.TileType = TileID.WoodenBeam; - // tile.HasTile = true; - // } - // } - // } - // lastPosX = x; - // lastPosY = y; - // } - // tunntelpherLeftX = 1360; - // tunntelpherRightX = 1440; - // telpherY = Main.maxTilesY - 382; - // for (int x = tunntelpherLeftX; x < tunntelpherRightX; x += 20) - // { - // int y = telpherY; - // if (lastPosX != 0 && lastPosY != 0) - // { - // WorldGenMisc.PlaceRope(lastPosX, lastPosY, x, y, ModContent.TileType()); - // Tile joint = TileUtils.SafeGetTile(x, y); - // joint.TileFrameX = 0; - // for (int j = 1; j < 100; j++) - // { - // Tile tile = TileUtils.SafeGetTile(x, y + j); - // if (tile.HasTile) - // { - // break; - // } - // else - // { - // tile.TileType = TileID.WoodenBeam; - // tile.HasTile = true; - // } - // } - // } - // lastPosX = x; - // lastPosY = y; - // } } /// @@ -1204,12 +859,12 @@ public static void BuildJellyBallHotbed() { for (int y = upBound; y <= bottomBound; y++) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); Vector2 toCenter = Center - new Vector2(x, y); float r = a - b * MathF.Sin(toCenter.ToRotation()); toCenter.Y /= 1.2f; - float valueNoise = PerlinPixelG[(int)((toCenter.ToRotation() + MathHelper.TwoPi + 0.5f) * 400) % 1024, (int)(toCenter.Length() * 0.7f) % 1024] / 255f; - float valueNoiseSecretion = PerlinPixelB[(int)((toCenter.ToRotation() + MathHelper.TwoPi + 0.5f) * 400) % 1024, (int)(toCenter.Length() * 0.6f) % 1024] / 255f; + float valueNoise = GetLargeSmokeTexturePixelG((int)((toCenter.ToRotation() + MathHelper.TwoPi + 0.5f) * 400), (int)(toCenter.Length() * 0.7f)); + float valueNoiseSecretion = GetLargeSmokeTexturePixelB((int)((toCenter.ToRotation() + MathHelper.TwoPi + 0.5f) * 400), (int)(toCenter.Length() * 0.6f)); float clearRange = 90f; float boundThick = 60f; if (toCenter.Length() > r) @@ -1241,7 +896,7 @@ public static void BuildJellyBallHotbed() tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; } - float valueNoise2 = PerlinPixelG[x % 1024, y % 1024] / 255f; + float valueNoise2 = GetLargeSmokeTexturePixelG(x, y); if (y < upBound + 30) { valueNoise2 += (upBound + 30 - y) / 30f; @@ -1280,7 +935,7 @@ public static void BuildJellyBallHotbed() } } - // SmoothTile(leftBound, upBound, rightBound, bottomBound); + // SmoothTile_XXYY(leftBound, upBound, rightBound, bottomBound); string mapIOPath = ModAsset.HotbedObervatory_66x44_Path; QuickBuild(rightBound - 100, (int)Center.Y, mapIOPath); @@ -1288,13 +943,13 @@ public static void BuildJellyBallHotbed() { for (int y = upBound; y <= bottomBound; y++) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); Vector2 toCenter = Center - new Vector2(x, y); float r = a - b * MathF.Sin(toCenter.ToRotation()); toCenter.Y /= 1.2f; - float valueNoise = PerlinPixelG[(int)((toCenter.ToRotation() + MathHelper.TwoPi + 0.5f) * 400) % 1024, (int)(toCenter.Length() * 0.7f) % 1024] / 255f; + float valueNoise = GetLargeSmokeTexturePixelG((int)((toCenter.ToRotation() + MathHelper.TwoPi + 0.5f) * 400), (int)(toCenter.Length() * 0.7f)); float valueNoiseWall = CellPixel[(int)((toCenter.ToRotation() + MathHelper.TwoPi + 0.5f) * 400) % 512, (int)(toCenter.Length() * 0.7f) % 512] / 255f; - float valueNoiseWallWood = PerlinPixelR[(int)((toCenter.ToRotation() + MathHelper.TwoPi + 0.5f) * 400) % 1024, (int)(toCenter.Length() * 0.7f) % 1024] / 255f; + float valueNoiseWallWood = GetLargeSmokeTexturePixelR((int)((toCenter.ToRotation() + MathHelper.TwoPi + 0.5f) * 400), (int)(toCenter.Length() * 0.7f)); float clearRange = 90f; float boundThick = 60f; if (toCenter.Length() > r) @@ -1311,20 +966,20 @@ public static void BuildJellyBallHotbed() } if (valueNoiseWall < 0.5f) { - if (valueNoise <= 1 && (tile.wall == (ushort)ModContent.WallType() || tile.wall == (ushort)ModContent.WallType() || tile.wall == (ushort)ModContent.WallType())) + if (valueNoise <= 1 && (tile.WallType == (ushort)ModContent.WallType() || tile.WallType == (ushort)ModContent.WallType() || tile.WallType == (ushort)ModContent.WallType())) { - tile.wall = 0; + tile.WallType = WallID.None; } } else if (valueNoise <= 1) { - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } if (valueNoiseWallWood >= 0.5f && valueNoise <= 1) { - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } - float valueNoise2 = PerlinPixelG[x % 1024, y % 1024] / 255f; + float valueNoise2 = GetLargeSmokeTexturePixelG(x, y); if (y < upBound + 30) { valueNoise2 += (upBound + 30 - y) / 30f; @@ -1335,9 +990,9 @@ public static void BuildJellyBallHotbed() { if (valueNoise2 < 0.45f) { - if (tile.wall == 0) + if (tile.WallType == WallID.None) { - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } } } @@ -1365,7 +1020,7 @@ public static void BuildLampWoodLand() int checkY = GenRand.Next(upBound, bottomBound); // 如果上下左å³éƒ½æœ‰å¤§äºŽ100的空间且ä¸åœ¨ä¸­å¿ƒé—迹区 - if (CheckSpaceWidth(checkX, checkY) > 100 && CheckSpaceDown(checkX, checkY) > 100 && CheckSpaceUp(checkX, checkY) > 100 && (new Vector2(checkX, checkY) - TwilightRelicCenter).Length() > 400 && (checkX < Main.maxTilesX - 200 && checkY < Main.maxTilesY - 620)) + if (CheckSpaceWidth(checkX, checkY) > 100 && CheckSpaceDown(checkX, checkY) > 100 && CheckSpaceUp(checkX, checkY) > 100 && (new Vector2(checkX, checkY) - TwilightRelicCenter).Length() > 400 && checkX < Main.maxTilesX - 200 && checkY < Main.maxTilesY - 620) { // è®¡å…¥ä¸€ä¸ªæ£®æž—å¹³å°æ•°é‡ countLamp++; @@ -1377,9 +1032,9 @@ public static void BuildLampWoodLand() { for (int y = checkY - 30; y <= checkY + 30; y++) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); float addXValue = 0; - float addYValue = PerlinPixelG[(x + x0CoordPerlin) % 1024, (y + y0CoordPerlin) % 1024] / 255f * 0.5f; + float addYValue = GetLargeSmokeTexturePixelG(x + x0CoordPerlin, y + y0CoordPerlin) * 0.5f; if (tile.WallType == ModContent.WallType()) { addXValue = EmbeddingDepthOfTileType(x, y, ModContent.TileType(), 10) / 20f; @@ -1398,7 +1053,7 @@ public static void BuildLampWoodLand() tile.HasTile = true; if (value < 0.94) { - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } } } @@ -1420,7 +1075,7 @@ public static void BuildLampWoodLand() for (int u = 0; u < 5; u++) { pos += vel; - Tile tile = TileUtils.SafeGetTile((int)pos.X, (int)pos.Y); + Tile tile = SafeGetTile((int)pos.X, (int)pos.Y); tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; } @@ -1435,7 +1090,7 @@ public static void BuildLampWoodLand() { for (int y = checkY - 50; y <= checkY + 50; y++) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); if (tile.TileType == (ushort)ModContent.TileType()) { tile.TileType = (ushort)ModContent.TileType(); @@ -1449,11 +1104,11 @@ public static void BuildLampWoodLand() { for (int y = checkY - 40; y <= checkY + 40; y++) { - float aValue = PerlinPixelR[(x + x0CoordPerlin + 10) % 1024, (y + y0CoordPerlin) % 1024] / 255f; + float aValue = GetLargeSmokeTexturePixelR(x + x0CoordPerlin, y + y0CoordPerlin) * 0.5f; float bValue = Math.Abs(checkY - y) / 120f - 0.1f + Math.Max(0, Math.Abs(checkX - x) / 120f - 0.6f); if (aValue + bValue < 0.2f) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; } @@ -1461,8 +1116,8 @@ public static void BuildLampWoodLand() } // å¹³å¦åŒ– - // SmoothTile(startX - 10, checkY - 30, endX + 10, checkY - 25); - // SmoothTile(startX - 10, checkY + 25, endX + 10, checkY + 30); + // SmoothTile_XXYY(startX - 10, checkY - 30, endX + 10, checkY - 25); + // SmoothTile_XXYY(startX - 10, checkY + 25, endX + 10, checkY + 30); // æˆ¿å­ int countCell = 0; @@ -1524,10 +1179,10 @@ public static void BuildLampWoodLand() for (int j = 0; j < 50; j++) { - Tile topLeft = TileUtils.SafeGetTile(x + xj - halfWidth, y + yj - roomHeight); - Tile topRight = TileUtils.SafeGetTile(x + xj + halfWidth, y + yj - roomHeight); - Tile bottomLeft = TileUtils.SafeGetTile(x + xj - halfWidth, y + yj); - Tile bottomRight = TileUtils.SafeGetTile(x + xj + halfWidth, y + yj); + Tile topLeft = SafeGetTile(x + xj - halfWidth, y + yj - roomHeight); + Tile topRight = SafeGetTile(x + xj + halfWidth, y + yj - roomHeight); + Tile bottomLeft = SafeGetTile(x + xj - halfWidth, y + yj); + Tile bottomRight = SafeGetTile(x + xj + halfWidth, y + yj); if (!topLeft.HasTile && !topRight.HasTile && bottomLeft.HasTile && (bottomLeft.TileType == ModContent.TileType() || bottomLeft.TileType == ModContent.TileType()) && @@ -1569,7 +1224,7 @@ public static void BuildLampWoodLand() { for (int yi = y + yj; yi < y + yj + 5; yi++) { - Tile tileBottomGrass = TileUtils.SafeGetTile(xi, yi); + Tile tileBottomGrass = SafeGetTile(xi, yi); tileBottomGrass.TileType = (ushort)ModContent.TileType(); tileBottomGrass.HasTile = true; } @@ -1586,13 +1241,13 @@ public static void BuildLampWoodLand() { for (int y = checkY - 40; y <= checkY + 10; y++) { - float valueG = PerlinPixelG[(int)(x * 2.24f) % 1024, (int)(y * 2.24) % 1024] / 255f; - Tile tile0 = TileUtils.SafeGetTile(x, y); - Tile tile1 = TileUtils.SafeGetTile(x + 1, y); - Tile tile2 = TileUtils.SafeGetTile(x, y + 1); - Tile tile3 = TileUtils.SafeGetTile(x + 1, y + 1); - Tile tile4 = TileUtils.SafeGetTile(x, y - 1); - Tile tile5 = TileUtils.SafeGetTile(x + 1, y - 1); + float valueG = GetLargeSmokeTexturePixelG(x * 2.24f, y * 2.24f); + Tile tile0 = SafeGetTile(x, y); + Tile tile1 = SafeGetTile(x + 1, y); + Tile tile2 = SafeGetTile(x, y + 1); + Tile tile3 = SafeGetTile(x + 1, y + 1); + Tile tile4 = SafeGetTile(x, y - 1); + Tile tile5 = SafeGetTile(x + 1, y - 1); // ç½å­ if (valueG > 0.4f) @@ -1603,11 +1258,11 @@ public static void BuildLampWoodLand() { if (GenRand.NextBool(2)) { - TileUtils.PlaceFrameImportantTiles(x, y - 1, 2, 2, ModContent.TileType(), GenRand.Next(6) * 36); + PlaceFrameImportantTiles(x, y - 1, 2, 2, ModContent.TileType(), GenRand.Next(6) * 36); } else { - TileUtils.PlaceFrameImportantTiles(x, y - 1, 2, 2, TileID.Pots, GenRand.Next(3) * 36, 36); + PlaceFrameImportantTiles(x, y - 1, 2, 2, TileID.Pots, GenRand.Next(3) * 36, 36); } } } @@ -1628,8 +1283,8 @@ public static void BuildLampWoodLand() { for (int y0 = -radiusI; y0 <= radiusI; y0++) { - Tile tile = TileUtils.SafeGetTile(checkTrunk + mesaOffset + new Vector2(x0, y0)); - float aValue = PerlinPixelR[Math.Abs((x0 + x0CoordPerlin) % 1024), Math.Abs((y0 + y0CoordPerlin) % 1024)] / 255f; + Tile tile = SafeGetTile(checkTrunk + mesaOffset + new Vector2(x0, y0)); + float aValue = GetLargeSmokeTexturePixelR(x0 + x0CoordPerlin, y0 + y0CoordPerlin); if (new Vector2(x0, y0).Length() <= radiusI - aValue * 10) { if (y0 > radiusI * 0.4f + aValue * 5) @@ -1641,7 +1296,7 @@ public static void BuildLampWoodLand() { tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } } } @@ -1672,8 +1327,8 @@ public static void BuildLampWoodLand() float distanceToWood = To100NearestTileTypeBlockDistance((int)placePos.X, (int)placePos.Y, ModContent.TileType()); if (distanceToLeaves > 7 && jointWidth > 2 && distanceToWood <= 2) { - Tile tile = TileUtils.SafeGetTile(placePos); - if (tile.wall != ModContent.WallType()) + Tile tile = SafeGetTile(placePos); + if (tile.WallType != ModContent.WallType()) { tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; @@ -1823,7 +1478,7 @@ public static void BuildStoneCageOfChallenges() { for (int y = Main.maxTilesY - 2400; y <= Main.maxTilesY - 1800; y += 1) { - float aValue = PerlinPixelR[(int)Math.Abs((x * 4.3f + x0CoordPerlin) % 1024), (int)Math.Abs((y * 4.3f + y0CoordPerlin) % 1024)] / 255f; + float aValue = GetLargeSmokeTexturePixelR(Math.Abs(x * 4.3f + x0CoordPerlin), Math.Abs(y * 4.3f + y0CoordPerlin)); float bValue = MathF.Abs((y - Main.maxTilesY + 2100) / 100f); float cValue = (x - Main.maxTilesX / 2f) / (Main.maxTilesX / 2f); cValue *= cValue; @@ -1837,11 +1492,11 @@ public static void BuildStoneCageOfChallenges() } if (aValue + bValue < 0.8f) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.TileType = (ushort)ModContent.TileType(); if (aValue + bValue < 0.75f) { - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } tile.HasTile = true; } @@ -1860,14 +1515,14 @@ public static void BuildStoneCageOfChallenges() { for (int y = Main.maxTilesY - 2100; y <= step2Y; y += 1) { - float aValue = PerlinPixelR[(int)Math.Abs((x * 4.3f + x0CoordPerlin) % 1024), (int)Math.Abs((y * 4.3f + y0CoordPerlin) % 1024)] / 255f; + float aValue = GetLargeSmokeTexturePixelR(Math.Abs(x * 4.3f + x0CoordPerlin), Math.Abs(y * 4.3f + y0CoordPerlin)); float bValue = MathF.Abs((y - step2Y) / 100f); float cValue = (x - step2X + 20) / 50f; cValue *= cValue; cValue = MathF.Pow(cValue, 0.9f); if (aValue + bValue < cValue) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; } @@ -1879,7 +1534,7 @@ public static void BuildStoneCageOfChallenges() { for (int y = Main.maxTilesY - 2200; y <= step2Y + 1; y += 1) { - float aValue = PerlinPixelR[(int)Math.Abs((x * 4.3f + x0CoordPerlin) % 1024), (int)Math.Abs((y * 4.3f + y0CoordPerlin) % 1024)] / 255f; + float aValue = GetLargeSmokeTexturePixelR(Math.Abs(x * 4.3f + x0CoordPerlin), Math.Abs(y * 4.3f + y0CoordPerlin)); float bValue = MathF.Abs((y - step2Y) / 70f); float cValue = (x - step2X - 240) / 200f; cValue *= cValue; @@ -1887,7 +1542,7 @@ public static void BuildStoneCageOfChallenges() cValue = MathF.Pow(cValue, 0.9f); if (aValue * 0.3f + bValue < cValue) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.HasTile = false; } } @@ -1898,7 +1553,7 @@ public static void BuildStoneCageOfChallenges() { for (int y = step2Y + 7; y <= step2Y + 500; y += 1) { - float bValue = PerlinPixelR[(int)Math.Abs((x * 4.3f + x0CoordPerlin) % 1024), (int)(y * 4.3f + y0CoordPerlin) % 1024] / 255f; + float bValue = GetLargeSmokeTexturePixelR(Math.Abs(x * 4.3f + x0CoordPerlin), Math.Abs(y * 4.3f + y0CoordPerlin)); int thick = y - step2Y - 7; float value = (x - step2X) / 480f; value *= value; @@ -1911,12 +1566,12 @@ public static void BuildStoneCageOfChallenges() { bValue += (thick - value * 240) / 60f; } - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); if (tile.HasTile) { bValue += 1f; } - if (tile.wall > 0) + if (tile.WallType > WallID.None) { bValue += 0.5f; if (x > step2X + 400) @@ -1943,7 +1598,7 @@ public static void BuildStoneCageOfChallenges() } } - TileUtils.PlaceFrameImportantTiles(step2X + 236, step2Y - 3, 20, 10, ModContent.TileType()); + PlaceFrameImportantTiles(step2X + 236, step2Y - 3, 20, 10, ModContent.TileType()); } /// @@ -2019,9 +1674,9 @@ public static void BuildTwilightLand() { for (int y0 = -radiusI; y0 <= radiusI; y0++) { - Tile tile = TileUtils.SafeGetTile(basePos + new Vector2(x0, y0)); - Tile tileUp = TileUtils.SafeGetTile(basePos + new Vector2(x0, y0 - 1)); - float aValue = PerlinPixelR[Math.Abs((x0 + x0CoordPerlin) % 1024), Math.Abs((y0 + y0CoordPerlin) % 1024)] / 255f; + Tile tile = SafeGetTile(basePos + new Vector2(x0, y0)); + Tile tileUp = SafeGetTile(basePos + new Vector2(x0, y0 - 1)); + float aValue = GetLargeSmokeTexturePixelR(x0 + x0CoordPerlin, y0 + y0CoordPerlin); if (new Vector2(x0, y0).Length() <= radiusI - aValue * 10) { if (!TileID.Sets.BasicChest[tile.TileType] && !TileID.Sets.BasicChest[tileUp.TileType]) @@ -2035,7 +1690,7 @@ public static void BuildTwilightLand() { tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } } } @@ -2073,7 +1728,7 @@ public static void BuildTwilightLand() { for (int v = 0; v < 4; v++) { - var tile = TileUtils.SafeGetTile((int)posCell.X + h, (int)posCell.Y - 2 + v); + var tile = SafeGetTile((int)posCell.X + h, (int)posCell.Y - 2 + v); if (!tile.HasTile) { tile.TileType = (ushort)ModContent.TileType(); @@ -2100,10 +1755,10 @@ public static void BuildTwilightLand() for (int y0 = -radiusI; y0 <= radiusI; y0++) { int height = GenRand.Next(7, 60); - Tile tile = TileUtils.SafeGetTile(basePos + new Vector2(x0, y0)); + Tile tile = SafeGetTile(basePos + new Vector2(x0, y0)); if (tile.TileType == ModContent.TileType()) { - if (GenRand.NextBool(3) && TileUtils.CanPlaceMultiAtTopTowardsUpRight((int)basePos.X + x0 - 3, (int)basePos.Y + y0, 8, height)) + if (GenRand.NextBool(3) && CanPlaceMultiAtTopTowardsUpRight((int)basePos.X + x0 - 3, (int)basePos.Y + y0, 8, height)) { TreePlacer.BuildTwilightTree((int)basePos.X + x0, (int)basePos.Y + y0 - 1, height); } @@ -2137,8 +1792,8 @@ public static void BuildTwilightRelic() { for (int y0 = -radiusI; y0 <= radiusI; y0++) { - Tile tile = TileUtils.SafeGetTile(TwilightRelicCenter + new Vector2(x0, y0)); - float aValue = PerlinPixelR[Math.Abs((x0 + x0CoordPerlin) % 1024), Math.Abs((y0 + y0CoordPerlin) % 1024)] / 255f; + Tile tile = SafeGetTile(TwilightRelicCenter + new Vector2(x0, y0)); + float aValue = GetLargeSmokeTexturePixelR(x0 + x0CoordPerlin, y0 + y0CoordPerlin); if (new Vector2(x0, y0).Length() <= radiusI - aValue * 10) { if (y0 > radiusI * 0.5f + aValue * 5) @@ -2150,7 +1805,7 @@ public static void BuildTwilightRelic() { tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } } } @@ -2164,10 +1819,10 @@ public static void BuildTwilightRelic() { for (int y = centerY - 103; y <= centerY + 200; y += 1) { - float aValue = PerlinPixelR[(int)Math.Abs((x * 4.3f + x0CoordPerlin) % 1024), (int)Math.Abs((y * 4.3f + y0CoordPerlin) % 1024)] / 255f; + float aValue = GetLargeSmokeTexturePixelR(Math.Abs(x * 4.3f + x0CoordPerlin), Math.Abs(y * 4.3f + y0CoordPerlin)); if (aValue < 0.4f) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; } @@ -2177,10 +1832,10 @@ public static void BuildTwilightRelic() { for (int y = centerY + 160; y <= centerY + 260; y += 1) { - float aValue = PerlinPixelR[(int)Math.Abs((x * 4.3f + x0CoordPerlin) % 1024), (int)Math.Abs((y * 4.3f + y0CoordPerlin) % 1024)] / 255f; + float aValue = GetLargeSmokeTexturePixelR(Math.Abs(x * 4.3f + x0CoordPerlin), Math.Abs(y * 4.3f + y0CoordPerlin)); if (aValue < 0.4f) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; } @@ -2202,10 +1857,10 @@ public static void BuildTwilightRelic() for (int y0 = -radiusI; y0 <= radiusI; y0++) { int height = GenRand.Next(7, 60); - Tile tile = TileUtils.SafeGetTile(TwilightRelicCenter + new Vector2(x0, y0)); + Tile tile = SafeGetTile(TwilightRelicCenter + new Vector2(x0, y0)); if (tile.TileType == ModContent.TileType()) { - if (GenRand.NextBool(3) && TileUtils.CanPlaceMultiAtTopTowardsUpRight(centerX + x0 - 3, centerY + y0, 8, height)) + if (GenRand.NextBool(3) && CanPlaceMultiAtTopTowardsUpRight(centerX + x0 - 3, centerY + y0, 8, height)) { TreePlacer.BuildTwilightTree(centerX + x0, centerY + y0 - 1, height); } @@ -2227,58 +1882,54 @@ public static void BuildTwilightRelic() int roomOriginY = centerY - 100 + y * 25 + 12; string[] randomRooms = new string[] { - ModAsset.TwilightCastle_Room_1_40x21_Path, - ModAsset.TwilightCastle_Room_2_40x21_Path, - ModAsset.TwilightCastle_Room_3_40x21_Path, - ModAsset.TwilightCastle_Room_4_40x21_Path, - ModAsset.TwilightCastle_Room_5_40x21_Path, - ModAsset.TwilightCastle_Room_6_40x21_Path, - ModAsset.TwilightCastle_Room_7_40x21_Path, - ModAsset.TwilightCastle_Room_8_40x21_Path, - ModAsset.TwilightCastle_Room_9_40x21_Path, - ModAsset.TwilightCastle_Room_10_40x21_Path, - ModAsset.TwilightCastle_Room_11_40x21_Path, - ModAsset.TwilightCastle_Room_12_40x21_Path, - ModAsset.TwilightCastle_Room_13_40x21_Path, - ModAsset.TwilightCastle_Room_14_40x21_Path, - ModAsset.TwilightCastle_Room_15_40x21_Path, + ModAsset.TCRoom_Rd_00_StoneCave_40x21_Path, + ModAsset.TCRoom_Rd_01_BloodyChurch_40x21_Path, + ModAsset.TCRoom_Rd_02_Desert_40x21_Path, + ModAsset.TCRoom_Rd_03_WaterSluice_40x21_Path, + ModAsset.TCRoom_Rd_04_Forest_40x21_Path, + ModAsset.TCRoom_Rd_05_DarkDragon_40x21_Path, }; - QuickBuild(roomOriginX - 20, roomOriginY - 10, randomRooms[GenRand.Next(randomRooms.Length)]); - - // KillRectangleAreaOfTile(roomOriginX - 18, roomOriginY - 9, roomOriginX + 18, roomOriginY + 9); - // int randLampCount = GenRand.Next(1, 4); - // for (int i = 0; i < randLampCount; i++) - // { - // int lampX = roomOriginX + (int)(36f / randLampCount * (i + 0.5f) - 18f + GenRand.Next(-2, 3)); - // var tile = TileUtils.SafeGetTile(lampX, roomOriginY - 9); - // tile.TileType = (ushort)ModContent.TileType(); - // tile.HasTile = true; - // tile.TileFrameY = (short)GenRand.Next(2, 30); - // } - // int chainCount = GenRand.Next(1, 3); - // for (int i = 0; i < chainCount; i++) - // { - // int randPos = GenRand.Next(8, 24); - // int randNeg = GenRand.Next(8, 24); - // int addX0 = (int)(randPos + ((i + 0.5f) / chainCount - 0.5f) * 12); - // int addY0 = 0; - // if (addX0 > 18) - // { - // addY0 = addX0 - 18; - // addX0 = 18; - // } - - // int addX1 = (int)(randNeg + ((i + 0.5f) / chainCount - 0.5f) * 12); - // int addY1 = 0; - // if (addX1 > 18) - // { - // addY1 = addX1 - 18; - // addX1 = 18; - // } - // addX1 *= -1; - - // WorldGenMisc.PlaceRope(roomOriginX + addX0, roomOriginY + addY0 - 9, roomOriginX + addX1, roomOriginY + addY1 - 9, ModContent.TileType()); - // } + if (x == 2) + { + randomRooms = new string[] + { + ModAsset.TCRoom_Ld_00_StoneCave_40x21_Path, + ModAsset.TCRoom_Ld_01_BloodyChurch_40x21_Path, + ModAsset.TCRoom_Ld_02_Desert_40x21_Path, + ModAsset.TCRoom_Ld_03_WaterSluice_40x21_Path, + ModAsset.TCRoom_Ld_04_Forest_40x21_Path, + ModAsset.TCRoom_Ld_05_DarkDragon_40x21_Path, + }; + } + int roomType = GenRand.Next(randomRooms.Length); + QuickBuild(roomOriginX - 20, roomOriginY - 10, randomRooms[roomType]); + int coreItemType = -1; + switch (roomType) + { + case 0: + coreItemType = ModContent.ItemType(); + break; + case 1: + coreItemType = ModContent.ItemType(); + break; + case 2: + coreItemType = ModContent.ItemType(); + break; + case 3: + coreItemType = ModContent.ItemType(); + break; + case 4: + coreItemType = ModContent.ItemType(); + break; + case 5: + coreItemType = ModContent.ItemType(); + break; + default: + coreItemType = ItemID.DirtBlock; + break; + } + List contents = [new Item(setDefaultsToType: coreItemType), .. NormalChestContents()]; + FillChestXYWH(roomOriginX - 20, roomOriginY - 10, 40, 21, contents); // æˆ¿é—´é€šé“ if (y == 9 && directionGate + 1 == x) @@ -2299,13 +1950,15 @@ public static void BuildTwilightRelic() { KillRectangleAreaOfTile(roomOriginX + 18, roomOriginY + 2, roomOriginX + 31, roomOriginY + 9); PlaceRectangleAreaOfBlock(roomOriginX + 19, roomOriginY + 2, roomOriginX + 22, roomOriginY + 6, ModContent.TileType()); - TileUtils.PlaceFrameImportantTiles(roomOriginX + 20, roomOriginY + 7, 1, 3, TileID.ClosedDoor, 0, 918); + + // PlaceFrameImportantTiles(roomOriginX + 20, roomOriginY + 7, 1, 3, TileID.ClosedDoor, 0, 918); } if (x == 2) { KillRectangleAreaOfTile(roomOriginX - 31, roomOriginY + 2, roomOriginX - 18, roomOriginY + 9); PlaceRectangleAreaOfBlock(roomOriginX - 22, roomOriginY + 2, roomOriginX - 19, roomOriginY + 6, ModContent.TileType()); - TileUtils.PlaceFrameImportantTiles(roomOriginX - 20, roomOriginY + 7, 1, 3, TileID.ClosedDoor, 0, 918); + + // PlaceFrameImportantTiles(roomOriginX - 20, roomOriginY + 7, 1, 3, TileID.ClosedDoor, 0, 918); } // PlaceTwilightLegacyBiomeChest(roomOriginX, roomOriginY + 9); @@ -2314,7 +1967,7 @@ public static void BuildTwilightRelic() // 清ç†ä¸­å¤®åž‚ç›´é€šé“ KillRectangleAreaOfTile(centerX - 18, centerY - 100 + 12 - 9, centerX + 18, centerY + 146); - TileUtils.PlaceFrameImportantTiles(centerX - 1, centerY + 144, 3, 3, ModContent.TileType()); + PlaceFrameImportantTiles(centerX - 1, centerY + 144, 3, 3, ModContent.TileType()); // 副塔 60 * 120 int directionSubTower = GenRand.NextBool() ? 1 : -1; @@ -2326,10 +1979,10 @@ public static void BuildTwilightRelic() { for (int y = subTowerCenterY - 63; y <= subTowerCenterY + 63; y += 1) { - float aValue = PerlinPixelR[(int)Math.Abs((x * 4.3f + x0CoordPerlin) % 1024), (int)Math.Abs((y * 4.3f + y0CoordPerlin) % 1024)] / 255f; + float aValue = GetLargeSmokeTexturePixelR(Math.Abs(x * 4.3f + x0CoordPerlin), Math.Abs(y * 4.3f + y0CoordPerlin)); if (aValue < 0.4f) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.TileType = (ushort)ModContent.TileType(); tile.HasTile = true; } @@ -2381,7 +2034,7 @@ public static void BuildTwilightRelic() { int checkX = subTowerCenterX - 25 + x * 10; int checkY = subTowerCenterY - 55 + y * 10; - Tile tile = TileUtils.SafeGetTile(checkX, checkY); + Tile tile = SafeGetTile(checkX, checkY); if ((x + y) % 2 == 1) { tile.TileType = (ushort)ModContent.TileType(); @@ -2401,7 +2054,7 @@ public static void BuildTwilightRelic() { int checkX = subTowerCenterX - 20 + x * 10; int checkY = subTowerCenterY - 50 + y * 10; - Tile tile = TileUtils.SafeGetTile(checkX, checkY); + Tile tile = SafeGetTile(checkX, checkY); tile.TileType = (ushort)ModContent.TileType(); if (x == 2 && y == 0) { @@ -2445,12 +2098,12 @@ public static void BuildTwilightRelic() int y = centerY + 180; for (int y0 = 10; y0 < 50; y0++) { - Tile tile = TileUtils.SafeGetTile(centerX + x0, y + y0); + Tile tile = SafeGetTile(centerX + x0, y + y0); if (!tile.HasTile) { float height = 0.15f; float value = Math.Abs(x0) * height + GenRand.NextFloat(1f); - if (y0 > value + 50 - (60 * height)) + if (y0 > value + 50 - 60 * height) { tile.TileType = TileID.GoldCoinPile; tile.HasTile = true; @@ -2465,7 +2118,7 @@ public static void BuildTwilightRelic() /// public static void SmoothYggdrasilTown() { - SmoothTile(0, (int)(Main.maxTilesY * 0.9), Main.maxTilesX, Main.maxTilesY); + // SmoothTile_XXYY(0, (int)(Main.maxTilesY * 0.9), Main.maxTilesX, Main.maxTilesY); } /// @@ -2538,8 +2191,8 @@ public static void BuildTwilightCellRoom(int x, int y) canBuild = false; } } - bool leftwall = TileUtils.SafeGetTile(x, y - roomHeight).wall == ModContent.WallType(); - bool rightwall = TileUtils.SafeGetTile(x + roomWidth, y - roomHeight).wall == ModContent.WallType(); + bool leftwall = SafeGetTile(x, y - roomHeight).wall == ModContent.WallType(); + bool rightwall = SafeGetTile(x + roomWidth, y - roomHeight).wall == ModContent.WallType(); if (canBuild) { QuickBuild(x, y - roomHeight, mapIOPath); @@ -2550,10 +2203,10 @@ public static void BuildTwilightCellRoom(int x, int y) { for (int j = y - roomHeight; j <= y; j++) { - var tile = TileUtils.SafeGetTile(i, j); - if (tile.wall <= 0) + var tile = SafeGetTile(i, j); + if (tile.WallType <= WallID.None) { - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } } } @@ -2564,10 +2217,10 @@ public static void BuildTwilightCellRoom(int x, int y) { for (int j = y - roomHeight; j <= y; j++) { - var tile = TileUtils.SafeGetTile(i, j); - if (tile.wall <= 0) + var tile = SafeGetTile(i, j); + if (tile.WallType <= WallID.None) { - tile.wall = (ushort)ModContent.WallType(); + tile.WallType = (ushort)ModContent.WallType(); } } } @@ -2577,13 +2230,13 @@ public static void BuildTwilightCellRoom(int x, int y) int maxHeight = GenRand.Next(10, 30); for (int i = x; i <= x + roomWidth; i++) { - var tile = TileUtils.SafeGetTile(i, y - 2); - if (tile.TileType == 124) + var tile = SafeGetTile(i, y - 2); + if (tile.TileType == TileID.WoodenBeam) { for (int j = 0; j < 30; j++) { - var tile2 = TileUtils.SafeGetTile(i, y + j); - if (tile2.HasTile && tile2.TileType != 124) + var tile2 = SafeGetTile(i, y + j); + if (tile2.HasTile && tile2.TileType != TileID.WoodenBeam) { break; } @@ -2591,7 +2244,7 @@ public static void BuildTwilightCellRoom(int x, int y) { if (ChestSafe(i, y + j)) { - tile2.TileType = 124; + tile2.TileType = TileID.WoodenBeam; tile2.HasTile = true; } } @@ -2603,8 +2256,8 @@ public static void BuildTwilightCellRoom(int x, int y) { for (int h = 0; h < 100; h++) { - var tile3 = TileUtils.SafeGetTile(i + h, y + j); - if (tile3.HasTile && tile2.TileType != 124) + var tile3 = SafeGetTile(i + h, y + j); + if (tile3.HasTile && tile2.TileType != TileID.WoodenBeam) { break; } @@ -2622,8 +2275,8 @@ public static void BuildTwilightCellRoom(int x, int y) { for (int h = 0; h < 100; h++) { - var tile3 = TileUtils.SafeGetTile(i - h, y + j); - if (tile3.HasTile && tile2.TileType != 124) + var tile3 = SafeGetTile(i - h, y + j); + if (tile3.HasTile && tile2.TileType != TileID.WoodenBeam) { break; } @@ -2653,17 +2306,17 @@ public static void PlaceChineseStyleLampPost(int x, int y, int style, int ai0 = switch (style) { case 0: - TileUtils.PlaceFrameImportantTiles(x, y - 5, 1, 5, ModContent.TileType()); + PlaceFrameImportantTiles(x, y - 5, 1, 5, ModContent.TileType()); break; case 1: PlaceRectangleAreaOfWall(x, y - 5, x, y, WallID.BambooFence); - Tile tile0 = TileUtils.SafeGetTile(x, y - 5); + Tile tile0 = SafeGetTile(x, y - 5); int tile1Dir = x + 1; if (ai0 % 2 == 0) { tile1Dir = x - 1; } - Tile tile1 = TileUtils.SafeGetTile(tile1Dir, y - 5); + Tile tile1 = SafeGetTile(tile1Dir, y - 5); tile0.TileType = TileID.Platforms; tile0.frameY = 786; tile0.HasTile = true; @@ -2675,7 +2328,7 @@ public static void PlaceChineseStyleLampPost(int x, int y, int style, int ai0 = { lanternType = 936; } - TileUtils.PlaceFrameImportantTiles(tile1Dir, y - 4, 1, 2, TileID.HangingLanterns, 0, lanternType); + PlaceFrameImportantTiles(tile1Dir, y - 4, 1, 2, TileID.HangingLanterns, 0, lanternType); break; case 2: int lampStyle = 918; @@ -2701,7 +2354,7 @@ public static void PlaceChineseStyleLampPost(int x, int y, int style, int ai0 = lampStyle = 108; lampStyleX = 36; } - TileUtils.PlaceFrameImportantTiles(x, y - 3, 1, 3, TileID.Lamps, lampStyleX, lampStyle); + PlaceFrameImportantTiles(x, y - 3, 1, 3, TileID.Lamps, lampStyleX, lampStyle); break; } } @@ -2860,7 +2513,7 @@ public static void CreateChineseFolkBox(int startX, int startY, int endX, int en // 左侧 bool canPlaceLeft = true; - while (TileUtils.SafeGetTile(startX - 1, placeY).HasTile) + while (SafeGetTile(startX - 1, placeY).HasTile) { placeY++; if (placeY - startY > 5) @@ -2873,7 +2526,7 @@ public static void CreateChineseFolkBox(int startX, int startY, int endX, int en { for (int y = placeY; y <= placeY + 2; y++) { - Tile check = TileUtils.SafeGetTile(x, y); + Tile check = SafeGetTile(x, y); if (check.HasTile) { canPlaceLeft = false; @@ -2882,13 +2535,13 @@ public static void CreateChineseFolkBox(int startX, int startY, int endX, int en } if (canPlaceLeft) { - TileUtils.PlaceFrameImportantTiles(startX - 2, placeY, 2, 3, type); + PlaceFrameImportantTiles(startX - 2, placeY, 2, 3, type); } // å³ä¾§ bool canPlaceRight = true; placeY = startY; - while (TileUtils.SafeGetTile(endX + 1, placeY).HasTile) + while (SafeGetTile(endX + 1, placeY).HasTile) { placeY++; if (placeY - startY > 5) @@ -2901,7 +2554,7 @@ public static void CreateChineseFolkBox(int startX, int startY, int endX, int en { for (int y = placeY; y <= placeY + 2; y++) { - Tile check = TileUtils.SafeGetTile(x, y); + Tile check = SafeGetTile(x, y); if (check.HasTile) { canPlaceRight = false; @@ -2910,7 +2563,7 @@ public static void CreateChineseFolkBox(int startX, int startY, int endX, int en } if (canPlaceRight) { - TileUtils.PlaceFrameImportantTiles(endX + 1, placeY, 2, 3, type, 36); + PlaceFrameImportantTiles(endX + 1, placeY, 2, 3, type, 36); } } @@ -2919,7 +2572,7 @@ public static void CreateChineseFolkBox(int startX, int startY, int endX, int en for (int x = endX + 1; x < endX + 5; x++) { int y = endY; - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); if (!tile.HasTile) { hasEndXDoor = false; @@ -2928,13 +2581,13 @@ public static void CreateChineseFolkBox(int startX, int startY, int endX, int en } if (hasEndXDoor) { - TileUtils.PlaceFrameImportantTiles(endX, endY - 3, 1, 3, TileID.ClosedDoor); + PlaceFrameImportantTiles(endX, endY - 3, 1, 3, TileID.ClosedDoor); } bool hasStartXDoor = true; for (int x = startX - 1; x > startX - 5; x--) { int y = endY; - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); if (!tile.HasTile) { hasStartXDoor = false; @@ -2943,7 +2596,7 @@ public static void CreateChineseFolkBox(int startX, int startY, int endX, int en } if (hasStartXDoor) { - TileUtils.PlaceFrameImportantTiles(startX, endY - 3, 1, 3, TileID.ClosedDoor); + PlaceFrameImportantTiles(startX, endY - 3, 1, 3, TileID.ClosedDoor); } DistributeChineseStyleDecorations(startX, startY, endX, endY); } @@ -2978,7 +2631,7 @@ public static void DistributeChineseStyleDecorations(int startX, int startY, int PlaceRectangleAreaOfBlock(middleCutX, startY, middleCutX, endY - 3, TileID.DynastyWood); // 横å‘分割需è¦åŠ é—¨ - TileUtils.PlaceFrameImportantTiles(middleCutX, endY - 3, 1, 3, TileID.ClosedDoor); + PlaceFrameImportantTiles(middleCutX, endY - 3, 1, 3, TileID.ClosedDoor); DistributeChineseStyleDecorations(startX, startY, middleCutX, endY); DistributeChineseStyleDecorations(middleCutX, startY, endX, endY); @@ -2989,9 +2642,9 @@ public static void DistributeChineseStyleDecorations(int startX, int startY, int for (int x = startX; x < endX; x++) { int y = endY + 1; - Tile tile = TileUtils.SafeGetTile(x, y); - Tile tileUp = TileUtils.SafeGetTile(x, y - 2); - if (tile.wall != 0 && !tile.HasTile && tileUp.wall != 0 && !tileUp.HasTile) + Tile tile = SafeGetTile(x, y); + Tile tileUp = SafeGetTile(x, y - 2); + if (tile.WallType != WallID.None && !tile.HasTile && tileUp.wall != 0 && !tileUp.HasTile) { emptyBottomX.Add(x); } @@ -3037,7 +2690,7 @@ public static void DistributeChineseStyleDecorations(int startX, int startY, int foreach (int x in continuePlatforms[createPlatformIndex]) { int y = endY; - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.TileType = TileID.Platforms; tile.TileFrameY = 342; tile.TileFrameX = 0; @@ -3050,7 +2703,7 @@ public static void DistributeChineseStyleDecorations(int startX, int startY, int tile.TileFrameX = 216; } - tile.wall = TileUtils.SafeGetTile(x, y - 1).wall; + tile.WallType = SafeGetTile(x, y - 1).wall; } } @@ -3082,7 +2735,7 @@ public static void CreateBoxRoom(int startX, int startY, int endX, int endY, int { for (int y = startY; y <= endY; y++) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); if (!Forced) { if (x == startX || x == endX || y == startY || y == endY) @@ -3095,9 +2748,9 @@ public static void CreateBoxRoom(int startX, int startY, int endX, int endY, int } else { - if (tile.wall == 0) + if (tile.WallType == WallID.None) { - tile.wall = (ushort)contentWallType; + tile.WallType = (ushort)contentWallType; } } } @@ -3111,7 +2764,7 @@ public static void CreateBoxRoom(int startX, int startY, int endX, int endY, int else { tile.HasTile = false; - tile.wall = (ushort)contentWallType; + tile.WallType = (ushort)contentWallType; } } } @@ -3124,11 +2777,11 @@ public static void CreateBoxRoom(int startX, int startY, int endX, int endY, int public static void CreateSlantCable(int x, int y, int direction, int type, int density = 12, int maxStep = 65535) { int count = 0; - while (!TileUtils.SafeGetTile(x, y).HasTile || count <= 2) + while (!SafeGetTile(x, y).HasTile || count <= 2) { count++; - Tile tile1 = TileUtils.SafeGetTile(x, y); - Tile tile2 = TileUtils.SafeGetTile(x + direction, y); + Tile tile1 = SafeGetTile(x, y); + Tile tile2 = SafeGetTile(x + direction, y); tile1.HasTile = true; tile1.TileType = (ushort)type; if (direction == -1) @@ -3161,9 +2814,9 @@ public static void CreateSlantCable(int x, int y, int direction, int type, int d { for (int y0 = 0; y0 < count; y0++) { - Tile tile3 = TileUtils.SafeGetTile(x + direction, y - y0); + Tile tile3 = SafeGetTile(x + direction, y - y0); tile3.wall = WallID.Shadewood; - if (y0 % (density * 2) == density - 1 && !TileUtils.SafeGetTile(x + direction, y - y0).HasTile) + if (y0 % (density * 2) == density - 1 && !SafeGetTile(x + direction, y - y0).HasTile) { CreateSlantCable(x + direction, y - y0, direction, type, density, density - 1); CreateSlantCable(x + direction * 0, y - y0, -direction, type, density, density - 1); @@ -3319,7 +2972,7 @@ public static void PlaceLargeCyanVineOre(int i, int j) { for (int y = 0; y < 3; y++) { - var tile = TileUtils.SafeGetTile(i + x, j + y); + var tile = SafeGetTile(i + x, j + y); if (x == 0 && y == 0) { continue; @@ -3367,7 +3020,7 @@ public static void PlaceLargeCyanVineOre(int i, int j) tile.HasTile = true; if (x == 0 && y == 2) { - var tile2 = TileUtils.SafeGetTile(i + x - 1, j + y + 1); + var tile2 = SafeGetTile(i + x - 1, j + y + 1); tile2.TileType = (ushort)ModContent.TileType(); tile2.HasTile = true; } @@ -3379,7 +3032,7 @@ public static void PlaceLargeCyanVineOre(int i, int j) { for (int y = 1; y < 3; y++) { - var tile = TileUtils.SafeGetTile(i + x, j + y); + var tile = SafeGetTile(i + x, j + y); if (x == 4 && y == 1) { continue; @@ -3426,7 +3079,7 @@ public static void PlaceMiddleCyanVineOre(int i, int j) { for (int y = 0; y < 3; y++) { - var tile = TileUtils.SafeGetTile(i + x, j + y); + var tile = SafeGetTile(i + x, j + y); if (x == 0 && y == 0) { continue; @@ -3471,7 +3124,7 @@ public static void PlaceMiddleCyanVineOre(int i, int j) { for (int y = 1; y < 3; y++) { - var tile = TileUtils.SafeGetTile(i + x, j + y); + var tile = SafeGetTile(i + x, j + y); if (x == 0 && y == 1) { @@ -3507,7 +3160,7 @@ public static void PlaceMiddleCyanVineOre(int i, int j) { for (int y = 1; y < 3; y++) { - var tile = TileUtils.SafeGetTile(i + x, j + y); + var tile = SafeGetTile(i + x, j + y); if (x == 3 && y == 1) { @@ -3534,7 +3187,7 @@ public static void PlaceMiddleCyanVineOre(int i, int j) { for (int y = 1; y < 3; y++) { - var tile = TileUtils.SafeGetTile(i + x, j + y); + var tile = SafeGetTile(i + x, j + y); if (x == 0 && y == 1) { @@ -3591,7 +3244,7 @@ public static void PlaceSmallCyanVineOre(int i, int j) { for (int y = 0; y < 2; y++) { - var tile = TileUtils.SafeGetTile(i + x, j + y); + var tile = SafeGetTile(i + x, j + y); if (x == 0 && y == 0) { continue; @@ -3617,7 +3270,7 @@ public static void PlaceSmallCyanVineOre(int i, int j) { for (int y = 0; y < 2; y++) { - var tile = TileUtils.SafeGetTile(i + x, j + y); + var tile = SafeGetTile(i + x, j + y); if (x == 0 && y == 0) { @@ -3657,7 +3310,7 @@ public static void PlaceSmallCyanVineOre(int i, int j) { for (int y = 0; y < 2; y++) { - var tile = TileUtils.SafeGetTile(i + x, j + y); + var tile = SafeGetTile(i + x, j + y); if (x == 0 && y == 0) { @@ -3708,13 +3361,13 @@ public static void PlaceSmallUpCyanVineOre(int i, int j) { case 0: { - var tile = TileUtils.SafeGetTile(i + 1, j); + var tile = SafeGetTile(i + 1, j); tile.TileType = (ushort)ModContent.TileType(); tile.TileFrameX = 18; tile.TileFrameY = 0; tile.HasTile = true; - var tileII = TileUtils.SafeGetTile(i + 1, j + 1); + var tileII = SafeGetTile(i + 1, j + 1); tileII.TileType = (ushort)ModContent.TileType(); tileII.TileFrameX = 18; tileII.TileFrameY = 18; @@ -3725,13 +3378,13 @@ public static void PlaceSmallUpCyanVineOre(int i, int j) break; case 1: { - var tile = TileUtils.SafeGetTile(i + 1, j); + var tile = SafeGetTile(i + 1, j); tile.TileType = (ushort)ModContent.TileType(); tile.TileFrameX = 72; tile.TileFrameY = 0; tile.HasTile = true; - var tileII = TileUtils.SafeGetTile(i + 1, j + 1); + var tileII = SafeGetTile(i + 1, j + 1); tileII.TileType = (ushort)ModContent.TileType(); tileII.TileFrameX = 18; tileII.TileFrameY = 18; @@ -3740,26 +3393,26 @@ public static void PlaceSmallUpCyanVineOre(int i, int j) break; case 2: { - var tile = TileUtils.SafeGetTile(i + 1, j); + var tile = SafeGetTile(i + 1, j); tile.TileType = (ushort)ModContent.TileType(); tile.TileFrameX = 126; tile.TileFrameY = 0; tile.HasTile = true; - var tileII = TileUtils.SafeGetTile(i + 1, j + 1); + var tileII = SafeGetTile(i + 1, j + 1); tileII.TileType = (ushort)ModContent.TileType(); tileII.TileFrameX = 18; tileII.TileFrameY = 18; tileII.HasTile = true; - var tileIII = TileUtils.SafeGetTile(i, j); + var tileIII = SafeGetTile(i, j); tileIII.TileType = (ushort)ModContent.TileType(); tileIII.TileFrameX = 0; tileIII.TileFrameY = 0; tileIII.Slope = SlopeType.SlopeUpRight; tileIII.HasTile = true; - var tileIV = TileUtils.SafeGetTile(i + 2, j); + var tileIV = SafeGetTile(i + 2, j); tileIV.TileType = (ushort)ModContent.TileType(); tileIV.TileFrameX = 36; tileIV.TileFrameY = 0; @@ -3769,26 +3422,26 @@ public static void PlaceSmallUpCyanVineOre(int i, int j) break; case 3: { - var tile = TileUtils.SafeGetTile(i + 1, j); + var tile = SafeGetTile(i + 1, j); tile.TileType = (ushort)ModContent.TileType(); tile.TileFrameX = 180; tile.TileFrameY = 0; tile.HasTile = true; - var tileII = TileUtils.SafeGetTile(i + 1, j + 1); + var tileII = SafeGetTile(i + 1, j + 1); tileII.TileType = (ushort)ModContent.TileType(); tileII.TileFrameX = 18; tileII.TileFrameY = 18; tileII.Slope = SlopeType.SlopeUpRight; tileII.HasTile = true; - var tileIII = TileUtils.SafeGetTile(i, j); + var tileIII = SafeGetTile(i, j); tileIII.TileType = (ushort)ModContent.TileType(); tileIII.TileFrameX = 0; tileIII.TileFrameY = 0; tileIII.HasTile = true; - var tileIV = TileUtils.SafeGetTile(i + 2, j); + var tileIV = SafeGetTile(i + 2, j); tileIV.TileType = (ushort)ModContent.TileType(); tileIV.TileFrameX = 36; tileIV.TileFrameY = 0; @@ -3810,7 +3463,7 @@ public static void PlaceLargeUpCyanVineOre(int i, int j) { for (int y = 0; y < 3; y++) { - var tile = TileUtils.SafeGetTile(i + x, j + y); + var tile = SafeGetTile(i + x, j + y); if (x == 1 && y == 2) { continue; @@ -3871,7 +3524,7 @@ public static void PlaceLampWoodBiomeChest(int x, int y) { for (int j = 0; j < 2; j++) { - Tile tile = TileUtils.SafeGetTile(i + x, y - j); + Tile tile = SafeGetTile(i + x, y - j); if (tile.HasTile) { tile.ClearEverything(); @@ -3997,19 +3650,26 @@ public static List TwilightNormalChestContents() chestContents.Add(new Item(setDefaultsToType: ModContent.ItemType(), 1)); break; } + chestContents.AddRange(NormalChestContents()); + return chestContents; + } - // é‡‘å¸ + public static List NormalChestContents() + { + List contents = new List(); + + // Gold coin if (WorldGen.genRand.NextBool(5)) { - chestContents.Add(new Item(setDefaultsToType: ItemID.GoldCoin, WorldGen.genRand.Next(1, 3))); + contents.Add(new Item(setDefaultsToType: ItemID.GoldCoin, WorldGen.genRand.Next(1, 3))); } - // ç»³å­ - chestContents.Add(new Item(setDefaultsToType: ItemID.Rope, WorldGen.genRand.Next(70, 151))); + // Rope + contents.Add(new Item(setDefaultsToType: ModContent.ItemType(), WorldGen.genRand.Next(70, 151))); - // è¯æ°´ + // Potion int potionType = 1; - switch (WorldGen.genRand.Next(5)) + switch (WorldGen.genRand.Next(6)) { case 0: potionType = ItemID.WarmthPotion; @@ -4026,22 +3686,37 @@ public static List TwilightNormalChestContents() case 4: potionType = ItemID.MiningPotion; break; + case 5: + potionType = ItemID.RecallPotion; + break; } - chestContents.Add(new Item(setDefaultsToType: potionType, WorldGen.genRand.Next(1, 4))); + contents.Add(new Item(setDefaultsToType: potionType, WorldGen.genRand.Next(1, 4))); - // è§å…‰æ£’ + // glow stick if (WorldGen.genRand.NextBool(2)) { if (WorldGen.genRand.NextBool(5)) { - chestContents.Add(new Item(setDefaultsToType: ItemID.StickyGlowstick, WorldGen.genRand.Next(20, 61))); + contents.Add(new Item(setDefaultsToType: ItemID.StickyGlowstick, WorldGen.genRand.Next(20, 61))); } else { - chestContents.Add(new Item(setDefaultsToType: ItemID.Glowstick, WorldGen.genRand.Next(20, 61))); + contents.Add(new Item(setDefaultsToType: ItemID.Glowstick, WorldGen.genRand.Next(20, 61))); } } - return chestContents; + + // yggdrasil Amber + if (WorldGen.genRand.NextBool(5)) + { + contents.Add(new Item(setDefaultsToType: ModContent.ItemType(), WorldGen.genRand.Next(5, 15))); + } + + // cyan ore + if (WorldGen.genRand.NextBool(5)) + { + contents.Add(new Item(setDefaultsToType: ModContent.ItemType(), WorldGen.genRand.Next(15, 75))); + } + return contents; } /// @@ -4055,7 +3730,7 @@ public static void PlaceTwilightLegacyBiomeChest(int x, int y) { for (int j = 0; j < 2; j++) { - Tile tile = TileUtils.SafeGetTile(i + x, y - j); + Tile tile = SafeGetTile(i + x, y - j); if (tile.HasTile) { tile.ClearEverything(); diff --git a/Sources/Modules/Yggdrasil/WorldGeneration/YggdrasilWorldGeneration.cs b/Sources/Modules/Yggdrasil/WorldGeneration/YggdrasilWorldGeneration.cs index c25e6f935..e73a1705a 100644 --- a/Sources/Modules/Yggdrasil/WorldGeneration/YggdrasilWorldGeneration.cs +++ b/Sources/Modules/Yggdrasil/WorldGeneration/YggdrasilWorldGeneration.cs @@ -3,13 +3,15 @@ using Everglow.Yggdrasil.HurricaneMaze.Tiles; using Everglow.Yggdrasil.KelpCurtain.Tiles; using Everglow.Yggdrasil.KelpCurtain.Walls; +using Everglow.Yggdrasil.YggdrasilTown.Liquids; using Everglow.Yggdrasil.YggdrasilTown.Tiles; using Everglow.Yggdrasil.YggdrasilTown.Tiles.CyanVine; using Everglow.Yggdrasil.YggdrasilTown.Walls; +using ModLiquidLib.ModLoader; using ReLogic.Utilities; using Terraria.IO; -using Terraria.Utilities; using Terraria.WorldBuilding; +using static Everglow.Commons.Utilities.TileUtils; using static Everglow.Yggdrasil.WorldGeneration.KelpCurtainGeneration; using static Everglow.Yggdrasil.WorldGeneration.YggdrasilTownGeneration; @@ -28,8 +30,8 @@ public override void ApplyPass(GenerationProgress progress, GameConfiguration co { Main.statusText = Terraria.Localization.Language.GetTextValue("Mods.Everglow.Common.WorldSystem.BuildtheTreeWorld"); TotalInitialize(); - Main.spawnTileX = 1400; - Main.spawnTileY = 20630; + Main.spawnTileX = 1475; + Main.spawnTileY = 20600; BuildYggdrasilTown(); BuildKelpCurtain(); @@ -54,9 +56,6 @@ public override void ApplyPass(GenerationProgress progress, GameConfiguration co public override void ModifyWorldGenTasks(List tasks, ref double totalWeight) => tasks.Add(new MainWorldPylonRelicGenPass_Yggdrasil()); - public static int[,] PerlinPixelR = new int[1024, 1024]; - public static int[,] PerlinPixelG = new int[1024, 1024]; - public static int[,] PerlinPixelB = new int[1024, 1024]; public static int[,] PerlinPixel2 = new int[1024, 1024]; public static int[,] CellPixel = new int[512, 512]; public static int[,] MeltingPixel = new int[256, 256]; @@ -67,40 +66,7 @@ public override void ApplyPass(GenerationProgress progress, GameConfiguration co /// /// /// - public static float GetPerlinPixelR(float x, float y) - { - return PerlinPixelR[(int)Math.Abs(x) % 1024, (int)Math.Abs(y) % 1024] / 255f; - } - - /// - /// A float value based on the texture;0.0f~1.0f. - /// - /// - /// - /// - public static float GetPerlinPixeG(float x, float y) - { - return PerlinPixelG[(int)Math.Abs(x) % 1024, (int)Math.Abs(y) % 1024] / 255f; - } - - /// - /// A float value based on the texture;0.0f~1.0f. - /// - /// - /// - /// - public static float GetPerlinPixelB(float x, float y) - { - return PerlinPixelB[(int)Math.Abs(x) % 1024, (int)Math.Abs(y) % 1024] / 255f; - } - - /// - /// A float value based on the texture;0.0f~1.0f. - /// - /// - /// - /// - public static float GetPerlinPixel2(float x, float y) + public static float GetLargeSmokeTexturePixel2(float x, float y) { return PerlinPixel2[(int)Math.Abs(x) % 1024, (int)Math.Abs(y) % 1024] / 255f; } @@ -132,14 +98,11 @@ public static float GetMeltingPixel(float x, float y) /// public static List ShouldNotSmoothAreas = new List(); - public static UnifiedRandom GenRand = new UnifiedRandom(); - /// /// 总åˆå§‹åŒ– /// public static void TotalInitialize() { - GenRand = WorldGen.genRand; FillPerlinPixel(); } @@ -148,27 +111,8 @@ public static void TotalInitialize() /// public static void FillPerlinPixel() { - var imageData = ImageReader.Read("Everglow/Yggdrasil/WorldGeneration/Noise_II_rgb.bmp"); - Vector2 perlinCoordCenter = new Vector2(GenRand.NextFloat(0f, 1f), GenRand.NextFloat(0f, 1f)); - imageData.ProcessPixelRows(accessor => - { - for (int y = 0; y < accessor.Height; y++) - { - int newY = (int)(accessor.Height * perlinCoordCenter.Y + y) % accessor.Height; - var pixelRow = accessor.GetRowSpan(newY); - for (int x = 0; x < pixelRow.Length; x++) - { - int newX = (int)(accessor.Width * perlinCoordCenter.X + x) % accessor.Width; - ref var pixel = ref pixelRow[newX]; - PerlinPixelR[x, y] = pixel.R; - PerlinPixelG[x, y] = pixel.G; - PerlinPixelB[x, y] = pixel.B; - } - } - }); - - imageData = ImageReader.Read("Everglow/Yggdrasil/WorldGeneration/Noise_perlin.bmp"); - perlinCoordCenter = new Vector2(GenRand.NextFloat(0f, 1f), GenRand.NextFloat(0f, 1f)); + var imageData = ImageReader.Read("Everglow/Yggdrasil/WorldGeneration/Noise_perlin.bmp"); + var perlinCoordCenter = new Vector2(GenRand.NextFloat(0f, 1f), GenRand.NextFloat(0f, 1f)); imageData.ProcessPixelRows(accessor => { for (int y = 0; y < accessor.Height; y++) @@ -258,7 +202,7 @@ public static void GenerateStalactite(Vector2 center, float radius, float height float limit = MathF.Pow(minCosX, 2); if (yValue < limit) { - Tile tile = TileUtils.SafeGetTile(i + cX, j + cY); + Tile tile = SafeGetTile(i + cX, j + cY); tile.TileType = (ushort)type; tile.HasTile = true; } @@ -277,7 +221,7 @@ public static void GenerateStalactite(Vector2 center, float radius, float height float limit = MathF.Pow(minCosX, 1); if (yValue < limit) { - Tile tile = TileUtils.SafeGetTile(i + cX, cY + heightLimit - j); + Tile tile = SafeGetTile(i + cX, cY + heightLimit - j); tile.TileType = (ushort)type; tile.HasTile = true; } @@ -290,10 +234,10 @@ public static void GenerateStalactite(Vector2 center, float radius, float height { int x = i + cX; int y = cY - j; - float value = j / topThick + (PerlinPixelR[Math.Abs(x) % 1024, Math.Abs(y) % 1024] - 128) / 64f * smoothTopValue; + float value = j / topThick + (GetLargeSmokeTexturePixelR(x, y) * 256 - 128) / 64f * smoothTopValue; if (value < 1) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.TileType = (ushort)type; tile.HasTile = true; } @@ -301,85 +245,6 @@ public static void GenerateStalactite(Vector2 center, float radius, float height } } - /// - /// Fill all chest by given area if exist. - /// - /// - /// - /// - /// - /// - public static void FillChestXYWH(int x, int y, int width, int height, List contents) - { - for (int i = 0; i < width; i++) - { - for (int j = 0; j < height; j++) - { - WorldGenMisc.TryFillChest(x + i, y + j, contents); - } - } - } - - /// - /// Smooth tiles by given area:(x0:left, y0:top, x1:right, y1:bottom) - /// - /// - /// - /// - /// - public static void SmoothTile(int x0, int y0, int x1, int y1) - { - x0 = Math.Clamp(x0, 20, Main.maxTilesX - 20); - x1 = Math.Clamp(x1, 20, Main.maxTilesX - 20); - y0 = Math.Clamp(y0, 20, Main.maxTilesY - 20); - y1 = Math.Clamp(y1, 20, Main.maxTilesY - 20); - for (int x = x0; x <= x1; x += 1) - { - for (int y = y0; y <= y1; y += 1) - { - if (!ChestSafe(x, y)) - { - continue; - } - if (!CanLegallySmooth(x, y)) - { - continue; - } - Tile.SmoothSlope(x, y, false, false); - WorldGen.TileFrame(x, y, true, false); - WorldGen.SquareWallFrame(x, y, true); - } - } - } - - /// - /// Fill tiles by given area:(x0:left, y0:top, x1:right, y1:bottom) - /// - /// - /// - /// - /// - /// - public static void PlaceRectangleAreaOfBlock(int x0, int y0, int x1, int y1, int type, bool smooth = true) - { - for (int x = x0; x <= x1; x += 1) - { - for (int y = y0; y <= y1; y += 1) - { - Tile tile = TileUtils.SafeGetTile(x, y); - if (ChestSafe(x, y)) - { - tile.TileType = (ushort)type; - tile.HasTile = true; - } - } - } - if (smooth) - { - SmoothTile(x0, y0, x1, y1); - } - } - /// /// Fill liquids by given area:(x0:left, y0:top, x1:right, y1:bottom) /// @@ -394,7 +259,7 @@ public static void PlaceRectangleAreaOfLiquid(int x0, int y0, int x1, int y1, in { for (int y = y0; y <= y1; y += 1) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); if (ChestSafe(x, y)) { tile.liquid = (byte)type; @@ -420,7 +285,7 @@ public static void PlaceSquareAreaOfBlock(Point point, int halfSideRange, int ty for (int y = 0; y <= halfSideRange * 2; y += 1) { Point check = startPoint + new Point(x, y); - Tile tile = TileUtils.SafeGetTile(check); + Tile tile = SafeGetTile(check); if (ChestSafe(check.X, check.Y)) { if (type >= 0) @@ -453,7 +318,7 @@ public static void PlaceSquareAreaOfLiquid(Point point, int halfSideRange, int t for (int y = 0; y <= halfSideRange * 2; y += 1) { Point check = startPoint + new Point(x, y); - Tile tile = TileUtils.SafeGetTile(check); + Tile tile = SafeGetTile(check); if (ChestSafe(check.X, check.Y)) { tile.liquid = (byte)type; @@ -479,10 +344,10 @@ public static void PlaceSquareAreaOfWall(Point point, int halfSideRange, int typ for (int y = 0; y <= halfSideRange * 2; y += 1) { Point check = startPoint + new Point(x, y); - Tile tile = TileUtils.SafeGetTile(check); + Tile tile = SafeGetTile(check); if (ChestSafe(check.X, check.Y)) { - tile.wall = (ushort)type; + tile.WallType = (ushort)type; } } } @@ -502,11 +367,11 @@ public static void PlaceRectangleAreaOfWall(int x0, int y0, int x1, int y1, int { for (int y = y0; y <= y1; y += 1) { - Tile tile = TileUtils.SafeGetTile(x, y); - tile.wall = (ushort)type; + Tile tile = SafeGetTile(x, y); + tile.WallType = (ushort)type; } } - SmoothTile(x0, y0, x1, y1); + SmoothTile_XXYY(x0, y0, x1, y1); } /// @@ -523,11 +388,11 @@ public static void ClearRectangleArea(int x0, int y0, int x1, int y1) { for (int y = y0; y <= y1; y += 1) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.ClearEverything(); } } - SmoothTile(x0, y0, x1, y1); + SmoothTile_XXYY(x0, y0, x1, y1); } /// @@ -544,14 +409,14 @@ public static void KillRectangleAreaOfTile(int x0, int y0, int x1, int y1) { for (int y = y0; y <= y1; y += 1) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); if (ChestSafe(x, y)) { tile.HasTile = false; } } } - SmoothTile(x0, y0, x1, y1); + SmoothTile_XXYY(x0, y0, x1, y1); } /// @@ -567,7 +432,7 @@ public static void KillRectangleAreaOfLiquid(int x0, int y0, int x1, int y1) { for (int y = y0; y <= y1; y += 1) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.LiquidAmount = 0; } } @@ -586,7 +451,7 @@ public static void KillRectangleAreaOfWire(int x0, int y0, int x1, int y1) { for (int y = y0; y <= y1; y += 1) { - Tile tile = TileUtils.SafeGetTile(x, y); + Tile tile = SafeGetTile(x, y); tile.RedWire = false; tile.GreenWire = false; tile.BlueWire = false; @@ -609,11 +474,11 @@ public static void KillRectangleAreaOfWall(int x0, int y0, int x1, int y1) { for (int y = y0; y <= y1; y += 1) { - Tile tile = TileUtils.SafeGetTile(x, y); - tile.wall = 0; + Tile tile = SafeGetTile(x, y); + tile.WallType = 0; } } - SmoothTile(x0, y0, x1, y1); + SmoothTile_XXYY(x0, y0, x1, y1); } /// @@ -638,190 +503,6 @@ public static void QuickBuild(int x, int y, string Path, bool stopSmooth = true) } } - /// - /// Return the summary of air-to-tile distances of given point to top and to bottom. - /// - /// - /// - /// - public static int CheckSpaceHeight(int x, int y) - { - int count = 0; - int x0 = x; - int y0 = y; - if (x0 > Main.maxTilesX || x0 < 0) - { - return count; - } - while (!TileUtils.SafeGetTile(x0, y0).HasTile) - { - if (y0 > Main.maxTilesY) - { - break; - } - y0++; - count++; - } - x0 = x; - y0 = y - 1; - while (!TileUtils.SafeGetTile(x0, y0).HasTile) - { - if (y0 < 0) - { - break; - } - y0--; - count++; - } - return count; - } - - /// - /// Return the summary of air-to-tile distances of given point to left and to right. - /// - /// - /// - /// - public static int CheckSpaceWidth(int x, int y) - { - int count = 0; - int x0 = x; - int y0 = y; - if (y0 > Main.maxTilesY || y0 < 0) - { - return count; - } - while (!TileUtils.SafeGetTile(x0, y0).HasTile) - { - if (x0 > Main.maxTilesX) - { - break; - } - x0++; - count++; - } - x0 = x - 1; - y0 = y; - while (!TileUtils.SafeGetTile(x0, y0).HasTile) - { - if (x0 < 0) - { - break; - } - x0--; - count++; - } - return count; - } - - /// - /// Return the air-to-tile distance from given point to LEFT. - /// - /// - /// - /// - public static int CheckSpaceLeft(int x, int y) - { - int count = 0; - int x0 = x; - int y0 = y; - if (y0 > Main.maxTilesY || y0 < 0) - { - return count; - } - while (!TileUtils.SafeGetTile(x0, y0).HasTile) - { - if (x0 < 0) - { - break; - } - x0--; - count++; - } - return count; - } - - /// - /// Return the air-to-tile distance from given point to RIGHT. - /// - /// - /// - /// - public static int CheckSpaceRight(int x, int y) - { - int count = 0; - int x0 = x; - int y0 = y; - if (y0 > Main.maxTilesY || y0 < 0) - { - return count; - } - while (!TileUtils.SafeGetTile(x0, y0).HasTile) - { - if (x0 > Main.maxTilesX) - { - break; - } - x0++; - count++; - } - return count; - } - - /// - /// Return the air-to-tile distance from given point to TOP. - /// - /// - /// - /// - public static int CheckSpaceUp(int x, int y) - { - int count = 0; - int x0 = x; - int y0 = y; - if (x0 > Main.maxTilesX || x0 < 0) - { - return count; - } - while (!TileUtils.SafeGetTile(x0, y0).HasTile) - { - if (y0 < 0) - { - break; - } - y0--; - count++; - } - return count; - } - - /// - /// Return the air-to-tile distance from given point to BOTTOM. - /// - /// - /// - /// - public static int CheckSpaceDown(int x, int y) - { - int count = 0; - int x0 = x; - int y0 = y; - if (y0 > Main.maxTilesY || y0 < 0) - { - return count; - } - while (!TileUtils.SafeGetTile(x0, y0).HasTile) - { - if (y0 > Main.maxTilesY) - { - break; - } - y0++; - count++; - } - return count; - } - /// /// Return the tile-embedded-depth by the given point, a float value, but 1 tile's length = 1.0f. /// @@ -833,7 +514,7 @@ public static float EmbeddingDepth(int x, int y, int maxRange = 4) { for (int j = -maxRange; j <= maxRange; j++) { - if (!TileUtils.SafeGetTile(i + x, j + y).HasTile) + if (!SafeGetTile(i + x, j + y).HasTile) { if (new Vector2(i, j).Length() <= minDepth) { @@ -858,7 +539,7 @@ public static float EmbeddingWallDepth(int x, int y, int maxRange = 50) { if (new Vector2(i, j).Length() <= depth) { - if (TileUtils.SafeGetTile(i + x, j + y).wall <= 0) + if (SafeGetTile(i + x, j + y).wall <= 0) { depth = new Vector2(i, j).Length(); } @@ -881,7 +562,7 @@ public static int EmbeddingDepthOfTileType(int x, int y, int type, int maxRange { if (new Vector2(i, j).Length() <= maxRange) { - Tile tile = TileUtils.SafeGetTile(i + x, j + y); + Tile tile = SafeGetTile(i + x, j + y); if (tile.HasTile && tile.TileType == type) { depth++; @@ -906,7 +587,7 @@ public static Vector2 TerrianSurfaceNormal(int x, int y, int maxRange = 4, int e Vector2 v1 = new Vector2(i, j); if (v1.Length() <= maxRange && v1.Length() > 0) { - Tile tile = TileUtils.SafeGetTile(i + x, j + y); + Tile tile = SafeGetTile(i + x, j + y); if (tile.HasTile && tile.TileType != excludeTileType) { v0 += Vector2.Normalize(v1) / v1.Length(); @@ -939,7 +620,7 @@ public static float TerrianSurfaceAngle(int x, int y, int maxRange = 4, int excl Vector2 v1 = new Vector2(i, j); if (v1.Length() <= maxRange && v1.Length() > 0) { - Tile tile = TileUtils.SafeGetTile(i + x, j + y); + Tile tile = SafeGetTile(i + x, j + y); if (tile.HasTile && tile.TileType != excludeTileType) { v0 += Vector2.Normalize(v1) / v1.Length(); @@ -1012,7 +693,7 @@ public static Vector2 TerrianTypeTileSurfaceNormal(int x, int y, int type, int m Vector2 v1 = new Vector2(i, j); if (v1.Length() <= maxRange && v1.Length() > 0) { - Tile tile = TileUtils.SafeGetTile(i + x, j + y); + Tile tile = SafeGetTile(i + x, j + y); if (tile.HasTile && tile.TileType == type) { v0 += Vector2.Normalize(v1) / v1.Length(); @@ -1045,7 +726,7 @@ public static float TerrianTypeTileSurfaceAngle(int x, int y, int type, int maxR Vector2 v1 = new Vector2(i, j); if (v1.Length() <= maxRange && v1.Length() > 0) { - Tile tile = TileUtils.SafeGetTile(i + x, j + y); + Tile tile = SafeGetTile(i + x, j + y); if (tile.HasTile && tile.TileType == type) { v0 += Vector2.Normalize(v1) / v1.Length(); @@ -1115,7 +796,7 @@ public static float To100NearestBlockDistance(int x, int y) { for (int j = -100; j <= 100; j++) { - Tile tile = TileUtils.SafeGetTile(i + x, j + y); + Tile tile = SafeGetTile(i + x, j + y); if (tile.HasTile) { Vector2 v1 = new Vector2(i, j); @@ -1140,7 +821,7 @@ public static float To100NearestTileTypeBlockDistance(int x, int y, int type) { for (int j = -100; j <= 100; j++) { - Tile tile = TileUtils.SafeGetTile(i + x, j + y); + Tile tile = SafeGetTile(i + x, j + y); if (tile.HasTile && tile.TileType == type) { Vector2 v1 = new Vector2(i, j); @@ -1166,7 +847,7 @@ public static Point NearestBlockCoordinateIn100Tile(int x, int y, int excludeTil { for (int j = -100; j <= 100; j++) { - Tile tile = TileUtils.SafeGetTile(i + x, j + y); + Tile tile = SafeGetTile(i + x, j + y); if (tile.HasTile && tile.TileType != excludeTileType) { Vector2 v1 = new Vector2(i, j); @@ -1192,7 +873,7 @@ public static float To100NearestEmptyDistance(int x, int y) { for (int j = -100; j <= 100; j++) { - Tile tile = TileUtils.SafeGetTile(i + x, j + y); + Tile tile = SafeGetTile(i + x, j + y); if (!tile.HasTile) { Vector2 v1 = new Vector2(i, j); @@ -1217,7 +898,7 @@ public static float To100NearestEmptyDistance(int x, int y) public static void CrawlCarpetOfTile(int x, int y, int step, int thick, int type, bool clockwise = false) { Point checkPoint = NearestBlockCoordinateIn100Tile(x, y, type); - if (!TileUtils.SafeGetTile(checkPoint).HasTile) + if (!SafeGetTile(checkPoint).HasTile) { return; } @@ -1230,7 +911,7 @@ public static void CrawlCarpetOfTile(int x, int y, int step, int thick, int type CircleTile(position + normal * thickValue, position, type); position += velocity; int count = 0; - while (!TileUtils.SafeGetTile(position).HasTile) + while (!SafeGetTile(position).HasTile) { count++; position += TerrianSurfaceNormal((int)position.X, (int)position.Y); @@ -1254,7 +935,7 @@ public static void CrawlCarpetOfTile(int x, int y, int step, int thick, int type public static void CrawlCarpetOfTypeTile(int x, int y, int step, int thick, int type, int backgroundType, bool clockwise = false) { Point checkPoint = NearestBlockCoordinateIn100Tile(x, y, type); - if (!TileUtils.SafeGetTile(checkPoint).HasTile) + if (!SafeGetTile(checkPoint).HasTile) { return; } @@ -1267,7 +948,7 @@ public static void CrawlCarpetOfTypeTile(int x, int y, int step, int thick, int CircleTile(position + normal * thickValue, position, type); position += velocity; int count = 0; - while (!TileUtils.SafeGetTile(position).HasTile) + while (!SafeGetTile(position).HasTile) { count++; position += TerrianTypeTileSurfaceNormal((int)position.X, (int)position.Y, backgroundType); @@ -1294,40 +975,29 @@ public static void CircleTile(Vector2 center, float radius, int type, bool force { for (int y = -radiusI; y <= radiusI; y++) { - Tile tile = TileUtils.SafeGetTile(center + new Vector2(x, y)); + Tile tile = SafeGetTile(center + new Vector2(x, y)); if (new Vector2(x, y).Length() <= radius) { if (ChestSafe(center + new Vector2(x, y))) { - if (force) + if (type == -2) { - if (type == -2) - { - tile.ClearEverything(); - } - else if (type == -1) - { - tile.HasTile = false; - } - else + tile.ClearEverything(); + } + else if (type == -1) + { + tile.HasTile = false; + } + else if (type >= 0) + { + if (force) { tile.TileType = (ushort)type; tile.HasTile = true; } - } - else - { - if (!tile.HasTile) + else { - if (type == -2) - { - tile.ClearEverything(); - } - else if (type == -1) - { - tile.HasTile = false; - } - else + if (!tile.HasTile) { tile.TileType = (ushort)type; tile.HasTile = true; @@ -1340,6 +1010,18 @@ public static void CircleTile(Vector2 center, float radius, int type, bool force } } + /// + /// Set a center and radius of a circle in tile coordinate, and (type >= 0, place that type of tile, type = -1,clear tiles; tile = -2,clear everything). + /// + /// + /// + /// + /// + public static void CircleTile(Point center, float radius, int type, bool force = false) + { + CircleTile(center.ToVector2(), radius, type, force); + } + /// /// Set 2 point as diameter that defines a circle in tile coordinate, and (type >= 0, place that type of tile, type = -1,clear tiles; tile = -2,clear everything). /// @@ -1368,25 +1050,25 @@ public static void CircleWall(Vector2 center, float radius, int type, bool force { for (int y = -radiusI; y <= radiusI; y++) { - Tile tile = TileUtils.SafeGetTile(center + new Vector2(x, y)); + Tile tile = SafeGetTile(center + new Vector2(x, y)); if (new Vector2(x, y).Length() <= radius) { - if (force) + if (type == -1) { - if (type == -1) + tile.ClearEverything(); + } + else if (type >= 0) + { + if (force) { - tile.ClearEverything(); + tile.WallType = (ushort)type; } else { - tile.wall = (ushort)type; - } - } - else - { - if (tile.wall == 0) - { - tile.wall = (ushort)type; + if (tile.WallType <= 0) + { + tile.WallType = (ushort)type; + } } } } @@ -1409,7 +1091,8 @@ public static void CircleWall(Vector2 pointA, Vector2 pointB, int type, bool for } /// - /// 圆心åŠå¾„,布设ä¸è§„则圆形物å—(å°äºŽåŠå¾„),=-1清ç†ç‰©å—,-2清ç†å…¨éƒ¨ + /// Transform the tile within the circle(center, radius) to the type, but with a random noise affect on the bound.
+ /// force = true, directly set the tile to the type; force = false, only set the tile to the type when there is no tile.
///
/// /// @@ -1424,31 +1107,31 @@ public static void CircleTileWithRandomNoise(Vector2 center, float radius, int t { for (int y = -radiusI; y <= radiusI; y++) { - Tile tile = TileUtils.SafeGetTile(center + new Vector2(x, y)); - float aValue = PerlinPixelR[Math.Abs((x + x0CoordPerlin) % 1024), Math.Abs((y + y0CoordPerlin) % 1024)] / 255f; + Tile tile = SafeGetTile(center + new Vector2(x, y)); + float aValue = GetLargeSmokeTexturePixelR(x + x0CoordPerlin, y + y0CoordPerlin); if (ChestSafe(center + new Vector2(x, y))) { if (new Vector2(x, y).Length() <= radius - aValue * noiseSize) { - if (force) + if (type == -1) { - if (type == -1) - { - tile.ClearEverything(); - } - else - { - tile.TileType = (ushort)type; - tile.HasTile = true; - } + tile.ClearEverything(); } - else + else if (type >= 0) { - if (!tile.HasTile) + if (force) { tile.TileType = (ushort)type; tile.HasTile = true; } + else + { + if (!tile.HasTile) + { + tile.TileType = (ushort)type; + tile.HasTile = true; + } + } } } } @@ -1456,6 +1139,18 @@ public static void CircleTileWithRandomNoise(Vector2 center, float radius, int t } } + /// + /// 圆心åŠå¾„,布设ä¸è§„则圆形物å—(å°äºŽåŠå¾„),=-1清ç†ç‰©å—,-2清ç†å…¨éƒ¨ + /// + /// + /// + /// + /// + public static void CircleTileWithRandomNoise(Point center, float radius, int type, float noiseSize = 10f, bool force = false) + { + CircleTileWithRandomNoise(center.ToVector2(), radius, type, noiseSize, force); + } + public static void CircleTileWithRandomNoise(Vector2 pointA, Vector2 pointB, int type, float noiseSize = 10f, bool force = false) { float radius = (pointA - pointB).Length() * 0.5f; @@ -1481,13 +1176,13 @@ public static void ShapeTile(string Shapepath, int a, int b, int type) for (int x = 0; x < pixelRow.Length; x++) { ref var pixel = ref pixelRow[x]; - Tile tile = TileUtils.SafeGetTile(x + a, y + b); + Tile tile = SafeGetTile(x + a, y + b); switch (type)// 21æ˜¯ç®±å­ { case 0: if (pixel.R == 255 && pixel.G == 0 && pixel.B == 0) { - if (tile.TileType != 21 && TileUtils.SafeGetTile(x + a, y + b - 1).TileType != 21) + if (tile.TileType != TileID.Containers && SafeGetTile(x + a, y + b - 1).TileType != TileID.Containers) { tile.ClearEverything(); } @@ -1508,8 +1203,8 @@ public static void ShapeTile(string Shapepath, int a, int b, int type) if (pixel.R == 31 && pixel.G == 26 && pixel.B == 45)// 黑淤泥 { - tile.TileType = (ushort)ModContent.TileType(); - tile.HasTile = true; + tile.LiquidType = LiquidLoader.LiquidType(); + tile.LiquidAmount = byte.MaxValue; } // è‹è‹”蔓帘 @@ -1565,28 +1260,28 @@ public static void ShapeTile(string Shapepath, int a, int b, int type) case 2: if (pixel.R == 24 && pixel.G == 0 && pixel.B == 0)// 石化龙鳞木 { - if (tile.TileType != 21 && TileUtils.SafeGetTile(x + a, y + b - 1).TileType != 21) + if (tile.TileType != TileID.Containers && SafeGetTile(x + a, y + b - 1).TileType != TileID.Containers) { tile.WallType = (ushort)ModContent.WallType(); } } if (pixel.R == 40 && pixel.G == 32 && pixel.B == 31)// 龙鳞木 { - if (tile.TileType != 21 && TileUtils.SafeGetTile(x + a, y + b - 1).TileType != 21) + if (tile.TileType != TileID.Containers && SafeGetTile(x + a, y + b - 1).TileType != TileID.Containers) { tile.WallType = (ushort)ModContent.WallType(); } } if (pixel.R == 56 && pixel.G == 56 && pixel.B == 56)// 石墙 { - if (tile.TileType != 21 && TileUtils.SafeGetTile(x + a, y + b - 1).TileType != 21) + if (tile.TileType != TileID.Containers && SafeGetTile(x + a, y + b - 1).TileType != TileID.Containers) { tile.WallType = WallID.Stone; } } if (pixel.R == 25 && pixel.G == 14 && pixel.B == 12)// 天穹土墙 { - if (tile.TileType != 21 && TileUtils.SafeGetTile(x + a, y + b - 1).TileType != 21) + if (tile.TileType != TileID.Containers && SafeGetTile(x + a, y + b - 1).TileType != TileID.Containers) { tile.WallType = (ushort)ModContent.WallType(); } @@ -1727,7 +1422,7 @@ public static Vector2D DigTunnel(double x, double y, double xDir, double yDir, i { if (Math.Abs(j - startX) + Math.Abs(k - startY) < checkSize * (1.0 + GenRand.Next(-10, 11) * 0.005) && j >= 0 && j < Main.maxTilesX && k >= 0 && k < Main.maxTilesY) { - Tile tile = TileUtils.SafeGetTile(j, k); + Tile tile = SafeGetTile(j, k); if (ChestSafe(j, k)) { tile.active(active: false); @@ -1737,7 +1432,7 @@ public static Vector2D DigTunnel(double x, double y, double xDir, double yDir, i } if (wallType != -1) { - tile.wall = (ushort)wallType; + tile.WallType = (ushort)wallType; } } } @@ -1818,7 +1513,7 @@ public static Vector2D DigTunnelInRequsetTiles(double x, double y, double xDir, { if (Math.Abs(j - startX) + Math.Abs(k - startY) < checkSize * (1.0 + GenRand.Next(-10, 11) * 0.005) && j >= 0 && j < Main.maxTilesX && k >= 0 && k < Main.maxTilesY) { - Tile tile = TileUtils.SafeGetTile(j, k); + Tile tile = SafeGetTile(j, k); if (ChestSafe(j, k)) { if (tile.TileType == type) @@ -1830,7 +1525,7 @@ public static Vector2D DigTunnelInRequsetTiles(double x, double y, double xDir, } if (wallType != -1) { - tile.wall = (ushort)wallType; + tile.WallType = (ushort)wallType; } } else @@ -1838,7 +1533,7 @@ public static Vector2D DigTunnelInRequsetTiles(double x, double y, double xDir, return new Vector2D(startX, startY); } } - Tile tileSafe = TileUtils.SafeGetTile((int)(j + (xVel + xDir) * 3), (int)(k + (yVel + yDir) * 3)); + Tile tileSafe = SafeGetTile((int)(j + (xVel + xDir) * 3), (int)(k + (yVel + yDir) * 3)); if (tile.TileType != type) { return new Vector2D(startX, startY); @@ -1891,23 +1586,6 @@ public static Vector2D DigTunnelInRequsetTiles(double x, double y, double xDir, return new Vector2D(startX, startY); } - /// - /// Return true when the given point can be killed safely(without chest). - /// - /// - /// - /// - public static bool ChestSafe(int x, int y) - { - Tile tile = TileUtils.SafeGetTile(x, y); - Tile tileUp = TileUtils.SafeGetTile(x, y - 1); - if (!TileID.Sets.BasicChest[tile.TileType] && !TileID.Sets.BasicChest[tileUp.TileType]) - { - return true; - } - return false; - } - /// /// Return true when the given point do not contained by any rectangles in ShouldNotSmoothAreas. /// @@ -1926,16 +1604,6 @@ public static bool CanLegallySmooth(int x, int y) return true; } - /// - /// Return true when the given point can be killed safely(without chest). - /// - /// - /// - public static bool ChestSafe(Vector2 center) - { - return ChestSafe((int)center.X, (int)center.Y); - } - /// /// Return true when no chest in given aren(include one row above). /// @@ -1950,8 +1618,8 @@ public static bool ChestSafeArea(int x, int y, int width, int height) { for (int y0 = y; y0 <= y + height; y0++) { - Tile tile = TileUtils.SafeGetTile(x, y); - Tile tileUp = TileUtils.SafeGetTile(x, y - 1); + Tile tile = SafeGetTile(x, y); + Tile tileUp = SafeGetTile(x, y - 1); if (TileID.Sets.BasicChest[tile.TileType] || TileID.Sets.BasicChest[tileUp.TileType]) { return false; @@ -1971,58 +1639,4 @@ public static bool ChestSafeArea(Vector2 center, Vector2 size) { return ChestSafeArea((int)center.X, (int)center.Y, (int)size.X, (int)size.Y); } - - private static readonly (int, int)[] directionsLiquid = - { - (1, 0), - (0, 1), - (-1, 0), - }; - - /// - /// Fill water or other liquid below center.center : in tile coord. - /// - /// - /// - public static void FillLiquid(Vector2 center, int type = 0, int maxCount = 900) - { - Queue queueChecked = new Queue(); - - // 将起始点加入队列 - queueChecked.Enqueue(center.ToPoint()); - List visited = new List(); - - while (queueChecked.Count > 0) - { - var tilePos = queueChecked.Dequeue(); - - foreach (var (dx, dy) in directionsLiquid) - { - int checkX = tilePos.X + dx; - int checkY = tilePos.Y + dy; - Point point = new Point(checkX, checkY); - - // 检查边界和障ç¢ç‰© - if (checkX >= 20 && checkX < Main.maxTilesX - 20 && checkY >= 20 && checkY < Main.maxTilesY - 20 && - !Collision.IsWorldPointSolid(point.ToWorldCoordinates()) && !visited.Contains(point)) - { - queueChecked.Enqueue(point); - visited.Add(point); - } - } - if (queueChecked.Count > maxCount || visited.Count > maxCount) - { - break; - } - } - if (visited.Count < maxCount) - { - foreach (var pos in visited) - { - Tile tile = TileUtils.SafeGetTile(pos); - tile.LiquidType = (byte)type; - tile.LiquidAmount = 255; - } - } - } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilModule.cs b/Sources/Modules/Yggdrasil/YggdrasilModule.cs index 3c5a10e41..3b63db789 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilModule.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilModule.cs @@ -7,7 +7,7 @@ namespace Everglow.Yggdrasil; -internal class YggdrasilModule : EverglowModule +public class YggdrasilModule : EverglowModule { public override string Name => "Yggdrasil"; @@ -125,7 +125,7 @@ private static void ILHook_DrawToMap_ChangeMapTargetColor(ref Color color, int x // 修改å°åœ°å›¾ç»˜åˆ¶é¢œè‰²åœ¨è¿™é‡Œå†™ Tile tile = Main.tile[x, y]; - if (tile.HasTile || tile.wall > 0 || tile.LiquidAmount > 0) + if (tile.HasTile || tile.WallType > 0 || tile.LiquidAmount > 0) { return; } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/JellyBallHotbed_Close.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/JellyBallHotbed_Close.png new file mode 100644 index 000000000..964783052 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/JellyBallHotbed_Close.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/JellyBallHotbed_Far.pdn b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/JellyBallHotbed_Far.pdn new file mode 100644 index 000000000..669454aa8 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/JellyBallHotbed_Far.pdn differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/JellyBallHotbed_Far.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/JellyBallHotbed_Far.png new file mode 100644 index 000000000..d73f104d3 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/JellyBallHotbed_Far.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/JellyBallHotbed_Far_old.pdn b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/JellyBallHotbed_Far_old.pdn new file mode 100644 index 000000000..376928a73 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/JellyBallHotbed_Far_old.pdn differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/JellyBallHotbed_Far_old.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/JellyBallHotbed_Far_old.png new file mode 100644 index 000000000..b0d5110b7 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/JellyBallHotbed_Far_old.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Close.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Close.png index ca4c35585..0005a98b6 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Close.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Close.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Middle_0.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Middle_0.png index d6bb5310a..aca1db0cd 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Middle_0.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Middle_0.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Middle_1.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Middle_1.png index bfe37e9ed..5ae98460c 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Middle_1.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Middle_1.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Middle_2.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Middle_2.png index 2f07ed47d..322c0dd95 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Middle_2.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Middle_2.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Sky.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Sky.png index 277d57762..7b3a00623 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Sky.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/MidnightBayou_Sky.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Swamp.pdn b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Swamp.pdn index 212d1dd39..562aa67d8 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Swamp.pdn and b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Swamp.pdn differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Town.pdn b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Town.pdn deleted file mode 100644 index baac83d7c..000000000 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Town.pdn and /dev/null differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Town_Close.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Town_Close.cs new file mode 100644 index 000000000..bf30834be --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Town_Close.cs @@ -0,0 +1,21 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain; + +namespace Everglow.Yggdrasil.YggdrasilTown.Background; + +public class Town_Close : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.Town_Close.Value; + Distance = 3f; + UseColorStyle = 2; + Shader = Effects.XWrap_YClamp_Shader; + } + + public override bool CanActive() + { + return YggdrasilTownCentralSystem.InYggdrasilTown(Main.screenPosition + new Vector2(Main.screenWidth, Main.screenHeight) * 0.5f); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Town_Far.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Town_Far.cs new file mode 100644 index 000000000..44c148446 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Town_Far.cs @@ -0,0 +1,21 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain; + +namespace Everglow.Yggdrasil.YggdrasilTown.Background; + +public class Town_Far : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.Town_Far.Value; + Distance = 15f; + UseColorStyle = 2; + Shader = Effects.XWrap_YWrap_Shader; + } + + public override bool CanActive() + { + return YggdrasilTownCentralSystem.InYggdrasilTown(Main.screenPosition + new Vector2(Main.screenWidth, Main.screenHeight) * 0.5f); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Town_Middle.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Town_Middle.cs new file mode 100644 index 000000000..3eba733f2 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Town_Middle.cs @@ -0,0 +1,21 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain; + +namespace Everglow.Yggdrasil.YggdrasilTown.Background; + +public class Town_Middle : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.Town_Middle.Value; + Distance = 6f; + UseColorStyle = 2; + Shader = Effects.XWrap_YWrap_Shader; + } + + public override bool CanActive() + { + return YggdrasilTownCentralSystem.InYggdrasilTown(Main.screenPosition + new Vector2(Main.screenWidth, Main.screenHeight) * 0.5f); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Town_Sky.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Town_Sky.cs new file mode 100644 index 000000000..935dd32d9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/Town_Sky.cs @@ -0,0 +1,21 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain; + +namespace Everglow.Yggdrasil.YggdrasilTown.Background; + +public class Town_Sky : BackgroundSlideBase +{ + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.Town_Sky.Value; + Distance = float.PositiveInfinity; + UseColorStyle = 2; + Shader = Effects.XWrap_YWrap_Shader; + } + + public override bool CanActive() + { + return YggdrasilTownCentralSystem.InYggdrasilTown(Main.screenPosition + new Vector2(Main.screenWidth, Main.screenHeight) * 0.5f); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTownBackground.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTownBackground.cs index c03d1d1fc..50e7a6316 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTownBackground.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTownBackground.cs @@ -3,7 +3,6 @@ using Everglow.Yggdrasil.YggdrasilTown.Biomes; using Everglow.Yggdrasil.YggdrasilTown.Tiles; using SubworldLibrary; -using static Everglow.Yggdrasil.WorldGeneration.YggdrasilWorldGeneration; namespace Everglow.Yggdrasil.YggdrasilTown.Background; @@ -15,7 +14,7 @@ public class YggdrasilTownBackground : ModSystem public static Vector2 BackgroundAnchoredCenter => YggdrasilTownBiome.BiomeCenter; /// - /// Origin Pylon + /// The world coord of [Origin Pylon] /// public static Vector2 OriginPylonCenter => new Vector2(1395, Main.maxTilesY - 405) * 16; @@ -63,6 +62,11 @@ public override void OnModLoad() ///
public float BackgroundAlphaCage = 0f; + /// + /// Background alpha of JellyBall hotbed + /// + public float BackgroundAlphaJellyBallHotbed = 0f; + public static Vector2 Stratum1Center => new Vector2(Main.maxTilesX / 2f * 16, (Main.maxTilesY - 1000) * 16); /// @@ -124,108 +128,151 @@ private void DrawYggdrasilTownBackground(Color baseColor) var texSky = ModAsset.YggdrasilTownBackgroundSky.Value; // 旧背景 - BackgroundManager.QuickDrawBG(texSky, float.PositiveInfinity, Stratum1Center, baseColor, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 16000)); + //BackgroundManager.DrawBG_RestrictY(texSky, float.PositiveInfinity, Stratum1Center, baseColor, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 16000)); - DrawYggdrasilTown_Town(baseColor); + //DrawYggdrasilTown_Town(baseColor); DrawMidnightBayou(baseColor); DrawLampWood(baseColor); DrawTwilightForsetAndRelic(baseColor); DrawCageOfChallengers(baseColor); + DrawJellyBallHotbed(baseColor); } - public void DrawYggdrasilTown_Town(Color baseColor) + //public void DrawYggdrasilTown_Town(Color baseColor) + //{ + // if (YggdrasilTownCentralSystem.InYggdrasilTown(Main.screenPosition + new Vector2(Main.screenWidth, Main.screenHeight) * 0.5f)) + // { + // if (BackgroundAlphaYggdrasilTown < 1f) + // { + // BackgroundAlphaYggdrasilTown += 0.02f; + // } + // else + // { + // BackgroundAlphaYggdrasilTown = 1f; + // } + // } + // else + // { + // if (BackgroundAlphaYggdrasilTown > 0f) + // { + // BackgroundAlphaYggdrasilTown -= 0.02f; + // } + // else + // { + // BackgroundAlphaYggdrasilTown = 0; + // } + // } + + // if (BackgroundAlphaYggdrasilTown > 0) + // { + // var townClose = ModAsset.Town_Close.Value; + // var townMiddle = ModAsset.Town_Middle.Value; + // var townFar = ModAsset.Town_Far.Value; + // var townSky = ModAsset.Town_Sky.Value; + // Vector2 correction = OriginPylonCenter; + // if (!YggdrasilTownCentralSystem.InCanteen_YggdrasilTown() && !YggdrasilTownCentralSystem.InUnion_YggdrasilTown() && !YggdrasilTownCentralSystem.InPlayerRoom_YggdrasilTown() && !YggdrasilTownCentralSystem.InArena_YggdrasilTown()) + // { + // BackgroundManager.DrawBG_RestrictY(townSky, float.PositiveInfinity, correction, baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); + // BackgroundManager.DrawBG_RestrictY(townFar, 15f, correction, baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); + // BackgroundManager.DrawBG_RestrictY(townMiddle, 6f, correction + new Vector2(0, 200), baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); + // BackgroundManager.DrawBG_RestrictY(townClose, 3f, correction + new Vector2(0, 200), baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); + // } + // else + // { + // BackgroundManager.DrawBG_RestrictY(townSky, float.PositiveInfinity, correction + new Vector2(0, 2000), baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); + // BackgroundManager.DrawBG_RestrictY(townFar, 15f, correction + new Vector2(0, 2000), baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); + // BackgroundManager.DrawBG_RestrictY(townMiddle, 6f, correction + new Vector2(0, 3800), baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); + // BackgroundManager.DrawBG_RestrictY(townClose, 3f, correction + new Vector2(0, 3800), baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); + // if (YggdrasilTownCentralSystem.InArena_YggdrasilTown()) + // { + // var arenaClose = ModAsset.ArenaBackground.Value; + // BackgroundManager.DrawBG_RestrictY(arenaClose, 1.5f, correction + new Vector2(3150, 3754), baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); + // } + // } + // } + //} + + public void DrawMidnightBayou(Color baseColor) { - if (YggdrasilTownCentralSystem.InYggdrasilTown(Main.screenPosition + new Vector2(Main.screenWidth, Main.screenHeight) * 0.5f)) + if (ModContent.GetInstance().IsBiomeActive(Main.LocalPlayer)) { - if (BackgroundAlphaYggdrasilTown < 1f) + if (BackgroundAlphaMidnightBayou < 1f) { - BackgroundAlphaYggdrasilTown += 0.02f; + BackgroundAlphaMidnightBayou += 0.02f; } else { - BackgroundAlphaYggdrasilTown = 1f; + BackgroundAlphaMidnightBayou = 1f; } } else { - if (BackgroundAlphaYggdrasilTown > 0f) + if (BackgroundAlphaMidnightBayou > 0f) { - BackgroundAlphaYggdrasilTown -= 0.02f; + BackgroundAlphaMidnightBayou -= 0.02f; } else { - BackgroundAlphaYggdrasilTown = 0; + BackgroundAlphaMidnightBayou = 0; } } - if (BackgroundAlphaYggdrasilTown > 0) + if (BackgroundAlphaMidnightBayou > 0) { - var townClose = ModAsset.Town_Close.Value; - var townMiddle = ModAsset.Town_Middle.Value; - var townFar = ModAsset.Town_Far.Value; - var townSky = ModAsset.Town_Sky.Value; + var bayouClose = ModAsset.MidnightBayou_Close.Value; + var bayouMiddle0 = ModAsset.MidnightBayou_Middle_0.Value; + var bayouMiddle1 = ModAsset.MidnightBayou_Middle_1.Value; + var bayouMiddle2 = ModAsset.MidnightBayou_Middle_2.Value; + var bayouSky = ModAsset.MidnightBayou_Sky.Value; Vector2 correction = OriginPylonCenter; - if (!YggdrasilTownCentralSystem.InCanteen_YggdrasilTown() && !YggdrasilTownCentralSystem.InUnion_YggdrasilTown() && !YggdrasilTownCentralSystem.InPlayerRoom_YggdrasilTown() && !YggdrasilTownCentralSystem.InArena_YggdrasilTown()) - { - BackgroundManager.QuickDrawBG(townSky, float.PositiveInfinity, correction, baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); - BackgroundManager.QuickDrawBG(townFar, 15f, correction, baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); - BackgroundManager.QuickDrawBG(townMiddle, 6f, correction + new Vector2(0, 200), baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); - BackgroundManager.QuickDrawBG(townClose, 3f, correction + new Vector2(0, 200), baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); - } - else - { - BackgroundManager.QuickDrawBG(townSky, float.PositiveInfinity, correction + new Vector2(0, 2000), baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); - BackgroundManager.QuickDrawBG(townFar, 15f, correction + new Vector2(0, 2000), baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); - BackgroundManager.QuickDrawBG(townMiddle, 6f, correction + new Vector2(0, 3800), baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); - BackgroundManager.QuickDrawBG(townClose, 3f, correction + new Vector2(0, 3800), baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); - if (YggdrasilTownCentralSystem.InArena_YggdrasilTown()) - { - var arenaClose = ModAsset.ArenaBackground.Value; - BackgroundManager.QuickDrawBG(arenaClose, 1.5f, correction + new Vector2(3150, 3754), baseColor * BackgroundAlphaYggdrasilTown, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); - } - } + + BackgroundManager.DrawBG_RestrictY(bayouSky, float.PositiveInfinity, correction, baseColor * BackgroundAlphaMidnightBayou, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); + BackgroundManager.DrawBG_RestrictY(bayouMiddle2, 80f, correction, baseColor * BackgroundAlphaMidnightBayou, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); + BackgroundManager.DrawBG_RestrictY(bayouMiddle1, 20f, correction, baseColor * BackgroundAlphaMidnightBayou, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); + BackgroundManager.DrawBG_RestrictY(bayouMiddle0, 10f, correction, baseColor * BackgroundAlphaMidnightBayou, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); + BackgroundManager.DrawBG_RestrictY(bayouClose, 6f, correction + new Vector2(0, 2950), baseColor * BackgroundAlphaMidnightBayou, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); } } - public void DrawMidnightBayou(Color baseColor) + public void DrawJellyBallHotbed(Color baseColor) { - if (ModContent.GetInstance().IsBiomeActive(Main.LocalPlayer)) + if (ModContent.GetInstance().IsBiomeActive(Main.LocalPlayer)) { - if (BackgroundAlphaMidnightBayou < 1f) + if (BackgroundAlphaJellyBallHotbed < 1f) { - BackgroundAlphaMidnightBayou += 0.02f; + BackgroundAlphaJellyBallHotbed += 0.02f; } else { - BackgroundAlphaMidnightBayou = 1f; + BackgroundAlphaJellyBallHotbed = 1f; } } else { - if (BackgroundAlphaMidnightBayou > 0f) + if (BackgroundAlphaJellyBallHotbed > 0f) { - BackgroundAlphaMidnightBayou -= 0.02f; + BackgroundAlphaJellyBallHotbed -= 0.02f; } else { - BackgroundAlphaMidnightBayou = 0; + BackgroundAlphaJellyBallHotbed = 0; } } - if (BackgroundAlphaMidnightBayou > 0) + if (BackgroundAlphaJellyBallHotbed > 0) { - var bayouClose = ModAsset.MidnightBayou_Close.Value; - var bayouMiddle0 = ModAsset.MidnightBayou_Middle_0.Value; - var bayouMiddle1 = ModAsset.MidnightBayou_Middle_1.Value; - var bayouMiddle2 = ModAsset.MidnightBayou_Middle_2.Value; - var bayouSky = ModAsset.MidnightBayou_Sky.Value; - Vector2 correction = OriginPylonCenter; - - BackgroundManager.QuickDrawBG(bayouSky, float.PositiveInfinity, correction, baseColor * BackgroundAlphaMidnightBayou, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); - BackgroundManager.QuickDrawBG(bayouMiddle2, 80f, correction, baseColor * BackgroundAlphaMidnightBayou, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); - BackgroundManager.QuickDrawBG(bayouMiddle1, 20f, correction, baseColor * BackgroundAlphaMidnightBayou, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); - BackgroundManager.QuickDrawBG(bayouMiddle0, 10f, correction, baseColor * BackgroundAlphaMidnightBayou, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); - BackgroundManager.QuickDrawBG(bayouClose, 6f, correction + new Vector2(0, 3000), baseColor * BackgroundAlphaMidnightBayou, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); + var jellyClose = ModAsset.JellyBallHotbed_Close.Value; + var jellyFar = ModAsset.JellyBallHotbed_Far.Value; + + int upBound = Main.maxTilesY - 500; + int bottomBound = Main.maxTilesY - 40; + int leftBound = Main.maxTilesX - 350; + int rightBound = Main.maxTilesX; + Vector2 anchorPos = new Vector2((leftBound + rightBound) / 2f, (upBound + bottomBound) / 2f - 120f); + anchorPos *= 16f; + + BackgroundManager.DrawBG_RestrictY(jellyFar, 20f, anchorPos, baseColor * BackgroundAlphaJellyBallHotbed, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), true, true); + BackgroundManager.DrawBG_RestrictY(jellyClose, 6f, anchorPos, baseColor * BackgroundAlphaJellyBallHotbed, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 18000), false, true); } } @@ -310,11 +357,11 @@ public void DrawCageOfChallengers(Color baseColor) var stoneFar = ModAsset.StoneCageOfChallengesFar.Value; var stoneSky = ModAsset.StoneCageOfChallengesSky.Value; - BackgroundManager.QuickDrawBG(stoneSky, float.PositiveInfinity, backgroundCenter + new Vector2(0, -1800), baseColor * BackgroundAlphaCage, (int)(Stratum1Center.Y - 25600), (int)(Stratum1Center.Y + 8000), true, true); - BackgroundManager.QuickDrawBG(stoneFar, 30, backgroundCenter + new Vector2(0, -9000), baseColor * BackgroundAlphaCage, (int)(Stratum1Center.Y - 25600), (int)(Stratum1Center.Y + 8000), true, true); - BackgroundManager.QuickDrawBG(stoneMiddle, 20, backgroundCenter + new Vector2(0, -4800), baseColor * BackgroundAlphaCage, (int)(Stratum1Center.Y - 25600), (int)(Stratum1Center.Y + 8000), true, true); - BackgroundManager.QuickDrawBG(stoneClose, 12, backgroundCenter + new Vector2(0, -1800), baseColor * BackgroundAlphaCage, (int)(Stratum1Center.Y - 25600), (int)(Stratum1Center.Y + 8000), true, true); - BackgroundManager.QuickDrawBG(stoneClose2, 3, backgroundCenter + new Vector2(0, 100), baseColor * BackgroundAlphaCage, (int)(Stratum1Center.Y - 25600), (int)(Stratum1Center.Y + 8000), true, true); + BackgroundManager.DrawBG_RestrictY(stoneSky, float.PositiveInfinity, backgroundCenter + new Vector2(0, -1800), baseColor * BackgroundAlphaCage, (int)(Stratum1Center.Y - 25600), (int)(Stratum1Center.Y + 8000), true, true); + BackgroundManager.DrawBG_RestrictY(stoneFar, 30, backgroundCenter + new Vector2(0, -9000), baseColor * BackgroundAlphaCage, (int)(Stratum1Center.Y - 25600), (int)(Stratum1Center.Y + 8000), true, true); + BackgroundManager.DrawBG_RestrictY(stoneMiddle, 20, backgroundCenter + new Vector2(0, -4800), baseColor * BackgroundAlphaCage, (int)(Stratum1Center.Y - 25600), (int)(Stratum1Center.Y + 8000), true, true); + BackgroundManager.DrawBG_RestrictY(stoneClose, 12, backgroundCenter + new Vector2(0, -1800), baseColor * BackgroundAlphaCage, (int)(Stratum1Center.Y - 25600), (int)(Stratum1Center.Y + 8000), true, true); + BackgroundManager.DrawBG_RestrictY(stoneClose2, 3, backgroundCenter + new Vector2(0, 100), baseColor * BackgroundAlphaCage, (int)(Stratum1Center.Y - 25600), (int)(Stratum1Center.Y + 8000), true, true); } } } @@ -368,10 +415,10 @@ public void DrawLampWood(Color baseColor) var lampSky = ModAsset.LampWoodSky.Value; Vector2 correction = new Vector2(0, LampWoodCenterY - 4000); - BackgroundManager.QuickDrawBG(lampSky, float.PositiveInfinity, correction, baseColor * BackgroundAlphaLampWood, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), false, true); - BackgroundManager.QuickDrawBG(lampFar, 20f, correction, baseColor * BackgroundAlphaLampWood, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), false, true); - BackgroundManager.QuickDrawBG(lampMiddle, 10f, correction, baseColor * BackgroundAlphaLampWood, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), false, true); - BackgroundManager.QuickDrawBG(lampClose, 6f, correction + new Vector2(0, 6000), baseColor * BackgroundAlphaLampWood, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), false, true); + BackgroundManager.DrawBG_RestrictY(lampSky, float.PositiveInfinity, correction, baseColor * BackgroundAlphaLampWood, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), false, true); + BackgroundManager.DrawBG_RestrictY(lampFar, 20f, correction, baseColor * BackgroundAlphaLampWood, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), false, true); + BackgroundManager.DrawBG_RestrictY(lampMiddle, 10f, correction, baseColor * BackgroundAlphaLampWood, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), false, true); + BackgroundManager.DrawBG_RestrictY(lampClose, 6f, correction + new Vector2(0, 6000), baseColor * BackgroundAlphaLampWood, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), false, true); } } @@ -408,12 +455,12 @@ public void DrawTwilightForsetAndRelic(Color baseColor) var twilightMiddleFar = ModAsset.TwilightMiddleFar.Value; var twilightFar = ModAsset.TwilightFar.Value; var twilightSky = ModAsset.TwilightSky.Value; - BackgroundManager.QuickDrawBG(twilightSky, float.PositiveInfinity, Stratum1Center, baseColor * BackgroundAlphaTwilight, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), true, true); - BackgroundManager.QuickDrawBG(twilightFar, 40, Stratum1Center, baseColor * BackgroundAlphaTwilight, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), true, true); - BackgroundManager.QuickDrawBG(twilightMiddleFar, 30, Stratum1Center, baseColor * BackgroundAlphaTwilight, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), true, true); - BackgroundManager.QuickDrawBG(twilightMiddle, 16, Stratum1Center, baseColor * BackgroundAlphaTwilight, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), true, true); - BackgroundManager.QuickDrawBG(twilightMiddleClose, 10, Stratum1Center, baseColor * BackgroundAlphaTwilight, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), true, true); - BackgroundManager.QuickDrawBG(twilightClose, 5, Stratum1Center, baseColor * BackgroundAlphaTwilight, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), true, true); + BackgroundManager.DrawBG_RestrictY(twilightSky, float.PositiveInfinity, Stratum1Center, baseColor * BackgroundAlphaTwilight, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), true, true); + BackgroundManager.DrawBG_RestrictY(twilightFar, 40, Stratum1Center, baseColor * BackgroundAlphaTwilight, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), true, true); + BackgroundManager.DrawBG_RestrictY(twilightMiddleFar, 30, Stratum1Center, baseColor * BackgroundAlphaTwilight, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), true, true); + BackgroundManager.DrawBG_RestrictY(twilightMiddle, 16, Stratum1Center, baseColor * BackgroundAlphaTwilight, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), true, true); + BackgroundManager.DrawBG_RestrictY(twilightMiddleClose, 10, Stratum1Center, baseColor * BackgroundAlphaTwilight, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), true, true); + BackgroundManager.DrawBG_RestrictY(twilightClose, 5, Stratum1Center, baseColor * BackgroundAlphaTwilight, (int)(Stratum1Center.Y - 20600), (int)(Stratum1Center.Y + 8000), true, true); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTown_Construct.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTown_Construct.cs new file mode 100644 index 000000000..50bc70d84 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTown_Construct.cs @@ -0,0 +1,207 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Background; + +public class YggdrasilTown_Construct : BackgroundSlideBase +{ + public Point TileAnchor; + + public List BgTiles = new List(); + + public List> AreaTiles = []; + + public List WindowFrames = new List(); + + public List GlowingLogos = new List(); + + public override void SetDefaults() + { + base.SetDefaults(); + for (int k = 0; k < 3; k++) + { + int offsetX = (TileAnchor - new Vector2(260, -464).ToTileCoordinates()).X; + var area = BgTiles + .Where(t => t.X >= (k - 0.5f) * 140 - 210 + offsetX && t.X < (k + 1.5f) * 140 - 210 + offsetX) + .ToList(); + AreaTiles.Add(area); + } + WindowFrames = new List + { + new Rectangle(5344, 1104, 48, 64), + new Rectangle(5424, 1104, 48, 64), + new Rectangle(5720, 832, 38, 48), + new Rectangle(6088, 910, 38, 50), + new Rectangle(6088, 1056, 38, 48), + new Rectangle(5760, 1168, 48, 64), + new Rectangle(5888, 1216, 48, 64), + new Rectangle(4928, 960, 48, 48), + new Rectangle(4928, 1056, 48, 48), + new Rectangle(4928, 1152, 48, 48), + new Rectangle(4928, 1248, 48, 48), + new Rectangle(4744, 736, 40, 48), + new Rectangle(4744, 848, 40, 48), + new Rectangle(4744, 960, 40, 48), + new Rectangle(4744, 1072, 40, 48), + new Rectangle(4744, 1184, 40, 48), + new Rectangle(4320, 1056, 18, 48), + new Rectangle(4384, 1056, 32, 48), + new Rectangle(4462, 1056, 18, 48), + new Rectangle(4368, 1200, 48, 64), + new Rectangle(4208, 1152, 48, 64), + new Rectangle(4128, 1152, 48, 64), + new Rectangle(4032, 1104, 48, 64), + new Rectangle(4032, 1216, 32, 48), + new Rectangle(4032, 1296, 32, 48), + new Rectangle(3968, 1104, 48, 64), + new Rectangle(3968, 1216, 24, 48), + new Rectangle(3968, 1296, 24, 48), + new Rectangle(3872, 1152, 48, 64), + new Rectangle(3794, 1152, 48, 64), + new Rectangle(3832, 960, 40, 32), + new Rectangle(3832, 864, 40, 48), + new Rectangle(3720, 752, 38, 48), + new Rectangle(3320, 824, 32, 40), + new Rectangle(2880, 1136, 32, 48), + new Rectangle(2880, 928, 32, 48), + new Rectangle(2784, 928, 32, 48), + new Rectangle(2784, 1040, 32, 48), + new Rectangle(2504, 1328, 40, 64), + new Rectangle(2120, 992, 40, 48), + new Rectangle(2072, 720, 40, 48), + new Rectangle(1520, 1056, 32, 30), + new Rectangle(1064, 848, 38, 48), + new Rectangle(1008, 912, 14, 30), + new Rectangle(1008, 992, 14, 32), + new Rectangle(1008, 1120, 14, 32), + new Rectangle(608, 880, 48, 48), + new Rectangle(608, 976, 48, 48), + new Rectangle(608, 1072, 48, 48), + + // new Rectangle(430, 1232, 18, 48), + // new Rectangle(174, 1232, 18, 48), + }; + + GlowingLogos = new List + { + new Rectangle(2032, 1040, 462, 236), + new Rectangle(5358, 850, 228, 254), + }; + Texture = ModAsset.YggdrasilTown_Construct.Value; + Distance = 1; + UseColorStyle = 1; + LayerPriority = 0; + Shader = Effects.XWrap_YWrap_Shader; + } + + public override void Update() + { + base.Update(); + } + + public override void Draw() + { + var topLeft = TileAnchor.ToWorldCoordinates() + new Vector2(260, -464) + new Vector2(-210, -89) * 16; + int index = (int)((Main.screenPosition.X + 480 + Main.screenWidth * 0.5f - topLeft.X) / 16 / 140); + index = Math.Clamp(index, 0, 2); + var bars = new List(); + if (Main.screenWidth <= 2560) + { + if (AreaTiles.Count > 0) + { + BackgroundHigherPerformanceHelper.Add_TileBgVertice(this, AreaTiles[index], bars, 3); + DrawVertexBackground(this, PrimitiveType.TriangleStrip, bars); + } + } + else + { + BackgroundHigherPerformanceHelper.Add_TileBgVertice(this, BgTiles, bars, 3); + DrawVertexBackground(this, PrimitiveType.TriangleStrip, bars); + } + foreach (var rectangle in WindowFrames) + { + if ((Main.time + TileUtils.GetFixedRandomNumber_SingleSeed(rectangle.X - rectangle.Y)) * 10 % 10240 > 5120) + { + if (VFXManager.InScreen(rectangle.Center() + topLeft, rectangle.Size().Length())) + { + bars = new List(); + AddWindow_Vertex_Frame(bars, rectangle); + DrawVertexBackground(ModAsset.YggdrasilTown_Construct_LightedWindows.Value, PrimitiveType.TriangleStrip, bars); + } + } + } + foreach (var rectangle in GlowingLogos) + { + if (VFXManager.InScreen(rectangle.Center() + topLeft, rectangle.Size().Length())) + { + bars = new List(); + AddGlowingLogo_Vertex_Frame(bars, rectangle); + DrawVertexBackground(ModAsset.YggdrasilTown_Construct_LightedWindows.Value, PrimitiveType.TriangleStrip, bars); + } + } + } + + public void AddGlowingLogo_Vertex_Frame(List bars, Rectangle frame) + { + Texture2D tex = ModAsset.YggdrasilTown_Construct_LightedWindows.Value; + var topLeft = TileAnchor.ToWorldCoordinates() + new Vector2(248, -472) + new Vector2(-210, -89) * 16 - Main.screenPosition; + var color = new Color(0.5f, 0.5f, 0.5f, 0); + var lightColor = new Vector3(1f, 1f, 1f); + + var pos0 = topLeft + frame.TopLeft(); + var pos1 = topLeft + frame.TopRight(); + var pos2 = topLeft + frame.BottomLeft(); + var pos3 = topLeft + frame.BottomRight(); + + Lighting.AddLight(pos0 + Main.screenPosition, lightColor); + Lighting.AddLight(pos1 + Main.screenPosition, lightColor); + Lighting.AddLight(pos2 + Main.screenPosition, lightColor); + Lighting.AddLight(pos3 + Main.screenPosition, lightColor); + + Lighting.AddLight((pos0 + pos1) * 0.5f + Main.screenPosition, lightColor); + Lighting.AddLight((pos0 + pos2) * 0.5f + Main.screenPosition, lightColor); + Lighting.AddLight((pos2 + pos3) * 0.5f + Main.screenPosition, lightColor); + Lighting.AddLight((pos3 + pos1) * 0.5f + Main.screenPosition, lightColor); + Lighting.AddLight((pos1 + pos2) * 0.5f + Main.screenPosition, lightColor); + + bars.Add(pos0, color, new Vector3(frame.TopLeft() / tex.Size(), 0)); + bars.Add(pos1, color, new Vector3(frame.TopRight() / tex.Size(), 0)); + + bars.Add(pos2, color, new Vector3(frame.BottomLeft() / tex.Size(), 0)); + bars.Add(pos3, color, new Vector3(frame.BottomRight() / tex.Size(), 0)); + } + + public void AddWindow_Vertex_Frame(List bars, Rectangle frame) + { + Texture2D tex = ModAsset.YggdrasilTown_Construct_LightedWindows.Value; + var topLeft = TileAnchor.ToWorldCoordinates() + new Vector2(248, -472) + new Vector2(-210, -89) * 16 - Main.screenPosition; + var color = new Color(0.5f, 0.5f, 0.5f, 0); + var lightColor = new Vector3(1f, 0.6f, 0.1f); + if (frame.X is 2880 or 2784) + { + lightColor = new Vector3(0.5f, 1f, 0.2f); + } + + var pos0 = topLeft + frame.TopLeft(); + var pos1 = topLeft + frame.TopRight(); + var pos2 = topLeft + frame.BottomLeft(); + var pos3 = topLeft + frame.BottomRight(); + + Lighting.AddLight(pos0 + Main.screenPosition, lightColor); + Lighting.AddLight(pos1 + Main.screenPosition, lightColor); + Lighting.AddLight(pos2 + Main.screenPosition, lightColor); + Lighting.AddLight(pos3 + Main.screenPosition, lightColor); + + bars.Add(pos0, color, new Vector3(frame.TopLeft() / tex.Size(), 0)); + bars.Add(pos1, color, new Vector3(frame.TopRight() / tex.Size(), 0)); + + bars.Add(pos2, color, new Vector3(frame.BottomLeft() / tex.Size(), 0)); + bars.Add(pos3, color, new Vector3(frame.BottomRight() / tex.Size(), 0)); + } + + public override bool CanActive() + { + // return false; + return TileUtils.SafeGetTile(TileAnchor).TileType == ModContent.TileType(); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTown_Construct.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTown_Construct.png new file mode 100644 index 000000000..f4025103d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTown_Construct.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTown_Construct2.pdn b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTown_Construct2.pdn new file mode 100644 index 000000000..52b7fc8cb Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTown_Construct2.pdn differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTown_Construct_LightedWindows.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTown_Construct_LightedWindows.png new file mode 100644 index 000000000..340342be6 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Background/YggdrasilTown_Construct_LightedWindows.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Biomes/MidnightBayouBiome.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Biomes/MidnightBayouBiome.cs index 73b9cd3d3..4b6103554 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Biomes/MidnightBayouBiome.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Biomes/MidnightBayouBiome.cs @@ -1,4 +1,6 @@ using Everglow.Yggdrasil.Common; +using Everglow.Yggdrasil.YggdrasilTown.Background; +using Everglow.Yggdrasil.YggdrasilTown.VFXs; using SubworldLibrary; namespace Everglow.Yggdrasil.YggdrasilTown.Biomes; @@ -48,6 +50,38 @@ public override void OnInBiome(Player player) Main.StopSlimeRain(); } Main.bloodMoon = false; + if (Main.rand.NextBool(15)) + { + Vector2 anchorPos = YggdrasilTownBackground.OriginPylonCenter; + Texture2D tex = ModAsset.MidnightBayouBackgroundCloud_0.Value; + switch (Main.rand.Next(4)) + { + case 0: + tex = ModAsset.MidnightBayouBackgroundCloud_0.Value; + break; + case 1: + tex = ModAsset.MidnightBayouBackgroundCloud_1.Value; + break; + case 2: + tex = ModAsset.MidnightBayouBackgroundCloud_2.Value; + break; + case 3: + tex = ModAsset.MidnightBayouBackgroundCloud_3.Value; + break; + } + + var cloud = new MidnightBayouBackgroundCloud + { + Position = anchorPos + new Vector2(Main.rand.Next(-1000, 3000), Main.rand.NextFloat(850, 960)), + Velocity = new Vector2(Main.windSpeedCurrent * 0.2f, 0), + Fade = 0, + AnchorPos = anchorPos, + Scale = Main.rand.NextFloat(0.85f, 1.15f), + MaxTime = Main.rand.NextFloat(300, 1500), + CloudTexture = tex, + }; + Ins.VFXManager.Add(cloud); + } base.OnInBiome(player); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Biomes/YggdrasilTownBiome.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Biomes/YggdrasilTownBiome.cs index eed0a8826..2967ee331 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Biomes/YggdrasilTownBiome.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Biomes/YggdrasilTownBiome.cs @@ -1,5 +1,9 @@ -using Everglow.Yggdrasil.WorldGeneration; +using Everglow.Commons.DeveloperContent.Items; +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.KelpCurtain.Background; +using Everglow.Yggdrasil.YggdrasilTown.Background; using Everglow.Yggdrasil.YggdrasilTown.Tiles; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; using SubworldLibrary; namespace Everglow.Yggdrasil.YggdrasilTown.Biomes; @@ -142,6 +146,74 @@ public override void OnInBiome(Player player) Main.StopSlimeRain(); } Main.bloodMoon = false; + + BackgroundSystem bgSystem = ModContent.GetInstance(); + Town_Sky town_Sky = new Town_Sky(); + town_Sky.WorldAnchor = BiomeCenter; + bgSystem.AddBackgroundSlide(town_Sky); + + Town_Far town_Far = new Town_Far(); + town_Far.WorldAnchor = BiomeCenter; + bgSystem.AddBackgroundSlide(town_Far); + + Town_Middle town_Middle = new Town_Middle(); + town_Middle.WorldAnchor = BiomeCenter + new Vector2(0, -500); + bgSystem.AddBackgroundSlide(town_Middle); + + Town_Close town_Close = new Town_Close(); + town_Close.WorldAnchor = BiomeCenter + new Vector2(0, -900); + bgSystem.AddBackgroundSlide(town_Close); + if (!bgSystem.HasBgSlide("Everglow.Yggdrasil.YggdrasilTown.Background.YggdrasilTown_Construct")) + { + AddBackground(bgSystem); + } base.OnInBiome(player); } + + public void AddBackground(BackgroundSystem bgSystem) + { + List polygon = new List(); + Vector2 centerPosWorld = BiomeCenter + new Vector2(228, -464); + polygon.Add(centerPosWorld + new Vector2(-210, 0) * 16); + polygon.Add(centerPosWorld + new Vector2(-210, -30) * 16); + polygon.Add(centerPosWorld + new Vector2(-150, -60) * 16); + polygon.Add(centerPosWorld + new Vector2(-50, -89) * 16); + polygon.Add(centerPosWorld + new Vector2(-20, -89) * 16); + polygon.Add(centerPosWorld + new Vector2(60, -50) * 16); + polygon.Add(centerPosWorld + new Vector2(120, -65) * 16); + polygon.Add(centerPosWorld + new Vector2(170, -60) * 16); + polygon.Add(centerPosWorld + new Vector2(210, -20) * 16); + polygon.Add(centerPosWorld + new Vector2(210, 0) * 16); + List bgArea = TileUtils.GetPolygonAreaOfTilePos(polygon); + + YggdrasilTown_Construct ytc = new YggdrasilTown_Construct(); + ytc.WorldAnchor = centerPosWorld + new Vector2(32, 704); + ytc.TileAnchor = centerPosWorld.ToTileCoordinates() + new Point(-14, 29); + ytc.BgTiles = bgArea; + bgSystem.AddBackgroundSlide(ytc); + + GiantFurnace_Construct gfc = new GiantFurnace_Construct(); + gfc.WorldAnchor = centerPosWorld + new Vector2(183, 63) * 16 + new Vector2(4, 24); + gfc.BgTiles = TileUtils.GetAABBAreaOfTile((int)centerPosWorld.X / 16 + 134, (int)centerPosWorld.Y / 16 + 32, 92, 60); + gfc.TileAnchor = centerPosWorld.ToTileCoordinates() + new Point(-14, 29); + bgSystem.AddBackgroundSlide(gfc); + + GiantFurnace_Construct_far gfcf = new GiantFurnace_Construct_far(); + gfcf.WorldAnchor = centerPosWorld + new Vector2(183, 63) * 16 + new Vector2(-264, -164); + gfcf.BgTiles = TileUtils.GetAABBAreaOfTile((int)centerPosWorld.X / 16 + 106, (int)centerPosWorld.Y / 16 + 34, 112, 60); + gfcf.TileAnchor = centerPosWorld.ToTileCoordinates() + new Point(-14, 29); + bgSystem.AddBackgroundSlide(gfcf); + + GiantFurnace_Construct_sky gfcs = new GiantFurnace_Construct_sky(); + gfcs.WorldAnchor = centerPosWorld + new Vector2(0, -240); + gfcs.BgTiles = TileUtils.GetAABBAreaOfTile((int)centerPosWorld.X / 16 + 106, (int)centerPosWorld.Y / 16 + 4, 112, 90); + gfcs.TileAnchor = centerPosWorld.ToTileCoordinates() + new Point(-14, 29); + bgSystem.AddBackgroundSlide(gfcs); + + FurnaceScoreShop fSS = new FurnaceScoreShop(); + fSS.WorldAnchor = centerPosWorld + new Vector2(-124, 920); + fSS.BgTiles = TileUtils.GetAABBAreaOfTile((int)centerPosWorld.X / 16 + 102, (int)centerPosWorld.Y / 16 + 78, 20, 14); + fSS.TileAnchor = centerPosWorld.ToTileCoordinates() + new Point(-14, 29); + bgSystem.AddBackgroundSlide(fSS); + } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Buffs/EvilMusicRemnant.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Buffs/EvilMusicRemnant.png index 9069bb913..46b708c9c 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Buffs/EvilMusicRemnant.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Buffs/EvilMusicRemnant.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/CustomTiles/YggdrasilTown_NormalMetro.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/CustomTiles/YggdrasilTown_NormalMetro.cs new file mode 100644 index 000000000..7a6e7563d --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/CustomTiles/YggdrasilTown_NormalMetro.cs @@ -0,0 +1,270 @@ +using Everglow.Commons.CustomTiles.Abstracts; +using Everglow.Commons.CustomTiles.Core; +using Everglow.Yggdrasil.YggdrasilTown.Items.Tools.Developer; +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.CustomTiles; + +public class YggdrasilTown_NormalMetro : BoxEntity +{ + public enum BehaviorType + { + Move, + Stop, + } + + public int StopTimer = 0; + + public int Direction = 1; + + public int StopTimeMax = 600; + + public int State = 0; + + public float TrackY = 0; + + public float StationX = 0; + + public float Speed = 0; + + public float ShellAlpha = 1; + + public override void SetDefaults() + { + Size = new Vector2(1696, 16); + } + + public override void OnSpawn() + { + SetTrackY(); + Position = new Vector2(Position.X, TrackY); + if (!SearchStation()) + { + Direction *= -1; + SearchStation(); + } + } + + public override Color MapColor => new Color(128, 131, 142); + + public override void AI() + { + switch (State) + { + case (int)BehaviorType.Move: + + if (StationX != 0) + { + Accelerate(); + } + Velocity = new Vector2(Direction * Speed, 0); + break; + case (int)BehaviorType.Stop: + Velocity *= 0; + StopTimer++; + if (StopTimer >= StopTimeMax) + { + if (!SearchStation()) + { + Direction *= -1; + SearchStation(); + } + State = (int)BehaviorType.Move; + } + break; + } + + Position += Velocity; + if (Main.LocalPlayer.HeldItem.type == ModContent.ItemType() && Main.mouseMiddle && Main.mouseMiddleRelease) + { + Active = false; + } + CheckPlayerInTrain(); + AddLight(); + } + + public void AddLight() + { + float value = 1 - ShellAlpha; + for (int m = 0; m < 2; m++) + { + for (int k = 0; k < 3; k++) + { + Lighting.AddLight(Position + new Vector2(61 + k * 126 + m * 958, -86), new Vector3(1f, 1f, 1f) * value); + } + for (int k = 0; k < 3; k++) + { + Lighting.AddLight(Position + new Vector2(535 + k * 126 + m * 958, -86), new Vector3(1f, 1f, 1f) * value); + } + } + } + + public void Accelerate() + { + float disToStationSign = (StationX - Box.Center.X) * Direction; + if (disToStationSign > 8000) + { + if (Speed < 8) + { + Speed += 0.02f; + } + } + else if (disToStationSign > 1600) + { + if (Speed >= 5) + { + Speed -= 0.02f; + } + else + { + Speed += 0.02f; + } + } + else if (disToStationSign > 200) + { + if (Speed >= 1) + { + Speed -= 0.02f; + } + else + { + Speed += 0.02f; + } + } + else if (disToStationSign > 10) + { + if (Speed >= 0.2f) + { + Speed -= 0.02f; + } + else + { + Speed += 0.02f; + } + } + else if (disToStationSign > 1) + { + if (Speed >= 0.02) + { + Speed -= 0.005f; + } + else + { + Speed += 0.005f; + } + } + else + { + if (disToStationSign < -10) + { + Direction *= -1; + } + else + { + Speed = 0; + State = (int)BehaviorType.Stop; + StopTimer = 0; + } + } + } + + public void SetTrackY() + { + TrackY = Position.Y - Position.Y % 16; + } + + public bool SearchStation() + { + int y = (int)(TrackY / 16f - 3); + int box_x = (int)(Box.Center.X / 16); + for (int dx = 10; dx < 6000; dx += 5) + { + int x = box_x + dx * Direction; + var tile = TileUtils.SafeGetTile(x, y); + if (tile.TileType == ModContent.TileType() || tile.TileType == ModContent.TileType()) + { + StationX = (x - tile.TileFrameX / 18 + 2) * 16; + return true; + } + } + return false; + } + + public override void Draw() + { + Texture2D metro = ModAsset.YggdrasilTown_NormalMetro.Value; + var frame = new Rectangle(174, 165, 848, 160); + var glow_frame = new Rectangle(174, 495, 848, 160); + var outShellFrame = frame; + outShellFrame.Y -= 170; + var pos0 = new Vector2((Box.Center.X + Box.Left) * 0.5f, Box.Bottom); + TileUtils.VertexDraw_Grid(pos0 - Main.screenPosition, frame, new Vector2(frame.Width / 2f, frame.Height), metro, Main.spriteBatch, 0); + Main.spriteBatch.Draw(metro, pos0 - Main.screenPosition, glow_frame, new Color(1f, 1f, 1f, 0) * (1 - ShellAlpha), 0, new Vector2(frame.Width / 2f, frame.Height), 1, SpriteEffects.None, 0); + if (ShellAlpha > 0) + { + TileUtils.VertexDraw_Grid(pos0 - Main.screenPosition, outShellFrame, new Vector2(frame.Width / 2f, frame.Height), metro, Main.spriteBatch, 0, ShellAlpha); + } + + var pos1 = new Vector2((Box.Center.X + Box.Right) * 0.5f, Box.Bottom); + TileUtils.VertexDraw_Grid(pos1 - Main.screenPosition, frame, new Vector2(frame.Width / 2f, frame.Height), metro, Main.spriteBatch, 0); + Main.spriteBatch.Draw(metro, pos1 - Main.screenPosition, glow_frame, new Color(1f, 1f, 1f, 0) * (1 - ShellAlpha), 0, new Vector2(frame.Width / 2f, frame.Height), 1, SpriteEffects.None, 0); + if (ShellAlpha > 0) + { + TileUtils.VertexDraw_Grid(pos1 - Main.screenPosition, outShellFrame, new Vector2(frame.Width / 2f, frame.Height), metro, Main.spriteBatch, 0, ShellAlpha); + } + + var headFrame = new Rectangle(0, 0, 172, 160); + var tailFrame = new Rectangle(1024, 0, 172, 160); + + var pos2 = new Vector2(Box.Left, Box.Bottom - 75); + var pos3 = new Vector2(Box.Right, Box.Bottom - 75); + TileUtils.VertexDraw_Grid(pos2 - Main.screenPosition, headFrame, new Vector2(headFrame.Width, headFrame.Height * 0.5f), metro, Main.spriteBatch, 0); + TileUtils.VertexDraw_Grid(pos3 - Main.screenPosition, tailFrame, new Vector2(0, tailFrame.Height * 0.5f), metro, Main.spriteBatch, 0); + + headFrame.Y += 330; + tailFrame.Y += 330; + Main.spriteBatch.Draw(metro, pos2 - Main.screenPosition, headFrame, new Color(1f, 1f, 1f, 0) * 0.36f, 0, new Vector2(headFrame.Width, headFrame.Height * 0.5f), 1, SpriteEffects.None, 0); + Main.spriteBatch.Draw(metro, pos3 - Main.screenPosition, tailFrame, new Color(1f, 1f, 1f, 0) * 0.36f, 0, new Vector2(0, tailFrame.Height * 0.5f), 1, SpriteEffects.None, 0); + } + + public void CheckPlayerInTrain() + { + if (PlayerIntersect()) + { + if (ShellAlpha > 0) + { + ShellAlpha -= 0.04f; + } + else + { + ShellAlpha = 0; + } + } + else + { + if (ShellAlpha < 1) + { + ShellAlpha += 0.04f; + } + else + { + ShellAlpha = 1; + } + } + } + + public bool PlayerIntersect() + { + Rectangle hitBox = new Rectangle((int)Position.X, (int)Position.Y - 146, (int)Box.Width, 146); + return hitBox.Contains((int)Main.LocalPlayer.Center.X, (int)Main.LocalPlayer.Center.Y); + } + + public void RightClick() + { + } + + public override Vector2 StandAccelerate(IBox obj) + { + return base.StandAccelerate(obj) * 2; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/CustomTiles/YggdrasilTown_NormalMetro.png b/Sources/Modules/Yggdrasil/YggdrasilTown/CustomTiles/YggdrasilTown_NormalMetro.png new file mode 100644 index 000000000..95f51900c Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/CustomTiles/YggdrasilTown_NormalMetro.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/DragonChest_DarkDragonRoom_Dust.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/DragonChest_DarkDragonRoom_Dust.cs new file mode 100644 index 000000000..ac77c3f61 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/DragonChest_DarkDragonRoom_Dust.cs @@ -0,0 +1,5 @@ +namespace Everglow.Yggdrasil.YggdrasilTown.Dusts; + +public class DragonChest_DarkDragonRoom_Dust : ModDust +{ +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/DragonChest_DarkDragonRoom_Dust.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/DragonChest_DarkDragonRoom_Dust.png new file mode 100644 index 000000000..de64c7d6b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/DragonChest_DarkDragonRoom_Dust.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/GravelStore_Dust.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/GravelStore_Dust.cs new file mode 100644 index 000000000..fb5fd7823 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/GravelStore_Dust.cs @@ -0,0 +1,5 @@ +namespace Everglow.Yggdrasil.YggdrasilTown.Dusts; + +public class GravelStore_Dust : ModDust +{ +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/GravelStore_Dust.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/GravelStore_Dust.png new file mode 100644 index 000000000..d23a400ab Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/GravelStore_Dust.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/SplashDust_DarkSludge.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/SplashDust_DarkSludge.cs new file mode 100644 index 000000000..481e586fe --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/SplashDust_DarkSludge.cs @@ -0,0 +1,6 @@ +namespace Everglow.Yggdrasil.YggdrasilTown.Dusts; + +public class SplashDust_DarkSludge : ModDust +{ + public override void OnSpawn(Dust dust) => base.OnSpawn(dust); +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/SplashDust_DarkSludge.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/SplashDust_DarkSludge.png new file mode 100644 index 000000000..9da24e8be Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/SplashDust_DarkSludge.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/WaterSluiceBubble.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/WaterSluiceBubble.cs new file mode 100644 index 000000000..597a49b42 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/WaterSluiceBubble.cs @@ -0,0 +1,30 @@ +using Everglow.Yggdrasil.WorldGeneration; + +namespace Everglow.Yggdrasil.YggdrasilTown.Dusts; + +public class WaterSluiceBubble : ModDust +{ + public override void OnSpawn(Dust dust) + { + dust.frame = new Rectangle(0, 8 * Main.rand.Next(4), 8, 8); + base.OnSpawn(dust); + } + + public override bool Update(Dust dust) + { + dust.scale *= 0.995f; + dust.velocity.Y += -0.05f; + dust.velocity *= 0.99f; + dust.position += dust.velocity; + if (dust.scale <= 0.15f) + { + dust.active = false; + } + Tile dustPosTile = TileUtils.SafeGetTile(dust.position.ToTileCoordinates()); + if (dust.position.Y % 16 > dustPosTile.LiquidAmount / 16f) + { + dust.active = false; + } + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/WaterSluiceBubble.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/WaterSluiceBubble.png new file mode 100644 index 000000000..20271569a Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/WaterSluiceBubble.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/YggdrasilAmber_crack.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/YggdrasilAmber_crack.cs index f2660fdfd..47f61f873 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/YggdrasilAmber_crack.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Dusts/YggdrasilAmber_crack.cs @@ -13,7 +13,7 @@ public override void OnSpawn(Dust dust) public override Color? GetAlpha(Dust dust, Color lightColor) { - if (Main.rand.NextBool(50)) + if ((int)Main.time % 50 == TileUtils.GetFixedRandomNumber_SingleSeed(dust.GetHashCode(), 50)) { dust.alpha = 1; return new Color?(new Color(1f, 1f, 1f, 0)); diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/FurnacePlayer.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/FurnacePlayer.cs new file mode 100644 index 000000000..523245089 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/FurnacePlayer.cs @@ -0,0 +1,65 @@ +using Terraria.ModLoader.IO; + +namespace Everglow.Yggdrasil.YggdrasilTown; + +public class FurnacePlayer : ModPlayer +{ + public int CurrentFurnaceScore; + public int TotalFurnaceScore; + + public List ReceivedReward = new List { false, false, false, false, false, false, false, false, false, false, false, false, false, false }; + + public override void Load() + { + base.Load(); + } + + public override void SyncPlayer(int toWho, int fromWho, bool newPlayer) + { + // ModPacket packet = Mod.GetPacket(); + // packet.Write(MessageID.PlayerLifeMana); + // packet.Write((byte)Player.whoAmI); + // packet.Write((byte)TotalFurnaceScore); + // packet.Send(toWho, fromWho); + } + + // Called in ExampleMod.Networking.cs + public void ReceivePlayerSync(BinaryReader reader) + { + TotalFurnaceScore = reader.ReadByte(); + } + + public override void CopyClientState(ModPlayer targetCopy) + { + var clone = (FurnacePlayer)targetCopy; + clone.TotalFurnaceScore = TotalFurnaceScore; + } + + public override void SendClientChanges(ModPlayer clientPlayer) + { + var clone = (FurnacePlayer)clientPlayer; + + if (TotalFurnaceScore != clone.TotalFurnaceScore) + { + SyncPlayer(toWho: -1, fromWho: Main.myPlayer, newPlayer: false); + } + } + + public override void SaveData(TagCompound tag) + { + tag["TotalFurnaceScore"] = TotalFurnaceScore; + tag["CurrentFurnaceScore"] = CurrentFurnaceScore; + tag.Add("ReceivedReward", ReceivedReward); + } + + public override void LoadData(TagCompound tag) + { + TotalFurnaceScore = tag.GetInt("TotalFurnaceScore"); + CurrentFurnaceScore = tag.GetInt("CurrentFurnaceScore"); + ReceivedReward = tag.Get>("ReceivedReward"); + if (ReceivedReward.Count < 14) + { + ReceivedReward = new List { false, false, false, false, false, false, false, false, false, false, false, false, false, false }; + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Accessories/AnemoShell.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Accessories/AnemoShell.cs index 0a4ed855f..7984685fd 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Accessories/AnemoShell.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Accessories/AnemoShell.cs @@ -3,6 +3,8 @@ using Everglow.Commons.Interfaces; using Everglow.Yggdrasil.Common.Fish; using Everglow.Yggdrasil.YggdrasilTown.Biomes; +using Everglow.Yggdrasil.YggdrasilTown.Liquids; +using ModLiquidLib.ModLoader; using Terraria.DataStructures; using Terraria.Enums; @@ -12,11 +14,6 @@ public class AnemoShell : ModItem { public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Accessories; - public override void SetStaticDefaults() - { - FishSystem.RegisterFish(ModContent.GetInstance(), new(Type, LiquidID.Water, 0.5f)); - } - public override void SetDefaults() { Item.DefaultToAccessory(28, 22); diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Accessories/TelescopicPlatform.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Accessories/TelescopicPlatform.cs index 03836cf07..7689090d2 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Accessories/TelescopicPlatform.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Accessories/TelescopicPlatform.cs @@ -115,6 +115,11 @@ public override void PostUpdate() public override void ProcessTriggers(TriggersSet triggersSet) { + if (Player.HasBuff(BuffID.Gravitation)) + { + return; + } + if (Player.velocity.Length() != 0) { InPlatform = false; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Miscs/ElectroProbe.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Miscs/ElectroProbe.cs index 8a515f1b1..3d09be0df 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Miscs/ElectroProbe.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Miscs/ElectroProbe.cs @@ -52,7 +52,11 @@ public override bool CanUseItem(Player player) if ((Main.MouseWorld - player.Center).Length() <= 300) { Point point = Main.MouseWorld.ToTileCoordinates(); - Wiring.TripWire(point.X, point.Y, 1, 1); + int i = point.X; + int j = point.Y; + + Wiring.HitWireSingle(i, j); + Wiring.TripWire(i, j, 1, 1); } return base.CanUseItem(player); } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Down.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Down.cs new file mode 100644 index 000000000..067ce8b02 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Down.cs @@ -0,0 +1,17 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class ArrowSign_Item_Down : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.value = 200; + Item.placeStyle = 3; + Item.width = 18; + Item.height = 28; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Down.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Down.png new file mode 100644 index 000000000..ae36fde76 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Down.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Left.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Left.cs new file mode 100644 index 000000000..1f6461b06 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Left.cs @@ -0,0 +1,17 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class ArrowSign_Item_Left : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.value = 200; + Item.placeStyle = 1; + Item.width = 18; + Item.height = 28; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Left.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Left.png new file mode 100644 index 000000000..fcb194201 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Left.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_LeftDown.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_LeftDown.cs new file mode 100644 index 000000000..ffc0cdca5 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_LeftDown.cs @@ -0,0 +1,17 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class ArrowSign_Item_LeftDown : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.value = 200; + Item.placeStyle = 7; + Item.width = 18; + Item.height = 28; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_LeftDown.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_LeftDown.png new file mode 100644 index 000000000..ce4ead0dc Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_LeftDown.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_LeftUp.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_LeftUp.cs new file mode 100644 index 000000000..b39826fb9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_LeftUp.cs @@ -0,0 +1,17 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class ArrowSign_Item_LeftUp : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.value = 200; + Item.placeStyle = 4; + Item.width = 18; + Item.height = 28; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_LeftUp.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_LeftUp.png new file mode 100644 index 000000000..2ebcc1046 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_LeftUp.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Right.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Right.cs new file mode 100644 index 000000000..c20377447 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Right.cs @@ -0,0 +1,17 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class ArrowSign_Item_Right : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.value = 200; + Item.placeStyle = 0; + Item.width = 18; + Item.height = 28; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Right.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Right.png new file mode 100644 index 000000000..55de35b0b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Right.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_RightDown.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_RightDown.cs new file mode 100644 index 000000000..62a4fd6e9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_RightDown.cs @@ -0,0 +1,17 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class ArrowSign_Item_RightDown : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.value = 200; + Item.placeStyle = 6; + Item.width = 18; + Item.height = 28; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_RightDown.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_RightDown.png new file mode 100644 index 000000000..5662874a3 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_RightDown.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_RightUp.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_RightUp.cs new file mode 100644 index 000000000..86a1b7c8c --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_RightUp.cs @@ -0,0 +1,17 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class ArrowSign_Item_RightUp : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.value = 200; + Item.placeStyle = 5; + Item.width = 18; + Item.height = 28; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_RightUp.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_RightUp.png new file mode 100644 index 000000000..14ae4f941 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_RightUp.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Up.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Up.cs new file mode 100644 index 000000000..67f071feb --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Up.cs @@ -0,0 +1,17 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class ArrowSign_Item_Up : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.value = 200; + Item.placeStyle = 2; + Item.width = 18; + Item.height = 28; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Up.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Up.png new file mode 100644 index 000000000..f169ebe41 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/ArrowSign_Item_Up.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/DarkSludgeBlock_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/DarkSludgeBlock_Item.cs new file mode 100644 index 000000000..e996de9bf --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/DarkSludgeBlock_Item.cs @@ -0,0 +1,11 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class DarkSludgeBlock_Item : ModItem +{ + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/DarkSludgeBlock_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/DarkSludgeBlock_Item.png new file mode 100644 index 000000000..1cd107093 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/DarkSludgeBlock_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/DarkSludge_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/DarkSludge_Item.png deleted file mode 100644 index 84284aee8..000000000 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/DarkSludge_Item.png and /dev/null differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/FurnaceCopperPipe_Large_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/FurnaceCopperPipe_Large_Item.png index 56a22a3e3..58b9ca57e 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/FurnaceCopperPipe_Large_Item.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/FurnaceCopperPipe_Large_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MeltingInputBox_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/FurnaceMeltingChest_Item.cs similarity index 69% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MeltingInputBox_Item.cs rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/FurnaceMeltingChest_Item.cs index 6d9491603..307a7a9e3 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MeltingInputBox_Item.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/FurnaceMeltingChest_Item.cs @@ -2,12 +2,12 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; -public class MeltingInputBox_Item : ModItem +public class FurnaceMeltingChest_Item : ModItem { public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; public override void SetDefaults() { - Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.DefaultToPlaceableTile(ModContent.TileType()); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MeltingInputBox_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/FurnaceMeltingChest_Item.png similarity index 100% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MeltingInputBox_Item.png rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/FurnaceMeltingChest_Item.png diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryBuckHead_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryBuckHead_Item.cs new file mode 100644 index 000000000..7eb4b09df --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryBuckHead_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class BakeryBuckHead_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 26; + Item.height = 22; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryBuckHead_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryBuckHead_Item.png new file mode 100644 index 000000000..5a6495708 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryBuckHead_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryChair_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryChair_Item.cs new file mode 100644 index 000000000..8e39fb017 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryChair_Item.cs @@ -0,0 +1,13 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class BakeryChair_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryChair_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryChair_Item.png new file mode 100644 index 000000000..8551538c0 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryChair_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryCounterSide_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryCounterSide_Item.cs new file mode 100644 index 000000000..9b273c669 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryCounterSide_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class BakeryCounterSide_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 26; + Item.height = 22; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryCounterSide_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryCounterSide_Item.png new file mode 100644 index 000000000..83617691c Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryCounterSide_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryCounter_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryCounter_Item.cs new file mode 100644 index 000000000..9c1c167d3 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryCounter_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class BakeryCounter_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 26; + Item.height = 22; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryCounter_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryCounter_Item.png new file mode 100644 index 000000000..e398e2d4f Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryCounter_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryGlassTable_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryGlassTable_Item.cs new file mode 100644 index 000000000..44f46b3f4 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryGlassTable_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class BakeryGlassTable_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 26; + Item.height = 22; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryGlassTable_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryGlassTable_Item.png new file mode 100644 index 000000000..8dda7c3f8 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryGlassTable_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryHangingLamp_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryHangingLamp_Item.cs new file mode 100644 index 000000000..e01327177 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryHangingLamp_Item.cs @@ -0,0 +1,13 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class BakeryHangingLamp_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryHangingLamp_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryHangingLamp_Item.png new file mode 100644 index 000000000..535edcc63 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryHangingLamp_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryMenu_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryMenu_Item.cs new file mode 100644 index 000000000..fb423531c --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryMenu_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class BakeryMenu_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 26; + Item.height = 22; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryMenu_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryMenu_Item.png new file mode 100644 index 000000000..42105e7c9 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryMenu_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryShelf_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryShelf_Item.cs new file mode 100644 index 000000000..d7d6a677b --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryShelf_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class BakeryShelf_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 68; + Item.height = 56; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryShelf_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryShelf_Item.png new file mode 100644 index 000000000..7a61d617d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryShelf_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakerySideLamp_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakerySideLamp_Item.cs new file mode 100644 index 000000000..29c74b526 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakerySideLamp_Item.cs @@ -0,0 +1,13 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class BakerySideLamp_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakerySideLamp_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakerySideLamp_Item.png new file mode 100644 index 000000000..4347bdb60 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakerySideLamp_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryTable_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryTable_Item.cs new file mode 100644 index 000000000..ae7ab8850 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryTable_Item.cs @@ -0,0 +1,13 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class BakeryTable_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryTable_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryTable_Item.png new file mode 100644 index 000000000..680515651 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryTable_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_GoldFlower.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_GoldFlower.cs new file mode 100644 index 000000000..cbfd44632 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_GoldFlower.cs @@ -0,0 +1,13 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class BakeryVase_GoldFlower : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType(), 2); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_GoldFlower.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_GoldFlower.png new file mode 100644 index 000000000..35ec56232 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_GoldFlower.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_LightTanFlower.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_LightTanFlower.cs new file mode 100644 index 000000000..bac38c80d --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_LightTanFlower.cs @@ -0,0 +1,13 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class BakeryVase_LightTanFlower : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType(), 1); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_LightTanFlower.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_LightTanFlower.png new file mode 100644 index 000000000..73f3e076d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_LightTanFlower.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_RedFlower.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_RedFlower.cs new file mode 100644 index 000000000..17938ace0 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_RedFlower.cs @@ -0,0 +1,13 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class BakeryVase_RedFlower : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType(), 0); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_RedFlower.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_RedFlower.png new file mode 100644 index 000000000..9fad721a4 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/BakeryVase_RedFlower.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShelf_Feature_Nature_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShelf_Feature_Nature_Item.cs new file mode 100644 index 000000000..79dcf8d00 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShelf_Feature_Nature_Item.cs @@ -0,0 +1,21 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class ClothesShelf_Feature_Nature_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 56; + Item.height = 38; + } + + public override void HoldItem(Player player) + { + Item.placeStyle = Math.Max(player.direction, 0); + base.HoldItem(player); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShelf_Feature_Nature_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShelf_Feature_Nature_Item.png new file mode 100644 index 000000000..08139115e Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShelf_Feature_Nature_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopBonsai_Feature_Nature_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopBonsai_Feature_Nature_Item.cs new file mode 100644 index 000000000..4cb46e1d4 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopBonsai_Feature_Nature_Item.cs @@ -0,0 +1,22 @@ +using Everglow.CagedDomain.Tiles; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class ClothesShopBonsai_Feature_Nature_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 22; + Item.height = 22; + } + + public override void HoldItem(Player player) + { + Item.placeStyle = Math.Max(player.direction, 0); + base.HoldItem(player); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopBonsai_Feature_Nature_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopBonsai_Feature_Nature_Item.png new file mode 100644 index 000000000..4bc520b58 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopBonsai_Feature_Nature_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopModel_Feature_Nature_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopModel_Feature_Nature_Item.cs new file mode 100644 index 000000000..0aba94766 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopModel_Feature_Nature_Item.cs @@ -0,0 +1,21 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class ClothesShopModel_Feature_Nature_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 16; + Item.height = 38; + } + + public override void HoldItem(Player player) + { + Item.placeStyle = Math.Max(player.direction, 0); + base.HoldItem(player); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopModel_Feature_Nature_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopModel_Feature_Nature_Item.png new file mode 100644 index 000000000..b62604802 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopModel_Feature_Nature_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopSofa_Feature_Nature_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopSofa_Feature_Nature_Item.cs new file mode 100644 index 000000000..7828b6a2f --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopSofa_Feature_Nature_Item.cs @@ -0,0 +1,28 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; +using Terraria.GameInput; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class ClothesShopSofa_Feature_Nature_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public int PlaceState = 0; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 22; + Item.height = 22; + } + + public override void HoldItem(Player player) + { + if (PlayerInput.Triggers.JustReleased.MouseRight) + { + PlaceState = (PlaceState + 1) % 2; + } + Item.placeStyle = Math.Max(player.direction, 0) + PlaceState * 2; + base.HoldItem(player); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopSofa_Feature_Nature_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopSofa_Feature_Nature_Item.png new file mode 100644 index 000000000..52eb67a95 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopSofa_Feature_Nature_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopTable_Feature_Nature_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopTable_Feature_Nature_Item.cs new file mode 100644 index 000000000..aa456a0bd --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopTable_Feature_Nature_Item.cs @@ -0,0 +1,21 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class ClothesShopTable_Feature_Nature_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 26; + Item.height = 22; + } + + public override void HoldItem(Player player) + { + Item.placeStyle = Math.Max(player.direction, 0); + base.HoldItem(player); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopTable_Feature_Nature_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopTable_Feature_Nature_Item.png new file mode 100644 index 000000000..2103e2e33 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/ClothesShopTable_Feature_Nature_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/FevensPortrait_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/FevensPortrait_Item.cs new file mode 100644 index 000000000..89020bf96 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/FevensPortrait_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.GravelStore; + +public class FevensPortrait_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 26; + Item.height = 22; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/FevensPortrait_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/FevensPortrait_Item.png new file mode 100644 index 000000000..ba0f92b7e Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/GravelStore/FevensPortrait_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyAnkhBanner_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyAnkhBanner_Item.cs new file mode 100644 index 000000000..a0211f49b --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyAnkhBanner_Item.cs @@ -0,0 +1,16 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.TwilightForest; + +public class Desert_NavyAnkhBanner_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 12; + Item.height = 28; + Item.value = 1000; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyAnkhBanner_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyAnkhBanner_Item.png new file mode 100644 index 000000000..4687e489f Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyAnkhBanner_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyBanner_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyBanner_Item.cs new file mode 100644 index 000000000..e7466e5cc --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyBanner_Item.cs @@ -0,0 +1,16 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.TwilightForest; + +public class Desert_NavyBanner_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 12; + Item.height = 28; + Item.value = 1000; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyBanner_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyBanner_Item.png new file mode 100644 index 000000000..5c535ac24 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyBanner_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyOmegaBanner_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyOmegaBanner_Item.cs new file mode 100644 index 000000000..aa89e1190 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyOmegaBanner_Item.cs @@ -0,0 +1,16 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.TwilightForest; + +public class Desert_NavyOmegaBanner_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 12; + Item.height = 28; + Item.value = 1000; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyOmegaBanner_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyOmegaBanner_Item.png new file mode 100644 index 000000000..fb8d344ae Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavyOmegaBanner_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavySnakeBanner_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavySnakeBanner_Item.cs new file mode 100644 index 000000000..594bdce9a --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavySnakeBanner_Item.cs @@ -0,0 +1,16 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.TwilightForest; + +public class Desert_NavySnakeBanner_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 12; + Item.height = 28; + Item.value = 1000; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavySnakeBanner_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavySnakeBanner_Item.png new file mode 100644 index 000000000..ef762bfb5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/Desert_NavySnakeBanner_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/DragonChest_DarkDragonRoom_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/DragonChest_DarkDragonRoom_Item.cs new file mode 100644 index 000000000..dc11f3a97 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/DragonChest_DarkDragonRoom_Item.cs @@ -0,0 +1,16 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.TwilightForest; + +public class DragonChest_DarkDragonRoom_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 32; + Item.height = 26; + Item.value = 5000; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/DragonChest_DarkDragonRoom_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/DragonChest_DarkDragonRoom_Item.png new file mode 100644 index 000000000..362399d5d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/DragonChest_DarkDragonRoom_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/RubyDarkGoldChest_BloodyChurch_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/RubyDarkGoldChest_BloodyChurch_Item.cs new file mode 100644 index 000000000..f0811a8a2 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/RubyDarkGoldChest_BloodyChurch_Item.cs @@ -0,0 +1,16 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.TwilightForest; + +public class RubyDarkGoldChest_BloodyChurch_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 32; + Item.height = 26; + Item.value = 5000; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/RubyDarkGoldChest_BloodyChurch_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/RubyDarkGoldChest_BloodyChurch_Item.png new file mode 100644 index 000000000..9df05db20 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/RubyDarkGoldChest_BloodyChurch_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/SandgoldLantern_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/SandgoldLantern_Item.cs new file mode 100644 index 000000000..fbf19e8a6 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/SandgoldLantern_Item.cs @@ -0,0 +1,16 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.TwilightForest; + +public class SandgoldLantern_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 16; + Item.height = 30; + Item.value = 1000; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/SandgoldLantern_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/SandgoldLantern_Item.png new file mode 100644 index 000000000..32be3424a Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/SandgoldLantern_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/WoodenChest_ForestCastle_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/WoodenChest_ForestCastle_Item.cs new file mode 100644 index 000000000..e2a980cb9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/WoodenChest_ForestCastle_Item.cs @@ -0,0 +1,16 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.TwilightForest; + +public class WoodenChest_ForestCastle_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 32; + Item.height = 26; + Item.value = 5000; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/WoodenChest_ForestCastle_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/WoodenChest_ForestCastle_Item.png new file mode 100644 index 000000000..37234fa6e Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Furniture/TwilightForest/WoodenChest_ForestCastle_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/GreenRelicBrick_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/GreenRelicBrick_Item.cs index ffbc292b5..a1459b895 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/GreenRelicBrick_Item.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/GreenRelicBrick_Item.cs @@ -1,4 +1,7 @@ +using Everglow.Yggdrasil.WorldGeneration; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest; +using Everglow.Yggdrasil.YggdrasilTown.Walls.TwilightForest; namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; @@ -8,8 +11,26 @@ public class GreenRelicBrick_Item : ModItem public override void SetDefaults() { - Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 16; Item.height = 16; } + + public override void HoldItem(Player player) + { + // Green brick runner. + Item.DefaultToPlaceableTile(ModContent.TileType()); + if (Main.mouseRight && Main.mouseRightRelease) + { + //Point point = Main.MouseWorld.ToTileCoordinates(); + //var checkTiles = TileUtils.BFSContinueTile(point, true, 1024); + //foreach (var tile in checkTiles) + //{ + // if (tile.TileType == TileID.GreenDungeonBrick) + // { + // tile.TileType = (ushort)ModContent.TileType(); + // } + //} + } + } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Ishta_per_The_Venus_painting_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Ishta_per_The_Venus_painting_Item.png index 3611568e0..e908bf560 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Ishta_per_The_Venus_painting_Item.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Ishta_per_The_Venus_painting_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/LargeCrystalShowTable_Blue_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/LargeCrystalShowTable_Blue_Item.png index 60b414da9..3122040d1 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/LargeCrystalShowTable_Blue_Item.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/LargeCrystalShowTable_Blue_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/LargeCrystalShowTable_Green_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/LargeCrystalShowTable_Green_Item.png index ee8b898a0..66155ed34 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/LargeCrystalShowTable_Green_Item.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/LargeCrystalShowTable_Green_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/LargeCrystalShowTable_Red_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/LargeCrystalShowTable_Red_Item.png index 243f7539e..2c281e897 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/LargeCrystalShowTable_Red_Item.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/LargeCrystalShowTable_Red_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MailBox_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MailBox_Item.cs new file mode 100644 index 000000000..0aee371c0 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MailBox_Item.cs @@ -0,0 +1,13 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class MailBox_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MailBox_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MailBox_Item.png new file mode 100644 index 000000000..7d2587b7e Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MailBox_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroSign_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroSign_Item.cs new file mode 100644 index 000000000..9b5a580f6 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroSign_Item.cs @@ -0,0 +1,16 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class MetroSign_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.value = 200; + Item.width = 18; + Item.height = 46; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroSign_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroSign_Item.png new file mode 100644 index 000000000..f96b4b7e3 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroSign_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroStationSign_PylonSquare_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroStationSign_PylonSquare_Item.cs new file mode 100644 index 000000000..da923967a --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroStationSign_PylonSquare_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class MetroStationSign_PylonSquare_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 16; + Item.height = 16; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroStationSign_PylonSquare_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroStationSign_PylonSquare_Item.png new file mode 100644 index 000000000..fd19af541 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroStationSign_PylonSquare_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroStationSign_YggdrasilTown_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroStationSign_YggdrasilTown_Item.cs new file mode 100644 index 000000000..ff8aaaec8 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroStationSign_YggdrasilTown_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class MetroStationSign_YggdrasilTown_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 16; + Item.height = 16; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroStationSign_YggdrasilTown_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroStationSign_YggdrasilTown_Item.png new file mode 100644 index 000000000..8e793b619 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MetroStationSign_YggdrasilTown_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MissionCounter_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MissionCounter_Item.png index cad9a66ae..daee3f055 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MissionCounter_Item.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/MissionCounter_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/PlantSpecimen_Branch_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/PlantSpecimen_Branch_Item.cs new file mode 100644 index 000000000..20935efbf --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/PlantSpecimen_Branch_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class PlantSpecimen_Branch_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 16; + Item.height = 16; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/PlantSpecimen_Branch_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/PlantSpecimen_Branch_Item.png new file mode 100644 index 000000000..daeb365a5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/PlantSpecimen_Branch_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/DarkSludge_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/PlantSpecimen_Fern_Item.cs similarity index 61% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/DarkSludge_Item.cs rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/PlantSpecimen_Fern_Item.cs index bdde490b5..64e286529 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/DarkSludge_Item.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/PlantSpecimen_Fern_Item.cs @@ -1,12 +1,14 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; -public class DarkSludge_Item : ModItem +public class PlantSpecimen_Fern_Item : ModItem { public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; public override void SetDefaults() { - Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.DefaultToPlaceableTile(ModContent.TileType()); Item.width = 16; Item.height = 16; } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/PlantSpecimen_Fern_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/PlantSpecimen_Fern_Item.png new file mode 100644 index 000000000..5130dadf4 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/PlantSpecimen_Fern_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/HolographicPylon_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/HolographicPylon_Item.cs new file mode 100644 index 000000000..f8d6f18fc --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/HolographicPylon_Item.cs @@ -0,0 +1,13 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.Pylons; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Pylons; + +public class HolographicPylon_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/HolographicPylon_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/HolographicPylon_Item.png new file mode 100644 index 000000000..50934b5dd Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/HolographicPylon_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/HolographicPylon_Item_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/HolographicPylon_Item_glow.png new file mode 100644 index 000000000..db0450325 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/HolographicPylon_Item_glow.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/TownGatePylon_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/TownGatePylon_Item.cs new file mode 100644 index 000000000..f8243bb36 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/TownGatePylon_Item.cs @@ -0,0 +1,13 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.Pylons; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Pylons; + +public class TownGatePylon_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/TownGatePylon_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/TownGatePylon_Item.png new file mode 100644 index 000000000..863d02c53 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/TownGatePylon_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/TownGatePylon_Item_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/TownGatePylon_Item_glow.png new file mode 100644 index 000000000..e09f9629c Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/TownGatePylon_Item_glow.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/UnregisteredPylon_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/UnregisteredPylon_Item.cs new file mode 100644 index 000000000..6d67b2bd9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/UnregisteredPylon_Item.cs @@ -0,0 +1,13 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles.Pylons; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Pylons; + +public class UnregisteredPylon_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/UnregisteredPylon_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/UnregisteredPylon_Item.png new file mode 100644 index 000000000..8443683dc Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/UnregisteredPylon_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/UnregisteredPylon_Item_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/UnregisteredPylon_Item_glow.png new file mode 100644 index 000000000..82534ac5c Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Pylons/UnregisteredPylon_Item_glow.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/RoadSignPost_ToArena_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/RoadSignPost_ToArena_Item.png index e9d3be5e2..3989f5902 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/RoadSignPost_ToArena_Item.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/RoadSignPost_ToArena_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/TrafficLight_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/TrafficLight_Item.png new file mode 100644 index 000000000..602f74ec5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/TrafficLight_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/UnionGiantChandelier_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/UnionGiantChandelier_Item.png index 85f0458d2..5bcb87a27 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/UnionGiantChandelier_Item.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/UnionGiantChandelier_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GravelStoreWall_Thick_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GravelStoreWall_Thick_Item.cs new file mode 100644 index 000000000..085da05bf --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GravelStoreWall_Thick_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.YggdrasilTown.Walls; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Walls; + +public class GravelStoreWall_Thick_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableWall(ModContent.WallType()); + Item.width = 24; + Item.height = 24; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GravelStoreWall_Thick_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GravelStoreWall_Thick_Item.png new file mode 100644 index 000000000..de9da662a Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GravelStoreWall_Thick_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GravelStoreWall_Thin_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GravelStoreWall_Thin_Item.cs new file mode 100644 index 000000000..7e493d11f --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GravelStoreWall_Thin_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.YggdrasilTown.Walls; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Walls; + +public class GravelStoreWall_Thin_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableWall(ModContent.WallType()); + Item.width = 24; + Item.height = 24; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GravelStoreWall_Thin_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GravelStoreWall_Thin_Item.png new file mode 100644 index 000000000..1da274df2 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GravelStoreWall_Thin_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GreenRelicWall_Style2_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GreenRelicWall_Style2_Item.cs new file mode 100644 index 000000000..d4cc3a393 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GreenRelicWall_Style2_Item.cs @@ -0,0 +1,23 @@ +using Everglow.Yggdrasil.YggdrasilTown.Walls.TwilightForest; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Walls; + +public class GreenRelicWall_Style2_Item : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableWall(ModContent.WallType()); + Item.width = 24; + Item.height = 24; + } + + public override void AddRecipes() + { + CreateRecipe(4) + .AddIngredient(ModContent.ItemType(), 1) + .AddTile(TileID.WorkBenches) + .Register(); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GreenRelicWall_Style2_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GreenRelicWall_Style2_Item.png new file mode 100644 index 000000000..408b93721 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/Walls/GreenRelicWall_Style2_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/YggdrasilGravelStoreGate_Exit_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/YggdrasilGravelStoreGate_Exit_Item.cs new file mode 100644 index 000000000..e83f88847 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/YggdrasilGravelStoreGate_Exit_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class YggdrasilGravelStoreGate_Exit_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 50; + Item.height = 46; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/YggdrasilGravelStoreGate_Exit_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/YggdrasilGravelStoreGate_Exit_Item.png new file mode 100644 index 000000000..c3ce02d35 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/YggdrasilGravelStoreGate_Exit_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/YggdrasilGravelStoreGate_Item.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/YggdrasilGravelStoreGate_Item.cs new file mode 100644 index 000000000..b568b1249 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/YggdrasilGravelStoreGate_Item.cs @@ -0,0 +1,15 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; + +public class YggdrasilGravelStoreGate_Item : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.DefaultToPlaceableTile(ModContent.TileType()); + Item.width = 50; + Item.height = 46; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/YggdrasilGravelStoreGate_Item.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/YggdrasilGravelStoreGate_Item.png new file mode 100644 index 000000000..d09408448 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Placeables/YggdrasilGravelStoreGate_Item.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/FurnaceScoreClear.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/FurnaceScoreClear.cs new file mode 100644 index 000000000..18c2bdbfc --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/FurnaceScoreClear.cs @@ -0,0 +1,18 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Tools.Developer; + +public class FurnaceScoreClear : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void HoldItem(Player player) + { + base.HoldItem(player); + if (Main.mouseLeft && Main.mouseLeftRelease) + { + player.GetModPlayer().TotalFurnaceScore = 0; + player.GetModPlayer().CurrentFurnaceScore = 0; + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/FurnaceScoreClear.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/FurnaceScoreClear.png new file mode 100644 index 000000000..6acab156f Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/FurnaceScoreClear.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/MetroHelper.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/MetroHelper.cs new file mode 100644 index 000000000..1280f151f --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/MetroHelper.cs @@ -0,0 +1,26 @@ +using Everglow.Commons.CustomTiles; +using Everglow.Yggdrasil.YggdrasilTown.CustomTiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Tools.Developer; + +public class MetroHelper : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.width = 16; + Item.height = 16; + Item.useTurn = true; + Item.useAnimation = 4; + Item.useTime = 4; + Item.autoReuse = false; + Item.useStyle = ItemUseStyleID.Swing; + } + + public override bool CanUseItem(Player player) + { + ColliderManager.Instance.Add(Main.MouseWorld); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/MetroHelper.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/MetroHelper.png new file mode 100644 index 000000000..9f59631e9 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/MetroHelper.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/ResetTheYggdrasilTown.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/ResetTheYggdrasilTown.cs index a9b9677d6..885566c15 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/ResetTheYggdrasilTown.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/ResetTheYggdrasilTown.cs @@ -17,19 +17,8 @@ public override void SetDefaults() public override bool CanUseItem(Player player) { - for (int i = 50; i < Main.maxTilesX - 50; i++) - { - for (int j = 10000; j < Main.maxTilesY - 50; j++) - { - Main.tile[i, j].ClearEverything(); - } - } - YggdrasilTownGeneration.BuildMidnightBayou(); + TileUtils.PlaceRectangleAreaOfBlock(20, Main.maxTilesY - 1500, Main.maxTilesX - 20, Main.maxTilesY, -1); + YggdrasilTownGeneration.BuildYggdrasilTown(); return false; } - - public override bool? UseItem(Player player) - { - return base.UseItem(player); - } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/TreePlacer.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/TreePlacer.cs index ed7bb06ff..0c8bc740f 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/TreePlacer.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/TreePlacer.cs @@ -1,5 +1,6 @@ using Everglow.Yggdrasil.WorldGeneration; using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest; +using static Everglow.Commons.Utilities.TileUtils; namespace Everglow.Yggdrasil.YggdrasilTown.Items.Tools.Developer; @@ -37,7 +38,7 @@ public static void BuildTwilightTree(int i, int j, int height = 20) { return; } - if (!YggdrasilWorldGeneration.ChestSafe(i, j) || !YggdrasilWorldGeneration.ChestSafe(i + 1, j)) + if (!ChestSafe(i, j) || !ChestSafe(i + 1, j)) { return; } @@ -47,7 +48,7 @@ public static void BuildTwilightTree(int i, int j, int height = 20) { Tile tile = TileUtils.SafeGetTile(i, j - g); Tile tileRight = TileUtils.SafeGetTile(i + 1, j - g); - if (!YggdrasilWorldGeneration.ChestSafe(i, j - g - 1) || !YggdrasilWorldGeneration.ChestSafe(i + 1, j - g - 1)) + if (!ChestSafe(i, j - g - 1) || !ChestSafe(i + 1, j - g - 1)) { Height = g + 1; } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/VFXPersonItem.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/VFXPersonItem.cs new file mode 100644 index 000000000..9271419a6 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/VFXPersonItem.cs @@ -0,0 +1,28 @@ +using Everglow.Yggdrasil.YggdrasilTown.VFXs.RandomNPC; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Tools.Developer; + +public class VFXPersonItem : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.Placeables; + + public override void SetDefaults() + { + Item.width = 16; + Item.height = 16; + Item.useTurn = true; + Item.useAnimation = 4; + Item.useTime = 4; + Item.autoReuse = false; + Item.useStyle = ItemUseStyleID.Swing; + } + + public override bool CanUseItem(Player player) + { + for (int k = 0; k < 10; k++) + { + YggdrasilTownPersonManager.AddRandomPerson(); + } + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/VFXPersonItem.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/VFXPersonItem.png new file mode 100644 index 000000000..7023b6ccb Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/Developer/VFXPersonItem.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/GlowstickLauncher.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/GlowstickLauncher.png index b894e0115..f7a5f98bb 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/GlowstickLauncher.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/GlowstickLauncher.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/GlowstickLauncher_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/GlowstickLauncher_glow.png new file mode 100644 index 000000000..f59396dd8 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Tools/GlowstickLauncher_glow.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/ArmorPiercingBlaster.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/ArmorPiercingBlaster.cs index 0a838fe00..e2f3c08a9 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/ArmorPiercingBlaster.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/ArmorPiercingBlaster.cs @@ -24,7 +24,7 @@ public override void SetDefaults() Item.noUseGraphic = true; Item.rare = ItemRarityID.Blue; - Item.value = 0; + Item.value = 4000; Item.shoot = ModContent.ProjectileType(); Item.shootSpeed = 6; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/ChainGrenade.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/ChainGrenade.cs new file mode 100644 index 000000000..83e693b20 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/ChainGrenade.cs @@ -0,0 +1,32 @@ +using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Ranged; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons; + +public class ChainGrenade : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.RangedWeapons; + + public override void SetDefaults() + { + Item.width = 30; + Item.height = 30; + + Item.DamageType = DamageClass.Ranged; + Item.damage = 40; + Item.knockBack = 1.0f; + Item.crit = 4; + + Item.useStyle = ItemUseStyleID.Swing; + Item.useAnimation = Item.useTime = 36; + Item.UseSound = SoundID.Item1; + Item.autoReuse = false; + Item.noMelee = true; + Item.noUseGraphic = true; + + Item.rare = ItemRarityID.Blue; + Item.value = 4000; + + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 6; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/ChainGrenade.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/ChainGrenade.png index cb23c3c06..e32f49b84 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/ChainGrenade.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/ChainGrenade.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/IntroductiontoThermalElectricity.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/IntroductiontoThermalElectricity.cs new file mode 100644 index 000000000..780124588 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/IntroductiontoThermalElectricity.cs @@ -0,0 +1,48 @@ +using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic; +using Terraria.Audio; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons; + +public class IntroductiontoThermalElectricity : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicWeapons; + + public override void SetDefaults() + { + Item.width = 28; + Item.height = 30; + + Item.DamageType = DamageClass.Magic; + Item.damage = 12; + Item.knockBack = 2; + Item.mana = 20; + + Item.useStyle = ItemUseStyleID.Shoot; + Item.useTime = Item.useAnimation = 36; + Item.noMelee = true; + Item.autoReuse = false; + + Item.rare = ItemRarityID.Orange; + Item.value = 80000; + + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 4.5f; + } + + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) + { + switch (Main.rand.Next(2)) + { + case 0: + SoundEngine.PlaySound(new SoundStyle(ModAsset.Introductiontothermalelectricity_launch_1_Mod), position); + break; + case 1: + SoundEngine.PlaySound(new SoundStyle(ModAsset.Introductiontothermalelectricity_launch_2_Mod), position); + break; + } + + Projectile.NewProjectileDirect(source, position + velocity * 4, velocity, type, damage, knockback, player.whoAmI); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/MagicalBoomerang.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/MagicalBoomerang.cs index e83432edd..15a5e65cf 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/MagicalBoomerang.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/MagicalBoomerang.cs @@ -24,7 +24,7 @@ public override void SetDefaults() Item.noUseGraphic = true; Item.rare = ItemRarityID.Blue; - Item.value = 0; + Item.value = 4000; Item.shoot = ModContent.ProjectileType(); Item.shootSpeed = 13; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/PearShapedNeedle.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/PearShapedNeedle.cs new file mode 100644 index 000000000..9cbf68478 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/PearShapedNeedle.cs @@ -0,0 +1,45 @@ +using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Ranged; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons; + +public class PearShapedNeedle : ModItem +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicWeapons; + + public override void SetStaticDefaults() + { + Item.staff[Type] = true; + } + + public override void SetDefaults() + { + Item.width = 28; + Item.height = 28; + + Item.DamageType = DamageClass.Ranged; + Item.damage = 17; + Item.knockBack = 2.5f; + + Item.useStyle = ItemUseStyleID.Shoot; + Item.useTime = Item.useAnimation = 12; + Item.noUseGraphic = true; + Item.noMelee = true; + Item.autoReuse = false; + + Item.rare = ItemRarityID.Blue; + Item.value = 4000; + + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 8; + } + + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) + { + if (player.ownedProjectileCounts[type] <= 0) + { + Projectile.NewProjectile(source, position, Vector2.zeroVector, type, damage, knockback, player.whoAmI); + } + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/PearShapedNeedle.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/PearShapedNeedle.png index e919400ad..d16ef4433 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/PearShapedNeedle.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/PearShapedNeedle.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/QuenchingBlade.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/QuenchingBlade.cs index 021b2e9cb..f18a09cbc 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/QuenchingBlade.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/QuenchingBlade.cs @@ -14,7 +14,7 @@ public override void SetDefaults() Item.DamageType = DamageClass.Melee; Item.damage = 27; - Item.knockBack = 3; + Item.knockBack = 35; Item.useStyle = ItemUseStyleID.Shoot; Item.UseSound = SoundID.Item1; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/RockElemental/VitalizedRocks.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/RockElemental/VitalizedRocks.cs index ce8b908f7..05d085168 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/RockElemental/VitalizedRocks.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/RockElemental/VitalizedRocks.cs @@ -16,7 +16,7 @@ public override void SetDefaults() Item.useTime = 15; Item.knockBack = 3f; Item.damage = 25; - Item.rare = ItemRarityID.Blue; + Item.rare = ItemRarityID.Green; Item.UseSound = SoundID.Item1; Item.value = 12000; Item.autoReuse = false; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/BloodySwamp.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/BloodySwamp.cs similarity index 89% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/BloodySwamp.cs rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/BloodySwamp.cs index 5697fd61b..2f20e56c3 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/BloodySwamp.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/BloodySwamp.cs @@ -1,11 +1,11 @@ using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic; using Terraria.DataStructures; -namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons; +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons.TwilightForest; public class BloodySwamp : ModItem { - public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicWeapons; + public override string LocalizationCategory => LocalizationUtils.Categories.MagicWeapons; public override void SetStaticDefaults() { diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/BloodySwamp.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/BloodySwamp.png similarity index 100% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/BloodySwamp.png rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/BloodySwamp.png diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/GunOfAvarice.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/GunOfAvarice.cs similarity index 94% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/GunOfAvarice.cs rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/GunOfAvarice.cs index 0b59a7d8d..c1724f420 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/GunOfAvarice.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/GunOfAvarice.cs @@ -6,11 +6,11 @@ using Terraria.GameContent; using Terraria.UI.Chat; -namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons; +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons.TwilightForest; public class GunOfAvarice : ModItem { - public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.RangedWeapons; + public override string LocalizationCategory => LocalizationUtils.Categories.RangedWeapons; public override void SetDefaults() { @@ -156,7 +156,7 @@ public override void PostDrawInInventory(SpriteBatch spriteBatch, Vector2 positi return; } - SpriteBatchState sBS = GraphicsUtils.GetState(spriteBatch).Value; + SpriteBatchState sBS = spriteBatch.GetState().Value; spriteBatch.End(); spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, default, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); @@ -207,14 +207,14 @@ public override void PostDrawInInventory(SpriteBatch spriteBatch, Vector2 positi { if (OldLevel < Level || Level >= 10) { - drawScale = MathF.Pow(Math.Clamp(Math.Abs(((LevelChangeTimer - 80f) / 10f) * 2), 0, 1), 0.3f); + drawScale = MathF.Pow(Math.Clamp(Math.Abs((LevelChangeTimer - 80f) / 10f * 2), 0, 1), 0.3f); } } if (LevelChangeTimer is > 70 and < 90) { if (OldLevel >= Level && Level < 10) { - textColor = Color.Lerp(Color.White, Color.Transparent, MathF.Pow(Math.Clamp(Math.Abs(((LevelChangeTimer - 80f) / 10f) * 2), 0, 1), 0.3f)); + textColor = Color.Lerp(Color.White, Color.Transparent, MathF.Pow(Math.Clamp(Math.Abs((LevelChangeTimer - 80f) / 10f * 2), 0, 1), 0.3f)); } } if (LevelChangeTimer is > 80) @@ -222,7 +222,7 @@ public override void PostDrawInInventory(SpriteBatch spriteBatch, Vector2 positi if (OldLevel >= Level && Level < 10) { Texture2D line = Commons.ModAsset.Trail_7.Value; - Rectangle frameOfLine = new Rectangle(0, 60, 256, 136); + var frameOfLine = new Rectangle(0, 60, 256, 136); float timeValue = MathF.Pow(Math.Clamp((LevelChangeTimer - 80) / 40f - 0.3f, 0, 1), 3); spriteBatch.Draw(line, drawCenter + new Vector2(-timeValue * 40, 10), frameOfLine, textColor, 0, frameOfLine.Size() * 0.5f, new Vector2(0.25f * (1 - timeValue), 0.01f), SpriteEffects.None, 0); } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/GunOfAvarice.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/GunOfAvarice.png similarity index 100% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/GunOfAvarice.png rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/GunOfAvarice.png diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/HexaCrystalStaff.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/HexaCrystalStaff.cs similarity index 85% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/HexaCrystalStaff.cs rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/HexaCrystalStaff.cs index cbcb7dab8..9aff5ff96 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/HexaCrystalStaff.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/HexaCrystalStaff.cs @@ -1,11 +1,11 @@ using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic; using Terraria.DataStructures; -namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons; +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons.TwilightForest; public class HexaCrystalStaff : ModItem { - public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicWeapons; + public override string LocalizationCategory => LocalizationUtils.Categories.MagicWeapons; public override void SetStaticDefaults() { diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/HexaCrystalStaff.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/HexaCrystalStaff.png similarity index 100% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/HexaCrystalStaff.png rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/HexaCrystalStaff.png diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/MagicOfLightAndShadow.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/MagicOfLightAndShadow.cs similarity index 88% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/MagicOfLightAndShadow.cs rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/MagicOfLightAndShadow.cs index 30bf9ee65..feac0400f 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/MagicOfLightAndShadow.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/MagicOfLightAndShadow.cs @@ -1,11 +1,11 @@ using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic; using Terraria.DataStructures; -namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons; +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons.TwilightForest; public class MagicOfLightAndShadow : ModItem { - public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicWeapons; + public override string LocalizationCategory => LocalizationUtils.Categories.MagicWeapons; public override void SetStaticDefaults() { diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/MagicOfLightAndShadow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/MagicOfLightAndShadow.png similarity index 100% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/MagicOfLightAndShadow.png rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/MagicOfLightAndShadow.png diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/MagicOfLightAndShadow_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/MagicOfLightAndShadow_glow.png similarity index 100% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/MagicOfLightAndShadow_glow.png rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/MagicOfLightAndShadow_glow.png diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/MechanismHalberd.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/MechanismHalberd.cs new file mode 100644 index 000000000..77f004dbf --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/MechanismHalberd.cs @@ -0,0 +1,48 @@ +using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Melee; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons.TwilightForest; + +/// +/// 机关长戟Itemç±» +/// +public class MechanismHalberd : ModItem +{ + public override void SetDefaults() + { + Item.width = 64; + Item.height = 64; + Item.useStyle = ItemUseStyleID.Swing; + Item.useTime = 22; + Item.useAnimation = 22; + Item.damage = 26; + Item.knockBack = 1.3f; + Item.crit = 4; + Item.DamageType = DamageClass.Melee; + Item.value = 14400; + Item.rare = ItemRarityID.Green; + Item.noMelee = true; + Item.noUseGraphic = true; + Item.shootSpeed = 1f; + } + + public override bool CanUseItem(Player player) + { + if (base.CanUseItem(player)) + { + if (Main.myPlayer == player.whoAmI) + { + if (player.altFunctionUse != 2) + { + Projectile.NewProjectile( + player.GetSource_ItemUse(Item), + player.Center, Vector2.Zero, + ModContent.ProjectileType(), + player.GetWeaponDamage(Item), + Item.knockBack, player.whoAmI); + } + } + return false; + } + return base.CanUseItem(player); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/MechanismHalberd.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/MechanismHalberd.png new file mode 100644 index 000000000..102269be6 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/MechanismHalberd.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/RockQuake.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/RockQuake.cs similarity index 84% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/RockQuake.cs rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/RockQuake.cs index 0a61f71ea..edc537455 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/RockQuake.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/RockQuake.cs @@ -1,11 +1,11 @@ using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic; using Terraria.DataStructures; -namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons; +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons.TwilightForest; public class RockQuake : ModItem { - public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicWeapons; + public override string LocalizationCategory => LocalizationUtils.Categories.MagicWeapons; public override void SetStaticDefaults() { diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/RockQuake.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/RockQuake.png similarity index 100% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/RockQuake.png rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/RockQuake.png diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/SpringOfQuicksand.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/SpringOfQuicksand.cs new file mode 100644 index 000000000..2b9373212 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/SpringOfQuicksand.cs @@ -0,0 +1,42 @@ +using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons.TwilightForest; + +public class SpringOfQuicksand : ModItem +{ + public override string LocalizationCategory => LocalizationUtils.Categories.MagicWeapons; + + public override void SetStaticDefaults() + { + Item.staff[Type] = true; + } + + public override void SetDefaults() + { + Item.width = 48; + Item.height = 48; + + Item.DamageType = DamageClass.Magic; + Item.damage = 16; + Item.knockBack = 0.5f; + Item.mana = 7; + + Item.useStyle = ItemUseStyleID.Shoot; + Item.UseSound = SoundID.Item20; + Item.useTime = Item.useAnimation = 32; + Item.noMelee = true; + Item.autoReuse = false; + Item.rare = ItemRarityID.Green; + Item.value = 14400; + + Item.shoot = ModContent.ProjectileType(); + Item.shootSpeed = 8; + } + + public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback) + { + Projectile.NewProjectile(source, position, velocity * 1.5f, type, damage, knockback, player.whoAmI); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/SpringOfQuicksand.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/SpringOfQuicksand.png new file mode 100644 index 000000000..472511ca4 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/SpringOfQuicksand.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/TwilightShamanStaff.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/TwilightShamanStaff.cs index 8537069f6..b160289ae 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/TwilightShamanStaff.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/TwilightShamanStaff.cs @@ -2,14 +2,14 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons.TwilightForest; public class TwilightShamanStaff : ModItem { - public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MeleeWeapons; + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicWeapons; public override void SetDefaults() { Item.width = 36; Item.height = 34; - Item.DamageType = DamageClass.Melee; + Item.DamageType = DamageClass.Magic; Item.damage = 30; Item.knockBack = 0.4f; Item.crit = 4; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/WiltedForestLamp.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/WiltedForestLamp.cs similarity index 84% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/WiltedForestLamp.cs rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/WiltedForestLamp.cs index 3ef3e9879..5304bb258 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/WiltedForestLamp.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/WiltedForestLamp.cs @@ -1,13 +1,12 @@ -using Everglow.Yggdrasil.YggdrasilTown.Projectiles; using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Summon; using Terraria.DataStructures; -namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons; +namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons.TwilightForest; public class WiltedForestLamp : ModItem { // Wilted Forest Lamp will not occupy minion slots, but can only exist 8 per player. - public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.SummonWeapons; + public override string LocalizationCategory => LocalizationUtils.Categories.SummonWeapons; // Wilted Forest Lamp will not occupy minion slots, but can only exist 8 per player. public override void SetDefaults() diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/WiltedForestLamp.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/WiltedForestLamp.png similarity index 100% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/WiltedForestLamp.png rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/WiltedForestLamp.png diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/WiltedForestLamp_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/WiltedForestLamp_glow.png similarity index 100% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/WiltedForestLamp_glow.png rename to Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/TwilightForest/WiltedForestLamp_glow.png diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Kitchen/Tiles/CanteenDoor.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Kitchen/Tiles/CanteenDoor.cs index 1d89962f2..ce3690f02 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Kitchen/Tiles/CanteenDoor.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Kitchen/Tiles/CanteenDoor.cs @@ -24,7 +24,7 @@ public void BuildCanteenGen() for (int y = 20; y < 23; y++) { Tile tile = TileUtils.SafeGetTile(x, y); - tile.wall = 1; + tile.WallType = 1; ushort typeChange = (ushort)ModContent.TileType(); if (y == 22) { diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeBucket.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeBucket.cs new file mode 100644 index 000000000..101318e07 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeBucket.cs @@ -0,0 +1,126 @@ +using ModLiquidLib.ID; +using ModLiquidLib.ModLoader; +using Terraria.Audio; +using Terraria.GameContent.Creative; + +namespace Everglow.Yggdrasil.YggdrasilTown.Liquids; + +public class DarkSludgeBucket : ModItem +{ + // This is an example of a modded bucket + // Here we do some extra logic to make our bucket dispense liquid + // While also using a new ID Set added by ModLiquid Library to allow buckets to create this item + // The SetStaticDefaults of a bucket + public override void SetStaticDefaults() + { + ItemID.Sets.IsLavaImmuneRegardlessOfRarity[Type] = true; + ItemID.Sets.AlsoABuildingItem[Type] = true; // Unused ID Set, but may be useful for other modders or when the game updates + ItemID.Sets.DuplicationMenuToolsFilter[Type] = true; + + // Here is how we make buckets create this item + // Using the CreateLiquidBucketItem ID Set, we are able to set which liquid creates an item as well as which item its creates + // NOTE: a liquid can only create 1 bucket item at a time + LiquidID_TLmod.Sets.CreateLiquidBucketItem[LiquidLoader.LiquidType()] = Type; + + CreativeItemSacrificesCatalog.Instance.SacrificeCountNeededByItemId[Type] = 5; + } + + // The normal SetDefaults for a bucket + public override void SetDefaults() + { + Item.width = 20; + Item.height = 24; + Item.maxStack = Item.CommonMaxStack; + Item.useTurn = true; + Item.autoReuse = true; + Item.useAnimation = 15; + Item.useTime = 10; + Item.useStyle = ItemUseStyleID.Swing; + } + + // Here is how we do the bucket logic. Calculating when the player is able to place a liquid tile or not. + // This is taken from the Lava bucket logic + // We use HoldItem, as its the hook/method ran just before the bucket logic is ran. + // This is so no other extra item logic is run inbetween this hook/method and when we would normally have bucket logic called + public override void HoldItem(Player player) + { + if (!player.JustDroppedAnItem)// make sure the player hasn't just dropped an item recently + { + if (player.whoAmI != Main.myPlayer) // make sure to only run on clients (we sync multiplayer data later down the line) + { + return; + } + + // We make sure the player is in range to be able to place the liquid tile + if (player.noBuilding || + !(player.position.X / 16f - (float)Player.tileRangeX - (float)Item.tileBoost <= (float)Player.tileTargetX) || + !((player.position.X + (float)player.width) / 16f + (float)Player.tileRangeX + (float)Item.tileBoost - 1f >= (float)Player.tileTargetX) || + !(player.position.Y / 16f - (float)Player.tileRangeY - (float)Item.tileBoost <= (float)Player.tileTargetY) || + !((player.position.Y + (float)player.height) / 16f + (float)Player.tileRangeY + (float)Item.tileBoost - 2f >= (float)Player.tileTargetY)) + { + return; + } + + // We set the cursor's item to be of the bucket item. To show the player that they are able to place a liquid tile at that coordinate normally + if (!Main.GamepadDisableCursorItemIcon) + { + player.cursorItemIconEnabled = true; + Main.ItemIconCacheUpdate(Item.type); + } + + // Make sure that the item is being used to place liquid + if (!player.ItemTimeIsZero || player.itemAnimation <= 0 || !player.controlUseItem) + { + return; + } + + // Get the tile position of the cursor + Tile tile = Main.tile[Player.tileTargetX, Player.tileTargetY]; + if (tile.LiquidAmount >= 200) + { + return; + } + + // Do additional tile check to make sure the target tile isn't a grate + if (tile.HasUnactuatedTile) + { + bool[] tileSolid = Main.tileSolid; + if (tileSolid[tile.TileType]) + { + bool[] tileSolidTop = Main.tileSolidTop; + if (!tileSolidTop[tile.TileType]) + { + if (tile.TileType != TileID.Grate) + { + return; + } + } + } + } + + // We then check if the liquid at the position is ours if the liquid amount isn't zero + if (tile.LiquidAmount != 0) + { + if (tile.LiquidType != LiquidLoader.LiquidType()) + { + return; + } + } + + // After all of that, we are able to place the liquid + // In which we... + SoundEngine.PlaySound(SoundID.SplashWeak, player.position); // ...play a sound + tile.LiquidType = LiquidLoader.LiquidType(); // ...create a liquid tile... + tile.LiquidAmount = byte.MaxValue; // ...at full liquid capacity + WorldGen.SquareTileFrame(Player.tileTargetX, Player.tileTargetY); // ...frame the tile to update the liquid + Item.stack--; // ...remove the item's count + player.PutItemInInventoryFromItemUsage(ItemID.EmptyBucket, player.selectedItem); //...create a bucket item + player.ApplyItemTime(Item); // ...do item usetime + + if (Main.netMode == NetmodeID.MultiplayerClient)// ...lastly, if the game is MP, then sync the liquid plavement + { + NetMessage.sendWater(Player.tileTargetX, Player.tileTargetY); + } + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeBucket.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeBucket.png new file mode 100644 index 000000000..d800ecf27 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeBucket.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeLiquid.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeLiquid.cs new file mode 100644 index 000000000..596675dc4 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeLiquid.cs @@ -0,0 +1,80 @@ +using Everglow.Yggdrasil.YggdrasilTown.Tiles; +using ModLiquidLib.ModLoader; +using ModLiquidLib.Utils.Structs; +using Terraria.DataStructures; +using Terraria.Graphics.Light; +using Terraria.Localization; + +namespace Everglow.Yggdrasil.YggdrasilTown.Liquids; + +public class DarkSludgeLiquid : ModLiquid +{ + public static bool CanDive = false; + + public override void SetStaticDefaults() + { + PlayerMovementMultiplier = 0.2f; + StopWatchMPHMultiplier = 0.2f; + NPCMovementMultiplierDefault = 0.2f; + SlopeOpacity = 1f; + WaterRippleMultiplier = 1f; + SplashDustType = ModContent.DustType(); + SplashSound = SoundID.SplashWeak; + AddMapEntry(new Color(31, 26, 45)); + } + + public override int LiquidMerge(int i, int j, int otherLiquid) + { + return ModContent.TileType(); + } + + public override LightMaskMode LiquidLightMaskMode(int i, int j) + { + return LightMaskMode.None; + } + + public override int ChooseWaterfallStyle(int i, int j) + { + return ModContent.GetInstance().Slot; + } + + public override void RetroDrawEffects(int i, int j, SpriteBatch spriteBatch, ref RetroLiquidDrawInfo drawData, float liquidAmountModified, int liquidGFXQuality) + { + drawData.liquidAlphaMultiplier = 1f; + } + + public override bool OnPlayerSplash(Player player, bool isEnter) + { + return true; + } + + public override bool PlayerLiquidMovement(Player player, bool fallThrough, bool ignorePlats) + { + if (!CanDive) + { + Vector2 topPos = player.position / 16f; + topPos.Y -= 1f; + Tile tile = Main.tile[topPos.ToPoint()]; + if (tile.LiquidType == LiquidLoader.LiquidType() && tile.LiquidAmount > 100) + { + player.KillMe(PlayerDeathReason.ByCustomReason(NetworkText.FromKey("KilledBySludge")), 1000f, 0); + } + } + return true; + } + + public override bool OnNPCSplash(NPC npc, bool isEnter) + { + return true; + } + + public override bool OnProjectileSplash(Projectile proj, bool isEnter) + { + return true; + } + + public override bool OnItemSplash(Item item, bool isEnter) + { + return true; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeLiquid.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeLiquid.png new file mode 100644 index 000000000..d24e8122a Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeLiquid.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeLiquid_Block.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeLiquid_Block.png new file mode 100644 index 000000000..e4fb0e1e0 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeLiquid_Block.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeLiquid_Slope.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeLiquid_Slope.png new file mode 100644 index 000000000..fe1a0c1fd Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeLiquid_Slope.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeWaterfall.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeWaterfall.cs new file mode 100644 index 000000000..d7400e69f --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeWaterfall.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ModLiquidLib.ModLoader; + +namespace Everglow.Yggdrasil.YggdrasilTown.Liquids; + +public class DarkSludgeWaterfall : ModLiquidFall +{ + public override bool PlayWaterfallSounds() + { + return false; + } + + public override float? Alpha(int x, int y, float Alpha, int maxSteps, int s, Tile tileCache) + { + return 0.7f; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeWaterfall.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeWaterfall.png new file mode 100644 index 000000000..7fdf01ba1 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Liquids/DarkSludgeWaterfall.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/706x275YggdrasilTown.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/706x275YggdrasilTown.mapio index 8146a33bd..a0430fa6d 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/706x275YggdrasilTown.mapio and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/706x275YggdrasilTown.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/GravelStore114x36.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/GravelStore114x36.mapio new file mode 100644 index 000000000..a3c064d43 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/GravelStore114x36.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/MetroBridgePiece3x15.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/MetroBridgePiece3x15.mapio new file mode 100644 index 000000000..df9fbd55c Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/MetroBridgePiece3x15.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/MetroBridgePiece_withPier3x15.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/MetroBridgePiece_withPier3x15.mapio new file mode 100644 index 000000000..ca0371e54 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/MetroBridgePiece_withPier3x15.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/MetroTunnelPiece3x16.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/MetroTunnelPiece3x16.mapio new file mode 100644 index 000000000..38b037e8b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/MetroTunnelPiece3x16.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/MetroTunnelPiece_WithLamp3x16.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/MetroTunnelPiece_WithLamp3x16.mapio new file mode 100644 index 000000000..c697a2949 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/MetroTunnelPiece_WithLamp3x16.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/OriginalPylonStation231x31.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/OriginalPylonStation231x31.mapio new file mode 100644 index 000000000..34eeffe75 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/OriginalPylonStation231x31.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_00_StoneCave_40x21.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_00_StoneCave_40x21.mapio new file mode 100644 index 000000000..ee8abf8e1 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_00_StoneCave_40x21.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_01_BloodyChurch_40x21.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_01_BloodyChurch_40x21.mapio new file mode 100644 index 000000000..8e4e3a3be Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_01_BloodyChurch_40x21.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_02_Desert_40x21.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_02_Desert_40x21.mapio new file mode 100644 index 000000000..4f4b6892b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_02_Desert_40x21.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_03_WaterSluice_40x21.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_03_WaterSluice_40x21.mapio new file mode 100644 index 000000000..38a77b4c4 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_03_WaterSluice_40x21.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_04_Forest_40x21.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_04_Forest_40x21.mapio new file mode 100644 index 000000000..05ad85f6f Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_04_Forest_40x21.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_05_DarkDragon_40x21.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_05_DarkDragon_40x21.mapio new file mode 100644 index 000000000..c78828d6c Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Ld_05_DarkDragon_40x21.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_00_StoneCave_40x21.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_00_StoneCave_40x21.mapio new file mode 100644 index 000000000..79e3b86ac Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_00_StoneCave_40x21.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_00_WaterDungeon_40x21.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_00_WaterDungeon_40x21.mapio new file mode 100644 index 000000000..3a6e87589 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_00_WaterDungeon_40x21.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_01_BloodyChurch_40x21.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_01_BloodyChurch_40x21.mapio new file mode 100644 index 000000000..d09ee575d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_01_BloodyChurch_40x21.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_02_Desert_40x21.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_02_Desert_40x21.mapio new file mode 100644 index 000000000..10423abe0 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_02_Desert_40x21.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_03_WaterSluice_40x21.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_03_WaterSluice_40x21.mapio new file mode 100644 index 000000000..11129390d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_03_WaterSluice_40x21.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_04_Forest_40x21.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_04_Forest_40x21.mapio new file mode 100644 index 000000000..bb9886032 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_04_Forest_40x21.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_05_DarkDragon_40x21.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_05_DarkDragon_40x21.mapio new file mode 100644 index 000000000..6a2088ecd Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/TwilightCastle/TCRoom_Rd_05_DarkDragon_40x21.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/YggdrasilTown_New_706x275.mapio b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/YggdrasilTown_New_706x275.mapio new file mode 100644 index 000000000..4ffb8bc7c Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/MapIOs/YggdrasilTown_New_706x275.mapio differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/BarkSpicyCaterpillar.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/BarkSpicyCaterpillar.cs index dcd5f93db..127fe98f8 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/BarkSpicyCaterpillar.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/BarkSpicyCaterpillar.cs @@ -1,6 +1,7 @@ using Everglow.Commons.Coroutines; using Everglow.Commons.Mechanics.Miscs; using Everglow.Commons.Templates.Enemies; +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.Biomes; using Everglow.Yggdrasil.YggdrasilTown.Dusts; using Everglow.Yggdrasil.YggdrasilTown.Items.Materials; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/BrownCaterpillar.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/BrownCaterpillar.cs index cd361222b..43a76837f 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/BrownCaterpillar.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/BrownCaterpillar.cs @@ -1,5 +1,6 @@ using Everglow.Commons.Mechanics.Miscs; using Everglow.Commons.Templates.Enemies; +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.Dusts; namespace Everglow.Yggdrasil.YggdrasilTown.NPCs; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/CarapaceCaterpillar.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/CarapaceCaterpillar.cs index 6af5e8fab..7f58b3c65 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/CarapaceCaterpillar.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/CarapaceCaterpillar.cs @@ -1,5 +1,6 @@ using Everglow.Commons.Coroutines; using Everglow.Commons.Templates.Enemies; +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.Biomes; using Everglow.Yggdrasil.YggdrasilTown.Dusts; using Everglow.Yggdrasil.YggdrasilTown.Items.Materials; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/CrimsonSpell.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/CrimsonSpell.cs index 7c909027f..aba237739 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/CrimsonSpell.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/CrimsonSpell.cs @@ -1,3 +1,4 @@ +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.Biomes; using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Enemies; using Terraria.DataStructures; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/CyanOreBeetle.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/CyanOreBeetle.cs index 116ca3a56..28d5c1b4a 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/CyanOreBeetle.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/CyanOreBeetle.cs @@ -1,3 +1,4 @@ +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.Biomes; using Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Ores; using Terraria.DataStructures; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/DarkGlimmeringRods.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/DarkGlimmeringRods.cs index 3ec415909..5741e1ebb 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/DarkGlimmeringRods.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/DarkGlimmeringRods.cs @@ -1,4 +1,5 @@ using Everglow.Commons.DataStructures; +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.Biomes; using Everglow.Yggdrasil.YggdrasilTown.Items.Materials; using Terraria.DataStructures; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/GiantJellyBall.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/GiantJellyBall.cs index 155c4dc97..762c5a8eb 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/GiantJellyBall.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/GiantJellyBall.cs @@ -1,4 +1,5 @@ using Everglow.Commons.CustomTiles; +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.Biomes; using Everglow.Yggdrasil.YggdrasilTown.Dusts; using Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/Guard_Slimy.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/Guard_Slimy.cs index 5cebbb2cf..a7a3235d7 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/Guard_Slimy.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/Guard_Slimy.cs @@ -1,4 +1,5 @@ using Everglow.Commons.Mechanics.Miscs; +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.NPCs.TownNPCs; using Terraria.DataStructures; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/JellyBall.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/JellyBall.cs index 657b29fa8..0d3c39af0 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/JellyBall.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/JellyBall.cs @@ -1,4 +1,5 @@ using Everglow.Commons.CustomTiles; +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.Biomes; using Everglow.Yggdrasil.YggdrasilTown.Dusts; using Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/KingJellyBall/KingJellyBall.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/KingJellyBall/KingJellyBall.cs index ef3425bb6..254a7effb 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/KingJellyBall/KingJellyBall.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/KingJellyBall/KingJellyBall.cs @@ -1,5 +1,6 @@ using Everglow.Commons.DataStructures; using Everglow.Commons.Mechanics.Miscs; +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.Dusts; using Everglow.Yggdrasil.YggdrasilTown.Items.Materials; using Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/LampFruitBorer.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/LampFruitBorer.cs index f0ccb5839..c0a661efb 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/LampFruitBorer.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/LampFruitBorer.cs @@ -1,6 +1,7 @@ using Everglow.Commons.Coroutines; using Everglow.Commons.Mechanics.Miscs; using Everglow.Commons.Templates.Enemies; +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.Biomes; using Everglow.Yggdrasil.YggdrasilTown.Items.PermanentBoosters; using Terraria.GameContent.ItemDropRules; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/LeafcutterAnt.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/LeafcutterAnt.cs index a38f6486a..5c7b7972e 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/LeafcutterAnt.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/LeafcutterAnt.cs @@ -1,3 +1,4 @@ +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.Biomes; using Terraria.DataStructures; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/LightBulb.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/LightBulb.cs index c2b021b91..85eae3128 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/LightBulb.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/LightBulb.cs @@ -1,4 +1,5 @@ using Everglow.Commons.Mechanics.Miscs; +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.Biomes; using Everglow.Yggdrasil.YggdrasilTown.Dusts; using Everglow.Yggdrasil.YggdrasilTown.Items.Materials; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/RockElemental.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/RockElemental.cs index 9fe4bb582..9cc8a3987 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/RockElemental.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/RockElemental.cs @@ -1,6 +1,7 @@ using Everglow.Commons.CustomTiles; using Everglow.Commons.DataStructures; using Everglow.Commons.Mechanics.Miscs; +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.Biomes; using Everglow.Yggdrasil.YggdrasilTown.Dusts; using Everglow.Yggdrasil.YggdrasilTown.Items.Weapons.RockElemental; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/ShadowstrikeCaterpillar.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/ShadowstrikeCaterpillar.cs index eeaa8c7a5..e0d0117aa 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/ShadowstrikeCaterpillar.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/ShadowstrikeCaterpillar.cs @@ -1,6 +1,7 @@ using Everglow.Commons.Coroutines; using Everglow.Commons.Mechanics.Miscs; using Everglow.Commons.Templates.Enemies; +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.Biomes; using Everglow.Yggdrasil.YggdrasilTown.Dusts; using Everglow.Yggdrasil.YggdrasilTown.Items.Materials; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/WhisperingGhost.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/WhisperingGhost.cs index ae795747d..77cc09f89 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/WhisperingGhost.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/NPCs/WhisperingGhost.cs @@ -1,3 +1,4 @@ +using Everglow.Yggdrasil.Common; using Everglow.Yggdrasil.YggdrasilTown.Biomes; using Everglow.Yggdrasil.YggdrasilTown.Dusts; using Terraria.DataStructures; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Bosses/SquamousShell/YggdrasilMoonBlade.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Bosses/SquamousShell/YggdrasilMoonBlade.cs index b4cee86e3..9531ebf1d 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Bosses/SquamousShell/YggdrasilMoonBlade.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Bosses/SquamousShell/YggdrasilMoonBlade.cs @@ -129,7 +129,7 @@ public void DrawWarp(VFXBatch spriteBatch) { Vector2 v0 = startVelocity.RotatedBy(x / 20f * Projectile.ai[1]) * 90f; Vector2 pos = Projectile.Center + v0 - Main.screenPosition - startVelocity * 40f; - bars.Add(pos, new Color(redValue, 0.02f * (Math.Abs(x) + 12), 0, 0), new Vector3(0.2f + timeValue, x / 35f, 0)); + bars.Add(pos, new Color(redValue, 0.002f * Math.Abs(x), 0, 0), new Vector3(0.2f + timeValue, x / 35f, 0)); bars.Add(pos - startVelocity * 50f, new Color(redValue, 0, 0, 0), new Vector3(0 + timeValue, x / 35f, 0)); } Texture2D t = Commons.ModAsset.Noise_melting.Value; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/IntroductiontoThermalElectricity_Ball.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/IntroductiontoThermalElectricity_Ball.cs new file mode 100644 index 000000000..76fa02925 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/IntroductiontoThermalElectricity_Ball.cs @@ -0,0 +1,261 @@ +using Everglow.Commons.DataStructures; +using Everglow.Yggdrasil.YggdrasilTown.VFXs; +using Terraria.Audio; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic; + +public class IntroductiontoThermalElectricity_Ball : ModProjectile +{ + public int Timer = 0; + + public int TimeToKill = -1; + + public float HitRange = 25; + + public int TimeToKillMax = 45; + + public override string LocalizationCategory => LocalizationUtils.Categories.MagicProjectiles; + + public override void OnSpawn(IEntitySource source) => base.OnSpawn(source); + + public override void SetDefaults() + { + Projectile.friendly = true; + Projectile.timeLeft = 900; + Projectile.tileCollide = true; + Projectile.penetrate = -1; + Projectile.width = 20; + Projectile.height = 20; + Projectile.aiStyle = -1; + Projectile.magic = true; + Projectile.tileCollide = true; + + Timer = 0; + TimeToKill = -1; + HitRange = 25; + } + + public void HitTarget() + { + switch (Main.rand.Next(2)) + { + case 0: + SoundEngine.PlaySound(new SoundStyle(ModAsset.Introductiontothermalelectricity_explosion_1_Mod), Projectile.Center); + break; + case 1: + SoundEngine.PlaySound(new SoundStyle(ModAsset.Introductiontothermalelectricity_explosion_2_Mod), Projectile.Center); + break; + } + TimeToKill = TimeToKillMax; + for (int k = 0; k < 40; k++) + { + var dust = new IntroductiontoThermalElectricity_Plasma + { + Velocity = new Vector2(0, Main.rand.NextFloat(2f, 5f)).RotatedByRandom(MathHelper.TwoPi), + Active = true, + Visible = true, + Position = Projectile.Center + new Vector2(0, 10).RotatedByRandom(MathHelper.TwoPi), + MaxTime = Main.rand.NextFloat(25f, 55f), + Scale = Main.rand.NextFloat(1f, 3f), + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + }; + Ins.VFXManager.Add(dust); + } + for (int k = 0; k < 12; k++) + { + var dust = new IntroductiontoThermalElectricity_Plasma_Trail + { + Velocity = new Vector2(0, Main.rand.NextFloat(2f, 6f)).RotatedByRandom(MathHelper.TwoPi), + Active = true, + Visible = true, + Position = Projectile.Center, + MaxTime = Main.rand.NextFloat(55f, 85f), + Scale = 2f, + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + }; + Ins.VFXManager.Add(dust); + } + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + if ((targetHitbox.Center() - Projectile.Center).Length() < targetHitbox.Width / 2f + HitRange) + { + return true; + } + return base.Colliding(projHitbox, targetHitbox); + } + + public override void AI() + { + Timer++; + if (Projectile.wet) + { + if (TimeToKill < 0) + { + HitTarget(); + } + } + if (TimeToKill > 0) + { + TimeToKill--; + float addRangeValue = (TimeToKillMax - TimeToKill) / (float)TimeToKillMax; + addRangeValue = MathF.Pow(addRangeValue, 0.5f); + HitRange = 25 + addRangeValue * 100; + Projectile.velocity *= 0; + if (TimeToKill <= 0) + { + Projectile.Kill(); + } + if (TimeToKill < 10) + { + Projectile.friendly = false; + } + } + else + { + if (Main.rand.NextBool()) + { + return; + } + if (Main.rand.NextBool(3)) + { + var dust = new IntroductiontoThermalElectricity_Plasma_Trail + { + Velocity = Projectile.velocity.RotatedByRandom(0.2f), + Active = true, + Visible = true, + Position = Projectile.Center + new Vector2(0, 10).RotatedByRandom(MathHelper.TwoPi), + MaxTime = Main.rand.NextFloat(25f, 55f), + Scale = Main.rand.NextFloat(1f, 2f), + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + }; + Ins.VFXManager.Add(dust); + } + else + { + var dust = new IntroductiontoThermalElectricity_Plasma + { + Velocity = Projectile.velocity.RotatedByRandom(0.2f), + Active = true, + Visible = true, + Position = Projectile.Center + new Vector2(0, 10).RotatedByRandom(MathHelper.TwoPi), + MaxTime = Main.rand.NextFloat(25f, 55f), + Scale = Main.rand.NextFloat(1f, 2f), + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + }; + Ins.VFXManager.Add(dust); + } + } + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + if (TimeToKill < 0) + { + HitTarget(); + } + base.OnHitNPC(target, hit, damageDone); + } + + public override bool OnTileCollide(Vector2 oldVelocity) + { + if (TimeToKill < 0) + { + Projectile.tileCollide = false; + HitTarget(); + } + return false; + } + + public override bool PreDraw(ref Color lightColor) + { + Texture2D tex = (Texture2D)ModContent.Request(Texture); + Texture2D tex_bloom = Commons.ModAsset.LightPoint.Value; + int frameCurrent = (int)((Timer / 3f) % 11); + Rectangle frame = new Rectangle(0, frameCurrent * 56, 56, 56); + Color drawColor = new Color(1f, 1f, 1f, 0.75f); + float lerpColorValue = 0.5f + MathF.Sin(Timer); + Color ringColor = Color.Lerp(new Color(255, 109, 91, 0), new Color(56, 255, 255, 0), lerpColorValue); + if (Timer % 7 == 1) + { + ringColor = new Color(1f, 1f, 1f, 0); + } + Color darkColor = Color.White * 0.4f; + float environmentLightValue = 1f; + float timeToKillValue = TimeToKill / 10f; + if (TimeToKill < 10 && TimeToKill >= 0) + { + ringColor *= timeToKillValue; + darkColor *= timeToKillValue; + Projectile.scale = timeToKillValue; + environmentLightValue *= timeToKillValue; + } + Vector2 drawPos = Projectile.Center - Main.screenPosition; + Main.EntitySpriteDraw(tex_bloom, drawPos, null, ringColor, Projectile.rotation, tex_bloom.Size() * 0.5f, Projectile.scale * 2, SpriteEffects.None, 0); + Main.EntitySpriteDraw(tex, drawPos, frame, drawColor, Projectile.rotation, frame.Size() * 0.5f, Projectile.scale, SpriteEffects.None, 0); + if (frameCurrent != 3 && frameCurrent != 7) + { + Lighting.AddLight(Projectile.Center, ringColor.ToVector3() * environmentLightValue); + } + if (TimeToKill < 0) + { + return false; + } + + float ringRange = HitRange + 5 * MathF.Sin(Timer * 0.15f); + List bars = new List(); + for (int i = 0; i <= 60; i++) + { + float rot = i / 60f * MathHelper.TwoPi; + bars.Add(drawPos + new Vector2(0, ringRange).RotatedBy(rot), ringColor, new Vector3(i / 60f, Timer / 120f, 0)); + bars.Add(drawPos + new Vector2(0, Math.Max(ringRange - 15, 0)).RotatedBy(rot), ringColor * 0, new Vector3(i / 60f, 0.1f + Timer / 120f, 0)); + Lighting.AddLight(Projectile.Center + new Vector2(0, ringRange).RotatedBy(rot), ringColor.ToVector3() * environmentLightValue * 0.3f); + } + + float outerRingThick = MathF.Pow(TimeToKill / (float)TimeToKillMax, 2) * 80; + float outerRingBoundVagueValue = 1 - TimeToKill / (float)TimeToKillMax; + outerRingBoundVagueValue = MathF.Sin(outerRingBoundVagueValue * MathHelper.Pi - MathHelper.PiOver2) * 0.5f + 0.5f; + outerRingBoundVagueValue *= 0.5f; + List bars_outerRing = new List(); + List bars_outerRing_dark = new List(); + for (int i = 0; i <= 60; i++) + { + float rot = i / 60f * MathHelper.TwoPi; + bars_outerRing.Add(drawPos + new Vector2(0, ringRange).RotatedBy(rot), ringColor, new Vector3(i / 60f, 0.5f, 0)); + bars_outerRing.Add(drawPos + new Vector2(0, Math.Max(ringRange - outerRingThick, 0)).RotatedBy(rot), ringColor, new Vector3(i / 60f, 0.5f + outerRingBoundVagueValue, 0)); + + bars_outerRing_dark.Add(drawPos + new Vector2(0, ringRange).RotatedBy(rot), darkColor, new Vector3(i / 60f, 0.5f, 0)); + bars_outerRing_dark.Add(drawPos + new Vector2(0, Math.Max(ringRange - outerRingThick * 1.4f, 0)).RotatedBy(rot), darkColor * 0, new Vector3(i / 60f, 1, 0)); + } + SpriteBatchState sBS = Main.spriteBatch.GetState().Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + + if (bars_outerRing_dark.Count > 2) + { + Main.graphics.graphicsDevice.Textures[0] = Commons.ModAsset.Trail_black.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_outerRing_dark.ToArray(), 0, bars_outerRing_dark.Count - 2); + } + + if (bars.Count > 2) + { + Main.graphics.graphicsDevice.Textures[0] = Commons.ModAsset.Noise_hiveNet.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + if (bars_outerRing.Count > 2) + { + Main.graphics.graphicsDevice.Textures[0] = Commons.ModAsset.Trail.Value; + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_outerRing.ToArray(), 0, bars_outerRing.Count - 2); + } + + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + return false; + } + + public override void OnKill(int timeLeft) + { + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/IntroductiontoThermalElectricity_Ball.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/IntroductiontoThermalElectricity_Ball.png new file mode 100644 index 000000000..d4b507ced Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/IntroductiontoThermalElectricity_Ball.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/IstafelsSunfireGrasp_Explosion.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/IstafelsSunfireGrasp_Explosion.cs index e7a7c68fc..de714403d 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/IstafelsSunfireGrasp_Explosion.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/IstafelsSunfireGrasp_Explosion.cs @@ -37,64 +37,58 @@ public override void AI() Timer++; if (Timer < 20 && Timer % 5 == 0) { - for (int x = 0; x < 60; x++) - { - LargeFlame(); - } - for (int x = 0; x < 30; x++) - { - SmallFlame(); - } + LargeFlame(60); + SmallFlame(30); } base.AI(); } - public void LargeFlame() + public void LargeFlame(int count) { - Vector2 newVelocity = new Vector2(0, MathF.Sqrt(Main.rand.NextFloat(1f)) * 12f).RotatedByRandom(MathHelper.TwoPi); - var somg = new MissleFlameDust + for (int x = 0; x < count; x++) { - velocity = newVelocity, - Active = true, - Visible = true, - position = Projectile.Center + new Vector2(Main.rand.NextFloat(6), 0).RotatedByRandom(6.283), - maxTime = Main.rand.Next(90, 120), - scale = Main.rand.NextFloat(24f, 36f), - rotation = Main.rand.NextFloat(6.283f), - ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), 0 }, - }; - Ins.VFXManager.Add(somg); + Vector2 newVelocity = new Vector2(0, MathF.Sqrt(Main.rand.NextFloat(1f)) * 12f).RotatedByRandom(MathHelper.TwoPi); + var somg = new MissleFlameDust + { + velocity = newVelocity, + Active = true, + Visible = true, + position = Projectile.Center + new Vector2(Main.rand.NextFloat(6), 0).RotatedByRandom(6.283), + maxTime = Main.rand.Next(90, 120), + scale = Main.rand.NextFloat(24f, 36f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), 0 }, + }; + Ins.VFXManager.Add(somg); + } } - public void SmallFlame() + public void SmallFlame(int count) { - Vector2 newVelocity = new Vector2(0, MathF.Sqrt(Main.rand.NextFloat(1f)) * 8f).RotatedByRandom(MathHelper.TwoPi); - var somg = new MissleFlameDust + for (int x = 0; x < count; x++) { - velocity = newVelocity, - Active = true, - Visible = true, - position = Projectile.Center + new Vector2(Main.rand.NextFloat(4), 0).RotatedByRandom(6.283), - maxTime = Main.rand.Next(50, 70), - scale = Main.rand.NextFloat(12f, 20f), - rotation = Main.rand.NextFloat(6.283f), - ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), 0 }, - }; - Ins.VFXManager.Add(somg); + Vector2 newVelocity = new Vector2(0, MathF.Sqrt(Main.rand.NextFloat(1f)) * 8f).RotatedByRandom(MathHelper.TwoPi); + var somg = new MissleFlameDust + { + velocity = newVelocity, + Active = true, + Visible = true, + position = Projectile.Center + new Vector2(Main.rand.NextFloat(4), 0).RotatedByRandom(6.283), + maxTime = Main.rand.Next(50, 70), + scale = Main.rand.NextFloat(12f, 20f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), 0 }, + }; + Ins.VFXManager.Add(somg); + } } public override void OnSpawn(IEntitySource source) { Projectile.ai[2] = 600; Projectile.velocity *= 0; - for (int x = 0; x < 60; x++) - { - LargeFlame(); - } - for (int x = 0; x < 30; x++) - { - SmallFlame(); - } + LargeFlame(60); + SmallFlame(30); for (int g = 0; g < 40; g++) { Vector2 afterVelocity = new Vector2(0, Main.rand.NextFloat(2, 7)).RotatedByRandom(MathHelper.TwoPi); diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/LightStartEffect_beam.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/LightStartEffect_beam.cs index 6ef40f403..88118e9a3 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/LightStartEffect_beam.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/LightStartEffect_beam.cs @@ -86,7 +86,7 @@ public void GenerateParticles(int duplicateTimes = 1) } for (int i = 0; i < duplicateTimes; i++) { - Vector2 newVelocity = new Vector2(0, 1.2f).RotatedBy(-Main.time * 0.05f + Projectile.whoAmI + (float)i / duplicateTimes * MathHelper.TwoPi + Math.Sin(Main.time * 0.14f) * 0.6); + Vector2 newVelocity = new Vector2(0, 1.2f).RotatedBy(-Main.time * 0.02f + Projectile.whoAmI + (float)i / duplicateTimes * MathHelper.TwoPi); var somg = new LightFruitParticleDust { velocity = newVelocity, diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/SpringOfQuicksand_Sandflow.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/SpringOfQuicksand_Sandflow.cs new file mode 100644 index 000000000..48b6d136b --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/SpringOfQuicksand_Sandflow.cs @@ -0,0 +1,143 @@ +using Everglow.Commons.Templates.Weapons; +using Everglow.Yggdrasil.YggdrasilTown.VFXs; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic; + +public class SpringOfQuicksand_Sandflow : TrailingProjectile +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicProjectiles; + + public override void SetCustomDefaults() + { + Projectile.width = 20; + Projectile.height = 20; + Projectile.aiStyle = -1; + Projectile.timeLeft = 1200; + Projectile.DamageType = DamageClass.Magic; + Projectile.penetrate = 8; + Projectile.ignoreWater = true; + Projectile.friendly = true; + TrailTexture = Commons.ModAsset.Trail_16.Value; + TrailTextureBlack = Commons.ModAsset.Trail_16_black.Value; + } + + public override void OnSpawn(IEntitySource source) => base.OnSpawn(source); + + public override void Behaviors() + { + float mulTime = 1f; + if (Projectile.timeLeft < 60f) + { + mulTime = Projectile.timeLeft / 60f; + } + Projectile.rotation = Projectile.velocity.ToRotation(); + var flow = new SpringOfQuicksand_SandTrail + { + Velocity = Projectile.velocity.RotatedByRandom(0.3f) * Main.rand.NextFloat(0.85f, 1.15f), + Active = true, + Visible = true, + Position = Projectile.Center, + MaxTime = Main.rand.NextFloat(35f, 40f) * mulTime, + Scale = Main.rand.NextFloat(16f, 24f), + Fade = 0, + }; + Ins.VFXManager.Add(flow); + for (int k = 0; k < 7; k++) + { + var dust = new SpringOfQuicksand_Dust + { + Velocity = Projectile.velocity.RotatedByRandom(0.05f) * Main.rand.NextFloat(0.55f, 0.82f), + Active = true, + Visible = true, + Position = Projectile.Center, + MaxTime = Main.rand.NextFloat(25f, 45f) * mulTime, + Scale = Main.rand.NextFloat(0.5f, 1.5f), + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + RanSeed = Main.rand.NextFloat(MathHelper.TwoPi), + }; + Ins.VFXManager.Add(dust); + } + if (Timer < 90) + { + if (Timer % 15 == 0) + { + Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center, new Vector2(0, 1), ModContent.ProjectileType(), (int)(Projectile.damage * 0.6f), Projectile.knockBack * 0.6f, Projectile.owner); + } + } + Projectile.velocity.Y += 0.15f; + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + for (int k = 0; k < Projectile.oldPos.Length; k++) + { + float fall = k * k * 0.5f; + fall = Math.Min(fall, 150); + if (targetHitbox.Intersects(new Rectangle((int)Projectile.oldPos[k].X, (int)Projectile.oldPos[k].Y, Projectile.width, (int)fall))) + { + return true; + } + } + return base.Colliding(projHitbox, targetHitbox); + } + + public override bool PreDraw(ref Color lightColor) => base.PreDraw(ref lightColor); + + public override float TrailWidthFunction(float factor) => base.TrailWidthFunction(factor); + + public override Color GetTrailColor(int style, Vector2 worldPos, int index, ref float factor, float extraValue0 = 0, float extraValue1 = 0) + { + Color drawColor = Color.White; + if (style == 0) + { + drawColor *= extraValue0; + if (factor > 0.5f) + { + drawColor *= (1 - factor) * 2f; + } + } + if (style == 1) + { + drawColor = TrailColor; + if (!SelfLuminous) + { + Color lightC = Lighting.GetColor(worldPos.ToTileCoordinates()); + drawColor.R = (byte)(lightC.R * drawColor.R / 255f * 0.75f); + drawColor.G = (byte)(lightC.G * drawColor.G / 255f * 0.6f); + drawColor.B = (byte)(lightC.B * drawColor.B / 255f * 0.2f); + if (factor > 0.2f) + { + drawColor *= (0.8f - factor) / 0.6f; + } + } + } + if (style == 2) + { + var normalDir = Projectile.velocity; + if (index >= 1) + { + normalDir = SmoothedOldPos[index - 1] - SmoothedOldPos[index]; + } + normalDir = normalDir.NormalizeSafe(); + drawColor = new Color(1 - (normalDir.X + 25f) / 50f, 1 - (normalDir.Y + 25f) / 50f, WarpStrength, 1); + } + return drawColor; + } + + public override Vector3 ModifyTrailTextureCoordinate(float factor, float timeValue, float phase, float widthValue) + { + float x = factor - timeValue * 0.45f; + float y = 1; + float z = widthValue; + if (phase == 2) + { + y = 0; + } + if (phase % 2 == 1) + { + y = 0.5f; + } + return new Vector3(x, y, z); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/SpringOfQuicksand_Sandflow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/SpringOfQuicksand_Sandflow.png new file mode 100644 index 000000000..a17f496f1 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/SpringOfQuicksand_Sandflow.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/SpringOfQuicksand_Sandflow_preview.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/SpringOfQuicksand_Sandflow_preview.png new file mode 100644 index 000000000..f84827168 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/SpringOfQuicksand_Sandflow_preview.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/SpringOfQuicksand_Sandflow_subproj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/SpringOfQuicksand_Sandflow_subproj.cs new file mode 100644 index 000000000..ad766fc64 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/SpringOfQuicksand_Sandflow_subproj.cs @@ -0,0 +1,135 @@ +using Everglow.Commons.Templates.Weapons; +using Everglow.Yggdrasil.YggdrasilTown.VFXs; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic; + +public class SpringOfQuicksand_Sandflow_subproj : TrailingProjectile +{ + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicProjectiles; + + public override void SetCustomDefaults() + { + Projectile.width = 20; + Projectile.height = 20; + Projectile.aiStyle = -1; + Projectile.timeLeft = 1200; + Projectile.DamageType = DamageClass.Magic; + Projectile.penetrate = 8; + Projectile.ignoreWater = true; + Projectile.friendly = true; + Projectile.scale = 0.5f; + TrailTexture = Commons.ModAsset.Trail_16.Value; + TrailTextureBlack = Commons.ModAsset.Trail_16_black.Value; + TrailWidth = 14; + TrailLength = 12; + } + + public override void OnSpawn(IEntitySource source) => base.OnSpawn(source); + + public override void Behaviors() + { + float mulTime = 1f; + if (Projectile.timeLeft < 60f) + { + mulTime = Projectile.timeLeft / 60f; + } + for (int k = 0; k < 1; k++) + { + var dust = new SpringOfQuicksand_Dust + { + Velocity = Projectile.velocity.RotatedByRandom(0.05f) * Main.rand.NextFloat(0.55f, 0.82f), + Active = true, + Visible = true, + Position = Projectile.Center, + MaxTime = Main.rand.NextFloat(25f, 45f) * mulTime, + Scale = Main.rand.NextFloat(0.5f, 1.5f), + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + RanSeed = Main.rand.NextFloat(MathHelper.TwoPi), + }; + Ins.VFXManager.Add(dust); + } + Projectile.velocity.Y += 0.15f; + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + for (int k = 0; k < Projectile.oldPos.Length; k++) + { + float fall = k * k * 0.5f; + fall = Math.Min(fall, 150); + if (targetHitbox.Intersects(new Rectangle((int)Projectile.oldPos[k].X, (int)Projectile.oldPos[k].Y, Projectile.width, (int)fall))) + { + return true; + } + } + return base.Colliding(projHitbox, targetHitbox); + } + + public override bool PreDraw(ref Color lightColor) + { + return base.PreDraw(ref lightColor); + } + + public override void DrawSelf() + { + var texMain = (Texture2D)ModContent.Request(Texture); + Color color = TrailColor; + if (!SelfLuminous) + { + color = Lighting.GetColor(Projectile.Center.ToTileCoordinates()); + } + Main.spriteBatch.Draw(texMain, Projectile.Center - Main.screenPosition, null, color, Projectile.rotation, texMain.Size() / 2f, Projectile.scale, SpriteEffects.None, 0); + } + + public override void DrawTrail() => base.DrawTrail(); + + public override float TrailWidthFunction(float factor) => base.TrailWidthFunction(factor); + + public override Color GetTrailColor(int style, Vector2 worldPos, int index, ref float factor, float extraValue0 = 0, float extraValue1 = 0) + { + Color drawColor = Color.White; + if (style == 0) + { + drawColor *= extraValue0; + } + if (style == 1) + { + drawColor = TrailColor; + if (!SelfLuminous) + { + Color lightC = Lighting.GetColor(worldPos.ToTileCoordinates()); + drawColor.R = (byte)(lightC.R * drawColor.R / 255f * 0.75f); + drawColor.G = (byte)(lightC.G * drawColor.G / 255f * 0.6f); + drawColor.B = (byte)(lightC.B * drawColor.B / 255f * 0.2f); + } + } + if (style == 2) + { + var normalDir = Projectile.velocity; + if (index >= 1) + { + normalDir = SmoothedOldPos[index - 1] - SmoothedOldPos[index]; + } + normalDir = normalDir.NormalizeSafe(); + drawColor = new Color(1 - (normalDir.X + 25f) / 50f, 1 - (normalDir.Y + 25f) / 50f, WarpStrength, 1); + } + return drawColor; + } + + public override Vector3 ModifyTrailTextureCoordinate(float factor, float timeValue, float phase, float widthValue) + { + float x = factor - timeValue * 0.45f; + float y = 1; + float z = widthValue; + if (phase == 2) + { + y = 0; + } + if (phase % 2 == 1) + { + y = 0.5f; + } + return new Vector3(x, y, z); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/SpringOfQuicksand_Sandflow_subproj.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/SpringOfQuicksand_Sandflow_subproj.png new file mode 100644 index 000000000..131aeef4c Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/SpringOfQuicksand_Sandflow_subproj.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/VitalizedRocksProj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/VitalizedRocksProj.cs index edefa4a57..27a1f0621 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/VitalizedRocksProj.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/VitalizedRocksProj.cs @@ -1,6 +1,6 @@ using Everglow.Commons.DataStructures; using Everglow.Yggdrasil.YggdrasilTown.Dusts; -using Terraria; +using Terraria.Audio; namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic; @@ -123,6 +123,21 @@ public override void AI() } } Projectile.NewProjectileDirect(player.GetSource_FromAI(), Pos, toMouse * speed, type, (int)(Projectile.damage * damageScale), Projectile.knockBack, player.whoAmI); + switch (Main.rand.Next(4)) + { + case 0: + SoundEngine.PlaySound(new SoundStyle(ModAsset.vitalizedrocks_attack_1_Mod), Projectile.Center); + break; + case 1: + SoundEngine.PlaySound(new SoundStyle(ModAsset.vitalizedrocks_attack_2_Mod), Projectile.Center); + break; + case 2: + SoundEngine.PlaySound(new SoundStyle(ModAsset.vitalizedrocks_attack_3_Mod), Projectile.Center); + break; + case 3: + SoundEngine.PlaySound(new SoundStyle(ModAsset.vitalizedrocks_attack_4_Mod), Projectile.Center); + break; + } } } Lighting.AddLight(Projectile.Center, new Vector3(0.7f, 0.2f, 1f) * Projectile.ai[0] / 60f); diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/VitalizedRocksStone.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/VitalizedRocksStone.cs index 71be8bc62..3548b25b4 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/VitalizedRocksStone.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/VitalizedRocksStone.cs @@ -78,9 +78,17 @@ public override void OnKill(int timeLeft) d.velocity = new Vector2(0, Main.rand.NextFloat(2f, 11f)).RotatedByRandom(6.283); } GenerateSmog(12); - SoundEngine.PlaySound(SoundID.DD2_ExplosiveTrapExplode.WithVolume(0.5f), Projectile.Center); ShakerManager.AddShaker(Projectile.Center, new Vector2(0, -1), 1, 30, 120); Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center, Vector2.zeroVector, ModContent.ProjectileType(), (int)(Projectile.damage * 0.4f), Projectile.knockBack, Projectile.owner, 1f); + switch (Main.rand.Next(2)) + { + case 0: + SoundEngine.PlaySound(new SoundStyle(ModAsset.vitalizedrocks_hit_1_Mod), Projectile.Center); + break; + case 1: + SoundEngine.PlaySound(new SoundStyle(ModAsset.vitalizedrocks_hit_2_Mod), Projectile.Center); + break; + } } public void GenerateSmog(int Frequency) diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/YggdrasilAmberLaser_proj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/YggdrasilAmberLaser_proj.cs index 4b73d4aec..68977299f 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/YggdrasilAmberLaser_proj.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/YggdrasilAmberLaser_proj.cs @@ -1,4 +1,3 @@ -using System.Net; using Everglow.Commons.DataStructures; using Everglow.Commons.Templates.Weapons; using Everglow.Yggdrasil.YggdrasilTown.Dusts; @@ -225,7 +224,7 @@ public override bool PreDraw(ref Color lightColor) effect.CurrentTechnique.Passes[0].Apply(); Vector2 mouseToPlayer = new Vector2(0, 1).RotatedBy(Projectile.rotation - Math.PI * 0.75); float timeValue = (float)Main.time * 0.06f; - var bars = new List(); + int step = -6; while (!Collision.SolidCollision(Projectile.Center + mouseToPlayer * step * 8, 0, 0)) { @@ -235,16 +234,6 @@ public override bool PreDraw(ref Color lightColor) break; } Vector2 checkPoint = Projectile.Center + mouseToPlayer * step * 8; - Vector2 toMouseLeft = mouseToPlayer.RotatedBy(MathHelper.PiOver2); - float width = duration * 25; - Color drawColor = Color.White; - float mulWidth = 1f; - if (step + 4 <= 10) - { - mulWidth = MathF.Pow((step + 4) / 10f, 0.3f); - } - bars.Add(checkPoint + toMouseLeft * width, drawColor, new Vector3(step * 0.03f - timeValue, 0, mulWidth)); - bars.Add(checkPoint - toMouseLeft * width, drawColor, new Vector3(step * 0.03f - timeValue, 1, mulWidth)); if (!Main.gamePaused && Main.rand.NextBool(30)) { Vector2 newVelocity = mouseToPlayer.RotatedBy(Main.rand.NextFloat(-0.4f, 0.4f)) * 4f * duration; @@ -264,12 +253,7 @@ public override bool PreDraw(ref Color lightColor) MaxStep = step; EndPoint = Projectile.Center + MaxStep * mouseToPlayer * 8; } - if (bars.Count > 2) - { - Main.graphics.graphicsDevice.Textures[0] = Commons.ModAsset.Trail_1_black.Value; - Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); - } - bars = new List(); + var bars = new List(); step = -6; while (!Collision.SolidCollision(Projectile.Center + mouseToPlayer * step * 8, 0, 0)) { @@ -280,9 +264,9 @@ public override bool PreDraw(ref Color lightColor) } Vector2 checkPoint = Projectile.Center + mouseToPlayer * step * 8; Vector2 toMouseLeft = mouseToPlayer.RotatedBy(MathHelper.PiOver2); - float width = duration * duration * 25; + float width = 25f; float duration2 = Math.Max(duration, 0); - var drawColor = new Color(duration * 0.7f, duration2 * duration2 * 0.52f, 0, 0); + var drawColor = new Color(duration * 0.7f, duration2 * duration2 * 0.52f, 0, 0) * 0.1f; float mulWidth = 1f; if (step + 4 <= 10) { @@ -291,9 +275,25 @@ public override bool PreDraw(ref Color lightColor) bars.Add(checkPoint + toMouseLeft * width, drawColor, new Vector3(step * 0.03f - timeValue, 0, mulWidth)); bars.Add(checkPoint - toMouseLeft * width, drawColor, new Vector3(step * 0.03f - timeValue, 1, mulWidth)); } + for (int k = 0; k < 24; k++) + { + if (bars.Count <= k * 2) + { + break; + } + Vertex2D v0 = bars[^(k * 2 + 1)]; + Vertex2D v1 = bars[^(k * 2 + 2)]; + float value = 24 - k; + value /= 4f; + value += 1f; + v0 = new Vertex2D(v0.position, v0.color * value, v0.texCoord); + v1 = new Vertex2D(v1.position, v1.color * value, v1.texCoord); + bars[^(k * 2 + 1)] = v0; + bars[^(k * 2 + 2)] = v1; + } if (bars.Count > 2) { - Main.graphics.graphicsDevice.Textures[0] = Commons.ModAsset.Trail_1.Value; + Main.graphics.graphicsDevice.Textures[0] = Commons.ModAsset.Trail_10.Value; Main.graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap; Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/CeremonialBladeProj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/CeremonialBladeProj.cs index 5eee5d328..139e8e51d 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/CeremonialBladeProj.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/CeremonialBladeProj.cs @@ -311,7 +311,7 @@ public void DrawWarp(VFXBatch batch) strength *= 0; } float colorValue = MathF.Cos(Projectile.localAI[1] + MathF.PI); - strength *= (1 - Projectile.Opacity) * colorValue * 0.6f; + strength *= (1 - Projectile.Opacity) * colorValue * 0.2f; var colorWarp = new Color(dir.X, dir.Y, strength, 1); var colorWarpFade = new Color(dir.X, dir.Y, strength * 0.1f, 1); bladeEffect_Warp.Add(drawPos + edge, colorWarp, new Vector3(0.5f, coordY, 1)); diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangDust.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangDust.png new file mode 100644 index 000000000..3ab2dbd36 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangDust.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangProj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangProj.cs index 6ffdbbb03..db92bbf77 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangProj.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangProj.cs @@ -1,5 +1,6 @@ using Everglow.Yggdrasil.YggdrasilTown.VFXs; using Terraria.DataStructures; +using Terraria.WorldBuilding; namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Melee; @@ -33,6 +34,22 @@ public override bool OnTileCollide(Vector2 oldVelocity) } Projectile.velocity *= -1; Returning = true; + for (int i = 0; i < 24; i++) + { + var dustVFX = new MagicalBoomerangDust + { + velocity = new Vector2(0, Main.rand.NextFloat(6)).RotatedByRandom(MathHelper.TwoPi), + gravity = true, + Active = true, + Visible = true, + position = Projectile.Center, + maxTime = Main.rand.Next(20, 90), + scale = Main.rand.NextFloat(6, 12), + rotation = Main.rand.NextFloat(MathHelper.TwoPi), + ai = new float[] { 0, 0, 0 }, + }; + Ins.VFXManager.Add(dustVFX); + } return false; } @@ -80,7 +97,7 @@ public override void AI() Visible = true, position = Projectile.Center + vel / 5f * step, maxTime = Main.rand.Next(30, 46), - scale = Main.rand.NextFloat(3, 4), + scale = Main.rand.NextFloat(30, 40), rotation = Main.rand.NextFloat(MathHelper.TwoPi), ai = new float[] { 0, 0, 0 }, }; @@ -94,7 +111,7 @@ public override void AI() Visible = true, position = Projectile.Center + vel / 5f * step + vel.RotatedBy(1.2f) / 6f * distanceSide, maxTime = Main.rand.Next(30, 46), - scale = Main.rand.NextFloat(3, 4), + scale = Main.rand.NextFloat(30, 40), rotation = Main.rand.NextFloat(MathHelper.TwoPi), ai = new float[] { 0, 0, 0 }, }; @@ -106,7 +123,7 @@ public override void AI() Visible = true, position = Projectile.Center + vel / 5f * step + vel.RotatedBy(-1.2f) / 6f * distanceSide, maxTime = Main.rand.Next(30, 46), - scale = Main.rand.NextFloat(3, 4), + scale = Main.rand.NextFloat(30, 40), rotation = Main.rand.NextFloat(MathHelper.TwoPi), ai = new float[] { 0, 0, 0 }, }; @@ -123,6 +140,22 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { Returning = true; } + for (int i = 0; i < 48; i++) + { + var dustVFX = new MagicalBoomerangDust + { + velocity = new Vector2(0, Main.rand.NextFloat(8)).RotatedByRandom(MathHelper.TwoPi) + Projectile.velocity * 0.5f, + gravity = true, + Active = true, + Visible = true, + position = Projectile.Center, + maxTime = Main.rand.Next(20, 90), + scale = Main.rand.NextFloat(6, 12), + rotation = Main.rand.NextFloat(MathHelper.TwoPi), + ai = new float[] { 0, 0, 0 }, + }; + Ins.VFXManager.Add(dustVFX); + } base.OnHitNPC(target, hit, damageDone); } @@ -132,8 +165,21 @@ public override bool PreDraw(ref Color lightColor) { Texture2D boomerang = ModAsset.MagicalBoomerangProj.Value; Texture2D boomerangGlow = ModAsset.MagicalBoomerangProj_glow.Value; + Texture2D shape = ModAsset.MagicalBoomerangProj_shape.Value; + Texture2D bloom = ModAsset.MagicalBoomerangProj_bloom.Value; Main.EntitySpriteDraw(boomerang, Projectile.Center - Main.screenPosition, null, lightColor, Projectile.rotation, boomerang.Size() * 0.5f, Projectile.scale, SpriteEffects.None, 0); Main.EntitySpriteDraw(boomerangGlow, Projectile.Center - Main.screenPosition, null, new Color(0.3f, 0.7f, 1f, 0), Projectile.rotation, boomerangGlow.Size() * 0.5f, Projectile.scale, SpriteEffects.None, 0); + + float value = (30 - Timer) / 30f; + if (value > 0) + { + Main.EntitySpriteDraw(shape, Projectile.Center - Main.screenPosition, null, Color.Lerp(Color.White, new Color(0f, 0.2f, 0.8f, 1f), MathF.Pow(1 - value, 0.5f)) * value, Projectile.rotation, shape.Size() * 0.5f, Projectile.scale, SpriteEffects.None, 0); + } + value = (240 - Timer) / 240f; + if (value > 0) + { + Main.EntitySpriteDraw(bloom, Projectile.Center - Main.screenPosition, null, new Color(1f, 1f, 1f, 0) * value, Projectile.rotation, bloom.Size() * 0.5f, Projectile.scale, SpriteEffects.None, 0); + } return false; } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangProj_bloom.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangProj_bloom.png new file mode 100644 index 000000000..aff1b4290 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangProj_bloom.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangProj_shape.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangProj_shape.png new file mode 100644 index 000000000..03cbf606a Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangProj_shape.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangSubProj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangSubProj.cs index bf19f50da..8632304e6 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangSubProj.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangSubProj.cs @@ -1,10 +1,11 @@ +using Everglow.Yggdrasil.YggdrasilTown.VFXs; using Terraria.DataStructures; namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Melee; public class MagicalBoomerangSubProj : ModProjectile { - public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MeleeProjectiles; + public override string LocalizationCategory => LocalizationUtils.Categories.MeleeProjectiles; public override void SetDefaults() { @@ -41,6 +42,22 @@ public override bool OnTileCollide(Vector2 oldVelocity) } Projectile.tileCollide = false; Returning = true; + for (int i = 0; i < 16; i++) + { + var dustVFX = new MagicalBoomerangDust + { + velocity = new Vector2(0, Main.rand.NextFloat(4)).RotatedByRandom(MathHelper.TwoPi), + gravity = true, + Active = true, + Visible = true, + position = Projectile.Center, + maxTime = Main.rand.Next(20, 90), + scale = Main.rand.NextFloat(6, 12), + rotation = Main.rand.NextFloat(MathHelper.TwoPi), + ai = new float[] { 0, 0, 0 }, + }; + Ins.VFXManager.Add(dustVFX); + } return false; } @@ -69,7 +86,7 @@ public override void AI() } Projectile.velocity = Projectile.velocity * 0.9f + toPlayer.NormalizeSafe() * speed * 0.1f; } - Lighting.AddLight(Projectile.Center, new Vector3(0.3f, 0.7f, 1f) * 0.5f); + Lighting.AddLight(Projectile.Center, new Vector3(0.1f, 0.4f, 1.4f) * 0.5f); } public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) @@ -78,6 +95,22 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) { Returning = true; } + for (int i = 0; i < 32; i++) + { + var dustVFX = new MagicalBoomerangDust + { + velocity = new Vector2(0, Main.rand.NextFloat(8)).RotatedByRandom(MathHelper.TwoPi) + Projectile.velocity * 0.5f, + gravity = true, + Active = true, + Visible = true, + position = Projectile.Center, + maxTime = Main.rand.Next(20, 90), + scale = Main.rand.NextFloat(6, 12), + rotation = Main.rand.NextFloat(MathHelper.TwoPi), + ai = new float[] { 0, 0, 0 }, + }; + Ins.VFXManager.Add(dustVFX); + } base.OnHitNPC(target, hit, damageDone); } @@ -87,8 +120,20 @@ public override bool PreDraw(ref Color lightColor) { Texture2D boomerang = ModAsset.MagicalBoomerangSubProj.Value; Texture2D boomerangGlow = ModAsset.MagicalBoomerangSubProj_glow.Value; + Texture2D shape = ModAsset.MagicalBoomerangSubProj_shape.Value; + Texture2D bloom = ModAsset.MagicalBoomerangSubProj_bloom.Value; Main.EntitySpriteDraw(boomerang, Projectile.Center - Main.screenPosition, null, lightColor, Projectile.rotation, boomerang.Size() * 0.5f, Projectile.scale, SpriteEffects.None, 0); Main.EntitySpriteDraw(boomerangGlow, Projectile.Center - Main.screenPosition, null, new Color(0.3f, 0.7f, 1f, 0), Projectile.rotation, boomerangGlow.Size() * 0.5f, Projectile.scale, SpriteEffects.None, 0); + float value = (30 - Timer) / 30f; + if (value > 0) + { + Main.EntitySpriteDraw(shape, Projectile.Center - Main.screenPosition, null, Color.Lerp(Color.White, new Color(0f, 0.2f, 0.8f, 1f), MathF.Pow(1 - value, 0.5f)) * value, Projectile.rotation, shape.Size() * 0.5f, Projectile.scale, SpriteEffects.None, 0); + } + value = (240 - Timer) / 240f; + if (value > 0) + { + Main.EntitySpriteDraw(bloom, Projectile.Center - Main.screenPosition, null, new Color(1f, 1f, 1f, 0) * value, Projectile.rotation, bloom.Size() * 0.5f, Projectile.scale, SpriteEffects.None, 0); + } return false; } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangSubProj_bloom.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangSubProj_bloom.png new file mode 100644 index 000000000..95bf6f5c3 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangSubProj_bloom.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangSubProj_shape.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangSubProj_shape.png new file mode 100644 index 000000000..ddffb434c Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MagicalBoomerangSubProj_shape.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MechanismHalberd_Color.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MechanismHalberd_Color.png new file mode 100644 index 000000000..9241bbd9d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MechanismHalberd_Color.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MechanismHalberd_Proj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MechanismHalberd_Proj.cs new file mode 100644 index 000000000..22a44425f --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MechanismHalberd_Proj.cs @@ -0,0 +1,258 @@ +using Terraria.Audio; + +namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Melee; + +/// +/// 机关长戟的挥舞弹幕,继承自MeleeProj +/// +public class MechanismHalberd_Proj : MeleeProj +{ + public override void SetDef() + { + maxAttackType = 2; // 三段攻击 + maxSlashTrailLength = 18; // 拖尾长度 + longHandle = true; // 长柄武器 + shaderType = Commons.MEAC.Enums.MeleeTrailShaderType.ArcBladeTransparentedByZ; + autoEnd = false; // ä¸ä½¿ç”¨é»˜è®¤ç»“æŸæ”»å‡»é€»è¾‘ + canLongLeftClick = false; // ä¸éœ€è¦å·¦é”®è“„力 + } + + public override string TrailColorTex() => ModAsset.MechanismHalberd_Color_Mod; + + public override BlendState TrailBlendState() => BlendState.Additive; + + public override float TrailAlpha(float factor) => base.TrailAlpha(factor) * 1.5f; + + /// + /// 攻击效果 + /// + public override void Attack() + { + Player player = Main.player[Projectile.owner]; + TestPlayerDrawer Tplayer = player.GetModPlayer(); + Tplayer.HideLeg = true; + + useSlash = true; + + Vector2 vToMouse = Main.MouseWorld - player.Top; + float AddHeadRotation = (float)Math.Atan2(vToMouse.Y, vToMouse.X) + (1 - player.direction) * 1.57f; + if (player.gravDir == -1) + { + if (player.direction == -1) + { + if (AddHeadRotation >= 0.57f && AddHeadRotation < 2) + { + AddHeadRotation = 0.57f; + } + } + else + { + if (AddHeadRotation <= -0.57f) + { + AddHeadRotation = -0.57f; + } + } + } + else + { + if (player.direction == -1) + { + if (AddHeadRotation >= 2 && AddHeadRotation < 5.71f) + { + AddHeadRotation = 5.71f; + } + } + else + { + if (AddHeadRotation >= 0.57f) + { + AddHeadRotation = 0.57f; + } + } + } + + // 上劈 + if (currantAttackType == 0) + { + LockPlayerDir(player); + float rot = player.direction; + + if (timer == 8) + { + AttSound(new SoundStyle(Commons.ModAsset.TrueMeleeSwing_Mod)); + } + if (timer < 20) + { + useSlash = false; + + float rot0 = -MathHelper.PiOver2 - rot * 1.2f; + mainAxisDirection = Vector2.Lerp(mainAxisDirection, Vector2Elipse(100, rot0, -0.8f, rot), 0.15f); + Projectile.rotation = mainAxisDirection.ToRotation(); + } + if (timer > 20 && timer < 40) + { + canHit = true; + Lighting.AddLight(Projectile.Center + mainAxisDirection, 0.25f, 0.3f, 0.35f); + + Projectile.rotation -= Projectile.spriteDirection * 0.22f; + + mainAxisDirection = Vector2Elipse(120, Projectile.rotation, -0.8f, rot); + } + if (timer > 45) + { + NextAttackType(); + } + + if (canHit && Main.rand.NextBool(4)) + { + Vector2 offset = mainAxisDirection * Main.rand.NextFloat(0.3f, 0.9f); + Dust.NewDustPerfect(Projectile.Center + offset, DustID.Smoke, Main.rand.NextVector2Unit() * 1.5f, 0, new Color(180, 200, 220), 1.1f).noGravity = true; + } + } + + // 下劈 + else if (currantAttackType == 1) + { + LockPlayerDir(player); + float rot = player.direction; + + if (timer == 8) + { + AttSound(new SoundStyle(Commons.ModAsset.TrueMeleeSwing_Mod)); + } + if (timer < 18) + { + float rot0 = -MathHelper.PiOver2 + 0.8f * rot; + mainAxisDirection = Vector2.Lerp(mainAxisDirection, Vector2Elipse(60, rot0, -0.8f, rot), 0.15f); + useSlash = false; + Projectile.rotation = mainAxisDirection.ToRotation(); + } + if (timer > 18 && timer < 35) + { + Lighting.AddLight(Projectile.Center + mainAxisDirection, 0.4f, 0.4f, 0.25f); + canHit = true; + + Projectile.rotation += Projectile.spriteDirection * 0.3f; + + mainAxisDirection = Vector2Elipse(160, Projectile.rotation, -0.8f, rot); + } + if (timer > 45) + { + NextAttackType(); + } + } + + // 横劈 + else if (currantAttackType == 2) + { + LockPlayerDir(player); + float rot = player.direction; + + if (timer < 30) + { + if (timer == 6) + { + SoundEngine.PlaySound(SoundID.Item24 with { Volume = 2f }, Projectile.Center); + } + + useSlash = false; + canHit = false; + + float rot0 = -MathHelper.PiOver2 - 0.4f * rot; + mainAxisDirection = Vector2.Lerp(mainAxisDirection, Vector2Elipse(80, rot0, -1.3f, rot * 0.1f), 0.2f); + Projectile.rotation = mainAxisDirection.ToRotation(); + } + else if (timer == 30) + { + AttSound(new SoundStyle(Commons.ModAsset.TrueMeleePowerSwing_Mod) with { Volume = 1.4f }); + } + else if (timer > 30 && timer < 45) + { + canHit = true; + useSlash = true; + + Lighting.AddLight(Projectile.Center + mainAxisDirection, 0.2f, 0.4f, 0.8f); + + Projectile.rotation += Projectile.spriteDirection * 0.35f; + mainAxisDirection = Vector2Elipse(180, Projectile.rotation, -1.3f, rot * 0.1f); + + if (timer % 5 == 0) + { + Lighting.AddLight(Projectile.Center + mainAxisDirection * 0.5f, 0.3f, 0.5f, 0.9f); + } + } + else if (timer > 45) + { + End(); + } + } + } + + /// + /// å‡»ä¸­æ•Œäººæ¦‚çŽ‡æŽ‰å‡ºåˆºçƒ + /// + /// + /// + /// + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + SoundEngine.PlaySound(SoundID.Item74 with { Volume = 2f }, Projectile.Center); + + for (int i = 0; i < 8; i++) + { + float angle = MathHelper.TwoPi / 8f * i; + Vector2 dir = angle.ToRotationVector2(); + + Vector2 dustVel = dir * Main.rand.NextFloat(2.5f, 3.5f); + Dust d = Dust.NewDustPerfect( + target.Center, + DustID.Torch, + dustVel, + 100, + new Color(Main.rand.Next(220, 255), Main.rand.Next(100, 160), 30), + Main.rand.NextFloat(0.7f, 1f)); + + d.noGravity = true; + d.fadeIn = Main.rand.NextFloat(1.2f, 1.5f); + } + + Lighting.AddLight(target.Center, 0.3f, 0.5f, 0.8f); + if (Main.rand.NextBool(3)) + { + Player player = Main.player[Projectile.owner]; + if (Main.myPlayer == player.whoAmI) + { + Vector2 dir = (target.Center - Projectile.Center).SafeNormalize(Vector2.UnitX); + Vector2 spawnPos = target.Center + dir * (target.width * 0.6f + 20f); + float angle = Main.rand.NextFloat() * MathHelper.TwoPi; + Vector2 velocity = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle)); + Projectile.NewProjectile( + Projectile.GetSource_FromThis(), + spawnPos, + velocity, + ModContent.ProjectileType(), + Projectile.damage / 2, 1f, player.whoAmI); + SoundEngine.PlaySound(SoundID.Item9 with { Volume = 0.6f }, Projectile.Center); + } + } + } + + public override void End() + { + Player player = Main.player[Projectile.owner]; + TestPlayerDrawer Tplayer = player.GetModPlayer(); + player.legFrame = new Rectangle(0, 0, player.legFrame.Width, player.legFrame.Height); + player.fullRotation = 0; + player.legRotation = 0; + Tplayer.HeadRotation = 0; + Tplayer.HideLeg = false; + player.legPosition = Vector2.Zero; + Projectile.Kill(); + player.GetModPlayer().isUsingMeleeProj = false; + } + + public override void DrawTrail(Color color) + { + base.DrawTrail(color); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MechanismHalberd_Proj.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MechanismHalberd_Proj.png new file mode 100644 index 000000000..1cd6140f6 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MechanismHalberd_Proj.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MechanismSpike.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MechanismSpike.cs new file mode 100644 index 000000000..08b5cf2a6 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MechanismSpike.cs @@ -0,0 +1,187 @@ +using Terraria.Audio; + +namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Melee; + +/// +/// 机关长戟概率掉出的刺çƒå¼¹å¹• +/// +public class MechanismSpike : ModProjectile +{ + private int collideCount = 8; + private float _rotationSpeed; + private bool _initialized; + + private const int TrailLength = 15; + private Vector2[] _trailPositions = new Vector2[TrailLength]; + + private int _soundTimer; + + public override void SetDefaults() + { + Projectile.width = 28; + Projectile.height = 28; + Projectile.friendly = true; + Projectile.timeLeft = 300; + Projectile.tileCollide = true; + Projectile.DamageType = DamageClass.Melee; + Projectile.aiStyle = 0; + + ProjectileID.Sets.TrailCacheLength[Type] = TrailLength; + ProjectileID.Sets.TrailingMode[Type] = 0; + + Projectile.penetrate = 2; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = -1; + } + + public override void AI() + { + if (!_initialized) + { + _rotationSpeed = Main.rand.NextBool() ? 0.25f : -0.25f; + Projectile.velocity *= 25f; + _initialized = true; + } + else + { + Projectile.velocity.Y += 0.4f; + if (Projectile.velocity.Y > 16f) + { + Projectile.velocity.Y = 16f; + } + } + + Projectile.rotation += _rotationSpeed; + + Lighting.AddLight(Projectile.Center, 0.6f, 0.6f, 0.65f); + + if (++_soundTimer >= 12) + { + _soundTimer = 0; + SoundEngine.PlaySound(SoundID.Item24 with { Volume = 0.4f, Pitch = -0.2f }, Projectile.Center); + } + + if (Main.rand.NextBool(3)) // 控制密度,3 帧一次 + { + Vector2 tailDir = -Projectile.velocity.SafeNormalize(Vector2.UnitY); + Vector2 dustPos = Projectile.Center + tailDir * 10f; + Vector2 dustVel = tailDir * Main.rand.NextFloat(1f, 2.5f); + + Dust d = Dust.NewDustPerfect(dustPos, DustID.Torch, dustVel, 150, + new Color(Main.rand.Next(230, 255), Main.rand.Next(150, 190), 40), + Main.rand.NextFloat(0.5f, 0.7f)); + d.noGravity = true; + d.fadeIn = Main.rand.NextFloat(1.2f, 1.6f); + } + + for (int i = TrailLength - 1; i > 0; i--) + { + _trailPositions[i] = _trailPositions[i - 1]; + } + + _trailPositions[0] = Projectile.Center; + } + + public override bool OnTileCollide(Vector2 oldVelocity) + { + if (--collideCount == 0) + { + return true; + } + SoundEngine.PlaySound(SoundID.Item10 with { Volume = 0.6f }, Projectile.Center); + + if (Projectile.velocity.X != oldVelocity.X) + { + Projectile.velocity.X = -oldVelocity.X; + } + + if (Projectile.velocity.Y != oldVelocity.Y) + { + Projectile.velocity.Y = -oldVelocity.Y; + } + + Projectile.velocity *= 0.7f; + + for (int i = 0; i < 3; i++) + { + Vector2 vel = Main.rand.NextVector2Circular(2f, 2f); + var dust = Dust.NewDustPerfect(Projectile.Center, DustID.Silver, vel); + dust.noGravity = true; + dust.scale = Main.rand.NextFloat(0.4f, 0.8f); + } + + return false; + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + Projectile.localNPCImmunity[target.whoAmI] = 30; + target.immune[Projectile.owner] = 0; + + Projectile.penetrate--; + if (Projectile.penetrate <= 0) + { + Projectile.Kill(); + } + } + + public override bool? CanHitNPC(NPC target) + { + return Projectile.penetrate > 0; + } + + public override void OnKill(int timeLeft) + { + SoundEngine.PlaySound(SoundID.Item14 with { Volume = 0.6f, Pitch = -0.1f }, Projectile.Center); + + for (int i = 0; i < 10; i++) + { + Vector2 vel = Main.rand.NextVector2Circular(2f, 2f); + var dust = Dust.NewDustPerfect(Projectile.Center, DustID.Silver, vel); + dust.noGravity = true; + dust.scale = Main.rand.NextFloat(0.6f, 1.0f); + } + } + + public override bool PreDraw(ref Color lightColor) + { + Texture2D texture = ModContent.Request(Texture).Value; + Vector2 origin = texture.Size() / 2f; + + for (int i = 1; i < _trailPositions.Length; i++) + { + if (_trailPositions[i] == Vector2.Zero) + { + continue; + } + + float t = i / (float)_trailPositions.Length; + Color trailColor = Color.Lerp(Color.Silver, Color.Transparent, t) * 0.6f; + float scale = Projectile.scale * (1f - 0.6f * t); + + Main.spriteBatch.Draw( + texture, + _trailPositions[i] - Main.screenPosition, + null, + trailColor, + Projectile.rotation, + origin, + scale, + SpriteEffects.None, + 0f); + } + + Main.spriteBatch.Draw( + texture, + Projectile.Center - Main.screenPosition, + null, + Color.White, + Projectile.rotation, + origin, + Projectile.scale * 1.05f, + SpriteEffects.None, + 0f); + + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MechanismSpike.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MechanismSpike.png new file mode 100644 index 000000000..06e4e9b83 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/MechanismSpike.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/QuenchingBladeProj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/QuenchingBladeProj.cs index 5ca566c63..91a8fbbe5 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/QuenchingBladeProj.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/QuenchingBladeProj.cs @@ -76,6 +76,7 @@ public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) modifiers.FinalDamage *= 1.4f; ShakeStrength = 1f; } + modifiers.HitDirectionOverride = target.Center.X > Main.player[Projectile.owner].Center.X ? 1 : -1; ShakerManager.AddShaker(Projectile.Center, Vector2.One.RotatedByRandom(MathHelper.Pi), 10 * ShakeStrength, 20f, 120, 0.9f, 0.8f, 30); } @@ -102,7 +103,7 @@ public override void Attack() } if (timer == (int)(8 * timeMul)) { - AttSound(new SoundStyle(Commons.ModAsset.TrueMeleeSwing_Mod)); + PlayAttackSound(); } if (timer > 20 * timeMul && timer < 75 * timeMul) @@ -188,7 +189,7 @@ public override void Attack() } if (timer == (int)(8 * timeMul)) { - AttSound(new SoundStyle(Commons.ModAsset.TrueMeleeSwing_Mod)); + PlayAttackSound(); } if (timer > 20 * timeMul && timer < 75 * timeMul) @@ -274,7 +275,7 @@ public override void Attack() } if (timer == (int)(8 * timeMul)) { - AttSound(new SoundStyle(Commons.ModAsset.TrueMeleeSwing_Mod)); + PlayAttackSound(); } if (timer == (int)(24 * timeMul)) { @@ -369,7 +370,7 @@ public override void Attack() { dir = 3.5f; } - Projectile.NewProjectile(Projectile.GetSource_FromAI(), player.Center, Vector2.zeroVector, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner, 1.2f, dir); + Projectile.NewProjectile(Projectile.GetSource_FromAI(), player.Center, Vector2.zeroVector, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack * 10, Projectile.owner, 1.2f, dir); } if (timer > 110 * timeMul) { @@ -378,6 +379,25 @@ public override void Attack() } } + public void PlayAttackSound() + { + switch (Main.rand.Next(4)) + { + case 0: + AttSound(new SoundStyle(ModAsset.QuenchingBlade_attack_1_Mod)); + break; + case 1: + AttSound(new SoundStyle(ModAsset.QuenchingBlade_attack_2_Mod)); + break; + case 2: + AttSound(new SoundStyle(ModAsset.QuenchingBlade_attack_3_Mod)); + break; + case 3: + AttSound(new SoundStyle(ModAsset.QuenchingBlade_attack_4_Mod)); + break; + } + } + public override void DrawTrail(Color color) { List smoothTrail_current = GraphicsUtils.CatmullRom(slashTrail.ToList()); // 平滑 @@ -551,6 +571,7 @@ public override void DrawWarp(VFXBatch spriteBatch) { w *= (length - i - 1) / 10f; } + w *= 0.1f; float d = trail[i].ToRotation() + 3.14f + 1.57f; if (d > 6.28f) { diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/QuenchingBladeProj_Smash.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/QuenchingBladeProj_Smash.cs index df5e51f2b..a1fe8cce3 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/QuenchingBladeProj_Smash.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/QuenchingBladeProj_Smash.cs @@ -1,5 +1,7 @@ using Everglow.Commons.DataStructures; using Everglow.Yggdrasil.YggdrasilTown.VFXs; +using Microsoft.Xna.Framework.Media; +using Terraria.Audio; using Terraria.DataStructures; namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Melee; @@ -193,6 +195,24 @@ public void SmashEffect() { Player player = Main.player[Projectile.owner]; ShakerManager.AddShaker(Projectile.Center, Vector2.One.RotatedByRandom(MathHelper.Pi), 120, 30f, 200, 0.9f, 0.8f, 150); + switch (Main.rand.Next(2)) + { + case 0: + SoundEngine.PlaySound(new SoundStyle(ModAsset.QuenchingBlade_superattack_1_Mod), Projectile.Center); + break; + case 1: + SoundEngine.PlaySound(new SoundStyle(ModAsset.QuenchingBlade_superattack_2_Mod), Projectile.Center); + break; + } + var hitVFX = new QuenchingBlade_SmashVFX + { + Active = true, + Visible = true, + Position = Projectile.Center + FallingMove + new Vector2(240 * FirstDirection, 30), + Direction = FirstDirection, + }; + Ins.VFXManager.Add(hitVFX); + for (int g = 0; g < 24; g++) { Vector2 newVelocity = new Vector2(0, -(Main.rand.NextFloat(12f, 25f) + g * 8)).RotatedBy(Main.rand.NextFloat(-0.04f, 0.14f) + g / 24f * FirstDirection); @@ -250,6 +270,7 @@ public void SmashEffect() public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) { modifiers.FinalDamage *= 1.7f; + modifiers.HitDirectionOverride = target.Center.X > Main.player[Projectile.owner].Center.X ? 1 : -1; ShakerManager.AddShaker(Projectile.Center, Vector2.One.RotatedByRandom(MathHelper.Pi), 20, 20f, 120, 0.9f, 0.8f, 30); } @@ -448,7 +469,7 @@ public void DrawWarp(VFXBatch spriteBatch) { warpValue = i / 10f; } - warpValue *= 0.8f; + warpValue *= 0.08f; var drawColor0 = new Color(normal.X / 2f + 0.5f, normal.Y / 2f + 0.5f, warpValue, 1); var drawColor1 = new Color(normal.X / 2f + 0.5f, normal.Y / 2f + 0.5f, warpValue * 0.3f, 1); diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/ResistanceWireBayonet_proj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/ResistanceWireBayonet_proj.cs index 25d909b79..b37fc84b1 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/ResistanceWireBayonet_proj.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Melee/ResistanceWireBayonet_proj.cs @@ -44,22 +44,65 @@ public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) { rWB = player.HeldItem.ModItem as ResistanceWireBayonet; } - if (rWB != null) + if (rWB == null) { - if (rWB.Power > 10) - { - rWB.Power -= 10; - } - else + return; + } + if (rWB.Power > 10) + { + rWB.Power -= 10; + } + else + { + rWB.Power = 0; + } + } + + public override void DrawEffect(Color lightColor) + { + Player player = Main.player[Projectile.owner]; + ResistanceWireBayonet rWB = null; + if (player.HeldItem.ModItem is not null) + { + rWB = player.HeldItem.ModItem as ResistanceWireBayonet; + } + if (rWB == null) + { + return; + } + Power = rWB.Power; + GlowColor = Color.Lerp(Color.Transparent, new Color(255, 106, 0, 0), Power / 10f); + Texture2D Shadow = Commons.ModAsset.Star2_black.Value; + Texture2D light = Commons.ModAsset.StabbingProjectile.Value; + Vector2 drawOrigin = light.Size() / 2f; + Vector2 drawShadowOrigin = Shadow.Size() / 2f; + if (OldColorFactor > 0) + { + for (int f = MaxDarkAttackUnitCount - 1; f > -1; f--) { - rWB.Power = 0; + Main.spriteBatch.Draw(Shadow, DarkAttackEffect[f].Postion - Main.screenPosition, null, Color.White * (DarkAttackEffect[f].Color.A / 255f), DarkAttackEffect[f].Rotation, drawShadowOrigin, DarkAttackEffect[f].Size, SpriteEffects.None, 0f); + Color fadeLight = AttackColor * (DarkAttackEffect[f].Color.A / 255f); + fadeLight.A = 0; + fadeLight = fadeLight * OldLightColorValue * MathF.Pow(LightColorValueMultiplicative_Modifier, f); + fadeLight = new Color(lightColor.R / 255f * fadeLight.R / 255f, lightColor.G / 255f * fadeLight.G / 255f, lightColor.B / 255f * fadeLight.B / 255f, 0); + Main.spriteBatch.Draw(light, DarkAttackEffect[f].Postion - Main.screenPosition, null, fadeLight, DarkAttackEffect[f].Rotation, drawOrigin, DarkAttackEffect[f].Size, SpriteEffects.None, 0f); + if (GlowColor != Color.Transparent) + { + Main.spriteBatch.Draw(light, DarkAttackEffect[f].Postion - Main.screenPosition, null, GlowColor * MathF.Pow(FadeGlowColorValue, f), DarkAttackEffect[f].Rotation, drawShadowOrigin, DarkAttackEffect[f].Size, SpriteEffects.None, 0f); + } } } - base.ModifyHitNPC(target, ref modifiers); + if (CurrentColorFactor > 0) + { + Main.spriteBatch.Draw(Shadow, LightAttackEffect.Postion - Main.screenPosition, null, Color.White * CurrentColorFactor, LightAttackEffect.Rotation, drawShadowOrigin, LightAttackEffect.Size, SpriteEffects.None, 0f); + } + Main.spriteBatch.Draw(light, LightAttackEffect.Postion - Main.screenPosition, null, new Color(lightColor.R / 255f * AttackColor.R / 255f, lightColor.G / 255f * AttackColor.G / 255f, lightColor.B / 255f * AttackColor.B / 255f, 0), LightAttackEffect.Rotation, drawOrigin, LightAttackEffect.Size, SpriteEffects.None, 0f); + if (GlowColor != Color.Transparent) + { + Main.spriteBatch.Draw(light, LightAttackEffect.Postion - Main.screenPosition, null, GlowColor, LightAttackEffect.Rotation, drawShadowOrigin, LightAttackEffect.Size, SpriteEffects.None, 0f); + } } - public override void DrawEffect(Color lightColor) => base.DrawEffect(lightColor); - public override void DrawItem(Color lightColor) { base.DrawItem(lightColor); diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Miscs/ShadowDragonAttack.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Miscs/ShadowDragonAttack.cs new file mode 100644 index 000000000..a0f912b35 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Miscs/ShadowDragonAttack.cs @@ -0,0 +1,89 @@ +using Everglow.Commons.CustomTiles; +using Everglow.Commons.Templates.Weapons; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Miscs; + +public class ShadowDragonAttack : TrailingProjectile +{ + public override void SetCustomDefaults() + { + TrailTexture = Commons.ModAsset.Empty.Value; + TrailTextureBlack = Commons.ModAsset.Trail_8_black.Value; + Projectile.hostile = true; + Projectile.friendly = false; + } + + public override void Behaviors() + { + Projectile.rotation = Projectile.velocity.ToRotation(); + + // Dust + if (Main.rand.NextBool(6)) + { + var dark = new DarkDragon_Scene_Dust() + { + Position = Projectile.Center, + Velocity = Projectile.velocity * 0.2f, + Fade = 1, + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + Timer = 0, + MaxTime = 90, + MaxPosY = float.PositiveInfinity, + Frame = new Rectangle(Main.rand.Next(4) * 10, 10 + Main.rand.Next(3) * 10, 10, 10), + Scale = Main.rand.NextFloat(1.45f, 1.6f), + Active = true, + Visible = true, + MoveLogic = 1, + }; + Ins.VFXManager.Add(dark); + } + + // Chase + Player target = Main.LocalPlayer; + float minLength = 600; + foreach (var player in Main.player) + { + if (player is not null && player.active) + { + float distance = (player.Center - Projectile.Center).Length(); + if (distance < minLength) + { + minLength = distance; + target = player; + } + } + } + Vector2 toTarget = target.Center - Projectile.Center - Projectile.velocity; + if (toTarget.Length() > 600) + { + return; + } + toTarget = toTarget.NormalizeSafe(); + Projectile.velocity = toTarget * 0.02f + Projectile.velocity * 0.98f; + Projectile.velocity = Projectile.velocity.NormalizeSafe() * 3; + } + + public override void DestroyEntityEffect() + { + for (int k = 0; k < 30; k++) + { + var dark = new DarkDragon_Scene_Dust() + { + Position = Projectile.Center, + Velocity = new Vector2(0, Main.rand.NextFloat(3, 3.5f)).RotatedByRandom(MathHelper.TwoPi), + Fade = 1, + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + Timer = 0, + MaxTime = 90, + MaxPosY = float.PositiveInfinity, + Frame = new Rectangle(Main.rand.Next(4) * 10, 10 + Main.rand.Next(3) * 10, 10, 10), + Scale = Main.rand.NextFloat(1.45f, 1.6f), + Active = true, + Visible = true, + MoveLogic = 1, + }; + Ins.VFXManager.Add(dark); + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Miscs/ShadowDragonAttack.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Miscs/ShadowDragonAttack.png new file mode 100644 index 000000000..5d573a4a4 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Miscs/ShadowDragonAttack.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeProj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeProj.cs new file mode 100644 index 000000000..7dc85fa32 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeProj.cs @@ -0,0 +1,117 @@ +using Terraria.Audio; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Ranged; + +public class ChainGrenadeProj : ModProjectile +{ + public override string LocalizationCategory => LocalizationUtils.Categories.RangedProjectiles; + + public override void SetDefaults() + { + Projectile.timeLeft = 360; + Projectile.aiStyle = -1; + Projectile.friendly = true; + Projectile.penetrate = 1; + Projectile.tileCollide = true; + Projectile.ignoreWater = true; + Projectile.DamageType = DamageClass.Ranged; + Projectile.width = 12; + Projectile.height = 12; + ProjectileID.Sets.PlayerHurtDamageIgnoresDifficultyScaling[Type] = true; + Timer = 0; + } + + public float Omega = 0; + + public int Timer = 0; + + public override bool OnTileCollide(Vector2 oldVelocity) + { + if (Projectile.velocity.Length() < 3) + { + Projectile.velocity *= 0; + if (Math.Abs(Projectile.rotation % MathHelper.PiOver2 - MathHelper.PiOver4) > 0.05) + { + Projectile.rotation = Main.rand.Next(4) * MathHelper.PiOver2 + MathHelper.PiOver4; + } + Omega = 0; + } + else + { + if (Projectile.velocity.X != oldVelocity.X) + { + Projectile.velocity.X = -oldVelocity.X; + } + + if (Projectile.velocity.Y != oldVelocity.Y) + { + Projectile.velocity.Y = -oldVelocity.Y; + } + + Projectile.velocity *= 0.6f; + Omega = Main.rand.NextFloat(-0.3f, .3f) * Projectile.velocity.Length() / 12f; + } + return false; + } + + public override void OnSpawn(IEntitySource source) + { + Omega = Main.rand.NextFloat(-0.3f, .3f); + } + + public override void AI() + { + Timer++; + if (!Collision.SolidCollision(Projectile.position, Projectile.width, Projectile.height)) + { + Projectile.velocity.Y += 0.25f; + } + else + { + } + Projectile.rotation += Omega; + if (Projectile.velocity.Length() < 0.3f) + { + foreach (NPC npc in Main.npc) + { + if (npc != null && npc.active && !npc.friendly && !npc.dontTakeDamage) + { + if ((npc.Center - Projectile.Center).Length() < 80) + { + Projectile.Kill(); + } + } + } + } + } + + public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) + { + modifiers._combatTextHidden = true; + modifiers.FinalDamage *= 0; + base.ModifyHitNPC(target, ref modifiers); + } + + public override void OnKill(int timeLeft) + { + if (Main.myPlayer == Projectile.owner) + { + Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center, Vector2.zeroVector, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner); + for (int i = 0; i < 3; i++) + { + Projectile proj = Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center, new Vector2(0, Main.rand.NextFloat(4, 12)).RotatedByRandom(MathHelper.TwoPi), ModContent.ProjectileType(), (int)(Projectile.damage * 0.6f), Projectile.knockBack, Projectile.owner); + proj.timeLeft = Main.rand.Next(14, 30); + } + SoundEngine.PlaySound(SoundID.DD2_BetsyFireballImpact, Projectile.Center); + } + base.OnKill(timeLeft); + } + + public override bool PreDraw(ref Color lightColor) + { + Texture2D tex = (Texture2D)ModContent.Request(Texture); + Main.EntitySpriteDraw(tex, Projectile.Center - Main.screenPosition, null, lightColor, Projectile.rotation, tex.Size() * 0.5f, Projectile.scale, SpriteEffects.None, 0); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeProj.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeProj.png new file mode 100644 index 000000000..e32f49b84 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeProj.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeProjExplosion.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeProjExplosion.cs new file mode 100644 index 000000000..7cae0fdd5 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeProjExplosion.cs @@ -0,0 +1,276 @@ +using Everglow.Commons.DataStructures; +using Everglow.Commons.VFX.CommonVFXDusts; +using Everglow.Yggdrasil.CityOfMagicFlute.VFXs; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Ranged; + +public class ChainGrenadeProjExplosion : ModProjectile, IWarpProjectile +{ + public override string LocalizationCategory => LocalizationUtils.Categories.RangedProjectiles; + + public override void SetDefaults() + { + Projectile.width = 160; + Projectile.height = 160; + Projectile.friendly = true; + Projectile.hostile = true; + Projectile.aiStyle = -1; + Projectile.penetrate = -1; + Projectile.timeLeft = 200; + Projectile.tileCollide = false; + Projectile.extraUpdates = 3; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 20; + Projectile.DamageType = DamageClass.Ranged; + ProjectileID.Sets.PlayerHurtDamageIgnoresDifficultyScaling[Type] = true; + Timer = 0; + } + + public int Timer = 0; + + public override void DrawBehind(int index, List behindNPCsAndTiles, List behindNPCs, List behindProjectiles, List overPlayers, List overWiresUI) + { + behindNPCsAndTiles.Add(index); + base.DrawBehind(index, behindNPCsAndTiles, behindNPCs, behindProjectiles, overPlayers, overWiresUI); + } + + public override void OnSpawn(IEntitySource source) + { + } + + public void LargeFlame(int count) + { + for (int x = 0; x < count; x++) + { + Vector2 newVelocity = new Vector2(0, MathF.Sqrt(Main.rand.NextFloat(1f)) * 8f).RotatedByRandom(MathHelper.TwoPi); + var somg = new MissleFlameDust + { + velocity = newVelocity, + Active = true, + Visible = true, + position = Projectile.Center + new Vector2(Main.rand.NextFloat(6), 0).RotatedByRandom(6.283), + maxTime = Main.rand.Next(90, 120), + scale = Main.rand.NextFloat(24f, 36f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), 0 }, + }; + Ins.VFXManager.Add(somg); + } + } + + public void SmallFlame(int count) + { + for (int x = 0; x < count; x++) + { + Vector2 newVelocity = new Vector2(0, MathF.Sqrt(Main.rand.NextFloat(1f)) * 4f).RotatedByRandom(MathHelper.TwoPi); + var somg = new MissleFlameDust + { + velocity = newVelocity, + Active = true, + Visible = true, + position = Projectile.Center + new Vector2(Main.rand.NextFloat(4), 0).RotatedByRandom(6.283), + maxTime = Main.rand.Next(50, 70), + scale = Main.rand.NextFloat(12f, 20f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), 0 }, + }; + Ins.VFXManager.Add(somg); + } + } + + public void FlameII(int count) + { + for (int x = 0; x < count; x++) + { + var newVelocity = new Vector2(0, -10); + Vector2 addPos = new Vector2(Main.rand.NextFloat(40), 0).RotatedByRandom(MathHelper.TwoPi); + var fire = new FireDust + { + velocity = newVelocity, + Active = true, + Visible = true, + position = Projectile.Center + addPos - newVelocity, + maxTime = Main.rand.Next(30, 45), + scale = Main.rand.NextFloat(20f, 60f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), addPos.X * 0.002f }, + }; + Ins.VFXManager.Add(fire); + } + } + + public void Spark(int count) + { + for (int x = 0; x < count; x++) + { + Vector2 newVelocity = new Vector2(0, Main.rand.NextFloat(2f, 22f)).RotatedByRandom(MathHelper.TwoPi); + var spark = new FireSparkDust + { + velocity = newVelocity, + Active = true, + Visible = true, + position = Projectile.Center + new Vector2(Main.rand.NextFloat(20), 0).RotatedByRandom(6.283) + newVelocity * 3, + maxTime = Main.rand.Next(10, 20), + scale = Main.rand.NextFloat(0.1f, Main.rand.NextFloat(1f, 25.0f)), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), Main.rand.NextFloat(-0.01f, 0.01f) }, + }; + Ins.VFXManager.Add(spark); + } + } + + public override void AI() + { + Timer++; + if (Timer > 5) + { + Projectile.friendly = false; + } + Projectile.hide = true; + Projectile.velocity *= 0; + if (Timer == 10) + { + Spark(120); + LargeFlame(35); + SmallFlame(75); + } + + if (Timer == 20) + { + FlameII(35); + } + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + float range = 120; + bool bool0 = (targetHitbox.TopLeft() - projHitbox.Center()).Length() < range; + bool bool1 = (targetHitbox.TopRight() - projHitbox.Center()).Length() < range; + bool bool2 = (targetHitbox.BottomLeft() - projHitbox.Center()).Length() < range; + bool bool3 = (targetHitbox.BottomRight() - projHitbox.Center()).Length() < range; + return bool0 || bool1 || bool2 || bool3; + } + + public void DrawWarp(VFXBatch spriteBatch) + { + // TODO : Bug + // var drawPos = Projectile.Center - Main.screenPosition; + // var duration = Timer / 200f; + // var fade = Projectile.timeLeft / 200f; + // var drawScale = MathHelper.Lerp(1f, 9f, duration); + // var drawSize = MathF.Sqrt(Projectile.width / 2 * drawScale) * 0.27f; + // var timeValue = (float)Main.timeForVisualEffects * 0.003f; + // float resolutionCircle = 50; + // var bars = new List(); + // var bars2 = new List(); + // for (int i = 0; i <= resolutionCircle; i++) + // { + // var radiusInner = new Vector2(0, 4 * drawSize).RotatedBy(i / resolutionCircle * MathHelper.TwoPi); + // var radiusMiddle = new Vector2(0, 24 * drawSize).RotatedBy(i / resolutionCircle * MathHelper.TwoPi); + // var radiusOuter = new Vector2(0, 90 * drawSize).RotatedBy(i / resolutionCircle * MathHelper.TwoPi); + + // float rot = MathHelper.PiOver2; + + // Vector2 dirInner = new Vector2(1, 0).RotatedBy(i / resolutionCircle * MathHelper.TwoPi + rot); + // Vector2 dirMiddle = dirInner.NormalizeSafe(); + // Vector2 dirOuter = dirMiddle.NormalizeSafe(); + + // var colorInner = new Color(-dirInner.X * 0.5f + 0.5f, -dirInner.Y * 0.5f + 0.5f, 0, 0); + // var colorMiddle = new Color(-dirMiddle.X * 0.5f + 0.5f, -dirMiddle.Y * 0.5f + 0.5f, fade * 1.2f, 0); + // var colorOuter = new Color(-dirOuter.X * 0.5f + 0.5f, -dirOuter.Y * 0.5f + 0.5f, 0, 0); + // bars.Add(drawPos + radiusMiddle, colorMiddle, new Vector3(timeValue, i / 50f, 1)); + // bars.Add(drawPos + radiusInner, colorInner, new Vector3(timeValue + 0.15f, i / 50f, 1)); + + // bars2.Add(drawPos + radiusMiddle, colorMiddle, new Vector3(timeValue, i / 50f, 1)); + // bars2.Add(drawPos + radiusOuter, colorOuter, new Vector3(timeValue - 0.15f, i / 50f, 1)); + // } + // Main.graphics.graphicsDevice.BlendState = BlendState.NonPremultiplied; + // Main.graphics.graphicsDevice.SamplerStates[0] = SamplerState.PointWrap; + // Main.graphics.graphicsDevice.RasterizerState = RasterizerState.CullNone; + // if (bars.Count > 2) + // { + // spriteBatch.Draw(Commons.ModAsset.Noise_melting_H.Value, bars, PrimitiveType.TriangleStrip); + // } + // if (bars2.Count > 2) + // { + // spriteBatch.Draw(Commons.ModAsset.Noise_melting_H.Value, bars2, PrimitiveType.TriangleStrip); + // } + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + base.OnHitNPC(target, hit, damageDone); + } + + public override void OnKill(int timeLeft) => base.OnKill(timeLeft); + + public override bool PreDraw(ref Color lightColor) + { + var drawPos = Projectile.Center - Main.screenPosition; + var duration = Timer / 200f; + var fade = Projectile.timeLeft / 200f; + var drawScale = MathHelper.Lerp(1f, 9f, duration); + var drawSize = MathF.Sqrt(Projectile.width / 2 * drawScale) * 0.12f; + var timeValue = MathF.Pow(Timer, 0.5f) * 0.03f; + float resolutionCircle = 50; + var bars = new List(); + var bars2 = new List(); + + var bars_dark = new List(); + var bars2_dark = new List(); + for (int i = 0; i <= resolutionCircle; i++) + { + var radiusInner = new Vector2(0, 4 * drawSize).RotatedBy(i / resolutionCircle * MathHelper.TwoPi); + var radiusMiddle = new Vector2(0, 24 * drawSize).RotatedBy(i / resolutionCircle * MathHelper.TwoPi) - Projectile.velocity; + var radiusOuter = new Vector2(0, 90 * drawSize).RotatedBy(i / resolutionCircle * MathHelper.TwoPi) - Projectile.velocity * 2; + var colorInner = new Color(0, 0, 0, 0); + Color colorMiddle = new Color(fade, MathF.Pow(fade, 2) * 0.6f, MathF.Pow(fade, 3) * 0.4f, 0) * MathF.Pow(fade, 0.5f); + Color colorMiddle_dark = Color.White * MathF.Pow(fade, 0.85f); + var colorOuter = new Color(0, 0, 0, 0); + + bars.Add(drawPos + radiusMiddle, colorMiddle, new Vector3(i / 50f, timeValue, 1)); + bars.Add(drawPos + radiusInner, colorInner, new Vector3(i / 50f, timeValue + 0.15f, 1)); + + bars2.Add(drawPos + radiusMiddle, colorMiddle, new Vector3(i / 50f, timeValue, 1)); + bars2.Add(drawPos + radiusOuter, colorOuter, new Vector3(i / 50f, timeValue - 0.15f, 1)); + + bars_dark.Add(drawPos + radiusMiddle, colorMiddle_dark, new Vector3(i / 50f, timeValue, 1)); + bars_dark.Add(drawPos + radiusInner, colorInner, new Vector3(i / 50f, timeValue + 0.15f, 1)); + + bars2_dark.Add(drawPos + radiusMiddle, colorMiddle_dark, new Vector3(i / 50f, timeValue, 1)); + bars2_dark.Add(drawPos + radiusOuter, colorOuter, new Vector3(i / 50f, timeValue - 0.15f, 1)); + } + + SpriteBatchState sBS = Main.spriteBatch.GetState().Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + Main.graphics.graphicsDevice.Textures[0] = Commons.ModAsset.Noise_melting_black.Value; + if (bars_dark.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_dark.ToArray(), 0, bars_dark.Count - 2); + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_dark.ToArray(), 0, bars_dark.Count - 2); + } + + if (bars2_dark.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars2_dark.ToArray(), 0, bars2_dark.Count - 2); + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars2_dark.ToArray(), 0, bars2_dark.Count - 2); + } + Main.graphics.graphicsDevice.Textures[0] = Commons.ModAsset.Noise_melting.Value; + if (bars.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + + if (bars2.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars2.ToArray(), 0, bars2.Count - 2); + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars2.ToArray(), 0, bars2.Count - 2); + } + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeProjExplosion.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeProjExplosion.png new file mode 100644 index 000000000..8ff673f28 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeProjExplosion.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeSub_Proj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeSub_Proj.cs new file mode 100644 index 000000000..75d2f5267 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeSub_Proj.cs @@ -0,0 +1,112 @@ +using Terraria.Audio; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Ranged; + +public class ChainGrenadeSub_Proj : ModProjectile +{ + public override string LocalizationCategory => LocalizationUtils.Categories.RangedProjectiles; + + public override void SetDefaults() + { + Projectile.timeLeft = 360; + Projectile.aiStyle = -1; + Projectile.friendly = false; + Projectile.penetrate = 1; + Projectile.tileCollide = true; + Projectile.ignoreWater = true; + Projectile.DamageType = DamageClass.Ranged; + Projectile.width = 12; + Projectile.height = 12; + ProjectileID.Sets.PlayerHurtDamageIgnoresDifficultyScaling[Type] = true; + Timer = 0; + } + + public float Omega = 0; + + public int Timer = 0; + + public override bool OnTileCollide(Vector2 oldVelocity) + { + if (Projectile.velocity.Length() < 3) + { + Projectile.velocity *= 0; + Omega = 0; + } + else + { + if (Projectile.velocity.X != oldVelocity.X) + { + Projectile.velocity.X = -oldVelocity.X; + } + + if (Projectile.velocity.Y != oldVelocity.Y) + { + Projectile.velocity.Y = -oldVelocity.Y; + } + + Projectile.velocity *= 0.6f; + Omega = Main.rand.NextFloat(-0.3f, .3f) * Projectile.velocity.Length() / 12f; + } + return false; + } + + public override void OnSpawn(IEntitySource source) + { + Omega = Main.rand.NextFloat(-0.3f, .3f); + } + + public override void AI() + { + Timer++; + if (Timer > 5) + { + Projectile.friendly = true; + } + if (!Collision.SolidCollision(Projectile.position, Projectile.width, Projectile.height)) + { + Projectile.velocity.Y += 0.25f; + } + else + { + } + Projectile.rotation += Omega; + if (Projectile.velocity.Length() < 0.3f) + { + foreach (NPC npc in Main.npc) + { + if (npc != null && npc.active && !npc.friendly && !npc.dontTakeDamage) + { + if ((npc.Center - Projectile.Center).Length() < 80) + { + Projectile.Kill(); + } + } + } + } + } + + public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers) + { + modifiers._combatTextHidden = true; + modifiers.FinalDamage *= 0; + base.ModifyHitNPC(target, ref modifiers); + } + + public override void OnKill(int timeLeft) + { + if (Main.myPlayer == Projectile.owner) + { + SoundEngine.PlaySound(SoundID.DD2_GoblinBomb.WithVolume(0.5f), Projectile.Center); + Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center, Vector2.zeroVector, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner); + } + base.OnKill(timeLeft); + } + + public override bool PreDraw(ref Color lightColor) + { + Texture2D tex = (Texture2D)ModContent.Request(Texture); + Main.EntitySpriteDraw(tex, Projectile.Center - Main.screenPosition, null, lightColor, Projectile.rotation, tex.Size() * 0.5f, Projectile.scale, SpriteEffects.None, 0); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeSub_Proj.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeSub_Proj.png new file mode 100644 index 000000000..0db88ad35 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeSub_Proj.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeSub_ProjExplosion.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeSub_ProjExplosion.cs new file mode 100644 index 000000000..a7436b497 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeSub_ProjExplosion.cs @@ -0,0 +1,278 @@ +using Everglow.Commons.DataStructures; +using Everglow.Commons.VFX.CommonVFXDusts; +using Everglow.Yggdrasil.CityOfMagicFlute.VFXs; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Ranged; + +public class ChainGrenadeSub_ProjExplosion : ModProjectile, IWarpProjectile +{ + public override string LocalizationCategory => LocalizationUtils.Categories.RangedProjectiles; + + public override void SetDefaults() + { + Projectile.width = 160; + Projectile.height = 160; + Projectile.friendly = true; + Projectile.hostile = true; + Projectile.aiStyle = -1; + Projectile.penetrate = -1; + Projectile.timeLeft = 200; + Projectile.tileCollide = false; + Projectile.extraUpdates = 3; + Projectile.usesLocalNPCImmunity = true; + Projectile.localNPCHitCooldown = 20; + Projectile.DamageType = DamageClass.Ranged; + ProjectileID.Sets.PlayerHurtDamageIgnoresDifficultyScaling[Type] = true; + + Timer = 0; + } + + public int Timer = 0; + + public override void DrawBehind(int index, List behindNPCsAndTiles, List behindNPCs, List behindProjectiles, List overPlayers, List overWiresUI) + { + behindNPCsAndTiles.Add(index); + base.DrawBehind(index, behindNPCsAndTiles, behindNPCs, behindProjectiles, overPlayers, overWiresUI); + } + + public override void OnSpawn(IEntitySource source) + { + } + + public void LargeFlame(int count) + { + for (int x = 0; x < count; x++) + { + Vector2 newVelocity = new Vector2(0, MathF.Sqrt(Main.rand.NextFloat(1f)) * 6f).RotatedByRandom(MathHelper.TwoPi); + var somg = new MissleFlameDust + { + velocity = newVelocity, + Active = true, + Visible = true, + position = Projectile.Center + new Vector2(Main.rand.NextFloat(6), 0).RotatedByRandom(6.283), + maxTime = Main.rand.Next(70, 90), + scale = Main.rand.NextFloat(18f, 24f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), 0 }, + }; + Ins.VFXManager.Add(somg); + } + } + + public void SmallFlame(int count) + { + for (int x = 0; x < count; x++) + { + Vector2 newVelocity = new Vector2(0, MathF.Sqrt(Main.rand.NextFloat(1f)) * 3f).RotatedByRandom(MathHelper.TwoPi); + var somg = new MissleFlameDust + { + velocity = newVelocity, + Active = true, + Visible = true, + position = Projectile.Center + new Vector2(Main.rand.NextFloat(4), 0).RotatedByRandom(6.283), + maxTime = Main.rand.Next(40, 60), + scale = Main.rand.NextFloat(8f, 15f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), 0 }, + }; + Ins.VFXManager.Add(somg); + } + } + + public void FlameII(int count) + { + for (int x = 0; x < count; x++) + { + var newVelocity = new Vector2(0, -6); + Vector2 addPos = new Vector2(Main.rand.NextFloat(20), 0).RotatedByRandom(MathHelper.TwoPi); + var fire = new FireDust + { + velocity = newVelocity, + Active = true, + Visible = true, + position = Projectile.Center + addPos - newVelocity, + maxTime = Main.rand.Next(20, 35), + scale = Main.rand.NextFloat(15f, 40f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), addPos.X * 0.002f }, + }; + Ins.VFXManager.Add(fire); + } + } + + public void Spark(int count) + { + for (int x = 0; x < count; x++) + { + Vector2 newVelocity = new Vector2(0, Main.rand.NextFloat(2f, 11f)).RotatedByRandom(MathHelper.TwoPi); + var spark = new FireSparkDust + { + velocity = newVelocity, + Active = true, + Visible = true, + position = Projectile.Center + new Vector2(Main.rand.NextFloat(20), 0).RotatedByRandom(6.283) + newVelocity * 3, + maxTime = Main.rand.Next(10, 20), + scale = Main.rand.NextFloat(0.1f, Main.rand.NextFloat(1f, 25.0f)), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(0.0f, 0.93f), Main.rand.NextFloat(-0.01f, 0.01f) }, + }; + Ins.VFXManager.Add(spark); + } + } + + public override void AI() + { + Timer++; + if (Timer > 5) + { + Projectile.friendly = false; + } + Projectile.hide = true; + Projectile.velocity *= 0; + if (Timer == 10) + { + Spark(60); + LargeFlame(18); + SmallFlame(37); + } + + if (Timer == 20) + { + FlameII(18); + } + } + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) + { + float range = 60; + bool bool0 = (targetHitbox.TopLeft() - projHitbox.Center()).Length() < range; + bool bool1 = (targetHitbox.TopRight() - projHitbox.Center()).Length() < range; + bool bool2 = (targetHitbox.BottomLeft() - projHitbox.Center()).Length() < range; + bool bool3 = (targetHitbox.BottomRight() - projHitbox.Center()).Length() < range; + return bool0 || bool1 || bool2 || bool3; + } + + public void DrawWarp(VFXBatch spriteBatch) + { + // var drawPos = Projectile.Center - Main.screenPosition; + // var duration = 1 - Projectile.timeLeft / 120f; + // var fade = Projectile.timeLeft / 120f; + // var drawScale = MathHelper.Lerp(1f, 9f, duration); + // var drawSize = MathF.Sqrt(Projectile.width / 2 * drawScale) * 0.27f; + // var timeValue = (float)Main.timeForVisualEffects * 0.003f; + // float resolutionCircle = 50; + // var bars = new List(); + // var bars2 = new List(); + // for (int i = 0; i <= resolutionCircle; i++) + // { + // var radiusInner = new Vector2(0, 4 * drawSize).RotatedBy(i / resolutionCircle * MathHelper.TwoPi); + // var radiusMiddle = new Vector2(0, 18 * drawSize).RotatedBy(i / resolutionCircle * MathHelper.TwoPi) - Projectile.velocity; + // var radiusOuter = new Vector2(0, 50 * drawSize).RotatedBy(i / resolutionCircle * MathHelper.TwoPi) - Projectile.velocity * 2; + + // float rot = MathHelper.PiOver2; + + // Vector2 dirInner = new Vector2(1, 0).RotatedBy(i / resolutionCircle * MathHelper.TwoPi + rot); + // Vector2 dirMiddle = (dirInner - Projectile.velocity.NormalizeSafe() * 0.15f).NormalizeSafe(); + // Vector2 dirOuter = (dirMiddle - Projectile.velocity.NormalizeSafe() * 0.15f).NormalizeSafe(); + + // var colorInner = new Color(-dirInner.X * 0.5f + 0.5f, -dirInner.Y * 0.5f + 0.5f, 0, 0); + // var colorMiddle = new Color(-dirMiddle.X * 0.5f + 0.5f, -dirMiddle.Y * 0.5f + 0.5f, fade * 1.2f * Main.GameViewMatrix.Zoom.X, 0); + // var colorOuter = new Color(-dirOuter.X * 0.5f + 0.5f, -dirOuter.Y * 0.5f + 0.5f, 0, 0); + + // bars.Add(drawPos + radiusMiddle, colorMiddle, new Vector3(timeValue, i / 50f, 1)); + // bars.Add(drawPos + radiusInner, colorInner, new Vector3(timeValue + 0.15f, i / 50f, 1)); + + // bars2.Add(drawPos + radiusMiddle, colorMiddle, new Vector3(timeValue, i / 50f, 1)); + // bars2.Add(drawPos + radiusOuter, colorOuter, new Vector3(timeValue - 0.15f, i / 50f, 1)); + // } + // if (bars.Count > 2) + // { + // Main.graphics.graphicsDevice.SamplerStates[0] = SamplerState.PointWrap; + // Main.graphics.graphicsDevice.RasterizerState = RasterizerState.CullNone; + // spriteBatch.Draw(Commons.ModAsset.Noise_melting_H.Value, bars, PrimitiveType.TriangleStrip); + // } + // if (bars2.Count > 2) + // { + // Main.graphics.graphicsDevice.SamplerStates[0] = SamplerState.PointWrap; + // Main.graphics.graphicsDevice.RasterizerState = RasterizerState.CullNone; + // spriteBatch.Draw(Commons.ModAsset.Noise_melting_H.Value, bars2, PrimitiveType.TriangleStrip); + // } + } + + public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone) + { + base.OnHitNPC(target, hit, damageDone); + } + + public override void OnKill(int timeLeft) => base.OnKill(timeLeft); + + public override bool PreDraw(ref Color lightColor) + { + var drawPos = Projectile.Center - Main.screenPosition; + var duration = Timer / 200f; + var fade = Projectile.timeLeft / 200f; + var drawScale = MathHelper.Lerp(1f, 9f, duration); + var drawSize = MathF.Sqrt(Projectile.width / 2 * drawScale) * 0.1f; + var timeValue = MathF.Pow(Timer, 0.5f) * 0.03f; + float resolutionCircle = 50; + var bars = new List(); + var bars2 = new List(); + + var bars_dark = new List(); + var bars2_dark = new List(); + for (int i = 0; i <= resolutionCircle; i++) + { + var radiusInner = new Vector2(0, 4 * drawSize).RotatedBy(i / resolutionCircle * MathHelper.TwoPi); + var radiusMiddle = new Vector2(0, 18 * drawSize).RotatedBy(i / resolutionCircle * MathHelper.TwoPi) - Projectile.velocity; + var radiusOuter = new Vector2(0, 50 * drawSize).RotatedBy(i / resolutionCircle * MathHelper.TwoPi) - Projectile.velocity * 2; + var colorInner = new Color(0, 0, 0, 0); + Color colorMiddle = new Color(fade, MathF.Pow(fade, 2) * 0.6f, MathF.Pow(fade, 3) * 0.4f, 0) * MathF.Pow(fade, 0.5f); + Color colorMiddle_dark = Color.White * MathF.Pow(fade, 0.85f); + var colorOuter = new Color(0, 0, 0, 0); + + bars.Add(drawPos + radiusMiddle, colorMiddle, new Vector3(i / 50f, timeValue, 1)); + bars.Add(drawPos + radiusInner, colorInner, new Vector3(i / 50f, timeValue + 0.15f, 1)); + + bars2.Add(drawPos + radiusMiddle, colorMiddle, new Vector3(i / 50f, timeValue, 1)); + bars2.Add(drawPos + radiusOuter, colorOuter, new Vector3(i / 50f, timeValue - 0.15f, 1)); + + bars_dark.Add(drawPos + radiusMiddle, colorMiddle_dark, new Vector3(i / 50f, timeValue, 1)); + bars_dark.Add(drawPos + radiusInner, colorInner, new Vector3(i / 50f, timeValue + 0.15f, 1)); + + bars2_dark.Add(drawPos + radiusMiddle, colorMiddle_dark, new Vector3(i / 50f, timeValue, 1)); + bars2_dark.Add(drawPos + radiusOuter, colorOuter, new Vector3(i / 50f, timeValue - 0.15f, 1)); + } + + SpriteBatchState sBS = Main.spriteBatch.GetState().Value; + Main.spriteBatch.End(); + Main.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointWrap, DepthStencilState.None, RasterizerState.CullNone, null, Main.GameViewMatrix.TransformationMatrix); + Main.graphics.graphicsDevice.Textures[0] = Commons.ModAsset.Noise_melting_black.Value; + if (bars_dark.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_dark.ToArray(), 0, bars_dark.Count - 2); + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars_dark.ToArray(), 0, bars_dark.Count - 2); + } + + if (bars2_dark.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars2_dark.ToArray(), 0, bars2_dark.Count - 2); + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars2_dark.ToArray(), 0, bars2_dark.Count - 2); + } + Main.graphics.graphicsDevice.Textures[0] = Commons.ModAsset.Noise_melting.Value; + if (bars.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars.ToArray(), 0, bars.Count - 2); + } + + if (bars2.Count > 3) + { + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars2.ToArray(), 0, bars2.Count - 2); + Main.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, bars2.ToArray(), 0, bars2.Count - 2); + } + Main.spriteBatch.End(); + Main.spriteBatch.Begin(sBS); + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeSub_ProjExplosion.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeSub_ProjExplosion.png new file mode 100644 index 000000000..c75fa0bf8 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/ChainGrenadeSub_ProjExplosion.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/CyanVineCrossBow_Proj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/CyanVineCrossBow_Proj.cs index 68d4febb4..70ab19914 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/CyanVineCrossBow_Proj.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/CyanVineCrossBow_Proj.cs @@ -10,6 +10,7 @@ public override void SetDef() ChordTexture = ModAsset.CyanVineCrossBow_Proj_Chord.Value; HeldProjectileOffset = new Vector2(-6, -6); } + public override void DrawChord(SpriteBatch spriteBatch, Color lightColor) { if (ChordTexture == null) @@ -41,7 +42,6 @@ public override void DrawChord(SpriteBatch spriteBatch, Color lightColor) sliderHead = sliderHead.RotatedBy(Projectile.rotation); sliderTail = sliderTail.RotatedBy(Projectile.rotation); - Vector2 upChord = upChordHead - upChordTail; Vector2 slider = sliderHead - sliderTail; Vector2 downChord = downChordHead - downChordTail; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/GunOfAvariceAutoReload.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/GunOfAvariceAutoReload.cs index bd7fb33fd..125498ed5 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/GunOfAvariceAutoReload.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/GunOfAvariceAutoReload.cs @@ -1,5 +1,6 @@ using Everglow.Commons.DataStructures; using Everglow.Yggdrasil.Common.Dusts; +using Everglow.Yggdrasil.YggdrasilTown.Items.Weapons.TwilightForest; using Everglow.Yggdrasil.YggdrasilTown.VFXs; using Terraria.Audio; using Terraria.DataStructures; @@ -22,7 +23,7 @@ public override void SetDefaults() { Projectile.width = 62; Projectile.height = 32; - Projectile.timeLeft = Items.Weapons.GunOfAvarice.AutoReloadDuration; + Projectile.timeLeft = GunOfAvarice.AutoReloadDuration; Projectile.penetrate = -1; Projectile.hide = true; Projectile.scale = 0.75f; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/GunOfAvariceManualReload.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/GunOfAvariceManualReload.cs index 29ed2039b..928a84bac 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/GunOfAvariceManualReload.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/GunOfAvariceManualReload.cs @@ -1,4 +1,5 @@ using Everglow.Yggdrasil.Common.Dusts; +using Everglow.Yggdrasil.YggdrasilTown.Items.Weapons.TwilightForest; using Everglow.Yggdrasil.YggdrasilTown.VFXs; using Terraria.Audio; @@ -16,7 +17,7 @@ public override void SetDefaults() { Projectile.width = 62; Projectile.height = 32; - Projectile.timeLeft = Items.Weapons.GunOfAvarice.ManualReloadDuration; + Projectile.timeLeft = GunOfAvarice.ManualReloadDuration; Projectile.penetrate = -1; Projectile.hide = true; Projectile.scale = 0.75f; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/NehemothBullet_Color.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/NehemothBullet_Color.png index be4621be9..058af0318 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/NehemothBullet_Color.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/NehemothBullet_Color.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_HeldProj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_HeldProj.cs new file mode 100644 index 000000000..0f5456e06 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_HeldProj.cs @@ -0,0 +1,226 @@ +using Everglow.Commons.Templates.Weapons; +using Terraria.Audio; + +namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Ranged; + +public class PearShapedNeedle_HeldProj : HandholdProjectile +{ + public float Timer = 0; + + public float MinChargeTime = 60; + + public float PrepareChargeAnimationPerNeedle = 3; + + public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.RangedProjectiles; + + public override void SetDef() + { + Projectile.friendly = false; + DepartLength = 30; + } + + public override void AI() + { + Timer++; + float preparedTime = 13 * PrepareChargeAnimationPerNeedle; + if (Timer % 3 == 0 && Timer >= 3 && Timer <= preparedTime) + { + SoundEngine.PlaySound(22, Projectile.Center); + } + base.AI(); + } + + public override void HeldProjectileAI() + { + Player player = Main.player[Projectile.owner]; + if (player.HeldItem.type != ModContent.ItemType()) + { + Projectile.Kill(); + } + player.heldProj = Projectile.whoAmI; + ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2); + + Vector2 mouseToPlayer = Main.MouseWorld - ArmRootPos; + mouseToPlayer = Vector2.Normalize(mouseToPlayer); + Projectile.rotation = mouseToPlayer.ToRotation() + MathHelper.PiOver4; + + player.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, (Projectile.rotation - MathF.PI * 0.25f) * player.gravDir - MathF.PI * 0.5f); + + Projectile.Center = ArmRootPos + new Vector2(0, 1).RotatedBy(Projectile.rotation - Math.PI * 0.75) * DepartLength; + if (player.controlUseItem) + { + Projectile.timeLeft = 10; + } + if (Projectile.Center.X < ArmRootPos.X) + { + player.direction = -1; + } + else + { + player.direction = 1; + } + } + + public override bool PreDraw(ref Color lightColor) + { + DrawNeedles(); + return base.PreDraw(ref lightColor); + } + + public void DrawNeedles() + { + for (int k = 0; k < 13; k++) + { + float distance = GetDistance(k); + if (distance < 0) + { + break; + } + DrawNeedlePiece(k); + if (k > 0) + { + DrawNeedlePiece(-k); + } + } + } + + public float GetDistance(int k) + { + k = Math.Abs(k); + float needlePhase = Timer - k * PrepareChargeAnimationPerNeedle; + if (needlePhase < 0) + { + return -1; + } + float distance = needlePhase * 18; + float maxDis = 30 + 5 * MathF.Sin(Timer * 0.1f + (k % 2) * 0.1f + k); + if (k % 2 == 0) + { + maxDis += 10; + } + if (!NeedleReady(k)) + { + maxDis *= 0.5f; + } + if (distance > maxDis) + { + distance = maxDis; + } + return distance; + } + + public float GetShineValue(int k) + { + k = Math.Abs(k); + float shineValue = 0; + float preparedTime = 13 * PrepareChargeAnimationPerNeedle; + if (Timer > preparedTime) + { + shineValue = (Timer - preparedTime) / (MinChargeTime - preparedTime) * 13f; + shineValue = 3 - (k - shineValue); + shineValue = Math.Max(shineValue, 0) / 3f; + } + if (shineValue > 1) + { + shineValue = MathF.Sin(Timer * 0.1f + (k % 2) * 0.1f + k) + 1; + shineValue *= 0.1f; + } + return shineValue; + } + + public void DrawNeedlePiece(int k) + { + Texture2D needle = ModAsset.PearShapedNeedle_Needle.Value; + Texture2D needle_bloom = ModAsset.PearShapedNeedle_shine.Value; + Texture2D needleReflect = ModAsset.PearShapedNeedle_Needle_reflection.Value; + Texture2D needleReflectStar = ModAsset.PearShapedNeedle_shine_star.Value; + float kAngle = 0.14f; + Vector2 drawPos = GetNeedleWorldPos(k); + Color lightColor = Lighting.GetColor(drawPos.ToTileCoordinates()); + drawPos -= Main.screenPosition; + float rotation = Projectile.rotation + k * kAngle; + Main.EntitySpriteDraw(needle, drawPos, null, lightColor, rotation, needle.Size() * 0.5f, 1f, SpriteEffects.None, 0); + + float shineValue = GetShineValue(k); + if (shineValue > 0) + { + Color shineColor = lightColor; + shineColor.A = 0; + shineColor *= shineValue; + Main.EntitySpriteDraw(needle_bloom, drawPos, null, shineColor, rotation, needle_bloom.Size() * 0.5f, 1f, SpriteEffects.None, 0); + } + + float reflect = GetReflectValue(rotation); + Color reflectColor = lightColor * reflect; + reflectColor.A = 0; + Main.EntitySpriteDraw(needleReflect, drawPos, null, reflectColor, rotation, needleReflect.Size() * 0.5f, 1f, SpriteEffects.None, 0); + if (reflect > 0.5f) + { + Vector2 addPos = new Vector2(7, -7).RotatedBy(rotation); + Main.EntitySpriteDraw(needleReflectStar, drawPos + addPos, null, reflectColor * 2, 0, needleReflectStar.Size() * 0.5f, (reflect - 0.5f) * 3f, SpriteEffects.None, 0); + } + } + + public float GetReflectValue(float rotation) + { + float reflect = (MathF.Sin(rotation * 2 + MathHelper.PiOver4) + 1) * 0.5f; + reflect = MathF.Pow(reflect, 2); + return reflect; + } + + public override void OnKill(int timeLeft) + { + ReleaseNeedles(); + base.OnKill(timeLeft); + } + + public bool NeedleReady(int k) + { + k = Math.Abs(k); + float shineValue = 0; + float preparedTime = 13 * PrepareChargeAnimationPerNeedle; + if (Timer > preparedTime) + { + shineValue = (Timer - preparedTime) / (MinChargeTime - preparedTime) * 13f; + shineValue = 3 - (k - shineValue); + shineValue = Math.Max(shineValue, 0) / 3f; + } + if (shineValue > 1) + { + return true; + } + return false; + } + + public Vector2 GetNeedleWorldPos(int k) + { + return Projectile.Center + GetReleaseVel(k); + } + + public Vector2 GetReleaseVel(int k) + { + float kAngle = 0.14f; + return new Vector2(GetDistance(k), 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4 + k * kAngle); + } + + public void ReleaseNeedles() + { + bool succeed = false; + for (int k = 0; k < 13; k++) + { + if (NeedleReady(k)) + { + succeed = true; + Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), GetNeedleWorldPos(k), GetReleaseVel(k).NormalizeSafe(), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner); + if (k > 0) + { + Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), GetNeedleWorldPos(-k), GetReleaseVel(-k).NormalizeSafe(), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner); + } + } + } + if (succeed) + { + SoundEngine.PlaySound(SoundID.DD2_SkyDragonsFuryShot, Projectile.Center); + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_HeldProj.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_HeldProj.png new file mode 100644 index 000000000..41e21aa76 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_HeldProj.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_Needle.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_Needle.cs new file mode 100644 index 000000000..91a0bcba0 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_Needle.cs @@ -0,0 +1,101 @@ +using Everglow.Yggdrasil.YggdrasilTown.VFXs; +using Terraria.DataStructures; + +namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Ranged; + +public class PearShapedNeedle_Needle : ModProjectile +{ + public float Timer = 0; + + public Vector2 StartPosition = default; + + public Vector2 EndPosition = default; + + public override void SetDefaults() + { + Projectile.friendly = true; + Projectile.width = 12; + Projectile.height = 12; + Projectile.tileCollide = false; + Projectile.ignoreWater = true; + Projectile.penetrate = 1; + Projectile.aiStyle = -1; + Projectile.timeLeft = 1; + Projectile.DamageType = DamageClass.Ranged; + } + + public override void OnSpawn(IEntitySource source) + { + StartPosition = Projectile.Center; + Vector2 endPos = Projectile.position; + Vector2 vel = Projectile.velocity.NormalizeSafe() * 5; + bool hit = false; + for (int i = 0; i < 30; i++) + { + endPos += vel; + if (Collision.SolidCollision(endPos, Projectile.width, Projectile.height)) + { + hit = true; + } + Rectangle hitbox = new Rectangle((int)endPos.X, (int)endPos.Y, Projectile.width, Projectile.height); + foreach (var npc in Main.npc) + { + if (npc != null && npc.active && npc.Hitbox.Intersects(hitbox)) + { + hit = true; + } + } + if (hit) + { + break; + } + } + Projectile.position = endPos; + EndPosition = Projectile.Center; + for (int k = 0; k < 5; k++) + { + var dust = new PearShapedNeedle_Dust + { + Velocity = vel * (3 + k * 0.5f), + Active = true, + Visible = true, + Position = EndPosition, + MaxTime = Main.rand.NextFloat(25f, 35f), + Scale = Main.rand.NextFloat(1f, 2f), + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + RanSeed = Main.rand.NextFloat(MathHelper.TwoPi), + }; + Ins.VFXManager.Add(dust); + } + var trail = new PearShapedNeedle_Trail + { + Active = true, + Visible = true, + Position_Start = StartPosition, + Position_End = EndPosition, + MaxTime = Main.rand.NextFloat(25f, 35f), + }; + Ins.VFXManager.Add(trail); + if (hit) + { + var dust = new PearShapedNeedle_HitStar + { + Active = true, + Visible = true, + Position = EndPosition, + MaxTime = Main.rand.NextFloat(25f, 35f), + Rotation = vel.ToRotation(), + }; + Ins.VFXManager.Add(dust); + } + } + + public override void AI() => base.AI(); + + public override bool? Colliding(Rectangle projHitbox, Rectangle targetHitbox) => base.Colliding(projHitbox, targetHitbox); + + public override bool PreDraw(ref Color lightColor) + { + return false; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_Needle.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_Needle.png new file mode 100644 index 000000000..f3d9f3f6d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_Needle.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_Needle_reflection.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_Needle_reflection.png new file mode 100644 index 000000000..28d933c5b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_Needle_reflection.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_shine.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_shine.png new file mode 100644 index 000000000..496177037 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_shine.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_shine_star.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_shine_star.png new file mode 100644 index 000000000..0425cf55b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_shine_star.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Summon/WiltedForestLamp_Proj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Summon/WiltedForestLamp_Proj.cs index c48c8cd32..1616f8943 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Summon/WiltedForestLamp_Proj.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Summon/WiltedForestLamp_Proj.cs @@ -199,7 +199,7 @@ public override void OnKill(int timeLeft) { if ((npc.Center - Projectile.Center).Length() < 220) { - npc.AddElementalDebuffBuildUp(Main.player[Projectile.owner], NecrosisDebuff.ID, 50 * player.maxMinions); + npc.AddElementalDebuffBuildUp(Main.player[Projectile.owner], BurnDebuff.ID, 5000); } } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Summon/WiltedForestLamp_Proj_shoot.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Summon/WiltedForestLamp_Proj_shoot.cs index 7da6b9306..b278e42d7 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Summon/WiltedForestLamp_Proj_shoot.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Summon/WiltedForestLamp_Proj_shoot.cs @@ -47,7 +47,7 @@ public override void Behaviors() if (npc == null || !npc.active) { OldVel = Projectile.velocity; - Projectile.velocity = Vector2.Normalize(Projectile.velocity) * 12; + Projectile.velocity = Projectile.velocity.NormalizeSafe() * 12; var dustVFX = new Leaf_VFX { velocity = new Vector2(0, 0.5f).RotatedByRandom(Math.PI * 2) + Projectile.velocity, @@ -67,7 +67,7 @@ public override void Behaviors() OldVel = Projectile.velocity; var toTarget = Vector2.Normalize(npc.Center - Projectile.Center - Projectile.velocity); Projectile.velocity = Projectile.velocity * 0.4f + toTarget; - Projectile.velocity = Vector2.Normalize(Projectile.velocity) * 12; + Projectile.velocity = Projectile.velocity.NormalizeSafe() * 12; float omegaVel = Vector3.Cross(new Vector3(OldVel / 12f, 0), new Vector3(Projectile.velocity / 12f, 0)).Z; omegaVel = MathF.Asin(omegaVel); float betaVel = Vector3.Cross(new Vector3(oldOldVel / 12f, 0), new Vector3(OldVel / 12f, 0)).Z; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Scenes/OriginPylonMusicSceneEffect.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Scenes/OriginPylonMusicSceneEffect.cs index 6233cb7cb..340fb692b 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Scenes/OriginPylonMusicSceneEffect.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Scenes/OriginPylonMusicSceneEffect.cs @@ -1,4 +1,4 @@ -using Everglow.Yggdrasil.YggdrasilTown.Tiles; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.OriginPylon; using SubworldLibrary; namespace Everglow.Yggdrasil.YggdrasilTown.Scenes; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/Introductiontothermalelectricity/Introductiontothermalelectricity_explosion_1.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/Introductiontothermalelectricity/Introductiontothermalelectricity_explosion_1.ogg new file mode 100644 index 000000000..2b6c210c5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/Introductiontothermalelectricity/Introductiontothermalelectricity_explosion_1.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/Introductiontothermalelectricity/Introductiontothermalelectricity_explosion_2.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/Introductiontothermalelectricity/Introductiontothermalelectricity_explosion_2.ogg new file mode 100644 index 000000000..9e1ba78d3 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/Introductiontothermalelectricity/Introductiontothermalelectricity_explosion_2.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/Introductiontothermalelectricity/Introductiontothermalelectricity_launch_1.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/Introductiontothermalelectricity/Introductiontothermalelectricity_launch_1.ogg new file mode 100644 index 000000000..83fbe4e67 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/Introductiontothermalelectricity/Introductiontothermalelectricity_launch_1.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/Introductiontothermalelectricity/Introductiontothermalelectricity_launch_2.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/Introductiontothermalelectricity/Introductiontothermalelectricity_launch_2.ogg new file mode 100644 index 000000000..e51bd9375 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/Introductiontothermalelectricity/Introductiontothermalelectricity_launch_2.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_attack_1.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_attack_1.ogg new file mode 100644 index 000000000..f346d71a7 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_attack_1.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_attack_2.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_attack_2.ogg new file mode 100644 index 000000000..fabbed020 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_attack_2.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_attack_3.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_attack_3.ogg new file mode 100644 index 000000000..f227926d0 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_attack_3.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_attack_4.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_attack_4.ogg new file mode 100644 index 000000000..24d6e36b9 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_attack_4.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_superattack_1.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_superattack_1.ogg new file mode 100644 index 000000000..c4d4f70bc Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_superattack_1.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_superattack_2.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_superattack_2.ogg new file mode 100644 index 000000000..cb8a8b644 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/QuenchingBlade/QuenchingBlade_superattack_2.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_attack_1.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_attack_1.ogg new file mode 100644 index 000000000..c9111dfe2 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_attack_1.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_attack_2.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_attack_2.ogg new file mode 100644 index 000000000..44b9dc083 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_attack_2.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_attack_3.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_attack_3.ogg new file mode 100644 index 000000000..5b88a2577 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_attack_3.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_attack_4.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_attack_4.ogg new file mode 100644 index 000000000..6443244a3 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_attack_4.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_hit_1.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_hit_1.ogg new file mode 100644 index 000000000..39619e829 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_hit_1.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_hit_2.ogg b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_hit_2.ogg new file mode 100644 index 000000000..46f10c813 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Sounds/VitalizedRocks/vitalizedrocks_hit_2.ogg differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/ArenaChallengeSettingTile.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/ArenaChallengeSettingTile.cs index 2f7810162..6a7352ed7 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/ArenaChallengeSettingTile.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/ArenaChallengeSettingTile.cs @@ -47,7 +47,7 @@ public void AddScene(int i, int j) Tile tile = TileUtils.SafeGetTile(i, j); if (tile.TileFrameX == 0 && tile.TileFrameY == 0) { - NPCBossTagsSystem nCTS = new NPCBossTagsSystem { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + NPCBossTagsSystem nCTS = new NPCBossTagsSystem { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(nCTS); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/ArrowSigns.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/ArrowSigns.cs new file mode 100644 index 000000000..7e09fd3e5 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/ArrowSigns.cs @@ -0,0 +1,33 @@ +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; + +public class ArrowSigns : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + Main.tileLavaDeath[Type] = false; + + Main.tileWaterDeath[Type] = false; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 4; + TileObjectData.newTile.Width = 2; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 16, + 16, + 18, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.addTile(Type); + AddMapEntry(new Color(153, 45, 45)); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/ArrowSigns.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/ArrowSigns.png new file mode 100644 index 000000000..2cdf9586b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/ArrowSigns.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/BoneAndPlatform_background.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/BoneAndPlatform_background.cs index 39c997a4a..029a17a07 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/BoneAndPlatform_background.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/BoneAndPlatform_background.cs @@ -3,10 +3,12 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; [Pipeline(typeof(WCSPipeline))] -public class BoneAndPlatform_background : BackgroundVFX +public class BoneAndPlatform_background : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawBG; + public override void OnSpawn() { - texture = ModAsset.BoneAndPlatform_background.Value; + Texture = ModAsset.BoneAndPlatform_background.Value; } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/BoneAndPlatform_foreground.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/BoneAndPlatform_foreground.cs index cfcad824e..1cae9fc16 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/BoneAndPlatform_foreground.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/BoneAndPlatform_foreground.cs @@ -3,10 +3,12 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; [Pipeline(typeof(WCSPipeline))] -public class BoneAndPlatform_foreground : ForegroundVFX +public class BoneAndPlatform_foreground : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; + public override void OnSpawn() { - texture = ModAsset.BoneAndPlatform_foreground.Value; + Texture = ModAsset.BoneAndPlatform_foreground.Value; } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/BoneAndPlatform_tile.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/BoneAndPlatform_tile.cs index 4c6da178c..6b8ce48d4 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/BoneAndPlatform_tile.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/BoneAndPlatform_tile.cs @@ -45,9 +45,9 @@ public void AddScene(int i, int j) Tile tile = Main.tile[i, j]; if (tile.TileFrameX == 0 && tile.TileFrameY == 0) { - BoneAndPlatform_background scene = new BoneAndPlatform_background { position = new Vector2(i, j - 14) * 16, Active = true, originTile = new Point(i, j), originType = ModContent.TileType() }; + BoneAndPlatform_background scene = new BoneAndPlatform_background { Position = new Vector2(i, j - 14) * 16, Active = true, OriginTilePos = new Point(i, j), OriginTileType = ModContent.TileType() }; Ins.VFXManager.Add(scene); - BoneAndPlatform_foreground scene2 = new BoneAndPlatform_foreground { position = new Vector2(i, j - 14) * 16, Active = true, originTile = new Point(i, j), originType = ModContent.TileType() }; + BoneAndPlatform_foreground scene2 = new BoneAndPlatform_foreground { Position = new Vector2(i, j - 14) * 16, Active = true, OriginTilePos = new Point(i, j), OriginTileType = ModContent.TileType() }; Ins.VFXManager.Add(scene2); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/CyanVine/CyanVineStone.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/CyanVine/CyanVineStone.cs index fb42e1629..796fccd67 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/CyanVine/CyanVineStone.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/CyanVine/CyanVineStone.cs @@ -1,5 +1,3 @@ -using Terraria.Localization; - namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.CyanVine; public class CyanVineStone : ModTile @@ -11,9 +9,9 @@ public override void PostSetDefaults() DustType = ModContent.DustType(); MineResist = 4f; Main.tileSpelunker[Type] = true; - var modTranslation = CreateMapEntryName(); - AddMapEntry(new Color(155, 173, 183), modTranslation); + AddMapEntry(new Color(84, 130, 154)); } + public override bool CanExplode(int i, int j) { return false; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/DarkSludge.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/DarkSludge.cs deleted file mode 100644 index f19553899..000000000 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/DarkSludge.cs +++ /dev/null @@ -1,77 +0,0 @@ - -using Everglow.Commons.VFX.Scene; -using Everglow.Yggdrasil.Common; -using Everglow.Yggdrasil.YggdrasilTown.VFXs; - -namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; - -public class DarkSludge : ModTile, ISceneTile -{ - public override void SetStaticDefaults() - { - Main.tileSolid[Type] = true; - Main.tileMerge[Type][(ushort)ModContent.TileType()] = true; - Main.tileMerge[(ushort)ModContent.TileType()][Type] = true; - Main.tileBlockLight[Type] = true; - Main.tileNoSunLight[Type] = true; - DustType = DustID.BorealWood; - MinPick = 250; - HitSound = SoundID.Dig; - AddMapEntry(new Color(31, 26, 45)); - } - - public override bool CanExplode(int i, int j) - { - return false; - } - - public override void FloorVisuals(Player player) - { - player.velocity *= 0.1f; - - // player.position += new Vector2(0, player.gravDir * 15f); - player.AddBuff(BuffID.Shimmer, 60); - } - - public override void RandomUpdate(int i, int j) - { - Tile thisTile = Main.tile[i, j]; - UpdateTileFrameX(thisTile); - if (i >= 24 && i <= Main.maxTilesX - 24) - { - for (int x = -5; x <= 5; x += 2) - { - Tile otherTile = Main.tile[i + x, j]; - UpdateTileFrameX(otherTile); - } - } - void UpdateTileFrameX(Tile tile) - { - if (tile.TileFrameY == 0) - { - if (tile.TileFrameX >= 18 && tile.TileFrameX <= 54) - { - tile.TileFrameX = (short)(Main.rand.Next(1, 4) * 18); - } - } - } - } - - public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) - { - if (!Main.tile[i, j - 1].HasTile && !Ins.VisualQuality.Low) - { - return false; - } - return base.PreDraw(i, j, spriteBatch); - } - - public void AddScene(int i, int j) - { - if (i == 1330 && j == Main.maxTilesY - 329 && !Ins.VisualQuality.Low) - { - DarkSludge_Scene scene = new DarkSludge_Scene { position = new Vector2(i, j), Active = true, originTile = new Point(i, j), originType = ModContent.TileType() }; - Ins.VFXManager.Add(scene); - } - } -} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/DarkSludge.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/DarkSludge.png deleted file mode 100644 index 184791c0f..000000000 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/DarkSludge.png and /dev/null differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/DarkSludgeLiquid_SolidBlock.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/DarkSludgeLiquid_SolidBlock.cs new file mode 100644 index 000000000..57dacb297 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/DarkSludgeLiquid_SolidBlock.cs @@ -0,0 +1,33 @@ +using Everglow.Yggdrasil.YggdrasilTown.Dusts; +using Everglow.Yggdrasil.YggdrasilTown.Liquids; +using ModLiquidLib.ModLoader; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; + +public class DarkSludgeLiquid_SolidBlock : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileSolid[Type] = true; + Main.tileMergeDirt[Type] = false; + Main.tileBlendAll[Type] = false; + Main.tileBlockLight[Type] = true; + DustType = ModContent.DustType(); + MinPick = int.MaxValue; + AddMapEntry(new Color(31, 26, 45)); + } + + public override bool CanExplode(int i, int j) + { + return false; + } + + public override void RandomUpdate(int i, int j) + { + Tile tile = Main.tile[i, j]; + tile.ClearTile(); + tile.LiquidType = LiquidLoader.LiquidType(); + tile.LiquidAmount = byte.MaxValue; + WorldGen.SquareTileFrame(i, j); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/DarkSludgeLiquid_SolidBlock.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/DarkSludgeLiquid_SolidBlock.png new file mode 100644 index 000000000..1d2b952ed Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/DarkSludgeLiquid_SolidBlock.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FossilDragonScaleWood_Rock_1x1.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FossilDragonScaleWood_Rock_1x1.png new file mode 100644 index 000000000..752bd4942 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FossilDragonScaleWood_Rock_1x1.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FossilDragonScaleWood_Rock_2x1.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FossilDragonScaleWood_Rock_2x1.png new file mode 100644 index 000000000..e6b50f2c2 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FossilDragonScaleWood_Rock_2x1.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FossilDragonScaleWood_Rock_3x1.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FossilDragonScaleWood_Rock_3x1.png new file mode 100644 index 000000000..0c1c9dce2 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FossilDragonScaleWood_Rock_3x1.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FossilDragonScaleWood_Rock_3x2.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FossilDragonScaleWood_Rock_3x2.png new file mode 100644 index 000000000..f3b57cfd1 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FossilDragonScaleWood_Rock_3x2.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/CurrentEnergyTube.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/CurrentEnergyTube.cs index c67ffce43..f26428ab7 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/CurrentEnergyTube.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/CurrentEnergyTube.cs @@ -49,7 +49,7 @@ public void AddScene(int i, int j) Tile tile = Main.tile[i, j]; if (tile.TileFrameX == 0 && tile.TileFrameY == 0) { - var scene = new CurrentEnergyTube_LavaBar { position = new Vector2(i, j) * 16, Active = true, originTile = new Point(i, j), originType = Type }; + var scene = new CurrentEnergyTube_LavaBar { Position = new Vector2(i, j) * 16, Active = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(scene); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/CurrentEnergyTube.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/CurrentEnergyTube.png index 4dbcca7b6..119be401a 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/CurrentEnergyTube.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/CurrentEnergyTube.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/CurrentEnergyTube_LavaBar.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/CurrentEnergyTube_LavaBar.cs index 9996dbe98..c540ffeb5 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/CurrentEnergyTube_LavaBar.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/CurrentEnergyTube_LavaBar.cs @@ -3,65 +3,65 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; [Pipeline(typeof(WCSPipeline))] -public class CurrentEnergyTube_LavaBar : BackgroundVFX +public class CurrentEnergyTube_LavaBar : TileVFX { public override CodeLayer DrawLayer => CodeLayer.PostDrawTiles; public override void Update() { - if (originTile.X > 0 && originTile.X < Main.maxTilesX) + if (OriginTilePos.X > 0 && OriginTilePos.X < Main.maxTilesX) { - if (originTile.Y > 0 && originTile.Y < Main.maxTilesY) + if (OriginTilePos.Y > 0 && OriginTilePos.Y < Main.maxTilesY) { - Tile tile = Main.tile[originTile.X, originTile.Y]; + Tile tile = Main.tile[OriginTilePos.X, OriginTilePos.Y]; if (tile != null) { if (TileLoader.GetTile(tile.TileType) is ISceneTile) { - if (tile.TileType == originType) + if (tile.TileType == OriginTileType) { if (!tile.HasTile) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - Vector2 checkPos = position; + Vector2 checkPos = Position; if (VFXManager.InScreen(checkPos, 1500)) { Visible = true; @@ -69,14 +69,14 @@ public override void Update() else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } public override void OnSpawn() { - texture = ModAsset.CurrentEnergyTube_LavaBar.Value; + Texture = ModAsset.CurrentEnergyTube_LavaBar.Value; } public override void Draw() @@ -88,7 +88,7 @@ public override void Draw() Vector2 frameSize = new Vector2(16, frameHeight); Vector2 frameXY = new Vector2(18, 176 - frameHeight); float surfaceY = 176 - frameHeight; - var drawPos = position + new Vector2(8, (176 - frameHeight * 0.5f) + 8); + var drawPos = Position + new Vector2(8, (176 - frameHeight * 0.5f) + 8); for (int j = 0; j < frameHeight; j += 5) { Lighting.AddLight(drawPos + new Vector2(0, j), new Vector3(1f, 0.7f, 0) * 0.5f); @@ -98,42 +98,42 @@ public override void Draw() var bottomLeft = drawPos + new Vector2(-frameSize.X, frameSize.Y) * 0.5f; var bottomRight = drawPos + new Vector2(frameSize.X, frameSize.Y) * 0.5f; var drawColor = Color.White; - bars.Add(topLeft, drawColor, new Vector3(frameXY / texture.Size(), 0)); - bars.Add(topRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y) / texture.Size(), 0)); - bars.Add(bottomRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); + bars.Add(topLeft, drawColor, new Vector3(frameXY / Texture.Size(), 0)); + bars.Add(topRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y) / Texture.Size(), 0)); + bars.Add(bottomRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / Texture.Size(), 0)); - bars.Add(topLeft, drawColor, new Vector3(frameXY / texture.Size(), 0)); - bars.Add(bottomRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); - bars.Add(bottomLeft, drawColor, new Vector3(new Vector2(frameXY.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); + bars.Add(topLeft, drawColor, new Vector3(frameXY / Texture.Size(), 0)); + bars.Add(bottomRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / Texture.Size(), 0)); + bars.Add(bottomLeft, drawColor, new Vector3(new Vector2(frameXY.X, frameXY.Y + frameSize.Y) / Texture.Size(), 0)); // Lava surface frameHeight = 176 * YggdrasilTownFurnaceSystem.CurrentEnergy / (float)YggdrasilTownFurnaceSystem.EnergtMax; frameSize = new Vector2(16, 14); frameXY = new Vector2(0, 162); - drawPos = position + new Vector2(8, surfaceY + 2); + drawPos = Position + new Vector2(8, surfaceY + 2); topLeft = drawPos + new Vector2(-frameSize.X, -frameSize.Y) * 0.5f; topRight = drawPos + new Vector2(frameSize.X, -frameSize.Y) * 0.5f; bottomLeft = drawPos + new Vector2(-frameSize.X, frameSize.Y) * 0.5f; bottomRight = drawPos + new Vector2(frameSize.X, frameSize.Y) * 0.5f; drawColor = new Color(1f, 1f, 1f, 0); - bars.Add(topLeft, drawColor, new Vector3(frameXY / texture.Size(), 0)); - bars.Add(topRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y) / texture.Size(), 0)); - bars.Add(bottomRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); + bars.Add(topLeft, drawColor, new Vector3(frameXY / Texture.Size(), 0)); + bars.Add(topRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y) / Texture.Size(), 0)); + bars.Add(bottomRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / Texture.Size(), 0)); - bars.Add(topLeft, drawColor, new Vector3(frameXY / texture.Size(), 0)); - bars.Add(bottomRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); - bars.Add(bottomLeft, drawColor, new Vector3(new Vector2(frameXY.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); + bars.Add(topLeft, drawColor, new Vector3(frameXY / Texture.Size(), 0)); + bars.Add(bottomRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / Texture.Size(), 0)); + bars.Add(bottomLeft, drawColor, new Vector3(new Vector2(frameXY.X, frameXY.Y + frameSize.Y) / Texture.Size(), 0)); if (bars.Count <= 0) { - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); } - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleList); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleList); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FloorScaleForPlayers.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FloorScaleForPlayers.cs index 64f716501..d66e0b2e6 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FloorScaleForPlayers.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FloorScaleForPlayers.cs @@ -1,4 +1,3 @@ -using Everglow.Commons.VFX.Scene; using Everglow.Yggdrasil.YggdrasilTown.Dusts; using Terraria.DataStructures; using Terraria.Enums; @@ -6,7 +5,7 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; -public class FloorScaleForPlayers : ModTile, ISceneTile +public class FloorScaleForPlayers : ModTile { public override void SetStaticDefaults() { @@ -41,15 +40,24 @@ public override void NearbyEffects(int i, int j, bool closer) Player player = Main.LocalPlayer; if (player.Bottom.ToTileCoordinates().X == i && player.Bottom.ToTileCoordinates().Y == j) { - if (YggdrasilTownFurnaceSystem.SwitchPlayerCooling == 0) + if (YggdrasilTownFurnaceSystem.PlayerDropInFloorScaleTimer == 0) { if (YggdrasilTownFurnaceSystem.CurrentPlayer == null || YggdrasilTownFurnaceSystem.CurrentPlayer != player) { - YggdrasilTownFurnaceSystem.SwitchPlayerCooling = 30; + YggdrasilTownFurnaceSystem.PlayerDropInFloorScaleTimer = 30; YggdrasilTownFurnaceSystem.CurrentPlayer = player; } } } + if (TileUtils.SafeGetTile(player.Bottom.ToTileCoordinates()).TileType != Type) + { + if (YggdrasilTownFurnaceSystem.CurrentPlayer is not null && YggdrasilTownFurnaceSystem.CurrentPlayer == player) + { + YggdrasilTownFurnaceSystem.PlayerLeaveFloorScaleTimer = 30; + YggdrasilTownFurnaceSystem.CurrentPlayer = null; + YggdrasilTownFurnaceSystem.CurrentScore = 0; + } + } base.NearbyEffects(i, j, closer); } @@ -57,13 +65,38 @@ public override void NearbyEffects(int i, int j, bool closer) public override bool CanKillTile(int i, int j, ref bool blockDamaged) => false; - public void AddScene(int i, int j) + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) { - Tile tile = Main.tile[i, j]; - if ((tile.TileFrameX == 18 || tile.TileFrameX == 144) && tile.TileFrameY == 0) + var tile = Main.tile[i, j]; + if (tile.TileFrameX % 90 == 72) { - var scene = new FloorScaleForPlayers_Screen { position = new Vector2(i, j) * 16, Active = true, originTile = new Point(i, j), originType = Type }; - Ins.VFXManager.Add(scene); + var zero = new Vector2(Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + for (int k = 0; k < 8; k++) + { + Texture2D tex = Commons.ModAsset.White.Value; + var frame = new Rectangle(0, 0, 2, 2); + Color drawColor = new Color(1f, 0.6f, 0.4f, 1f); + if (YggdrasilTownFurnaceSystem.CurrentPlayer is null) + { + drawColor *= MathF.Sin(Main.GlobalTimeWrappedHourly * 12 + k); + } + spriteBatch.Draw(tex, new Vector2(i, j) * 16 + new Vector2(11 - k * 10, 3) + zero - Main.screenPosition, frame, drawColor, 0, frame.Size() * 0.5f, 1f, SpriteEffects.None, 0); + drawColor.A = 0; + float bloomSize = 3f; + if (YggdrasilTownFurnaceSystem.PlayerDropInFloorScaleTimer > 0) + { + bloomSize = 3f + YggdrasilTownFurnaceSystem.PlayerDropInFloorScaleTimer / 10f; + } + spriteBatch.Draw(tex, new Vector2(i, j) * 16 + new Vector2(11 - k * 10, 3) + zero - Main.screenPosition, frame, drawColor * 0.25f, MathHelper.PiOver4, frame.Size() * 0.5f, bloomSize, SpriteEffects.None, 0); + if (bloomSize > 3.2f) + { + spriteBatch.Draw(tex, new Vector2(i, j) * 16 + new Vector2(11 - k * 10, 3) + zero - Main.screenPosition, frame, drawColor * 0.25f, MathHelper.PiOver4, frame.Size() * 0.5f, bloomSize - 3.2f, SpriteEffects.None, 0); + } + } } } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FloorScaleForPlayers_Screen.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FloorScaleForPlayers_Screen.cs deleted file mode 100644 index 1f6bcfb83..000000000 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FloorScaleForPlayers_Screen.cs +++ /dev/null @@ -1,148 +0,0 @@ -using Everglow.Commons.VFX.Scene; - -namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; - -[Pipeline(typeof(WCSPipeline))] -public class FloorScaleForPlayers_Screen : BackgroundVFX -{ - public override CodeLayer DrawLayer => CodeLayer.PostDrawTiles; - - public override void Update() - { - if (originTile.X > 0 && originTile.X < Main.maxTilesX) - { - if (originTile.Y > 0 && originTile.Y < Main.maxTilesY) - { - Tile tile = Main.tile[originTile.X, originTile.Y]; - if (tile != null) - { - if (TileLoader.GetTile(tile.TileType) is ISceneTile) - { - if (tile.TileType == originType) - { - if (!tile.HasTile) - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - Vector2 checkPos = position; - if (VFXManager.InScreen(checkPos, 1500)) - { - Visible = true; - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - - public override void OnSpawn() - { - texture = ModAsset.FloorScaleForPlayers_Screen.Value; - } - - public override void Draw() - { - var bars = new List(); - - // Screen - Vector2 frameSize = new Vector2(24, 30); - Vector2 frameXY = new Vector2(0, 0); - var drawPos = position + new Vector2(4, -15); - var topLeft = drawPos + new Vector2(-frameSize.X, -frameSize.Y) * 0.5f; - var topRight = drawPos + new Vector2(frameSize.X, -frameSize.Y) * 0.5f; - var bottomLeft = drawPos + new Vector2(-frameSize.X, frameSize.Y) * 0.5f; - var bottomRight = drawPos + new Vector2(frameSize.X, frameSize.Y) * 0.5f; - bars.Add(topLeft, GetColor(topLeft), new Vector3(frameXY / texture.Size(), 0)); - bars.Add(topRight, GetColor(topRight), new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y) / texture.Size(), 0)); - bars.Add(bottomRight, GetColor(bottomRight), new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); - - bars.Add(topLeft, GetColor(topLeft), new Vector3(frameXY / texture.Size(), 0)); - bars.Add(bottomRight, GetColor(bottomRight), new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); - bars.Add(bottomLeft, GetColor(bottomLeft), new Vector3(new Vector2(frameXY.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); - - // Fresh Effect - if (YggdrasilTownFurnaceSystem.CurrentPlayer != null) - { - frameXY = new Vector2(48, 0); - float colorValue = YggdrasilTownFurnaceSystem.SwitchPlayerCooling / 30f; - var drawColor = new Color(colorValue, colorValue, colorValue, 0); - bars.Add(topLeft, drawColor, new Vector3(frameXY / texture.Size(), 0)); - bars.Add(topRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y) / texture.Size(), 0)); - bars.Add(bottomRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); - - bars.Add(topLeft, drawColor, new Vector3(frameXY / texture.Size(), 0)); - bars.Add(bottomRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); - bars.Add(bottomLeft, drawColor, new Vector3(new Vector2(frameXY.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); - } - - // Content - if (YggdrasilTownFurnaceSystem.CurrentPlayer != null) - { - frameXY = new Vector2(24, 0); - var drawColor = new Color(1f, 1f, 1f, 0); - bars.Add(topLeft, drawColor, new Vector3(frameXY / texture.Size(), 0)); - bars.Add(topRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y) / texture.Size(), 0)); - bars.Add(bottomRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); - - bars.Add(topLeft, drawColor, new Vector3(frameXY / texture.Size(), 0)); - bars.Add(bottomRight, drawColor, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); - bars.Add(bottomLeft, drawColor, new Vector3(new Vector2(frameXY.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); - } - - if (bars.Count <= 0) - { - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - } - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleList); - } - - public Color GetColor(Vector2 drawPos) - { - return Lighting.GetColor(drawPos.ToTileCoordinates()); - } -} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FloorScaleForPlayers_Screen.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FloorScaleForPlayers_Screen.png deleted file mode 100644 index 2ff3917af..000000000 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FloorScaleForPlayers_Screen.png and /dev/null differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceCopperPipe_Large_Corner.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceCopperPipe_Large_Corner.png index 4592ff7ff..5ad204dff 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceCopperPipe_Large_Corner.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceCopperPipe_Large_Corner.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceCopperPipe_Large_V.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceCopperPipe_Large_V.png index 2d0bb035d..95c95e715 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceCopperPipe_Large_V.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceCopperPipe_Large_V.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceEmergencyLamp.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceEmergencyLamp.cs index 4c57831b5..c561e6020 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceEmergencyLamp.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceEmergencyLamp.cs @@ -14,7 +14,7 @@ public override void SetStaticDefaults() Main.tileWaterDeath[Type] = false; TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3Wall); - TileObjectData.newTile.Origin = new(0, 0); + TileObjectData.newTile.Origin = new(1, 0); TileObjectData.newTile.Height = 2; TileObjectData.newTile.Width = 3; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/MeltingInputBox.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest.cs similarity index 84% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/MeltingInputBox.cs rename to Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest.cs index 1ef7932ad..a1302458a 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/MeltingInputBox.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest.cs @@ -6,10 +6,11 @@ using Terraria.GameContent.ObjectInteractions; using Terraria.Localization; using Terraria.ObjectData; +using Terraria.UI; namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; -public class MeltingInputBox : ModTile +public class FurnaceMeltingChest : ModTile { public override void SetStaticDefaults() { @@ -37,7 +38,7 @@ public override void SetStaticDefaults() // Style 1 is ExampleChest when locked. We want that tile style to drop the ExampleChest item as well. Use the Chest Lock item to lock this chest. // No item places ExampleChest in the locked style, so the automatically determined item drop is unknown, this is why RegisterItemDrop is necessary in this situation. - RegisterItemDrop(ModContent.ItemType(), 1); + RegisterItemDrop(ModContent.ItemType(), 1); // Sometimes mods remove content, such as tile styles, or tiles accidentally get corrupted. We can, if desired, register a fallback item for any tile style that doesn't have an automatically determined item drop. This is done by omitting the tileStyles parameter. // RegisterItemDrop(ItemID.Chest); @@ -138,7 +139,7 @@ public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) if (chestIndex >= 0) { Chest chest = Main.chest[chestIndex]; - var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + var zero = new Vector2(Main.offScreenRange); if (Main.drawToScreen) { zero = Vector2.Zero; @@ -151,11 +152,37 @@ public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) return base.PreDraw(i, j, spriteBatch); } - public override void DrawEffects(int i, int j, SpriteBatch spriteBatch, ref TileDrawInfo drawData) => base.DrawEffects(i, j, spriteBatch, ref drawData); - - public override void SetDrawPositions(int i, int j, ref int width, ref int offsetY, ref int height, ref short tileFrameX, ref short tileFrameY) => base.SetDrawPositions(i, j, ref width, ref offsetY, ref height, ref tileFrameX, ref tileFrameY); + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + int maxTimer = 0; + foreach (var timer in YggdrasilTownFurnaceSystem.MeltingAnimationTimer) + { + if (timer > maxTimer) + { + maxTimer = timer; + } + } + maxTimer -= 80; + if (maxTimer > 0) + { + var tile = Main.tile[i, j]; + float value = maxTimer / 40f; + if (tile.TileFrameX == 36 && tile.TileFrameY == 18) + { + var zero = new Vector2(Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + var glow = ModAsset.FurnaceMeltingChest_meltingGlow.Value; + spriteBatch.Draw(glow, new Vector2(i, j) * 16 - Main.screenPosition + zero + new Vector2(-28, -14), null, new Color(1f, 1f, 1f, 0) * value, 0, Vector2.zeroVector, 1, SpriteEffects.None, 0); - public override void SpecialDraw(int i, int j, SpriteBatch spriteBatch) => base.SpecialDraw(i, j, spriteBatch); + var bloom = ModAsset.FurnaceMeltingChest_meltingBloom.Value; + spriteBatch.Draw(bloom, new Vector2(i, j) * 16 - Main.screenPosition + zero + new Vector2(-28 - 28, -14 - 32), null, new Color(1f, 1f, 1f, 0) * value, 0, Vector2.zeroVector, 1, SpriteEffects.None, 0); + } + Lighting.AddLight(new Vector2(i, j) * 16 + new Vector2(8), new Vector3(2f, 1.1f, 0.3f) * value); + } + } public override bool RightClick(int i, int j) { @@ -262,13 +289,12 @@ public override void MouseOver(int i, int j) Chest chest = Main.chest[chestIndex]; if (chest.frame == 0) { - } string defaultName = TileLoader.DefaultContainerName(tile.TileType, tile.TileFrameX, tile.TileFrameY); // This gets the ContainerName text for the currently selected language player.cursorItemIconText = chest.name.Length > 0 ? chest.name : defaultName; if (player.cursorItemIconText == defaultName) { - player.cursorItemIconID = ModContent.ItemType(); + player.cursorItemIconID = ModContent.ItemType(); player.cursorItemIconText = string.Empty; } } @@ -284,7 +310,7 @@ public override void MouseOverFar(int i, int j) if (player.cursorItemIconText == string.Empty) { player.cursorItemIconEnabled = false; - player.cursorItemIconID = 0; + player.cursorItemIconID = ItemID.None; } } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/MeltingInputBox.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest.png similarity index 100% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/MeltingInputBox.png rename to Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest.png diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/MeltingInputBox_Highlight.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest_Highlight.png similarity index 100% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/MeltingInputBox_Highlight.png rename to Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest_Highlight.png diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest_MeltingIcon.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest_MeltingIcon.png new file mode 100644 index 000000000..adf1329c5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest_MeltingIcon.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest_meltingBloom.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest_meltingBloom.png new file mode 100644 index 000000000..e47761362 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest_meltingBloom.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest_meltingGlow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest_meltingGlow.png new file mode 100644 index 000000000..dd5e052be Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceMeltingChest_meltingGlow.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceNumberAxis.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceNumberAxis.cs index 76fce9c75..aab9500ae 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceNumberAxis.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceNumberAxis.cs @@ -3,65 +3,65 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; [Pipeline(typeof(WCSPipeline))] -public class FurnaceNumberAxis : BackgroundVFX +public class FurnaceNumberAxis : TileVFX { public override CodeLayer DrawLayer => CodeLayer.PostDrawTiles; public override void Update() { - if (originTile.X > 0 && originTile.X < Main.maxTilesX) + if (OriginTilePos.X > 0 && OriginTilePos.X < Main.maxTilesX) { - if (originTile.Y > 0 && originTile.Y < Main.maxTilesY) + if (OriginTilePos.Y > 0 && OriginTilePos.Y < Main.maxTilesY) { - Tile tile = Main.tile[originTile.X, originTile.Y]; + Tile tile = Main.tile[OriginTilePos.X, OriginTilePos.Y]; if (tile != null) { if (TileLoader.GetTile(tile.TileType) is ISceneTile) { - if (tile.TileType == originType) + if (tile.TileType == OriginTileType) { if (!tile.HasTile) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - Vector2 checkPos = position; + Vector2 checkPos = Position; if (VFXManager.InScreen(checkPos, 1500)) { Visible = true; @@ -69,7 +69,7 @@ public override void Update() else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } Score = YggdrasilTownFurnaceSystem.CurrentScore; @@ -112,7 +112,7 @@ public override void Update() public override void OnSpawn() { - texture = ModAsset.FurnaceNumberAxis.Value; + Texture = ModAsset.FurnaceNumberAxis.Value; } public override void Draw() @@ -124,41 +124,41 @@ public override void Draw() { int value = NumberSlotFrameY[i]; Vector2 frameXY = new Vector2(0, value * frameSize.Y); - var drawPos = position + new Vector2(i * 36 + 22, 25); + var drawPos = Position + new Vector2(i * 36 + 22, 25); var topLeft = drawPos + new Vector2(-frameSize.X, -frameSize.Y) * 0.5f; var topRight = drawPos + new Vector2(frameSize.X, -frameSize.Y) * 0.5f; var bottomLeft = drawPos + new Vector2(-frameSize.X, frameSize.Y) * 0.5f; var bottomRight = drawPos + new Vector2(frameSize.X, frameSize.Y) * 0.5f; - bars.Add(topLeft, GetColor(topLeft), new Vector3(frameXY / texture.Size(), 0)); - bars.Add(topRight, GetColor(topRight), new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y) / texture.Size(), 0)); - bars.Add(bottomRight, GetColor(bottomRight), new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); + bars.Add(topLeft, GetColor(topLeft), new Vector3(frameXY / Texture.Size(), 0)); + bars.Add(topRight, GetColor(topRight), new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y) / Texture.Size(), 0)); + bars.Add(bottomRight, GetColor(bottomRight), new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / Texture.Size(), 0)); - bars.Add(topLeft, GetColor(topLeft), new Vector3(frameXY / texture.Size(), 0)); - bars.Add(bottomRight, GetColor(bottomRight), new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); - bars.Add(bottomLeft, GetColor(bottomLeft), new Vector3(new Vector2(frameXY.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); + bars.Add(topLeft, GetColor(topLeft), new Vector3(frameXY / Texture.Size(), 0)); + bars.Add(bottomRight, GetColor(bottomRight), new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / Texture.Size(), 0)); + bars.Add(bottomLeft, GetColor(bottomLeft), new Vector3(new Vector2(frameXY.X, frameXY.Y + frameSize.Y) / Texture.Size(), 0)); frameXY = new Vector2(36, value * frameSize.Y); float reflectValue = 2f; - bars.Add(topLeft, GetColor(topLeft) * reflectValue, new Vector3(frameXY / texture.Size(), 0)); - bars.Add(topRight, GetColor(topRight) * reflectValue, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y) / texture.Size(), 0)); - bars.Add(bottomRight, GetColor(bottomRight) * reflectValue, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); + bars.Add(topLeft, GetColor(topLeft) * reflectValue, new Vector3(frameXY / Texture.Size(), 0)); + bars.Add(topRight, GetColor(topRight) * reflectValue, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y) / Texture.Size(), 0)); + bars.Add(bottomRight, GetColor(bottomRight) * reflectValue, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / Texture.Size(), 0)); - bars.Add(topLeft, GetColor(topLeft) * reflectValue, new Vector3(frameXY / texture.Size(), 0)); - bars.Add(bottomRight, GetColor(bottomRight) * reflectValue, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); - bars.Add(bottomLeft, GetColor(bottomLeft) * reflectValue, new Vector3(new Vector2(frameXY.X, frameXY.Y + frameSize.Y) / texture.Size(), 0)); + bars.Add(topLeft, GetColor(topLeft) * reflectValue, new Vector3(frameXY / Texture.Size(), 0)); + bars.Add(bottomRight, GetColor(bottomRight) * reflectValue, new Vector3(new Vector2(frameXY.X + frameSize.X, frameXY.Y + frameSize.Y) / Texture.Size(), 0)); + bars.Add(bottomLeft, GetColor(bottomLeft) * reflectValue, new Vector3(new Vector2(frameXY.X, frameXY.Y + frameSize.Y) / Texture.Size(), 0)); } if (bars.Count <= 0) { - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); } - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleList); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleList); } public Color GetColor(Vector2 drawPos) @@ -166,14 +166,14 @@ public Color GetColor(Vector2 drawPos) return Lighting.GetColor(drawPos.ToTileCoordinates()); } - public int GetDigitAtPosition(int number, int position) + public int GetDigitAtPosition(int number, int Position) { string numberStr = number.ToString(); - if (position < 1 || position > numberStr.Length) + if (Position < 1 || Position > numberStr.Length) { return -1; } - char digitChar = numberStr[numberStr.Length - position]; + char digitChar = numberStr[numberStr.Length - Position]; return (int)char.GetNumericValue(digitChar); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceScoreShop.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceScoreShop.cs new file mode 100644 index 000000000..2dc91f48c --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceScoreShop.cs @@ -0,0 +1,183 @@ +using Everglow.Commons.UI; +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Yggdrasil.YggdrasilTown.UI; +using Terraria.GameContent; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; + +public class FurnaceScoreShop : BackgroundSlideBase +{ + public Point TileAnchor; + + public List BgTiles = new List(); + + public List GlowFrames = new List(); + + /// + /// A dictionary mapping item types to their sell prices in furnace scores(type, sellPrice). + /// + public static Dictionary SellPricesInFurnaceScore = new Dictionary(); + + /// + /// 0:Normal, 1:Talk, 2:Play + /// + public int SaleGirlState = 0; + + public int SaleGirlAnimationTimer = 0; + + public bool MouseOverSaleGirl = false; + + public bool OpenShop = false; + + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.FurnaceScoreShop.Value; + Distance = 1; + UseColorStyle = 1; + LayerPriority = 1; + Shader = Effects.XWrap_YWrap_Shader; + } + + public override void Update() + { + base.Update(); + Player player = Main.LocalPlayer; + if (SaleGirlAnimationTimer == 0) + { + int k = Main.rand.Next(10); + if (k <= 5) + { + SaleGirlState = 0; + } + else if (k <= 8) + { + SaleGirlState = 1; + } + else + { + SaleGirlState = 2; + } + switch (SaleGirlState) + { + case 0: + SaleGirlAnimationTimer = Main.rand.Next(300, 900); + break; + case 1: + SaleGirlAnimationTimer = 120; + break; + case 2: + SaleGirlAnimationTimer = 180; + break; + } + } + else + { + SaleGirlAnimationTimer--; + } + Vector2 girlPos = WorldAnchor + new Vector2(1935, 492); + MouseOverSaleGirl = false; + Rectangle girlHitBox = new Rectangle((int)girlPos.X, (int)girlPos.Y, 58, 36); + if (girlHitBox.Contains(Main.MouseWorld.ToPoint())) + { + Main.instance.MouseText("Furnace Points Redemption"); + MouseOverSaleGirl = true; + if (Main.mouseRight && Main.mouseRightRelease && CanInteract()) + { + Main.playerInventory = true; + YggdrasilTownFurnaceSystem.FurnaceScoreShopOpen = true; + UISystem.Instance.CurrentSpecialShop = 0; + OpenShop = true; + } + } + if (!Main.playerInventory) + { + YggdrasilTownFurnaceSystem.FurnaceScoreShopOpen = false; + UISystem.Instance.CurrentSpecialShop = -1; + OpenShop = false; + } + if (OpenShop) + { + if (!CanInteract()) + { + YggdrasilTownFurnaceSystem.FurnaceScoreShopOpen = false; + UISystem.Instance.CurrentSpecialShop = -1; + FurnaceScoreShopUI.Instance.Close(); + OpenShop = false; + } + else + { + if (player.talkNPC != -1) + { + player.talkNPC = -1; + } + FurnaceScoreShopUI.Instance.Show(); + } + } + else + { + if (FurnaceScoreShopUI.Instance.IsVisible) + { + FurnaceScoreShopUI.Instance.Close(); + } + } + } + + public override void Draw() + { + var bars = new List(); + BackgroundHigherPerformanceHelper.Add_TileBgVertice(this, BgTiles, bars, 1); + DrawVertexBackground(this, PrimitiveType.TriangleStrip, bars); + Player player = Main.LocalPlayer; + + Texture2D girl = ModAsset.FurnaceScoreShop_SaleGirl.Value; + Vector2 pos = WorldAnchor + new Vector2(1964, 528); + var girlFrame = new Rectangle(0, 0, 58, 36); + switch (SaleGirlState) + { + case 0: + girlFrame.Y = 0; + if (SaleGirlAnimationTimer % 240 is > 120 and < 130) + { + girlFrame.Y = 36; + } + break; + case 1: + girlFrame.Y = 72 + SaleGirlAnimationTimer / 12 % 4 * 36; + break; + case 2: + girlFrame.Y = 216 + (180 - SaleGirlAnimationTimer) / 10 % 18 * 36; + break; + } + SpriteEffects flip = SpriteEffects.None; + int k = Player.FindClosest(pos, 1, 1); + int dir = 1; + if (k >= 0) + { + Player closestPlayer = Main.player[k]; + if (closestPlayer.Center.X < pos.X) + { + flip = SpriteEffects.FlipHorizontally; + dir = -1; + } + } + Main.spriteBatch.Draw(girl, pos - Main.screenPosition, girlFrame, Lighting.GetColor(pos.ToTileCoordinates()), 0, new Vector2(girlFrame.Width * 0.5f, girlFrame.Height), 1f, flip, 0); + if (MouseOverSaleGirl && CanInteract()) + { + Texture2D chatBubble = TextureAssets.Chat.Value; + Main.spriteBatch.Draw(chatBubble, pos - Main.screenPosition + new Vector2(-16 + 16 * dir, -16), null, Lighting.GetColor(pos.ToTileCoordinates()), 0, new Vector2(0, chatBubble.Height), 1f, flip, 0); + } + } + + public bool CanInteract() + { + Player player = Main.LocalPlayer; + Vector2 pos = WorldAnchor + new Vector2(1964, 528); + return (player.Center - pos).Length() < new Vector2(player.lastTileRangeX, player.lastTileRangeY).Length() * 16 + 16 && player.chest == -1; + } + + public override bool CanActive() + { + return TileUtils.SafeGetTile(TileAnchor).TileType == ModContent.TileType(); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceScoreShop.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceScoreShop.png new file mode 100644 index 000000000..fb199e570 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceScoreShop.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceScoreShop_SaleGirl.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceScoreShop_SaleGirl.png new file mode 100644 index 000000000..91980da05 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceScoreShop_SaleGirl.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceScreen_Animation.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceScreen_Animation.png new file mode 100644 index 000000000..c0ea6a248 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/FurnaceScreen_Animation.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace.cs index b7ed19b33..1fcbf59d0 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace.cs @@ -45,14 +45,14 @@ public override void SetStaticDefaults() public void AddScene(int i, int j) { Tile tile = Main.tile[i, j]; - if (tile.TileFrameX == 468 && tile.TileFrameY == 702) - { - var scene = new GiantFurnace_Body { position = new Vector2(i, j) * 16 + new Vector2(-226, -640), Active = true, originTile = new Point(i, j), originType = Type }; - Ins.VFXManager.Add(scene); - } + //if (tile.TileFrameX == 468 && tile.TileFrameY == 702) + //{ + // var scene = new GiantFurnace_Body { Position = new Vector2(i, j) * 16 + new Vector2(-226, -640), Active = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; + // Ins.VFXManager.Add(scene); + //} if (tile.TileFrameX == 468 && tile.TileFrameY == 306) { - var scene = new GiantFurnace_LavaWindow { position = new Vector2(i, j) * 16 + new Vector2(-46, 12), Active = true, originTile = new Point(i, j), originType = Type }; + var scene = new GiantFurnace_LavaWindow { Position = new Vector2(i, j) * 16 + new Vector2(-46, 14), Active = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(scene); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace.png index 7c1aabaf0..871c0c4a8 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Block.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Block.cs index 49b4d40eb..b5164bb69 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Block.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Block.cs @@ -28,13 +28,13 @@ public void AddScene(int i, int j) Tile tile = Main.tile[i, j]; if (tile.TileFrameX == 126 && tile.TileFrameY == 144) { - GiantFurnace_TopFence scene = new GiantFurnace_TopFence { position = new Vector2(i, j) * 16 + new Vector2(-18, -26), Active = true, originTile = new Point(i, j), originType = Type }; + GiantFurnace_TopFence scene = new GiantFurnace_TopFence { Position = new Vector2(i, j) * 16 + new Vector2(-18, -26), Active = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(scene); } if (tile.TileFrameX == 360 && tile.TileFrameY == 522) { - GiantFurnace_MiddleFence scene = new GiantFurnace_MiddleFence { position = new Vector2(i, j) * 16 + new Vector2(-10, -18), Active = true, originTile = new Point(i, j), originType = Type }; + GiantFurnace_MiddleFence scene = new GiantFurnace_MiddleFence { Position = new Vector2(i, j) * 16 + new Vector2(-10, -18), Active = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(scene); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Body.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Body.cs deleted file mode 100644 index d820ea629..000000000 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Body.cs +++ /dev/null @@ -1,116 +0,0 @@ -using Everglow.Commons.VFX.Scene; - -namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; - -[Pipeline(typeof(WCSPipeline))] -public class GiantFurnace_Body : BackgroundVFX -{ - public override void Update() - { - if (originTile.X > 0 && originTile.X < Main.maxTilesX) - { - if (originTile.Y > 0 && originTile.Y < Main.maxTilesY) - { - Tile tile = Main.tile[originTile.X, originTile.Y]; - if (tile != null) - { - if (TileLoader.GetTile(tile.TileType) is ISceneTile) - { - if (tile.TileType == originType) - { - if (!tile.HasTile) - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - Vector2 checkPos = position; - if (VFXManager.InScreen(checkPos, 1500)) - { - Visible = true; - } - else - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - } - - public override void OnSpawn() - { - texture = ModAsset.GiantFurnace_Body.Value; - } - - public override void Draw() - { - var bars = new List(); - float width = 15; - float height = 26; - for (int i = 0; i < width; i++) - { - for (int j = 0; j < height; j++) - { - Color lightColor0 = Lighting.GetColor((int)position.X / 16 + i * 2, (int)position.Y / 16 + j * 2); - Color lightColor1 = Lighting.GetColor((int)position.X / 16 + i * 2 + 2, (int)position.Y / 16 + j * 2); - Color lightColor2 = Lighting.GetColor((int)position.X / 16 + i * 2, (int)position.Y / 16 + j * 2 + 2); - Color lightColor3 = Lighting.GetColor((int)position.X / 16 + i * 2 + 2, (int)position.Y / 16 + j * 2 + 2); - - bars.Add(position + new Vector2(i, j) * 32, lightColor0, new Vector3(i / width, j / height, 0)); - bars.Add(position + new Vector2(i + 1, j) * 32, lightColor1, new Vector3((i + 1) / width, j / height, 0)); - bars.Add(position + new Vector2(i, j + 1) * 32, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); - - bars.Add(position + new Vector2(i, j + 1) * 32, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); - bars.Add(position + new Vector2(i + 1, j) * 32, lightColor1, new Vector3((i + 1) / width, j / height, 0)); - bars.Add(position + new Vector2(i + 1, j + 1) * 32, lightColor3, new Vector3((i + 1) / width, (j + 1) / height, 0)); - } - } - - if (bars.Count <= 0) - { - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - } - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleList); - } -} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Body.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Body.png deleted file mode 100644 index 9702a55d9..000000000 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Body.png and /dev/null differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct.cs new file mode 100644 index 000000000..63b0596b2 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct.cs @@ -0,0 +1,139 @@ +using System.Timers; +using Everglow.Commons.Utilities.BackgroundHelper; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; + +public class GiantFurnace_Construct : BackgroundSlideBase +{ + public Point TileAnchor; + + public List BgTiles = new List(); + + public List GlowFrames = new List(); + + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.GiantFurnace_Construct.Value; + Distance = 1; + UseColorStyle = 1; + LayerPriority = 1; + Shader = Effects.XWrap_YWrap_Shader; + + Rectangle currentFrame = new Rectangle(0, 158, 6, 6); + Point step = new Point(0, 14); + for (int k = 0; k < 78; k++) + { + switch (k) + { + case 1: + step = new Point(4, 10); + break; + case 2: + step = new Point(18, 2); + break; + case 3: + step = new Point(16, 0); + break; + case 45: + step = new Point(8, -4); + break; + case 46: + step = new Point(2, -14); + break; + case 47: + step = new Point(0, -16); + break; + case 51: + step = new Point(-4, -10); + break; + case 52: + step = new Point(-14, -2); + break; + case 53: + step = new Point(-16, 0); + break; + case 67: + step = new Point(-18, 0); + break; + case 68: + step = new Point(0, -10); + break; + case 69: + step = new Point(0, -16); + break; + default: + break; + } + GlowFrames.Add(currentFrame); + currentFrame.X += step.X; + currentFrame.Y += step.Y; + } + } + + public override void Update() + { + base.Update(); + for (int i = 0; i < 76; i++) + { + Vector2 worldPos = new Vector2(i * 16, 0) + WorldAnchor - (new Vector2(47, 63 - 92) * 16 + new Vector2(4, 24)); + Lighting.AddLight(worldPos, new Vector3(3f, 1.8f, 0.6f)); + } + } + + public override void Draw() + { + var bars = new List(); + BackgroundHigherPerformanceHelper.Add_TileBgVertice(this, BgTiles, bars, 3); + DrawVertexBackground(this, PrimitiveType.TriangleStrip, bars); + + Texture2D glow = ModAsset.GiantFurnace_Construct_glow.Value; + Vector2 pos = WorldAnchor - Main.screenPosition + new Vector2(-412, 288); + foreach (var timer in YggdrasilTownFurnaceSystem.MeltingAnimationTimer) + { + if (timer > 0) + { + float value = (120 - timer) / 120f * 1.2f; + value -= 0.1f; + for (int i = 0; i < GlowFrames.Count; i++) + { + float index = i / (float)GlowFrames.Count * 1.05f; + float valueLerp = index - value; + valueLerp *= 10; + if (valueLerp is >= 0 and <= 1f) + { + var frame = GlowFrames[i]; + var color = Color.Lerp(new Color(1f, 0.75f, 0.1f, 1), new Color(0.4f, 0f, 0, 0), 1 - valueLerp); + color = Color.Lerp(color, new Color(0, 0, 0, 0), 1 - valueLerp); + Main.spriteBatch.Draw(glow, new Rectangle((int)pos.X + frame.X, (int)pos.Y + frame.Y, frame.Width, frame.Height), GlowFrames[i], color); + if (i <= 73) + { + Lighting.AddLight(WorldAnchor + new Vector2(-412 + frame.X, 288 + frame.Y), color.ToVector3() * 2); + } + } + } + } + } + Texture2D screen = ModAsset.FurnaceScreen_Animation.Value; + if (YggdrasilTownFurnaceSystem.CurrentPlayer is not null || YggdrasilTownFurnaceSystem.PlayerLeaveFloorScaleTimer > 0) + { + var frame = new Rectangle(0, 0, 80, 48); + if (YggdrasilTownFurnaceSystem.PlayerDropInFloorScaleTimer > 0) + { + int value = (int)((30 - YggdrasilTownFurnaceSystem.PlayerDropInFloorScaleTimer) / 30f * 7f); + frame = new Rectangle(0, 336 + 48 * value, 80, 48); + } + if (YggdrasilTownFurnaceSystem.PlayerLeaveFloorScaleTimer > 0) + { + int value = (int)((30 - YggdrasilTownFurnaceSystem.PlayerLeaveFloorScaleTimer) / 30f * 7f); + frame = new Rectangle(0, 48 * value, 80, 48); + } + Main.spriteBatch.Draw(screen, new Rectangle((int)pos.X - 166, (int)pos.Y + 96, frame.Width, frame.Height), frame, Color.White); + } + } + + public override bool CanActive() + { + return TileUtils.SafeGetTile(TileAnchor).TileType == ModContent.TileType(); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct.png new file mode 100644 index 000000000..24b363285 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_far.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_far.cs new file mode 100644 index 000000000..cf6b82aa3 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_far.cs @@ -0,0 +1,37 @@ +using Everglow.Commons.Utilities.BackgroundHelper; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; + +public class GiantFurnace_Construct_far : BackgroundSlideBase +{ + public Point TileAnchor; + + public List BgTiles = new List(); + + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.GiantFurnace_Construct_far.Value; + Distance = 1.5f; + UseColorStyle = 2; + LayerPriority = 1; + Shader = Effects.XClamp_YClamp_Shader; + } + + public override void Update() + { + base.Update(); + } + + public override void Draw() + { + var bars = new List(); + BackgroundHigherPerformanceHelper.Add_TileBgVertice(this, BgTiles, bars, 3); + DrawVertexBackground(this, PrimitiveType.TriangleStrip, bars); + } + + public override bool CanActive() + { + return TileUtils.SafeGetTile(TileAnchor).TileType == ModContent.TileType(); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_far.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_far.png new file mode 100644 index 000000000..831be43f6 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_far.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_far2.pdn b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_far2.pdn new file mode 100644 index 000000000..f06a6e5b4 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_far2.pdn differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_glow.png new file mode 100644 index 000000000..2fce7072c Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_glow.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_sky.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_sky.cs new file mode 100644 index 000000000..10da8ac40 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_sky.cs @@ -0,0 +1,43 @@ +using Everglow.Commons.Utilities.BackgroundHelper; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; + +public class GiantFurnace_Construct_sky : BackgroundSlideBase +{ + public Point TileAnchor; + + public List BgTiles = new List(); + + public override void SetDefaults() + { + base.SetDefaults(); + Texture = ModAsset.GiantFurnace_Construct_sky.Value; + Distance = 3; + UseColorStyle = 2; + LayerPriority = 1; + Shader = Effects.XWrap_YClamp_Shader; + } + + public override void Update() + { + base.Update(); + //if(Main.mouseLeft && Main.mouseLeftRelease) + //{ + // Distance = 3; + // WorldAnchor.Y = 320000; + // Main.NewText(WorldAnchor.Y); + //} + } + + public override void Draw() + { + var bars = new List(); + BackgroundHigherPerformanceHelper.Add_TileBgVertice(this, BgTiles, bars, 10); + DrawVertexBackground(this, PrimitiveType.TriangleStrip, bars); + } + + public override bool CanActive() + { + return TileUtils.SafeGetTile(TileAnchor).TileType == ModContent.TileType(); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_sky.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_sky.png new file mode 100644 index 000000000..9a4700566 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Construct_sky.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_LavaWindow.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_LavaWindow.cs index c932ec9bc..5518eb4ee 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_LavaWindow.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_LavaWindow.cs @@ -3,8 +3,10 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; [Pipeline(typeof(GiantFurnace_LavaWindowPipeline), typeof(BloomPipeline))] -public class GiantFurnace_LavaWindow : BackgroundVFX +public class GiantFurnace_LavaWindow : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawBG; + public override void Update() { base.Update(); @@ -12,26 +14,27 @@ public override void Update() public override void OnSpawn() { - texture = ModAsset.GiantFurnace_LavaWindow.Value; + Texture = ModAsset.GiantFurnace_LavaWindow.Value; } public override void Draw() { var bars = new List(); - Color drawColor = new Color(1f, 0.7f, 0.4f, 1f); - bars.Add(position + new Vector2(0, 0), drawColor, new Vector3(0, 0, 0)); - bars.Add(position + new Vector2(texture.Width, 0), drawColor, new Vector3(1, 0, 0)); - bars.Add(position + new Vector2(0, texture.Height), drawColor, new Vector3(0, 1, 0)); - bars.Add(position + new Vector2(texture.Width, texture.Height), drawColor, new Vector3(1, 1, 0)); + Color drawColor = new Color(1f, 1f, 1f, 1f); + var pos = Position - Main.screenPosition; + bars.Add(pos + new Vector2(0, 0), drawColor, new Vector3(0, 0, 0)); + bars.Add(pos + new Vector2(Texture.Width, 0), drawColor, new Vector3(1, 0, 0)); + bars.Add(pos + new Vector2(0, Texture.Height), drawColor, new Vector3(0, 1, 0)); + bars.Add(pos + new Vector2(Texture.Width, Texture.Height), drawColor, new Vector3(1, 1, 0)); if (bars.Count <= 0) { - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(pos, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(pos, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(pos, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(pos, Color.Transparent, new Vector3(0, 0, 0)); } - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleStrip); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_LavaWindowPipeline.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_LavaWindowPipeline.cs index 79dbb09a8..0f13c8cb8 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_LavaWindowPipeline.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_LavaWindowPipeline.cs @@ -6,10 +6,6 @@ public class GiantFurnace_LavaWindowPipeline : Pipeline public override void BeginRender() { Ins.Batch.Begin(); - effect.Value.Parameters["uTransform"].SetValue( - Matrix.CreateTranslation(new Vector3(-Main.screenPosition, 0)) * - Main.GameViewMatrix.TransformationMatrix * - Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1)); effect.Value.CurrentTechnique.Passes[0].Apply(); effect.Value.Parameters["uSize"].SetValue(0.6f); effect.Value.Parameters["uTime"].SetValue((float)Main.time * 0.01f); @@ -24,6 +20,6 @@ public override void EndRender() public override void Load() { - effect = ModAsset.LavaWindow; + effect = ModAsset.GiantFurnace_LavaWindow_shader; } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/LavaWindow.fx b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_LavaWindow_shader.fx similarity index 67% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/LavaWindow.fx rename to Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_LavaWindow_shader.fx index e687ddf52..c9e9e9dba 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/LavaWindow.fx +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_LavaWindow_shader.fx @@ -24,15 +24,6 @@ sampler_state AddressV = CLAMP; }; -float4x4 uTransform; - -struct VSInput -{ - float2 Pos : POSITION0; - float4 Color : COLOR0; - float3 Texcoord : TEXCOORD0; -}; - struct PSInput { float4 Pos : SV_POSITION; @@ -40,15 +31,6 @@ struct PSInput float3 Texcoord : TEXCOORD0; }; -PSInput VertexShaderFunction(VSInput input) -{ - PSInput output; - output.Color = input.Color; - output.Texcoord = input.Texcoord; - output.Pos = mul(float4(input.Pos, 0, 1), uTransform); - return output; -} - float4 PixelShaderFunction(PSInput input) : COLOR0 { float4 drawColor=input.Color; @@ -56,18 +38,23 @@ float4 PixelShaderFunction(PSInput input) : COLOR0 float4 col = tex2D(uImage0, uv); float lightColor = tex2D(uLightSampler, uv * uSize + float2(0, uTime * 0.05)).r; float uLavaLevelHeight = 0.25; + if(!any(col)) + { + return float4(0, 0, 0, 0); + } + for (int k = 0; k < 8;k++) { uLavaLevelHeight += 0.04 * pow(2, -k) * sin(uTime * cos(k * 3.73) + uv.x * 4 * pow(2, k)); } - float4 lavaColor = tex2D(uHeatmapSampler, lightColor); + float4 lavaColor = float4(1,0.5,0,1); if (uv.y < uLavaLevelHeight) { - return float4(91 / 255, 43 / 255, 40/ 255, 1); + return float4(0.3, 0.1, 0.18, 1); } if (uv.y < uLavaLevelHeight + 0.03) { - lavaColor = tex2D(uHeatmapSampler, 0.99); + lavaColor = float4(0.75, 0, 0, 1); } return col * lavaColor * input.Color; } @@ -76,7 +63,6 @@ technique Technique1 { pass Shader2D { - VertexShader = compile vs_3_0 VertexShaderFunction(); PixelShader = compile ps_3_0 PixelShaderFunction(); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_MiddleFence.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_MiddleFence.cs index f0ce1d35a..5d9d5ba9f 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_MiddleFence.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_MiddleFence.cs @@ -3,8 +3,9 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; [Pipeline(typeof(WCSPipeline))] -public class GiantFurnace_MiddleFence : ForegroundVFX +public class GiantFurnace_MiddleFence : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; public override void Update() { base.Update(); @@ -12,7 +13,7 @@ public override void Update() public override void OnSpawn() { - texture = ModAsset.GiantFurnace_MiddleFence.Value; + Texture = ModAsset.GiantFurnace_MiddleFence.Value; } public override void Draw() @@ -24,31 +25,31 @@ public override void Draw() { for (int j = 0; j < height; j++) { - Color lightColor0 = Lighting.GetColor((int)position.X / 16 + i, (int)position.Y / 16 + j); - Color lightColor1 = Lighting.GetColor((int)position.X / 16 + i + 1, (int)position.Y / 16 + j); - Color lightColor2 = Lighting.GetColor((int)position.X / 16 + i, (int)position.Y / 16 + j + 1); - Color lightColor3 = Lighting.GetColor((int)position.X / 16 + i + 1, (int)position.Y / 16 + j + 1); - - bars.Add(position + new Vector2(i, j) * 16, lightColor0, new Vector3(i / width, j / height, 0)); - bars.Add(position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); - bars.Add(position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); - - bars.Add(position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); - bars.Add(position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); - bars.Add(position + new Vector2(i + 1, j + 1) * 16, lightColor3, new Vector3((i + 1) / width, (j + 1) / height, 0)); + Color lightColor0 = Lighting.GetColor((int)Position.X / 16 + i, (int)Position.Y / 16 + j); + Color lightColor1 = Lighting.GetColor((int)Position.X / 16 + i + 1, (int)Position.Y / 16 + j); + Color lightColor2 = Lighting.GetColor((int)Position.X / 16 + i, (int)Position.Y / 16 + j + 1); + Color lightColor3 = Lighting.GetColor((int)Position.X / 16 + i + 1, (int)Position.Y / 16 + j + 1); + + bars.Add(Position + new Vector2(i, j) * 16, lightColor0, new Vector3(i / width, j / height, 0)); + bars.Add(Position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); + bars.Add(Position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); + + bars.Add(Position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); + bars.Add(Position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); + bars.Add(Position + new Vector2(i + 1, j + 1) * 16, lightColor3, new Vector3((i + 1) / width, (j + 1) / height, 0)); } } if (bars.Count <= 0) { - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); } - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleList); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleList); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_MiddleFence.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_MiddleFence.png index f1020bd7c..4c6b7d720 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_MiddleFence.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_MiddleFence.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Platform.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Platform.cs index 9c2ce098c..6c1e9c9f5 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Platform.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_Platform.cs @@ -48,7 +48,7 @@ public void AddScene(int i, int j) Tile tile = Main.tile[i, j]; if (tile.TileFrameX == 648 && tile.TileFrameY == 144) { - var scene = new GiantFurnace_SideLadder { position = new Vector2(i, j) * 16 + new Vector2(-16, -4), Active = true, originTile = new Point(i, j), originType = Type }; + var scene = new GiantFurnace_SideLadder { Position = new Vector2(i, j) * 16 + new Vector2(-16, -4), Active = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(scene); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_SideLadder.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_SideLadder.cs index 524ee59ee..a89d3f794 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_SideLadder.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_SideLadder.cs @@ -3,63 +3,65 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; [Pipeline(typeof(WCSPipeline))] -public class GiantFurnace_SideLadder : BackgroundVFX +public class GiantFurnace_SideLadder : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawBG; + public override void Update() { - if (originTile.X > 0 && originTile.X < Main.maxTilesX) + if (OriginTilePos.X > 0 && OriginTilePos.X < Main.maxTilesX) { - if (originTile.Y > 0 && originTile.Y < Main.maxTilesY) + if (OriginTilePos.Y > 0 && OriginTilePos.Y < Main.maxTilesY) { - Tile tile = Main.tile[originTile.X, originTile.Y]; + Tile tile = Main.tile[OriginTilePos.X, OriginTilePos.Y]; if (tile != null) { if (TileLoader.GetTile(tile.TileType) is ISceneTile) { - if (tile.TileType == originType) + if (tile.TileType == OriginTileType) { if (!tile.HasTile) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - Vector2 checkPos = position; + Vector2 checkPos = Position; if (VFXManager.InScreen(checkPos, 1500)) { Visible = true; @@ -67,14 +69,14 @@ public override void Update() else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } public override void OnSpawn() { - texture = ModAsset.GiantFurnace_SideLadder.Value; + Texture = ModAsset.GiantFurnace_SideLadder.Value; } public override void Draw() @@ -86,31 +88,31 @@ public override void Draw() { for (int j = 0; j < height; j++) { - Color lightColor0 = Lighting.GetColor((int)position.X / 16 + i, (int)position.Y / 16 + j); - Color lightColor1 = Lighting.GetColor((int)position.X / 16 + i + 1, (int)position.Y / 16 + j); - Color lightColor2 = Lighting.GetColor((int)position.X / 16 + i, (int)position.Y / 16 + j + 1); - Color lightColor3 = Lighting.GetColor((int)position.X / 16 + i + 1, (int)position.Y / 16 + j + 1); + Color lightColor0 = Lighting.GetColor((int)Position.X / 16 + i, (int)Position.Y / 16 + j); + Color lightColor1 = Lighting.GetColor((int)Position.X / 16 + i + 1, (int)Position.Y / 16 + j); + Color lightColor2 = Lighting.GetColor((int)Position.X / 16 + i, (int)Position.Y / 16 + j + 1); + Color lightColor3 = Lighting.GetColor((int)Position.X / 16 + i + 1, (int)Position.Y / 16 + j + 1); - bars.Add(position + new Vector2(i, j) * 16, lightColor0, new Vector3(i / width, j / height, 0)); - bars.Add(position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); - bars.Add(position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); + bars.Add(Position + new Vector2(i, j) * 16, lightColor0, new Vector3(i / width, j / height, 0)); + bars.Add(Position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); + bars.Add(Position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); - bars.Add(position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); - bars.Add(position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); - bars.Add(position + new Vector2(i + 1, j + 1) * 16, lightColor3, new Vector3((i + 1) / width, (j + 1) / height, 0)); + bars.Add(Position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); + bars.Add(Position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); + bars.Add(Position + new Vector2(i + 1, j + 1) * 16, lightColor3, new Vector3((i + 1) / width, (j + 1) / height, 0)); } } if (bars.Count <= 0) { - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); } - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleList); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleList); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_SideLadder.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_SideLadder.png index bd1f81dd0..cf8a0dd05 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_SideLadder.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_SideLadder.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_TopFence.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_TopFence.cs index f436d1cad..be0d680dd 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_TopFence.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_TopFence.cs @@ -3,8 +3,9 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; [Pipeline(typeof(WCSPipeline))] -public class GiantFurnace_TopFence : ForegroundVFX +public class GiantFurnace_TopFence : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; public override void Update() { base.Update(); @@ -12,7 +13,7 @@ public override void Update() public override void OnSpawn() { - texture = ModAsset.GiantFurnace_TopFence.Value; + Texture = ModAsset.GiantFurnace_TopFence.Value; } public override void Draw() @@ -24,31 +25,31 @@ public override void Draw() { for (int j = 0; j < height; j++) { - Color lightColor0 = Lighting.GetColor((int)position.X / 16 + i, (int)position.Y / 16 + j); - Color lightColor1 = Lighting.GetColor((int)position.X / 16 + i + 1, (int)position.Y / 16 + j); - Color lightColor2 = Lighting.GetColor((int)position.X / 16 + i, (int)position.Y / 16 + j + 1); - Color lightColor3 = Lighting.GetColor((int)position.X / 16 + i + 1, (int)position.Y / 16 + j + 1); - - bars.Add(position + new Vector2(i, j) * 16, lightColor0, new Vector3(i / width, j / height, 0)); - bars.Add(position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); - bars.Add(position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); - - bars.Add(position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); - bars.Add(position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); - bars.Add(position + new Vector2(i + 1, j + 1) * 16, lightColor3, new Vector3((i + 1) / width, (j + 1) / height, 0)); + Color lightColor0 = Lighting.GetColor((int)Position.X / 16 + i, (int)Position.Y / 16 + j); + Color lightColor1 = Lighting.GetColor((int)Position.X / 16 + i + 1, (int)Position.Y / 16 + j); + Color lightColor2 = Lighting.GetColor((int)Position.X / 16 + i, (int)Position.Y / 16 + j + 1); + Color lightColor3 = Lighting.GetColor((int)Position.X / 16 + i + 1, (int)Position.Y / 16 + j + 1); + + bars.Add(Position + new Vector2(i, j) * 16, lightColor0, new Vector3(i / width, j / height, 0)); + bars.Add(Position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); + bars.Add(Position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); + + bars.Add(Position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); + bars.Add(Position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); + bars.Add(Position + new Vector2(i + 1, j + 1) * 16, lightColor3, new Vector3((i + 1) / width, (j + 1) / height, 0)); } } if (bars.Count <= 0) { - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); } - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleList); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleList); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_TopFence.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_TopFence.png index f05280c01..0aed8dd7c 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_TopFence.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_TopFence.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_shape.bmp b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_shape.bmp index c1ced7934..ed39430af 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_shape.bmp and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/GiantFurnace_shape.bmp differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/HeatproofTable.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/HeatproofTable.cs index c87d22716..4e9ef0e36 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/HeatproofTable.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/HeatproofTable.cs @@ -1,5 +1,4 @@ using Everglow.Yggdrasil.YggdrasilTown.Dusts; -using Terraria.DataStructures; using Terraria.Localization; using Terraria.ObjectData; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/MeltingButton.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/MeltingButton.cs index aac9984dc..3023f1885 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/MeltingButton.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/MeltingButton.cs @@ -40,35 +40,45 @@ public override void ModifyLight(int i, int j, ref float r, ref float g, ref flo public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) { - // Tile tile = Main.tile[i, j]; - // var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); - - // if (Main.drawToScreen) - // { - // zero = Vector2.Zero; - // } - // var texture = ModContent.Request(Texture).Value; - // spriteBatch.Draw(texture, new Vector2(i, j) * 16 - Main.screenPosition + zero, new Rectangle(tile.TileFrameX, tile.TileFrameY + 36, 16, 16), new Color(1f, 0.3f, 0.1f, 0), 0, Vector2.zeroVector, 1, SpriteEffects.None, 0); return base.PreDraw(i, j, spriteBatch); } public override void NearbyEffects(int i, int j, bool closer) { Tile tile = TileUtils.SafeGetTile(i, j); - tile.TileFrameX = 0; + if (YggdrasilTownFurnaceSystem.CurrentPlayer is not null) + { + tile.TileFrameX = 0; + } + else + { + tile.TileFrameX = 36; + } base.NearbyEffects(i, j, closer); } public override void MouseOver(int i, int j) { - Tile tile = TileUtils.SafeGetTile(i, j); - tile.TileFrameX = 18; - string text = "Meltdown"; - Main.instance.MouseText(text, ItemRarityID.Red); + if (YggdrasilTownFurnaceSystem.CurrentPlayer is not null && Main.LocalPlayer.chest == -1) + { + Tile tile = TileUtils.SafeGetTile(i, j); + tile.TileFrameX = 18; + string text = "Meltdown"; + Main.instance.MouseText(text, ItemRarityID.Red); + } base.MouseOver(i, j); } public override bool RightClick(int i, int j) + { + if (YggdrasilTownFurnaceSystem.CurrentPlayer is not null && Main.LocalPlayer.chest == -1) + { + MeltDown(i, j); + } + return base.RightClick(i, j); + } + + public static void MeltDown(int i, int j) { for (int x = -15; x <= 15; x++) { @@ -77,7 +87,7 @@ public override bool RightClick(int i, int j) if (new Vector2(x, y).Length() <= 15) { int chestIndex = Chest.FindChest(i + x, j + y); - if (chestIndex >= 0) + if (chestIndex >= 0 && TileUtils.SafeGetTile(i + x, j + y).TileType == ModContent.TileType()) { Chest chest = Main.chest[chestIndex]; int totalValue = 0; @@ -90,34 +100,23 @@ public override bool RightClick(int i, int j) int rare = Math.Min(10, item.rare); float rareValue = 6f - (rare - 10) * (rare - 10) / 20f; int value = (int)(rareValue * itemValue * item.stack); - item.stack = 0; - item.active = false; - item.type = ItemID.None; - item.ModItem = null; - - // if(item.stack > 0) - // { - // Main.NewText(rareValue, Color.Yellow); - // Main.NewText(itemValue, Color.Red); - // Main.NewText(item.stack, Color.Green); - // } + item.TurnToAir(); totalValue += value; } } - string name = chest.name; - chest = new Chest(); - chest.name = name; if (YggdrasilTownFurnaceSystem.CurrentPlayer != null) { Player player = YggdrasilTownFurnaceSystem.CurrentPlayer; FurnacePlayer fPlayer = player.GetModPlayer(); - fPlayer.FurnaceScore += totalValue; + fPlayer.TotalFurnaceScore += totalValue; + fPlayer.CurrentFurnaceScore += totalValue; } YggdrasilTownFurnaceSystem.CurrentEnergy += totalValue; + YggdrasilTownFurnaceSystem.MeltingAnimationTimer.Add(120); + CombatText.NewText(Main.LocalPlayer.Hitbox, new Color(1f, 0.45f, 0.02f, 1f), "Furnace Energy + " + totalValue); } } } } - return base.RightClick(i, j); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/MeltingButton.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/MeltingButton.png index cdf2e7dcb..9623e2dad 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/MeltingButton.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/MeltingButton.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/TotalFurnaceScoreBoard.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/TotalFurnaceScoreBoard.cs index 2acf1a657..e63103bda 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/TotalFurnaceScoreBoard.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/FurnaceTiles/TotalFurnaceScoreBoard.cs @@ -51,7 +51,7 @@ public void AddScene(int i, int j) Tile tile = Main.tile[i, j]; if (tile.TileFrameX == 0 && tile.TileFrameY == 0) { - var scene = new FurnaceNumberAxis { position = new Vector2(i, j) * 16, Active = true, originTile = new Point(i, j), originType = Type }; + var scene = new FurnaceNumberAxis { Position = new Vector2(i, j) * 16, Active = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(scene); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/Bakery.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/Bakery.png new file mode 100644 index 000000000..64d79ef28 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/Bakery.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryBuckHead.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryBuckHead.cs new file mode 100644 index 000000000..e0b61dd7b --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryBuckHead.cs @@ -0,0 +1,27 @@ +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class BakeryBuckHead : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileNoAttach[Type] = false; + Main.tileWaterDeath[Type] = false; + + TileUtils.DefaultToMultiTileWall(5, 5); + TileObjectData.addTile(Type); + + DustType = DustID.Glass; + AddMapEntry(new Color(86, 64, 33)); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryBuckHead.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryBuckHead.png new file mode 100644 index 000000000..3fd228f77 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryBuckHead.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryChair.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryChair.cs new file mode 100644 index 000000000..eaef67d4a --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryChair.cs @@ -0,0 +1,121 @@ +using Everglow.Yggdrasil.YggdrasilTown.Dusts; +using Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.Furnace; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.GameContent; +using Terraria.GameContent.ObjectInteractions; +using Terraria.Localization; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class BakeryChair : ModTile +{ + public const int NextStyleHeight = 40; // Calculated by adding all CoordinateHeights + CoordinatePaddingFix.Y applied to all of them + 2 + + public override void SetStaticDefaults() + { + // Properties + Main.tileFrameImportant[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileLavaDeath[Type] = true; + TileID.Sets.HasOutlines[Type] = true; + TileID.Sets.CanBeSatOnForNPCs[Type] = true; // Facilitates calling ModifySittingTargetInfo for NPCs + TileID.Sets.CanBeSatOnForPlayers[Type] = true; // Facilitates calling ModifySittingTargetInfo for Players + TileID.Sets.DisableSmartCursor[Type] = true; + + AddToArray(ref TileID.Sets.RoomNeeds.CountsAsChair); + + DustType = DustID.BorealWood; // You should set a kind of dust manually. + AdjTiles = new int[] { TileID.Chairs }; + + // Names + AddMapEntry(new Color(200, 200, 200), Language.GetText("MapObject.Chair")); + + // Placement + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x2); + TileObjectData.newTile.CoordinateHeights = new[] { 16, 18 }; + TileObjectData.newTile.CoordinatePaddingFix = new Point16(0, 2); + TileObjectData.newTile.Direction = TileObjectDirection.PlaceLeft; + + // The following 3 lines are needed if you decide to add more styles and stack them vertically + TileObjectData.newTile.StyleWrapLimit = 2; + TileObjectData.newTile.StyleMultiplier = 2; + TileObjectData.newTile.StyleHorizontal = true; + + TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile); + TileObjectData.newAlternate.Direction = TileObjectDirection.PlaceRight; + TileObjectData.addAlternate(1); // Facing right will use the second texture style + TileObjectData.addTile(Type); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + } + + public override bool HasSmartInteract(int i, int j, SmartInteractScanSettings settings) + { + return settings.player.IsWithinSnappngRangeToTile(i, j, PlayerSittingHelper.ChairSittingMaxDistance); // Avoid being able to trigger it from long range + } + + public override void ModifySittingTargetInfo(int i, int j, ref TileRestingInfo info) + { + // It is very important to know that this is called on both players and NPCs, so do not use Main.LocalPlayer for example, use info.restingEntity + Tile tile = Framing.GetTileSafely(i, j); + + // info.directionOffset = info.restingEntity is Player ? 6 : 2; // Default to 6 for players, 2 for NPCs + // info.visualOffset = Vector2.Zero; // Defaults to (0,0) + info.TargetDirection = -1; + if (tile.TileFrameX != 0) + { + info.TargetDirection = 1; // Facing right if sat down on the right alternate (added through addAlternate in SetStaticDefaults earlier) + } + + // The anchor represents the bottom-most tile of the chair. This is used to align the entity hitbox + // Since i and j may be from any coordinate of the chair, we need to adjust the anchor based on that + info.AnchorTilePosition.X = i; // Our chair is only 1 wide, so nothing special required + info.AnchorTilePosition.Y = j; + + if (tile.TileFrameY % NextStyleHeight == 0) + { + info.AnchorTilePosition.Y++; // Here, since our chair is only 2 tiles high, we can just check if the tile is the top-most one, then move it 1 down + } + } + + public override bool RightClick(int i, int j) + { + return FurnitureUtils.ChairRightClick(i, j); + } + + public override void MouseOver(int i, int j) + { + FurnitureUtils.ChairMouseOver(i, j); + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + Tile tile = Main.tile[i, j]; + if (tile.TileFrameY == 0) + { + Rectangle frame = new Rectangle(0, 0, 24, 38); + if (tile.TileFrameX == 18) + { + frame.X += 26; + } + Texture2D tex = ModAsset.BakeryChair_full.Value; + Vector2 zero = new Vector2(Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.zeroVector; + } + spriteBatch.Draw(tex, new Point(i, j).ToWorldCoordinates() - Main.screenPosition + zero + new Vector2(-12, -12), frame, Lighting.GetColor(i, j), 0, Vector2.zeroVector, 1, SpriteEffects.None, 0); + } + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + return false; + return base.PreDraw(i, j, spriteBatch); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryChair.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryChair.png new file mode 100644 index 000000000..979af100b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryChair.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryChair_Highlight.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryChair_Highlight.png new file mode 100644 index 000000000..4ea1cb71d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryChair_Highlight.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryChair_full.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryChair_full.png new file mode 100644 index 000000000..59fb57d0d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryChair_full.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryCounter.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryCounter.cs new file mode 100644 index 000000000..9f3616c52 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryCounter.cs @@ -0,0 +1,24 @@ +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class BakeryCounter : ModTile +{ + public override void PostSetDefaults() + { + Main.tileSolid[Type] = false; + Main.tileLavaDeath[Type] = true; + Main.tileFrameImportant[Type] = true; + TileUtils.DefaultToMultiTileAnchorBottom(7, 6); + TileObjectData.addTile(Type); + DustType = DustID.WoodFurniture; + AddMapEntry(new Color(76, 57, 46)); + HitSound = SoundID.DD2_SkeletonHurt; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryCounter.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryCounter.png new file mode 100644 index 000000000..33521852d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryCounter.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryCounterSide.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryCounterSide.cs new file mode 100644 index 000000000..a0b63d16f --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryCounterSide.cs @@ -0,0 +1,24 @@ +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class BakeryCounterSide : ModTile +{ + public override void PostSetDefaults() + { + Main.tileSolid[Type] = false; + Main.tileLavaDeath[Type] = true; + Main.tileFrameImportant[Type] = true; + TileUtils.DefaultToMultiTileAnchorBottom(3, 6); + TileObjectData.addTile(Type); + DustType = DustID.WoodFurniture; + AddMapEntry(new Color(76, 57, 46)); + HitSound = SoundID.DD2_SkeletonHurt; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryCounterSide.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryCounterSide.png new file mode 100644 index 000000000..55fd3622f Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryCounterSide.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryGlassTable.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryGlassTable.cs new file mode 100644 index 000000000..447dc7308 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryGlassTable.cs @@ -0,0 +1,24 @@ +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class BakeryGlassTable : ModTile +{ + public override void PostSetDefaults() + { + Main.tileSolid[Type] = false; + Main.tileLavaDeath[Type] = true; + Main.tileFrameImportant[Type] = true; + TileUtils.DefaultToMultiTileAnchorBottom(7, 3); + TileObjectData.addTile(Type); + DustType = DustID.WoodFurniture; + AddMapEntry(new Color(76, 57, 46)); + HitSound = SoundID.DD2_SkeletonHurt; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryGlassTable.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryGlassTable.png new file mode 100644 index 000000000..81953bf66 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryGlassTable.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryHangingLamp.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryHangingLamp.cs new file mode 100644 index 000000000..4d88fd7d8 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryHangingLamp.cs @@ -0,0 +1,176 @@ +using Everglow.Commons.TileHelper; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.GameContent.Drawing; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class BakeryHangingLamp : ModTile, ITileFluentlyDrawn +{ + public override void SetStaticDefaults() + { + // Properties + Main.tileFrameImportant[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileLighted[Type] = true; + Main.tileSolid[Type] = false; + Main.tileNoFail[Type] = true; + + AddToArray(ref TileID.Sets.RoomNeeds.CountsAsTorch); + + DustType = DustID.BorealWood; // You should set a kind of dust manually. + AdjTiles = new int[] { TileID.HangingLanterns }; + + // Placement + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x2Top); + TileObjectData.newTile.Height = 4; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 16, + 16, + 16, + }; + TileObjectData.newTile.CoordinateWidth = 36; + TileObjectData.newTile.DrawYOffset = -2; + TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile); + TileObjectData.newAlternate.DrawYOffset = -10; + TileObjectData.newAlternate.AnchorTop = new AnchorData(AnchorType.Platform, TileObjectData.newTile.Width, 0); + TileObjectData.addAlternate(0); + TileObjectData.addTile(Type); // addTileä¸€å®šè¦æ”¾åœ¨addAlternateåŽé¢ + + AddMapEntry(new Color(175, 115, 63)); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + } + + public override void HitWire(int i, int j) + { + FurnitureUtils.LightHitwire(i, j, Type, 1, 4); + } + + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + Tile tile = Main.tile[i, j]; + if (tile.TileFrameX < 18) + { + r = 1.200f; + g = 1.200f; + b = 1.00f; + Lighting.AddLight(i + 1, j, r, g, b); + } + else + { + r = 0f; + g = 0f; + b = 0f; + } + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + return false; + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + var tile = Main.tile[pos]; + var tileData = TileObjectData.GetTileData(tile.type, 0); + + if (!TileDrawing.IsVisible(tile) || tileData is null) + { + return; + } + float swayOffset = 0f; + int top = pos.Y - Main.tile[pos].TileFrameY / 18; + Point topLeft = new Point(pos.X, top); + + // Paints + Texture2D tex = tileDrawing.GetTileDrawTexture(tile, pos.X, pos.Y); + + short tileFrameX = tile.frameX; + short tileFrameY = tile.frameY; + + // ç”¨äºŽé£Žé€Ÿã€æŽ¨åŠ›ç­‰ä¸€ç³»åˆ—åˆ¤å®šçš„ç‰©å—åæ ‡ï¼Œé€šå¸¸æ¥è¯´æ˜¯æŒ‚在墙上的那一格(这边是origin格) + int topTileX = topLeft.X + tileData.Origin.X; + int topTileY = topLeft.Y + tileData.Origin.Y; + int sizeX = tileData.Width; + int sizeY = tileData.Height; + + int offsetY = tileData.DrawYOffset; + + // 锤孿˜¯è¿™æ ·çš„ + if (WorldGen.IsBelowANonHammeredPlatform(topTileX, topTileY)) + { + offsetY -= 8; + } + + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(topLeft.X, topLeft.Y, sizeX, sizeY)) + { + windCycle = tileDrawing.GetWindCycle(topTileX, topTileY, tileDrawing._sunflowerWindCounter); + } + + // 普通æºç ç½¢äº† + int totalPushTime = 60; + float pushForcePerFrame = 1.26f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(topTileX, topTileY, sizeX, sizeY, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + windCycle += highestWindGridPushComplex; + + // 适é…å‘光涂料 + Rectangle rectangle = new Rectangle(tileFrameX, tileFrameY, 34, 16); + Color tileLight = Lighting.GetColor(pos); + tileDrawing.DrawAnimatedTile_AdjustForVisionChangers(pos.X, pos.Y, tile, tile.type, tileFrameX, tileFrameY, ref tileLight, tileDrawing._rand.NextBool(4)); + tileLight = tileDrawing.DrawTiles_GetLightOverride(pos.Y, pos.X, tile, tile.type, tileFrameX, tileFrameY, tileLight); + + // åŸºç¡€çš„åæ ‡ + Vector2 center = new Vector2(topTileX, topTileY).ToWorldCoordinates(autoAddY: 0) - screenPosition; + Vector2 offset = new Vector2(0f, offsetY); + center += offset; + + // heightStrength是用于旗帜类物å—的,根æ®é«˜åº¦æ¥å†³å®šè¯¥æ ¼ç‰©å—的摇曳力度 + float heightStrength = (pos.Y - topLeft.Y + 1) / (float)sizeY; + if (heightStrength == 0f) + { + heightStrength = 0.1f; + } + + // è®¡ç®—ç»˜åˆ¶åæ ‡å’Œoriginï¼ŒåŽŸç‰ˆä»£ç  + Vector2 tileCoordPos = pos.ToWorldCoordinates(0, 0) - screenPosition; + tileCoordPos += offset; + + // 用于旗帜 + float swayCorrection = Math.Abs(windCycle) * swayOffset * heightStrength; + Vector2 finalOrigin = center - tileCoordPos; + Vector2 finalDrawPos = center + new Vector2(0, swayCorrection); + + // 旋转角度 + if (swayOffset == 0f) + { + heightStrength = 1f; + } + if (tile.TileFrameY >= 36) + { + heightStrength = 2f; + } + + float swayStrength = 0.1f; + + float rotation = -windCycle * swayStrength * heightStrength; + + // 绘制 + spriteBatch.Draw(tex, finalDrawPos, rectangle, tileLight, rotation, finalOrigin, 1f, SpriteEffects.None, 0f); + + // 有ç«çš„è¯ç»˜åˆ¶ç« + if (TileLoader.GetTile(tile.type) is not ITileFlameData tileFlame) + { + return; + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryHangingLamp.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryHangingLamp.png new file mode 100644 index 000000000..e110f8366 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryHangingLamp.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryHangingLamp_Full.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryHangingLamp_Full.png new file mode 100644 index 000000000..9467324a5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryHangingLamp_Full.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryMenu.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryMenu.cs new file mode 100644 index 000000000..692f9aef1 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryMenu.cs @@ -0,0 +1,27 @@ +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class BakeryMenu : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileNoAttach[Type] = false; + Main.tileWaterDeath[Type] = false; + + TileUtils.DefaultToMultiTileWall(7, 5); + TileObjectData.addTile(Type); + + DustType = DustID.Glass; + AddMapEntry(new Color(28, 34, 51)); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryMenu.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryMenu.png new file mode 100644 index 000000000..9c6f1e56d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryMenu.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryRoof.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryRoof.png new file mode 100644 index 000000000..1c8846e6a Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryRoof.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryShelf.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryShelf.cs new file mode 100644 index 000000000..1670de27f --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryShelf.cs @@ -0,0 +1,36 @@ +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class BakeryShelf : ModTile +{ + public override void PostSetDefaults() + { + Main.tileSolid[Type] = false; + Main.tileLavaDeath[Type] = true; + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + TileUtils.DefaultToMultiTileAnchorBottom(12, 10); + TileObjectData.addTile(Type); + DustType = DustID.WoodFurniture; + AddMapEntry(new Color(76, 57, 46)); + HitSound = SoundID.DD2_SkeletonHurt; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } + + public override void NearbyEffects(int i, int j, bool closer) + { + Tile tile = Main.tile[i, j]; + if (tile.TileFrameY == 90) + { + Lighting.AddLight(i, j, 0.6f, 0.6f, 0.5f); + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryShelf.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryShelf.png new file mode 100644 index 000000000..4139ba6fa Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryShelf.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakerySideLamp.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakerySideLamp.cs new file mode 100644 index 000000000..2a04e274c --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakerySideLamp.cs @@ -0,0 +1,66 @@ +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class BakerySideLamp : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileLighted[Type] = true; + DustType = DustID.DynastyWood; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style2xX); + TileObjectData.newTile.Height = 3; + TileObjectData.newTile.Width = 2; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 16, + 16, + }; + + TileObjectData.newAlternate.Alternates = new List(); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.CoordinateWidth = 16; + + TileObjectData.newTile.AnchorBottom = new AnchorData(0, 0, 0); + TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile); + TileObjectData.newAlternate.AnchorLeft = new AnchorData(AnchorType.SolidTile | AnchorType.SolidSide | AnchorType.Tree | AnchorType.AlternateTile, TileObjectData.newTile.Height, 0); + TileObjectData.addAlternate(1); + TileObjectData.newTile.AnchorRight = new AnchorData(AnchorType.SolidTile | AnchorType.SolidSide | AnchorType.Tree | AnchorType.AlternateTile, TileObjectData.newTile.Height, 0); + TileObjectData.addTile(Type); + + AddMapEntry(new Color(175, 115, 63)); + } + + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + var tile = Main.tile[i, j]; + if (tile.TileFrameY < 54 && tile.TileFrameY >= 0) + { + r = 1.2f; + g = 1.2f; + b = 1.0f; + } + else + { + r = 0f; + g = 0f; + b = 0f; + } + } + + public override void HitWire(int i, int j) + { + FurnitureUtils.LightHitwireStyleVertical(i, j, Type, 2, 3); + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + return true; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakerySideLamp.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakerySideLamp.png new file mode 100644 index 000000000..94034a03f Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakerySideLamp.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakerySovietBanner.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakerySovietBanner.cs new file mode 100644 index 000000000..f678f0d5f --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakerySovietBanner.cs @@ -0,0 +1,27 @@ +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class BakerySovietBanner : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileNoAttach[Type] = false; + Main.tileWaterDeath[Type] = false; + + TileUtils.DefaultToMultiTileWall(11, 3); + TileObjectData.addTile(Type); + + DustType = DustID.RedMoss; + AddMapEntry(new Color(81, 32, 35)); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakerySovietBanner.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakerySovietBanner.png new file mode 100644 index 000000000..a83afddfb Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakerySovietBanner.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryTable.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryTable.cs new file mode 100644 index 000000000..03369b6d1 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryTable.cs @@ -0,0 +1,35 @@ +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class BakeryTable : ModTile +{ + public override void PostSetDefaults() + { + // Properties + Main.tileTable[Type] = true; + Main.tileSolidTop[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileFrameImportant[Type] = true; + TileID.Sets.DisableSmartCursor[Type] = true; + TileID.Sets.IgnoredByNpcStepUp[Type] = true; // This line makes NPCs not try to step up this tile during their movement. Only use this for furniture with solid tops. + AdjTiles = new int[] { TileID.Tables }; + DustType = DustID.WoodFurniture; + + // Placement + TileObjectData.newTile.CopyFrom(TileObjectData.Style3x2); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.CoordinateHeights = new[] { 16, 18 }; + TileObjectData.addTile(Type); + + AddMapEntry(new Color(76, 57, 46)); + HitSound = SoundID.DD2_SkeletonHurt; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryTable.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryTable.png new file mode 100644 index 000000000..cc7aae789 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryTable.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryVase.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryVase.cs new file mode 100644 index 000000000..8b7716da2 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryVase.cs @@ -0,0 +1,84 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.Common.Elevator.Tiles; +using Everglow.Yggdrasil.YggdrasilTown.Dusts; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.GameContent.Drawing; +using Terraria.Localization; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class BakeryVase : ModTile, ITileFluentlyDrawn +{ + public override void SetStaticDefaults() + { + Main.tileTable[Type] = true; + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileLavaDeath[Type] = true; + TileID.Sets.HasOutlines[Type] = true; + + DustType = ModContent.DustType(); + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.SolidWithTop | AnchorType.Table, 1, 0); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.addTile(Type); + + AddMapEntry(new Color(69, 36, 78)); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + return base.PreDraw(i, j, spriteBatch); + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + Tile tile = Main.tile[pos]; + var tileData = TileObjectData.GetTileData(tile.type, 0); + if (!TileDrawing.IsVisible(tile) || tileData is null) + { + return; + } + + if (tile.TileFrameY == 0) + { + Vector2 offset = new Vector2(-2, -4); + Rectangle frame = new Rectangle(0, 16, 14, 20); + if (tile.TileFrameX == 18) + { + frame = new Rectangle(16, 16, 14, 20); + offset = new Vector2(2, -4); + } + if (tile.TileFrameX == 36) + { + frame = new Rectangle(32, 22, 6, 14); + offset = new Vector2(-2, -4); + } + Texture2D tex = tileDrawing.GetTileDrawTexture(tile, pos.X, pos.Y); + + float windCycle = 0; + if (tileDrawing.InAPlaceWithWind(pos.X, pos.Y, 1, 1)) + { + windCycle = tileDrawing.GetWindCycle(pos.X, pos.Y, tileDrawing._sunflowerWindCounter); + } + + // Wind push rotation + int totalPushTime = 30; + float pushForcePerFrame = 1.26f; + float highestWindGridPushComplex = tileDrawing.GetHighestWindGridPushComplex(pos.X, pos.Y, 1, 1, totalPushTime, pushForcePerFrame, 3, swapLoopDir: true); + windCycle += highestWindGridPushComplex; + float rotation = windCycle * 0.4f; + + spriteBatch.Draw(tex, pos.ToWorldCoordinates() - Main.screenPosition + offset, frame, Lighting.GetColor(pos), rotation, new Vector2(frame.Width * 0.5f, frame.Height), 1, SpriteEffects.None, 0); + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryVase.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryVase.png new file mode 100644 index 000000000..b18ba865d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryVase.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryVase_Flower.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryVase_Flower.png new file mode 100644 index 000000000..3f5d9541d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryVase_Flower.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryVase_Highlight.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryVase_Highlight.png new file mode 100644 index 000000000..30628b35c Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryVase_Highlight.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryWall.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryWall.png new file mode 100644 index 000000000..3a4d03036 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/BakeryWall.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/Bakery_Scene.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/Bakery_Scene.cs new file mode 100644 index 000000000..ab8c038b0 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/Bakery_Scene.cs @@ -0,0 +1,68 @@ +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class Bakery_Scene : ModTile, ISceneTile +{ + public override string Texture => Commons.ModAsset.Empty_Mod; + + public override void SetStaticDefaults() + { + Main.tileSolid[Type] = true; + Main.tileMerge[ModContent.TileType()][Type] = true; + Main.tileBlockLight[Type] = true; + DustType = DustID.BorealWood; + HitSound = SoundID.Dig; + MinPick = int.MaxValue; + AddMapEntry(new Color(63, 47, 38)); + } + + public override bool CanKillTile(int i, int j, ref bool blockDamaged) => false; + + public override bool CanExplode(int i, int j) + { + return false; + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) => base.PreDraw(i, j, spriteBatch); + + public void AddScene(int i, int j) + { + // TODO: A more general scene_VFX for more wide utilities in lieu of TwilightCastle. + var scene_Close = new TwilightCastle_RoomScene_OverTiles { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; + scene_Close.CustomDraw += DrawBakeryOverTile; + + var scene_Background = new TwilightCastle_RoomScene_Background { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; + scene_Background.CustomDraw += DrawBakeryBackground; + + Ins.VFXManager.Add(scene_Close); + Ins.VFXManager.Add(scene_Background); + } + + public void DrawBakeryOverTile(TwilightCastle_RoomScene_OverTiles otD) + { + bool flipH = false; + Texture2D tex0 = ModAsset.BakeryRoof.Value; + + var bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(otD.OriginTilePos.X - 1, otD.OriginTilePos.Y - 1, tex0, bars, flipH); + Ins.Batch.Draw(tex0, bars, PrimitiveType.TriangleList); + } + + public void DrawBakeryBackground(TwilightCastle_RoomScene_Background bg) + { + bool flipH = false; + Texture2D tex0 = ModAsset.BakeryWall.Value; + + var bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(bg.OriginTilePos.X, bg.OriginTilePos.Y, tex0, bars, flipH); + Ins.Batch.Draw(tex0, bars, PrimitiveType.TriangleList); + } + + public override void NearbyEffects(int i, int j, bool closer) + { + base.NearbyEffects(i, j, closer); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShelf_Feature_Nature.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShelf_Feature_Nature.cs new file mode 100644 index 000000000..85ab2789f --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShelf_Feature_Nature.cs @@ -0,0 +1,32 @@ +using Terraria.DataStructures; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class ClothesShelf_Feature_Nature : ModTile +{ + public override void PostSetDefaults() + { + Main.tileSolid[Type] = false; + Main.tileLavaDeath[Type] = true; + Main.tileFrameImportant[Type] = true; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 5; + TileObjectData.newTile.Width = 7; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.CoordinateHeights = new int[TileObjectData.newTile.Height]; + Array.Fill(TileObjectData.newTile.CoordinateHeights, 16); + TileObjectData.newTile.CoordinateWidth = 16; + TileObjectData.newTile.Origin = new Point16(2, 4); + TileObjectData.addTile(Type); + DustType = DustID.WoodFurniture; + AddMapEntry(new Color(127, 89, 77)); + HitSound = SoundID.DD2_SkeletonHurt; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShelf_Feature_Nature.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShelf_Feature_Nature.png new file mode 100644 index 000000000..d3b1bb97b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShelf_Feature_Nature.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopBonsai_Feature_Nature.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopBonsai_Feature_Nature.cs new file mode 100644 index 000000000..0900e3ea3 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopBonsai_Feature_Nature.cs @@ -0,0 +1,25 @@ +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class ClothesShopBonsai_Feature_Nature : ModTile +{ + public override void PostSetDefaults() + { + Main.tileSolid[Type] = false; + Main.tileLavaDeath[Type] = true; + Main.tileFrameImportant[Type] = true; + TileObjectData.newTile.CopyFrom(TileObjectData.Style2x2); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.addTile(Type); + DustType = DustID.WoodFurniture; + AddMapEntry(new Color(66, 99, 50)); + HitSound = SoundID.DD2_SkeletonHurt; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopBonsai_Feature_Nature.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopBonsai_Feature_Nature.png new file mode 100644 index 000000000..9205dcf5e Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopBonsai_Feature_Nature.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopModel_Feature_Nature.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopModel_Feature_Nature.cs new file mode 100644 index 000000000..3b9a7d5b9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopModel_Feature_Nature.cs @@ -0,0 +1,32 @@ +using Terraria.DataStructures; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class ClothesShopModel_Feature_Nature : ModTile +{ + public override void PostSetDefaults() + { + Main.tileSolid[Type] = false; + Main.tileLavaDeath[Type] = true; + Main.tileFrameImportant[Type] = true; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 5; + TileObjectData.newTile.Width = 2; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.CoordinateHeights = new int[TileObjectData.newTile.Height]; + Array.Fill(TileObjectData.newTile.CoordinateHeights, 16); + TileObjectData.newTile.CoordinateWidth = 16; + TileObjectData.newTile.Origin = new Point16(2, 4); + TileObjectData.addTile(Type); + DustType = DustID.WoodFurniture; + AddMapEntry(new Color(127, 89, 77)); + HitSound = SoundID.DD2_SkeletonHurt; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopModel_Feature_Nature.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopModel_Feature_Nature.png new file mode 100644 index 000000000..b868c06a0 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopModel_Feature_Nature.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopSofa_Feature_Nature.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopSofa_Feature_Nature.cs new file mode 100644 index 000000000..aa66961ca --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopSofa_Feature_Nature.cs @@ -0,0 +1,25 @@ +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class ClothesShopSofa_Feature_Nature : ModTile +{ + public override void PostSetDefaults() + { + Main.tileSolid[Type] = false; + Main.tileLavaDeath[Type] = true; + Main.tileFrameImportant[Type] = true; + TileObjectData.newTile.CopyFrom(TileObjectData.Style2x2); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.addTile(Type); + DustType = DustID.WoodFurniture; + AddMapEntry(new Color(127, 89, 77)); + HitSound = SoundID.DD2_SkeletonHurt; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopSofa_Feature_Nature.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopSofa_Feature_Nature.png new file mode 100644 index 000000000..f9d6fae64 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopSofa_Feature_Nature.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopTable_Feature_Nature.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopTable_Feature_Nature.cs new file mode 100644 index 000000000..579dce0b4 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopTable_Feature_Nature.cs @@ -0,0 +1,25 @@ +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class ClothesShopTable_Feature_Nature : ModTile +{ + public override void PostSetDefaults() + { + Main.tileSolid[Type] = false; + Main.tileLavaDeath[Type] = true; + Main.tileFrameImportant[Type] = true; + TileObjectData.newTile.CopyFrom(TileObjectData.Style2x2); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.addTile(Type); + DustType = DustID.WoodFurniture; + AddMapEntry(new Color(127, 89, 77)); + HitSound = SoundID.DD2_SkeletonHurt; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopTable_Feature_Nature.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopTable_Feature_Nature.png new file mode 100644 index 000000000..abad5663c Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/ClothesShopTable_Feature_Nature.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/FevensPortrait.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/FevensPortrait.cs new file mode 100644 index 000000000..86db0b6de --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/FevensPortrait.cs @@ -0,0 +1,27 @@ +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.GravelStore; + +public class FevensPortrait : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileNoAttach[Type] = false; + Main.tileWaterDeath[Type] = false; + + TileUtils.DefaultToMultiTileWall(3, 5); + TileObjectData.addTile(Type); + + DustType = DustID.Glass; + AddMapEntry(new Color(215, 212, 216)); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/FevensPortrait.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/FevensPortrait.png new file mode 100644 index 000000000..d081e7e59 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStore/FevensPortrait.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStoreCommandBlock.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStoreCommandBlock.cs new file mode 100644 index 000000000..4d09c11e2 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStoreCommandBlock.cs @@ -0,0 +1,37 @@ +using Everglow.Yggdrasil.YggdrasilTown.Dusts; +using Everglow.Yggdrasil.YggdrasilTown.NPCs.TownNPCs; +using SubworldLibrary; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; + +public class GravelStoreCommandBlock : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileNoAttach[Type] = false; + Main.tileWaterDeath[Type] = false; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3Wall); + TileObjectData.newTile.Origin = new(0, 0); + TileObjectData.newTile.Height = 2; + TileObjectData.newTile.Width = 2; + TileObjectData.newTile.AnchorTop = new AnchorData(AnchorType.None, 0, 0); + TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.None, 0, 0); + TileObjectData.newTile.CoordinateHeights = new int[2]; + Array.Fill(TileObjectData.newTile.CoordinateHeights, 16); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + TileObjectData.newTile.Origin = new Point16(0, 0); + + TileObjectData.addTile(Type); + DustType = ModContent.DustType(); + MinPick = int.MaxValue; + AddMapEntry(new Color(96, 96, 96)); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStoreCommandBlock.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStoreCommandBlock.png new file mode 100644 index 000000000..92043cf4b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/GravelStoreCommandBlock.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/JellyBallSecretion.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/JellyBallSecretion.cs index 6289b0297..d5213fb53 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/JellyBallSecretion.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/JellyBallSecretion.cs @@ -21,6 +21,7 @@ public override void SetStaticDefaults() public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) { + Lighting.AddLight(i, j, 0, 0.5f, 0.94f); return base.PreDraw(i, j, spriteBatch); } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/DarkForestGrass.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/DarkForestGrass.cs index eba9c3749..2e6d1455d 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/DarkForestGrass.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/DarkForestGrass.cs @@ -309,7 +309,7 @@ public static void BuildLampTree(int i, int j, int height = 0) public void AddScene(int i, int j) { - DarkForestGrass_grass_fore leaf = new DarkForestGrass_grass_fore { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + DarkForestGrass_grass_fore leaf = new DarkForestGrass_grass_fore { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; leaf.scale = 1f; leaf.style = i % 3; Ins.VFXManager.Add(leaf); diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/DarkForestGrass_grass.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/DarkForestGrass_grass.cs index 25de90dae..24175f31c 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/DarkForestGrass_grass.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/DarkForestGrass_grass.cs @@ -3,38 +3,39 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.LampWood; [Pipeline(typeof(WCSPipeline))] -public class DarkForestGrass_grass_fore : ForegroundVFX +public class DarkForestGrass_grass_fore : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; public override void OnSpawn() { - texture = ModAsset.DarkForestGrass_grass.Value; + Texture = ModAsset.DarkForestGrass_grass.Value; } public override void Update() { - if (originTile.X >= Main.maxTilesX - 1 || originTile.X <= 1) + if (OriginTilePos.X >= Main.maxTilesX - 1 || OriginTilePos.X <= 1) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - if (originTile.Y >= Main.maxTilesY - 1 || originTile.Y <= 1) + if (OriginTilePos.Y >= Main.maxTilesY - 1 || OriginTilePos.Y <= 1) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - if (!VFXManager.InScreen(originTile.ToWorldCoordinates(), 150)) + if (!VFXManager.InScreen(OriginTilePos.ToWorldCoordinates(), 150)) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - Tile tile = Main.tile[originTile]; - if (tile.TileType != originType || !tile.HasTile) + Tile tile = Main.tile[OriginTilePos]; + if (tile.TileType != OriginTileType || !tile.HasTile) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } @@ -44,23 +45,23 @@ public override void Update() public override void Draw() { - if (originTile.X >= Main.maxTilesX - 1 || originTile.X <= 1) + if (OriginTilePos.X >= Main.maxTilesX - 1 || OriginTilePos.X <= 1) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - if (originTile.Y >= Main.maxTilesY - 1 || originTile.Y <= 1) + if (OriginTilePos.Y >= Main.maxTilesY - 1 || OriginTilePos.Y <= 1) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - Tile tile = Main.tile[originTile]; - if (tile.TileType != originType || !tile.HasTile) + Tile tile = Main.tile[OriginTilePos]; + if (tile.TileType != OriginTileType || !tile.HasTile) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } @@ -70,7 +71,7 @@ public override void Draw() // int rectangleX = (int)(Main.screenPosition - deltaPos).X; // int rectangleY = (int)(Main.screenPosition - deltaPos).Y; // Rectangle checkRectangle = new Rectangle(rectangleX, rectangleY, Main.screenWidth - 8, Main.screenHeight - 8); - // if (checkRectangle.Contains((int)position.X, (int)position.Y)) + // if (checkRectangle.Contains((int)Position.X, (int)Position.Y)) // { // return; // } @@ -80,199 +81,199 @@ public override void Draw() { if (tile.TileFrameX >= 18 && tile.TileFrameX <= 54 && tile.TileFrameY == 0) { - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameX >= 18 && tile.TileFrameX <= 54 && tile.TileFrameY == 36) { - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } if (tile.TileFrameX == 0 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) { - AddDrawingFace(bars, new Vector2(-1, 0), position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); } if (tile.TileFrameX == 72 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) { - AddDrawingFace(bars, new Vector2(1, 0), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); } if (tile.TileFrameX == 90 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(-1, 0), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); } if (tile.TileFrameY == 72 && tile.TileFrameX >= 108 && tile.TileFrameX <= 144) { - AddDrawingFace(bars, new Vector2(0, 1), position); - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameY == 0 && tile.TileFrameX >= 108 && tile.TileFrameX <= 144) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(-1, 0), position); - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameY == 54 && tile.TileFrameX >= 108 && tile.TileFrameX <= 144) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(-1, 0), position); - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } if (tile.TileFrameX == 162 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) { - AddDrawingFace(bars, new Vector2(0, 1), position); - AddDrawingFace(bars, new Vector2(0, -1), position); - AddDrawingFace(bars, new Vector2(-1, 0), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); } if (tile.TileFrameX == 216 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) { - AddDrawingFace(bars, new Vector2(0, 1), position); - AddDrawingFace(bars, new Vector2(0, -1), position); - AddDrawingFace(bars, new Vector2(1, 0), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); + AddDrawingFace(bars, new Vector2(1, 0), Position); } if (tile.TileFrameY == 54 && tile.TileFrameX >= 162 && tile.TileFrameX <= 198) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(-1, 0), position); - AddDrawingFace(bars, new Vector2(0, 1), position); - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameY == 54 && tile.TileFrameX % 36 == 0 && tile.TileFrameX <= 90) { - AddDrawingFace(bars, new Vector2(-1, 0), position); - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameY == 72 && tile.TileFrameX % 36 == 0 && tile.TileFrameX <= 90) { - AddDrawingFace(bars, new Vector2(-1, 0), position); - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } if (tile.TileFrameY == 54 && tile.TileFrameX % 36 == 18 && tile.TileFrameX <= 90) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameY == 72 && tile.TileFrameX % 36 == 18 && tile.TileFrameX <= 90) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } } else { if (tile.Slope == SlopeType.SlopeUpLeft) { - AddDrawingFace(bars, new Vector2(1, 1) * 0.85f, position, 1.4143f, new Vector2(-5, -5)); - Tile upTile = Main.tile[originTile + new Point(0, -1)]; + AddDrawingFace(bars, new Vector2(1, 1) * 0.85f, Position, 1.4143f, new Vector2(-5, -5)); + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; if (!upTile.HasTile) { - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } - Tile leftTile = Main.tile[originTile + new Point(-1, 0)]; + Tile leftTile = Main.tile[OriginTilePos + new Point(-1, 0)]; if (!leftTile.HasTile) { - AddDrawingFace(bars, new Vector2(-1, 0), position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); } - Tile downTile = Main.tile[originTile + new Point(0, 1)]; - if (downTile.HasTile && downTile.TileType == originType) + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; + if (downTile.HasTile && downTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(0, -1), position, 1, new Vector2(0, 16)); + AddDrawingFace(bars, new Vector2(0, -1), Position, 1, new Vector2(0, 16)); } } if (tile.Slope == SlopeType.SlopeDownLeft) { - AddDrawingFace(bars, new Vector2(1, -1) * 0.85f, position, 1.4143f, new Vector2(-5, 5)); - Tile downTile = Main.tile[originTile + new Point(0, 1)]; + AddDrawingFace(bars, new Vector2(1, -1) * 0.85f, Position, 1.4143f, new Vector2(-5, 5)); + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; if (!downTile.HasTile) { - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } - Tile leftTile = Main.tile[originTile + new Point(-1, 0)]; + Tile leftTile = Main.tile[OriginTilePos + new Point(-1, 0)]; if (!leftTile.HasTile) { - AddDrawingFace(bars, new Vector2(-1, 0), position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); } - Tile upTile = Main.tile[originTile + new Point(0, -1)]; - if (upTile.HasTile && upTile.TileType == originType) + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; + if (upTile.HasTile && upTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(0, 1), position, 1, new Vector2(0, -16)); + AddDrawingFace(bars, new Vector2(0, 1), Position, 1, new Vector2(0, -16)); } } if (tile.Slope == SlopeType.SlopeUpRight) { - AddDrawingFace(bars, new Vector2(-1, 1) * 0.85f, position, 1.4143f, new Vector2(5, -5)); - Tile upTile = Main.tile[originTile + new Point(0, -1)]; + AddDrawingFace(bars, new Vector2(-1, 1) * 0.85f, Position, 1.4143f, new Vector2(5, -5)); + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; if (!upTile.HasTile) { - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } - Tile rightTile = Main.tile[originTile + new Point(1, 0)]; + Tile rightTile = Main.tile[OriginTilePos + new Point(1, 0)]; if (!rightTile.HasTile) { - AddDrawingFace(bars, new Vector2(1, 0), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); } - Tile downTile = Main.tile[originTile + new Point(0, 1)]; - if (downTile.HasTile && downTile.TileType == originType) + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; + if (downTile.HasTile && downTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(0, -1), position, 1, new Vector2(0, 16)); + AddDrawingFace(bars, new Vector2(0, -1), Position, 1, new Vector2(0, 16)); } } if (tile.Slope == SlopeType.SlopeDownRight) { - AddDrawingFace(bars, new Vector2(-1, -1) * 0.85f, position, 1.4143f, new Vector2(5, 5)); - Tile downTile = Main.tile[originTile + new Point(0, 1)]; + AddDrawingFace(bars, new Vector2(-1, -1) * 0.85f, Position, 1.4143f, new Vector2(5, 5)); + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; if (!downTile.HasTile) { - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } - Tile rightTile = Main.tile[originTile + new Point(1, 0)]; + Tile rightTile = Main.tile[OriginTilePos + new Point(1, 0)]; if (!rightTile.HasTile) { - AddDrawingFace(bars, new Vector2(1, 0), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); } - Tile upTile = Main.tile[originTile + new Point(0, -1)]; - if (upTile.HasTile && upTile.TileType == originType) + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; + if (upTile.HasTile && upTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(0, 1), position, 1, new Vector2(0, -16)); + AddDrawingFace(bars, new Vector2(0, 1), Position, 1, new Vector2(0, -16)); } } if (tile.halfBrick()) { - AddDrawingFace(bars, new Vector2(0, -1), position, 1, new Vector2(0, 6)); - if (!Main.tile[originTile + new Point(0, 1)].HasTile) + AddDrawingFace(bars, new Vector2(0, -1), Position, 1, new Vector2(0, 6)); + if (!Main.tile[OriginTilePos + new Point(0, 1)].HasTile) { - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } - Tile upTile = Main.tile[originTile + new Point(0, -1)]; - if (upTile.HasTile && upTile.TileType == originType) + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; + if (upTile.HasTile && upTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(0, 1), position, 1, new Vector2(0, -16)); + AddDrawingFace(bars, new Vector2(0, 1), Position, 1, new Vector2(0, -16)); } - Tile leftTile = Main.tile[originTile + new Point(-1, 0)]; - if (leftTile.HasTile && leftTile.TileType == originType) + Tile leftTile = Main.tile[OriginTilePos + new Point(-1, 0)]; + if (leftTile.HasTile && leftTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(1, 0), position, 0.5f, new Vector2(-14, -4)); + AddDrawingFace(bars, new Vector2(1, 0), Position, 0.5f, new Vector2(-14, -4)); } if (!leftTile.HasTile) { - AddDrawingFace(bars, new Vector2(-1, 0), position, 0.5f, new Vector2(0, 4)); + AddDrawingFace(bars, new Vector2(-1, 0), Position, 0.5f, new Vector2(0, 4)); } - Tile rightTile = Main.tile[originTile + new Point(1, 0)]; - if (rightTile.HasTile && rightTile.TileType == originType) + Tile rightTile = Main.tile[OriginTilePos + new Point(1, 0)]; + if (rightTile.HasTile && rightTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(-1, 0), position, 0.5f, new Vector2(14, -4)); + AddDrawingFace(bars, new Vector2(-1, 0), Position, 0.5f, new Vector2(14, -4)); } if (!rightTile.HasTile) { - AddDrawingFace(bars, new Vector2(1, 0), position, 0.5f, new Vector2(0, 4)); + AddDrawingFace(bars, new Vector2(1, 0), Position, 0.5f, new Vector2(0, 4)); } } } - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleList); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleList); } - public void AddDrawingFace(List bars, Vector2 direction, Vector2 position, float length = 1, Vector2 offset = default(Vector2)) + public void AddDrawingFace(List bars, Vector2 Direction, Vector2 Position, float length = 1, Vector2 offset = default(Vector2)) { - Vector2 drawCenter = position + new Vector2(8) + offset; - Vector2 directionN = Vector2.Normalize(direction); + Vector2 drawCenter = Position + new Vector2(8) + offset; + Vector2 directionN = Vector2.Normalize(Direction); float rot = -MathF.Asin(Vector3.Cross(new Vector3(directionN, 0), new Vector3(0, -1, 0)).Z); float cos = Vector2.Dot(directionN, new Vector2(0, -1)); if (cos < 0) @@ -280,10 +281,10 @@ public override void Draw() rot = MathHelper.Pi - rot; } float dLength = 16 / 52f; - Vector2 point0 = drawCenter + new Vector2(-8 * length, -8).RotatedBy(rot) + direction * 8; - Vector2 point1 = drawCenter + new Vector2(8 * length, -8).RotatedBy(rot) + direction * 8; - Vector2 point2 = drawCenter + new Vector2(-8 * length, 8).RotatedBy(rot) + direction * 12; - Vector2 point3 = drawCenter + new Vector2(8 * length, 8).RotatedBy(rot) + direction * 12; + Vector2 point0 = drawCenter + new Vector2(-8 * length, -8).RotatedBy(rot) + Direction * 8; + Vector2 point1 = drawCenter + new Vector2(8 * length, -8).RotatedBy(rot) + Direction * 8; + Vector2 point2 = drawCenter + new Vector2(-8 * length, 8).RotatedBy(rot) + Direction * 12; + Vector2 point3 = drawCenter + new Vector2(8 * length, 8).RotatedBy(rot) + Direction * 12; Color color0 = Lighting.GetColor(point0.ToTileCoordinates()); Color color1 = Lighting.GetColor(point1.ToTileCoordinates()); diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/FemaleLampLeaves.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/FemaleLampLeaves.cs index 7cbf9c143..8d3aa7e5c 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/FemaleLampLeaves.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/FemaleLampLeaves.cs @@ -26,7 +26,7 @@ public void AddScene(int i, int j) float mainRot = 0.4f + Main.rand.NextFloat(-0.3f, 0.3f) + YggdrasilWorldGeneration.TerrianSurfaceNormal(i, j).ToRotation() - MathHelper.PiOver2; for (int x = 1; x < 3; x++) { - FemaleLampLeaves_leaf_fore leaf = new FemaleLampLeaves_leaf_fore { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + FemaleLampLeaves_leaf_fore leaf = new FemaleLampLeaves_leaf_fore { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; leaf.rotation = -(x + 0.3f) * 0.7f - Main.rand.NextFloat(.3f) + mainRot; leaf.startRotation = leaf.rotation; leaf.scale = Main.rand.NextFloat(0.75f, 1.25f); @@ -36,7 +36,7 @@ public void AddScene(int i, int j) } for (int x = 1; x < 3; x++) { - FemaleLampLeaves_leaf_fore leaf = new FemaleLampLeaves_leaf_fore { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + FemaleLampLeaves_leaf_fore leaf = new FemaleLampLeaves_leaf_fore { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; leaf.rotation = (x + 0.3f) * 0.7f + Main.rand.NextFloat(.3f) + mainRot; leaf.startRotation = leaf.rotation; leaf.scale = Main.rand.NextFloat(0.75f, 1.25f); @@ -50,7 +50,7 @@ public void AddScene(int i, int j) { continue; } - FemaleLampLeaves_leaf_fore leaf = new FemaleLampLeaves_leaf_fore { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + FemaleLampLeaves_leaf_fore leaf = new FemaleLampLeaves_leaf_fore { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; leaf.rotation = (x + 0.3f) * 0.2f + Main.rand.NextFloat(.3f) + mainRot; leaf.startRotation = leaf.rotation; leaf.scale = Main.rand.NextFloat(0.75f, 1.25f); @@ -60,7 +60,7 @@ public void AddScene(int i, int j) } if (Main.rand.NextBool(3)) { - FemaleLampLeaves_leaf_fore topLeaf = new FemaleLampLeaves_leaf_fore { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + FemaleLampLeaves_leaf_fore topLeaf = new FemaleLampLeaves_leaf_fore { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; topLeaf.rotation = mainRot + MathHelper.Pi; topLeaf.startRotation = topLeaf.rotation; topLeaf.scale = Main.rand.NextFloat(0.75f, 1.25f); @@ -70,7 +70,7 @@ public void AddScene(int i, int j) } else { - FemaleLampLeaves_leaf_fore topLeaf = new FemaleLampLeaves_leaf_fore { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + FemaleLampLeaves_leaf_fore topLeaf = new FemaleLampLeaves_leaf_fore { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; topLeaf.rotation = mainRot + MathHelper.Pi; topLeaf.startRotation = topLeaf.rotation; topLeaf.scale = Main.rand.NextFloat(0.75f, 1.25f); @@ -80,7 +80,7 @@ public void AddScene(int i, int j) } for (int x = 0; x < 3; x++) { - FemaleLampLeaves_leaf leaf = new FemaleLampLeaves_leaf { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + FemaleLampLeaves_leaf leaf = new FemaleLampLeaves_leaf { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; leaf.rotation = x * 0.6f + Main.rand.NextFloat(.3f) + mainRot; leaf.startRotation = leaf.rotation; leaf.scale = Main.rand.NextFloat(0.75f, 1.25f); @@ -90,7 +90,7 @@ public void AddScene(int i, int j) } for (int x = 0; x < 3; x++) { - FemaleLampLeaves_leaf leaf = new FemaleLampLeaves_leaf { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + FemaleLampLeaves_leaf leaf = new FemaleLampLeaves_leaf { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; leaf.rotation = -x * 0.6f + Main.rand.NextFloat(.3f) + mainRot; leaf.startRotation = leaf.rotation; leaf.scale = Main.rand.NextFloat(0.75f, 1.25f); diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/FemaleLampLeaves_leaf.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/FemaleLampLeaves_leaf.cs index d1c32e4a8..c60a051f8 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/FemaleLampLeaves_leaf.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/FemaleLampLeaves_leaf.cs @@ -3,11 +3,13 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.LampWood; [Pipeline(typeof(WCSPipeline))] -public class FemaleLampLeaves_leaf : BackgroundVFX +public class FemaleLampLeaves_leaf : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawBG; + public override void OnSpawn() { - texture = ModAsset.FemaleLampWood_leaves_dark.Value; + Texture = ModAsset.FemaleLampWood_leaves_dark.Value; } public override void Update() @@ -16,7 +18,7 @@ public override void Update() { if (player != null && player.active && !player.dead) { - if (Collision.CheckAABBvLineCollision(player.position, new Vector2(player.Hitbox.Width, player.Hitbox.Height), position, position + new Vector2(80, 140).RotatedBy(rotation) * scale)) + if (Collision.CheckAABBvLineCollision(player.position, new Vector2(player.Hitbox.Width, player.Hitbox.Height), Position, Position + new Vector2(80, 140).RotatedBy(rotation) * scale)) { omega -= Vector3.Cross(new Vector3(player.velocity, 0), new Vector3(new Vector2(80, 140).RotatedBy(rotation), 0)).Z / 30000f; } @@ -55,27 +57,29 @@ public override void Draw() point3 = Vector2.Normalize(point4).RotatedBy(point4.ToRotation() - point3.ToRotation()) * frame.Height; } - Color lightColor0 = Lighting.GetColor(position.ToTileCoordinates()); - Color lightColor1 = Lighting.GetColor((position + point2.RotatedBy(rotation) * scale).ToTileCoordinates()); - Color lightColor2 = Lighting.GetColor((position + point3.RotatedBy(rotation) * scale).ToTileCoordinates()); - Color lightColor3 = Lighting.GetColor((position + point4.RotatedBy(rotation) * scale).ToTileCoordinates()); + Color lightColor0 = Lighting.GetColor(Position.ToTileCoordinates()); + Color lightColor1 = Lighting.GetColor((Position + point2.RotatedBy(rotation) * scale).ToTileCoordinates()); + Color lightColor2 = Lighting.GetColor((Position + point3.RotatedBy(rotation) * scale).ToTileCoordinates()); + Color lightColor3 = Lighting.GetColor((Position + point4.RotatedBy(rotation) * scale).ToTileCoordinates()); List bars = new List() { - new Vertex2D(position, lightColor0, new Vector3((0 + Style) / 6f, frameY, 0)), - new Vertex2D(position + point2.RotatedBy(rotation) * scale, lightColor1, new Vector3((1 + Style) / 6f, frameY, 0)), + new Vertex2D(Position, lightColor0, new Vector3((0 + Style) / 6f, frameY, 0)), + new Vertex2D(Position + point2.RotatedBy(rotation) * scale, lightColor1, new Vector3((1 + Style) / 6f, frameY, 0)), - new Vertex2D(position + point3.RotatedBy(rotation) * scale, lightColor2, new Vector3((0 + Style) / 6f, frameY + 0.5f, 0)), - new Vertex2D(position + new Vector2(frame.Width, frame.Height).RotatedBy(rotation) * scale, lightColor3, new Vector3((1 + Style) / 6f, frameY + 0.5f, 0)), + new Vertex2D(Position + point3.RotatedBy(rotation) * scale, lightColor2, new Vector3((0 + Style) / 6f, frameY + 0.5f, 0)), + new Vertex2D(Position + new Vector2(frame.Width, frame.Height).RotatedBy(rotation) * scale, lightColor3, new Vector3((1 + Style) / 6f, frameY + 0.5f, 0)), }; - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleStrip); } } -public class FemaleLampLeaves_leaf_fore : ForegroundVFX +public class FemaleLampLeaves_leaf_fore : TileVFX { + + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; public override void OnSpawn() { - texture = ModAsset.FemaleLampWood_leaves.Value; + Texture = ModAsset.FemaleLampWood_leaves.Value; } public override void Update() @@ -87,13 +91,13 @@ public override void Update() } if (Style >= 12) { - Lighting.AddLight(position + new Vector2(0, 100).RotatedBy(rotation - 0.4f), new Vector3(1f, 0.8f, 0.3f)); + Lighting.AddLight(Position + new Vector2(0, 100).RotatedBy(rotation - 0.4f), new Vector3(1f, 0.8f, 0.3f)); } foreach (Player player in Main.player) { if (player != null && player.active && !player.dead) { - if (Collision.CheckAABBvLineCollision(player.position, new Vector2(player.Hitbox.Width, player.Hitbox.Height), position, position + new Vector2(80, 140).RotatedBy(rotation) * scale)) + if (Collision.CheckAABBvLineCollision(player.position, new Vector2(player.Hitbox.Width, player.Hitbox.Height), Position, Position + new Vector2(80, 140).RotatedBy(rotation) * scale)) { omega -= Vector3.Cross(new Vector3(player.velocity, 0), new Vector3(new Vector2(80, 140).RotatedBy(rotation), 0)).Z / stability / 10000f; } @@ -136,19 +140,19 @@ public override void Draw() float newRot = rotation - 0.4f; Vector2 dirH = new Vector2(-30 * scale * (Flip_H ? -1 : 1), 0).RotatedBy(newRot); Vector2 dirV = new Vector2(0, 210 * scale).RotatedBy(newRot); - Color lightColor0 = Lighting.GetColor((position + dirH).ToTileCoordinates()); - Color lightColor1 = Lighting.GetColor((position - dirH).ToTileCoordinates()); - Color lightColor2 = Lighting.GetColor((position + dirH + dirV).ToTileCoordinates()); - Color lightColor3 = Lighting.GetColor((position - dirH + dirV).ToTileCoordinates()); + Color lightColor0 = Lighting.GetColor((Position + dirH).ToTileCoordinates()); + Color lightColor1 = Lighting.GetColor((Position - dirH).ToTileCoordinates()); + Color lightColor2 = Lighting.GetColor((Position + dirH + dirV).ToTileCoordinates()); + Color lightColor3 = Lighting.GetColor((Position - dirH + dirV).ToTileCoordinates()); List bars = new List() { - new Vertex2D(position + dirH, lightColor0, new Vector3((0 + newStyle) / 6f, frameY + 0.25f, 0)), - new Vertex2D(position - dirH, lightColor1, new Vector3((1 + newStyle) / 6f, frameY + 0.25f, 0)), + new Vertex2D(Position + dirH, lightColor0, new Vector3((0 + newStyle) / 6f, frameY + 0.25f, 0)), + new Vertex2D(Position - dirH, lightColor1, new Vector3((1 + newStyle) / 6f, frameY + 0.25f, 0)), - new Vertex2D(position + dirH + dirV, lightColor2, new Vector3((0 + newStyle) / 6f, frameY, 0)), - new Vertex2D(position - dirH + dirV, lightColor3, new Vector3((1 + newStyle) / 6f, frameY, 0)), + new Vertex2D(Position + dirH + dirV, lightColor2, new Vector3((0 + newStyle) / 6f, frameY, 0)), + new Vertex2D(Position - dirH + dirV, lightColor3, new Vector3((1 + newStyle) / 6f, frameY, 0)), }; - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleStrip); } else { @@ -157,47 +161,47 @@ public override void Draw() float newRot = rotation - 0.4f; Vector2 dirH = new Vector2(-120 * scale * (Flip_H ? -1 : 1), 0).RotatedBy(newRot); Vector2 dirV = new Vector2(0, 140 * scale).RotatedBy(newRot); - Color lightColor0 = Lighting.GetColor((position + dirH).ToTileCoordinates()); - Color lightColor1 = Lighting.GetColor((position - dirH).ToTileCoordinates()); - Color lightColor2 = Lighting.GetColor((position + dirH + dirV).ToTileCoordinates()); - Color lightColor3 = Lighting.GetColor((position - dirH + dirV).ToTileCoordinates()); + Color lightColor0 = Lighting.GetColor((Position + dirH).ToTileCoordinates()); + Color lightColor1 = Lighting.GetColor((Position - dirH).ToTileCoordinates()); + Color lightColor2 = Lighting.GetColor((Position + dirH + dirV).ToTileCoordinates()); + Color lightColor3 = Lighting.GetColor((Position - dirH + dirV).ToTileCoordinates()); Color glowColor = new Color(1f, 1f, 1f, 0); List bars = new List() { - new Vertex2D(position + dirH, lightColor0, new Vector3((0 + newStyle) / 2f, frameY + 0.25f, 0)), - new Vertex2D(position - dirH, lightColor1, new Vector3((1 + newStyle) / 2f, frameY + 0.25f, 0)), - new Vertex2D(position + dirH + dirV, lightColor2, new Vector3((0 + newStyle) / 2f, frameY, 0)), + new Vertex2D(Position + dirH, lightColor0, new Vector3((0 + newStyle) / 2f, frameY + 0.25f, 0)), + new Vertex2D(Position - dirH, lightColor1, new Vector3((1 + newStyle) / 2f, frameY + 0.25f, 0)), + new Vertex2D(Position + dirH + dirV, lightColor2, new Vector3((0 + newStyle) / 2f, frameY, 0)), - new Vertex2D(position + dirH + dirV, lightColor2, new Vector3((0 + newStyle) / 2f, frameY, 0)), - new Vertex2D(position - dirH + dirV, lightColor3, new Vector3((1 + newStyle) / 2f, frameY, 0)), - new Vertex2D(position - dirH, lightColor1, new Vector3((1 + newStyle) / 2f, frameY + 0.25f, 0)), + new Vertex2D(Position + dirH + dirV, lightColor2, new Vector3((0 + newStyle) / 2f, frameY, 0)), + new Vertex2D(Position - dirH + dirV, lightColor3, new Vector3((1 + newStyle) / 2f, frameY, 0)), + new Vertex2D(Position - dirH, lightColor1, new Vector3((1 + newStyle) / 2f, frameY + 0.25f, 0)), - new Vertex2D(position + dirH, glowColor, new Vector3((0 + newStyle) / 2f, frameY + 0.5f, 0)), - new Vertex2D(position - dirH, glowColor, new Vector3((1 + newStyle) / 2f, frameY + 0.5f, 0)), - new Vertex2D(position + dirH + dirV, glowColor, new Vector3((0 + newStyle) / 2f, frameY + 0.25f, 0)), + new Vertex2D(Position + dirH, glowColor, new Vector3((0 + newStyle) / 2f, frameY + 0.5f, 0)), + new Vertex2D(Position - dirH, glowColor, new Vector3((1 + newStyle) / 2f, frameY + 0.5f, 0)), + new Vertex2D(Position + dirH + dirV, glowColor, new Vector3((0 + newStyle) / 2f, frameY + 0.25f, 0)), - new Vertex2D(position + dirH + dirV, glowColor, new Vector3((0 + newStyle) / 2f, frameY + 0.25f, 0)), - new Vertex2D(position - dirH + dirV, glowColor, new Vector3((1 + newStyle) / 2f, frameY + 0.25f, 0)), - new Vertex2D(position - dirH, glowColor, new Vector3((1 + newStyle) / 2f, frameY + 0.5f, 0)), + new Vertex2D(Position + dirH + dirV, glowColor, new Vector3((0 + newStyle) / 2f, frameY + 0.25f, 0)), + new Vertex2D(Position - dirH + dirV, glowColor, new Vector3((1 + newStyle) / 2f, frameY + 0.25f, 0)), + new Vertex2D(Position - dirH, glowColor, new Vector3((1 + newStyle) / 2f, frameY + 0.5f, 0)), }; - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleList); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleList); } } else { - Color lightColor0 = Lighting.GetColor(position.ToTileCoordinates()); - Color lightColor1 = Lighting.GetColor((position + point2.RotatedBy(rotation) * scale).ToTileCoordinates()); - Color lightColor2 = Lighting.GetColor((position + point3.RotatedBy(rotation) * scale).ToTileCoordinates()); - Color lightColor3 = Lighting.GetColor((position + point4.RotatedBy(rotation) * scale).ToTileCoordinates()); + Color lightColor0 = Lighting.GetColor(Position.ToTileCoordinates()); + Color lightColor1 = Lighting.GetColor((Position + point2.RotatedBy(rotation) * scale).ToTileCoordinates()); + Color lightColor2 = Lighting.GetColor((Position + point3.RotatedBy(rotation) * scale).ToTileCoordinates()); + Color lightColor3 = Lighting.GetColor((Position + point4.RotatedBy(rotation) * scale).ToTileCoordinates()); List bars = new List() { - new Vertex2D(position, lightColor0, new Vector3((0 + Style) / 6f, frameY, 0)), - new Vertex2D(position + point2.RotatedBy(rotation) * scale, lightColor1, new Vector3((1 + Style) / 6f, frameY, 0)), + new Vertex2D(Position, lightColor0, new Vector3((0 + Style) / 6f, frameY, 0)), + new Vertex2D(Position + point2.RotatedBy(rotation) * scale, lightColor1, new Vector3((1 + Style) / 6f, frameY, 0)), - new Vertex2D(position + point3.RotatedBy(rotation) * scale, lightColor2, new Vector3((0 + Style) / 6f, frameY + 0.25f, 0)), - new Vertex2D(position + new Vector2(frame.Width, frame.Height).RotatedBy(rotation) * scale, lightColor3, new Vector3((1 + Style) / 6f, frameY + 0.25f, 0)), + new Vertex2D(Position + point3.RotatedBy(rotation) * scale, lightColor2, new Vector3((0 + Style) / 6f, frameY + 0.25f, 0)), + new Vertex2D(Position + new Vector2(frame.Width, frame.Height).RotatedBy(rotation) * scale, lightColor3, new Vector3((1 + Style) / 6f, frameY + 0.25f, 0)), }; - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleStrip); } } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/Furniture/LampWoodCandelabra.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/Furniture/LampWoodCandelabra.cs index 1a3345568..034d3da76 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/Furniture/LampWoodCandelabra.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/Furniture/LampWoodCandelabra.cs @@ -28,15 +28,19 @@ public override void SetStaticDefaults() TileObjectData.newTile.CoordinateHeights = new[] { 16, 16 }; TileObjectData.addTile(Type); if (!Main.dedServ) + { flameTexture = ModAsset.LampWoodCandelabra_Flame; + } LocalizedText name = CreateMapEntryName(); AddMapEntry(new Color(69, 36, 78), name); } + public override void NumDust(int i, int j, bool fail, ref int num) { num = 0; } + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) { r = 1f; @@ -48,12 +52,16 @@ public override void HitWire(int i, int j) { FurnitureUtils.LightHitwire(i, j, Type, 2, 2); } + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) { var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); if (Main.drawToScreen) + { zero = Vector2.Zero; + } + var color = new Color(55, 5, 255, 0); int width = 20; int height = 20; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/Furniture/LampWood_Chest.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/Furniture/LampWood_Chest.cs index 68bfe4afc..0cf299088 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/Furniture/LampWood_Chest.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/LampWood/Furniture/LampWood_Chest.cs @@ -21,6 +21,10 @@ public override void SetStaticDefaults() TileID.Sets.HasOutlines[Type] = true; TileID.Sets.BasicChest[Type] = true; TileID.Sets.DisableSmartCursor[Type] = true; + TileID.Sets.AvoidedByNPCs[Type] = true; + TileID.Sets.InteractibleByNPCs[Type] = true; + TileID.Sets.IsAContainer[Type] = true; + TileID.Sets.FriendlyFairyCanLureTo[Type] = true; DustType = ModContent.DustType(); AdjTiles = new int[] { TileID.Containers }; @@ -30,7 +34,14 @@ public override void SetStaticDefaults() TileObjectData.newTile.CoordinateHeights = new[] { 16, 18 }; TileObjectData.newTile.HookCheckIfCanPlace = new PlacementHook(Chest.FindEmptyChest, -1, 0, true); TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(Chest.AfterPlacement_Hook, -1, 0, false); - TileObjectData.newTile.AnchorInvalidTiles = new int[] { TileID.MagicalIceBlock }; + TileObjectData.newTile.AnchorInvalidTiles = new int[] + { + TileID.MagicalIceBlock, + TileID.Boulder, + TileID.BouncyBoulder, + TileID.LifeCrystalBoulder, + TileID.RollingCactus, + }; TileObjectData.newTile.StyleHorizontal = true; TileObjectData.newTile.LavaDeath = false; TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.SolidTile | AnchorType.SolidWithTop | AnchorType.SolidSide, TileObjectData.newTile.Width, 0); @@ -146,13 +157,18 @@ public override void PostDraw(int i, int j, SpriteBatch spriteBatch) { Color lightColor = Lighting.GetColor(i, j); Tile tile = Main.tile[i, j]; - var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); - - if (Main.drawToScreen) + int left = i - tile.TileFrameX / 18; + int top = j - tile.TileFrameY / 18; + int chestIndex = Chest.FindChest(left, top); + if (chestIndex >= 0) { - zero = Vector2.Zero; + Chest chest = Main.chest[chestIndex]; + var zero = new Vector2(Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + spriteBatch.Draw(ModAsset.LampWood_Chest_crystal.Value, new Vector2(i, j) * 16 - Main.screenPosition + zero, new Rectangle(tile.TileFrameX, tile.TileFrameY + chest.frame * 38, 16, 16), lightColor * 2.5f, 0, Vector2.zeroVector, 1, SpriteEffects.None, 0); } - - spriteBatch.Draw(ModAsset.LampWood_Chest_crystal.Value, new Vector2(i, j) * 16 - Main.screenPosition + zero, new Rectangle(tile.TileFrameX, tile.TileFrameY, 16, 16), lightColor * 2.5f, 0, Vector2.zeroVector, 1, SpriteEffects.None, 0); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MailBox.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MailBox.cs new file mode 100644 index 000000000..71344b25b --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MailBox.cs @@ -0,0 +1,269 @@ +using Everglow.Yggdrasil.YggdrasilTown.Dusts; +using Everglow.Yggdrasil.YggdrasilTown.Items.Placeables; +using Terraria.Audio; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.GameContent.ObjectInteractions; +using Terraria.Localization; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; + +public class MailBox : ModTile +{ + public override void SetStaticDefaults() + { + // Properties + Main.tileSpelunker[Type] = true; + Main.tileContainer[Type] = true; + Main.tileFrameImportant[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileOreFinderPriority[Type] = 1; + TileID.Sets.HasOutlines[Type] = true; + TileID.Sets.BasicChest[Type] = true; + TileID.Sets.DisableSmartCursor[Type] = true; + TileID.Sets.AvoidedByNPCs[Type] = true; + TileID.Sets.InteractibleByNPCs[Type] = true; + TileID.Sets.IsAContainer[Type] = true; + TileID.Sets.GeneralPlacementTiles[Type] = false; + + DustType = ModContent.DustType(); + AdjTiles = new int[] { TileID.Containers }; + + // Other tiles with just one map entry use CreateMapEntryName() to use the default translationkey, "MapEntry" + // Since ExampleChest needs multiple, we register our own MapEntry keys + AddMapEntry(new Color(200, 200, 200), this.GetLocalization("MapEntry0"), MapChestName); + + // Style 1 is ExampleChest when locked. We want that tile style to drop the ExampleChest item as well. Use the Chest Lock item to lock this chest. + // No item places ExampleChest in the locked style, so the automatically determined item drop is unknown, this is why RegisterItemDrop is necessary in this situation. + RegisterItemDrop(ModContent.ItemType(), 1); + + // Sometimes mods remove content, such as tile styles, or tiles accidentally get corrupted. We can, if desired, register a fallback item for any tile style that doesn't have an automatically determined item drop. This is done by omitting the tileStyles parameter. + // RegisterItemDrop(ItemID.Chest); + + // Placement + TileObjectData.newTile.CopyFrom(TileObjectData.Style2x2); + TileObjectData.newTile.Height = 3; + TileObjectData.newTile.Width = 2; + TileObjectData.newTile.Origin = new Point16(0, 2); + TileObjectData.newTile.CoordinateHeights = new[] { 16, 16, 18 }; + TileObjectData.newTile.HookCheckIfCanPlace = new PlacementHook(Chest.FindEmptyChest, -1, 0, true); + TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(Chest.AfterPlacement_Hook, -1, 0, false); + TileObjectData.newTile.AnchorInvalidTiles = new int[] + { + TileID.MagicalIceBlock, + TileID.Boulder, + TileID.BouncyBoulder, + TileID.LifeCrystalBoulder, + TileID.RollingCactus, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.SolidTile | AnchorType.SolidWithTop | AnchorType.SolidSide, TileObjectData.newTile.Width, 0); + TileObjectData.addTile(Type); + } + + public override LocalizedText DefaultContainerName(int frameX, int frameY) + { + return this.GetLocalization("MapEntry0"); + } + + public override bool HasSmartInteract(int i, int j, SmartInteractScanSettings settings) + { + return true; + } + + public static string MapChestName(string name, int i, int j) + { + int left = i; + int top = j; + Tile tile = Main.tile[i, j]; + if (tile.TileFrameX % 36 != 0) + { + left--; + } + + if (tile.TileFrameY != 0) + { + top--; + } + + int chest = Chest.FindChest(left, top); + if (chest < 0) + { + return Language.GetTextValue("LegacyChestType.0"); + } + + if (Main.chest[chest].name == string.Empty) + { + return name; + } + + return name + ": " + Main.chest[chest].name; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 1; + } + + public override void KillMultiTile(int i, int j, int frameX, int frameY) + { + // We override KillMultiTile to handle additional logic other than the item drop. In this case, unregistering the Chest from the world + Chest.DestroyChest(i, j); + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + Tile tile = Main.tile[i, j]; + + int left = i; + int top = j; + left -= tile.TileFrameX / 18; + top -= tile.TileFrameY / 18; + int chestIndex = Chest.FindChest(left, top); + if (chestIndex >= 0) + { + Chest chest = Main.chest[chestIndex]; + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + var texture = ModContent.Request(Texture).Value; + spriteBatch.Draw(texture, new Vector2(i, j) * 16 - Main.screenPosition + zero, new Rectangle(tile.TileFrameX, tile.TileFrameY + chest.frame * 54, 16, 16), Lighting.GetColor(i, j), 0, Vector2.zeroVector, 1, SpriteEffects.None, 0); + return false; + } + return false; + } + + public override bool RightClick(int i, int j) + { + return ChestRightClick2(i, j); + } + + public bool ChestRightClick2(int i, int j) + { + Player player = Main.LocalPlayer; + Tile tile = Main.tile[i, j]; + Main.mouseRightRelease = false; + int left = i; + int top = j; + if (tile.TileFrameX % 54 != 0) + { + left -= tile.TileFrameX / 18; + } + + if (tile.TileFrameY != 0) + { + top--; + } + + player.CloseSign(); + player.SetTalkNPC(-1); + Main.npcChatCornerItem = 0; + Main.npcChatText = string.Empty; + if (Main.editChest) + { + SoundEngine.PlaySound(SoundID.MenuTick); + Main.editChest = false; + Main.npcChatText = string.Empty; + } + + if (player.editedChestName) + { + NetMessage.SendData(MessageID.SyncPlayerChest, -1, -1, NetworkText.FromLiteral(Main.chest[player.chest].name), player.chest, 1f); + player.editedChestName = false; + } + + if (Main.netMode == NetmodeID.MultiplayerClient) + { + if (left == player.chestX && top == player.chestY && player.chest >= 0) + { + player.chest = -1; + Recipe.FindRecipes(); + SoundEngine.PlaySound(SoundID.MenuClose); + } + else + { + NetMessage.SendData(MessageID.RequestChestOpen, -1, -1, null, left, top); + Main.stackSplit = 600; + } + } + else + { + int chest = Chest.FindChest(left, top); + if (chest >= 0) + { + Main.stackSplit = 600; + if (chest == player.chest) + { + player.chest = -1; + SoundEngine.PlaySound(SoundID.MenuClose); + } + else + { + player.chest = chest; + Main.playerInventory = true; + Main.recBigList = false; + player.chestX = left; + player.chestY = top; + SoundEngine.PlaySound(SoundID.MenuOpen); + } + + Recipe.FindRecipes(); + } + } + return true; + } + + public override void MouseOver(int i, int j) + { + Player player = Main.LocalPlayer; + Tile tile = Main.tile[i, j]; + int left = i; + int top = j; + if (tile.TileFrameX % 54 != 0) + { + left -= tile.TileFrameX / 18; + } + if (tile.TileFrameY != 0) + { + top--; + } + int chestIndex = Chest.FindChest(left, top); + player.cursorItemIconID = -1; + if (chestIndex < 0) + { + player.cursorItemIconText = Language.GetTextValue("LegacyChestType.0"); + } + else + { + Chest chest = Main.chest[chestIndex]; + if (chest.frame == 0) + { + } + string defaultName = TileLoader.DefaultContainerName(tile.TileType, tile.TileFrameX, tile.TileFrameY); // This gets the ContainerName text for the currently selected language + player.cursorItemIconText = chest.name.Length > 0 ? chest.name : defaultName; + if (player.cursorItemIconText == defaultName) + { + player.cursorItemIconID = ModContent.ItemType(); + player.cursorItemIconText = string.Empty; + } + } + + player.noThrow = 2; + player.cursorItemIconEnabled = true; + } + + public override void MouseOverFar(int i, int j) + { + MouseOver(i, j); + Player player = Main.LocalPlayer; + if (player.cursorItemIconText == string.Empty) + { + player.cursorItemIconEnabled = false; + player.cursorItemIconID = ItemID.None; + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MailBox.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MailBox.png new file mode 100644 index 000000000..e10aa9ab3 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MailBox.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MailBox_Highlight.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MailBox_Highlight.png new file mode 100644 index 000000000..c1c970dd8 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MailBox_Highlight.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MarbleGate.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MarbleGate.cs index 090d4dbd5..9e2d1b723 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MarbleGate.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MarbleGate.cs @@ -49,8 +49,10 @@ public void AddScene(int i, int j) Tile tile = TileUtils.SafeGetTile(i, j); if (tile.TileFrameX == 0 && tile.TileFrameY == 0) { - MarbleGate_BackgroundTile mGBT = new MarbleGate_BackgroundTile { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + MarbleGate_BackgroundTile mGBT = new MarbleGate_BackgroundTile { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; + MarbleGate_UnionMarblePost mGUMP = new MarbleGate_UnionMarblePost { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(mGBT); + Ins.VFXManager.Add(mGUMP); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MarbleGate_BackgroundTile.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MarbleGate_BackgroundTile.cs index 599fe04ec..9bf4a0962 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MarbleGate_BackgroundTile.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MarbleGate_BackgroundTile.cs @@ -2,19 +2,20 @@ using Everglow.Commons.VFX.Scene; using Everglow.SubSpace; using Everglow.Yggdrasil.WorldGeneration; -using Everglow.Yggdrasil.YggdrasilTown.Kitchen.Tiles; namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; [Pipeline(typeof(WCSPipeline_PointWrap))] -public class MarbleGate_BackgroundTile : BackgroundVFX +public class MarbleGate_BackgroundTile : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawBG; + public override void Update() { base.Update(); - if (Main.MouseWorld.X > position.X && Main.MouseWorld.X < position.X + 112) + if (Main.MouseWorld.X > Position.X && Main.MouseWorld.X < Position.X + 112) { - if (Main.MouseWorld.Y > position.Y && Main.MouseWorld.Y < position.Y + 128) + if (Main.MouseWorld.Y > Position.Y && Main.MouseWorld.Y < Position.Y + 128) { Main.instance.MouseText("Rightclick to Enter Union."); if (Main.mouseRight && Main.mouseRightRelease && !Main.mapFullscreen) @@ -59,7 +60,7 @@ public void BuildUnionGen() for (int y = 20; y < 23; y++) { Tile tile = TileUtils.SafeGetTile(x, y); - tile.wall = 1; + tile.WallType = 1; ushort typeChange = (ushort)ModContent.TileType(); if (y == 22) { @@ -78,41 +79,41 @@ public void BuildUnionGen() public override void OnSpawn() { - texture = ModAsset.MarbleGate.Value; + Texture = ModAsset.MarbleGate.Value; } public override void Draw() { - Color lightColor0 = Lighting.GetColor((int)position.X / 16, (int)position.Y / 16); - Color lightColor1 = Lighting.GetColor((int)(position.X + texture.Width) / 16, (int)position.Y / 16); - Color lightColor2 = Lighting.GetColor((int)position.X / 16, (int)(position.Y + texture.Height) / 16); - Color lightColor3 = Lighting.GetColor((int)(position.X + texture.Width) / 16, (int)(position.Y + texture.Height) / 16); + Color lightColor0 = Lighting.GetColor((int)Position.X / 16, (int)Position.Y / 16); + Color lightColor1 = Lighting.GetColor((int)(Position.X + Texture.Width) / 16, (int)Position.Y / 16); + Color lightColor2 = Lighting.GetColor((int)Position.X / 16, (int)(Position.Y + Texture.Height) / 16); + Color lightColor3 = Lighting.GetColor((int)(Position.X + Texture.Width) / 16, (int)(Position.Y + Texture.Height) / 16); - Vector2 subBackgroundScale = texture.Size() / ModAsset.MarbleGate_Background.Value.Size(); + Vector2 subBackgroundScale = Texture.Size() / ModAsset.MarbleGate_Background.Value.Size(); // Vector2 offsetMouse = new Vector2((Main.MouseScreen.X / 150) % 1f, (Main.MouseScreen.Y / 150) % 1f); - Vector2 viewOffset = (position - Main.LocalPlayer.position) * 0.0004f + new Vector2(10000) + new Vector2(0.44f); + Vector2 viewOffset = (Position - Main.LocalPlayer.position) * 0.0004f + new Vector2(10000) + new Vector2(0.44f); // Main.NewText(offsetMouse); viewOffset.X %= 1; viewOffset.Y %= 1; List bars = new List() { - new Vertex2D(position, Color.White, new Vector3(viewOffset, 0)), - new Vertex2D(position + new Vector2(texture.Width, 0), Color.White, new Vector3(viewOffset + new Vector2(subBackgroundScale.X, 0), 0)), + new Vertex2D(Position, Color.White, new Vector3(viewOffset, 0)), + new Vertex2D(Position + new Vector2(Texture.Width, 0), Color.White, new Vector3(viewOffset + new Vector2(subBackgroundScale.X, 0), 0)), - new Vertex2D(position + new Vector2(0, texture.Height), Color.White, new Vector3(viewOffset + new Vector2(0, subBackgroundScale.Y), 0)), - new Vertex2D(position + new Vector2(texture.Width, texture.Height), Color.White, new Vector3(viewOffset + subBackgroundScale, 0)), + new Vertex2D(Position + new Vector2(0, Texture.Height), Color.White, new Vector3(viewOffset + new Vector2(0, subBackgroundScale.Y), 0)), + new Vertex2D(Position + new Vector2(Texture.Width, Texture.Height), Color.White, new Vector3(viewOffset + subBackgroundScale, 0)), }; Ins.Batch.Draw(ModAsset.MarbleGate_Background.Value, bars, PrimitiveType.TriangleStrip); bars = new List() { - new Vertex2D(position, lightColor0, new Vector3(0, 0, 0)), - new Vertex2D(position + new Vector2(texture.Width, 0), lightColor1, new Vector3(1, 0, 0)), + new Vertex2D(Position, lightColor0, new Vector3(0, 0, 0)), + new Vertex2D(Position + new Vector2(Texture.Width, 0), lightColor1, new Vector3(1, 0, 0)), - new Vertex2D(position + new Vector2(0, texture.Height), lightColor2, new Vector3(0, 1, 0)), - new Vertex2D(position + new Vector2(texture.Width, texture.Height), lightColor3, new Vector3(1, 1, 0)), + new Vertex2D(Position + new Vector2(0, Texture.Height), lightColor2, new Vector3(0, 1, 0)), + new Vertex2D(Position + new Vector2(Texture.Width, Texture.Height), lightColor3, new Vector3(1, 1, 0)), }; - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleStrip); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MarbleGate_UnionMarblePost.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MarbleGate_UnionMarblePost.cs new file mode 100644 index 000000000..fafc0d5ff --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MarbleGate_UnionMarblePost.cs @@ -0,0 +1,29 @@ +using Everglow.Commons.TileHelper; +using Everglow.Commons.VFX.Scene; +using Everglow.SubSpace; +using Everglow.Yggdrasil.WorldGeneration; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; + +[Pipeline(typeof(WCSPipeline_PointWrap))] +public class MarbleGate_UnionMarblePost : TileVFX +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawDusts; + + public override void Update() + { + base.Update(); + } + + public override void OnSpawn() + { + Texture = ModAsset.MarbleGate_UnionMarblePost.Value; + } + + public override void Draw() + { + List bars = new List(); + SpriteBatchUtils.AddVertex_Grid(bars, Position + new Vector2(151, 128), null, Texture.Size() * new Vector2(0.5f, 1f), Texture, false, 128); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleStrip); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MarbleGate_UnionMarblePost.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MarbleGate_UnionMarblePost.png new file mode 100644 index 000000000..4a5099c78 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MarbleGate_UnionMarblePost.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroSign.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroSign.cs new file mode 100644 index 000000000..a22ed7c46 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroSign.cs @@ -0,0 +1,36 @@ +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; + +public class MetroSign : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + Main.tileLavaDeath[Type] = false; + + Main.tileWaterDeath[Type] = false; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 7; + TileObjectData.newTile.Width = 2; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 16, + 16, + 16, + 16, + 16, + 18, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.addTile(Type); + AddMapEntry(new Color(153, 45, 45)); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroSign.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroSign.png new file mode 100644 index 000000000..721e1fb1c Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroSign.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroStationSign_PylonSquare.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroStationSign_PylonSquare.cs new file mode 100644 index 000000000..6e76771b4 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroStationSign_PylonSquare.cs @@ -0,0 +1,58 @@ +using Everglow.Commons.CustomTiles; +using Everglow.Yggdrasil.YggdrasilTown.CustomTiles; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; + +public class MetroStationSign_PylonSquare : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + Main.tileLavaDeath[Type] = false; + + Main.tileWaterDeath[Type] = false; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 5; + TileObjectData.newTile.Width = 5; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 16, + 16, + 16, + 16, + }; + TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.SolidTile | AnchorType.SolidWithTop, 5, 0); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + TileObjectData.addTile(Type); + MinPick = int.MaxValue; + AddMapEntry(new Color(226, 226, 226)); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + } + + public override bool CanExplode(int i, int j) => false; + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + noBreak = true; + return base.TileFrame(i, j, ref resetFrame, ref noBreak); + } + + public override void NearbyEffects(int i, int j, bool closer) + { + var tile = Main.tile[i, j]; + if (tile.HasTile && tile.TileFrameX == 36 && tile.TileFrameY == 72 && ColliderManager.Instance.OfType().Count() <= 0) + { + ColliderManager.Instance.Add(new Point(i, j).ToWorldCoordinates() + new Vector2(-1400, 0)); + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroStationSign_PylonSquare.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroStationSign_PylonSquare.png new file mode 100644 index 000000000..6781ea38a Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroStationSign_PylonSquare.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroStationSign_YggdrasilTown.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroStationSign_YggdrasilTown.cs new file mode 100644 index 000000000..d6f909a53 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroStationSign_YggdrasilTown.cs @@ -0,0 +1,58 @@ +using Everglow.Commons.CustomTiles; +using Everglow.Yggdrasil.YggdrasilTown.CustomTiles; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; + +public class MetroStationSign_YggdrasilTown : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + Main.tileLavaDeath[Type] = false; + + Main.tileWaterDeath[Type] = false; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 5; + TileObjectData.newTile.Width = 5; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 16, + 16, + 16, + 16, + }; + TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.SolidTile | AnchorType.SolidWithTop, 5, 0); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + TileObjectData.addTile(Type); + MinPick = int.MaxValue; + AddMapEntry(new Color(226, 226, 226)); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + } + + public override bool CanExplode(int i, int j) => false; + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + noBreak = true; + return base.TileFrame(i, j, ref resetFrame, ref noBreak); + } + + public override void NearbyEffects(int i, int j, bool closer) + { + var tile = Main.tile[i, j]; + if (tile.HasTile && tile.TileFrameX == 36 && tile.TileFrameY == 72 && ColliderManager.Instance.OfType().Count() <= 0) + { + ColliderManager.Instance.Add(new Point(i, j).ToWorldCoordinates()); + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroStationSign_YggdrasilTown.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroStationSign_YggdrasilTown.png new file mode 100644 index 000000000..4b5abf6b5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MetroStationSign_YggdrasilTown.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MissionCounter.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MissionCounter.png index f6d7bdba6..b56b3bf47 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MissionCounter.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/MissionCounter.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon.png deleted file mode 100644 index f67823dfe..000000000 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon.png and /dev/null differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon/OriginPylon.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon/OriginPylon.cs new file mode 100644 index 000000000..e8f97cd92 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon/OriginPylon.cs @@ -0,0 +1,157 @@ +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.Common.Projectiles; +using Everglow.Yggdrasil.YggdrasilTown.VFXs; +using SubworldLibrary; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.OriginPylon; + +public class OriginPylon : ModTile, ISceneTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + Main.tileLavaDeath[Type] = false; + + Main.tileWaterDeath[Type] = false; + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); + TileObjectData.newTile.Height = 12; + TileObjectData.newTile.Width = 8; + TileObjectData.newTile.CoordinateHeights = new int[] + { + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 16, + 20, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + TileObjectData.addTile(Type); + AddMapEntry(new Color(188, 189, 185)); + MinPick = int.MaxValue; + } + + public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) + { + noBreak = true; + return base.TileFrame(i, j, ref resetFrame, ref noBreak); + } + + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + Tile tile = Main.tile[i, j]; + if (tile.TileFrameX < 108) + { + r = 1f; + g = 1f; + b = 1f; + } + else + { + r = 1f; + g = 1f; + b = 1f; + } + base.ModifyLight(i, j, ref r, ref g, ref b); + } + + public override bool CanExplode(int i, int j) + { + return false; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + base.NumDust(i, j, fail, ref num); + } + + public override bool CanKillTile(int i, int j, ref bool blockDamaged) + { + return false; + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + Tile tile = Main.tile[i, j]; + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + + if (Ins.VisualQuality.Low) + { + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + if (tile.TileFrameX == 4 * 18 && tile.TileFrameY == 6 * 18) + { + spriteBatch.Draw(ModAsset.OriginPylon.Value, new Vector2(i, j) * 16 - Main.screenPosition + zero + new Vector2(16, -36), null, Color.White, 0, ModAsset.OriginPylon.Value.Size() * 0.5f, 1, SpriteEffects.None, 0); + } + } + return false; + } + + public override void NearbyEffects(int i, int j, bool closer) + { + if (!Main.gamePaused && YggdrasilWorld.YggdrasilTimer > 5 && !Ins.VisualQuality.Low) + { + if (Main.rand.NextBool(600)) + { + Vector2 newVelocity = new Vector2(0, Main.rand.NextFloat(0f, 1f)).RotatedByRandom(MathHelper.TwoPi); + Vector2 pos = new Vector2(i, j) * 16; + Vector2 addPos = new Vector2(Main.rand.NextFloat(1f) * 120f, 0).RotatedByRandom(6.283); + addPos.Y = -Math.Abs(addPos.Y) * 4 + 100; + float size = Math.Max(addPos.Y + 500, 0) / 500f; + size *= (130 - Math.Abs(addPos.X)) / 120f; + addPos.X += 16; + pos += addPos; + if (Collision.SolidCollision(pos, 0, 0)) + { + return; + } + var dust = new WhiteTriangle + { + velocity = newVelocity + new Vector2(0, addPos.Y * 0.01f), + Active = true, + Visible = true, + position = pos, + maxTime = Main.rand.Next(50, 192), + scale = 0, + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(4.0f, 14.5f) * size, Main.rand.NextFloat(-0.03f, 0.03f) }, + }; + Ins.VFXManager.Add(dust); + } + } + } + + public void AddScene(int i, int j) + { + Tile tile = Main.tile[i, j]; + if (tile.TileFrameX == 0 && tile.TileFrameY == 0) + { + var oPVFX = new OriginalPylon_VFX { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = ModContent.TileType() }; + Ins.VFXManager.Add(oPVFX); + } + } + + public override bool RightClick(int i, int j) + { + Player player = Main.LocalPlayer; + int projectileType = ModContent.ProjectileType(); + if (player.ownedProjectileCounts[projectileType] <= 0) + { + player.AddBuff(BuffID.Shimmer, 30); + Projectile.NewProjectileDirect(WorldGen.GetProjectileSource_PlayerOrWires(i, j, false, player), Main.MouseWorld, Vector2.zeroVector, projectileType, 0, 0, player.whoAmI); + } + return base.RightClick(i, j); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon_hang.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon/OriginPylon.png similarity index 100% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon_hang.png rename to Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon/OriginPylon.png diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon/OriginPylon_WhiteTriangleDust.cs similarity index 55% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon.cs rename to Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon/OriginPylon_WhiteTriangleDust.cs index ce1f2045b..ec7c4c7cd 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon/OriginPylon_WhiteTriangleDust.cs @@ -4,172 +4,24 @@ using SubworldLibrary; using Terraria.ObjectData; -namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; - -public class OriginPylon : ModTile, ISceneTile -{ - public override void SetStaticDefaults() - { - Main.tileFrameImportant[Type] = true; - Main.tileLighted[Type] = true; - Main.tileLavaDeath[Type] = false; - - Main.tileWaterDeath[Type] = false; - TileObjectData.newTile.CopyFrom(TileObjectData.Style1x1); - TileObjectData.newTile.Height = 12; - TileObjectData.newTile.Width = 8; - TileObjectData.newTile.CoordinateHeights = new int[] - { - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 16, - 20, - }; - TileObjectData.newTile.StyleHorizontal = true; - TileObjectData.newTile.LavaDeath = false; - TileObjectData.addTile(Type); - AddMapEntry(new Color(188, 189, 185)); - MinPick = int.MaxValue; - } - - public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) - { - noBreak = true; - return base.TileFrame(i, j, ref resetFrame, ref noBreak); - } - - public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) - { - Tile tile = Main.tile[i, j]; - if (tile.TileFrameX < 108) - { - r = 1f; - g = 1f; - b = 1f; - } - else - { - r = 1f; - g = 1f; - b = 1f; - } - base.ModifyLight(i, j, ref r, ref g, ref b); - } - - public override bool CanExplode(int i, int j) - { - return false; - } - - public override void NumDust(int i, int j, bool fail, ref int num) - { - num = 0; - base.NumDust(i, j, fail, ref num); - } - - public override bool CanKillTile(int i, int j, ref bool blockDamaged) - { - return false; - } - - public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) - { - Tile tile = Main.tile[i, j]; - var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); - - if (Ins.VisualQuality.Low) - { - if (Main.drawToScreen) - { - zero = Vector2.Zero; - } - if (tile.TileFrameX == 4 * 18 && tile.TileFrameY == 6 * 18) - { - spriteBatch.Draw(ModAsset.OriginPylon_hang.Value, new Vector2(i, j) * 16 - Main.screenPosition + zero + new Vector2(16, -36), null, Color.White, 0, ModAsset.OriginPylon_hang.Value.Size() * 0.5f, 1, SpriteEffects.None, 0); - } - } - return false; - } - - public override void NearbyEffects(int i, int j, bool closer) - { - if (!Main.gamePaused && YggdrasilWorld.YggdrasilTimer > 5 && !Ins.VisualQuality.Low) - { - if (Main.rand.NextBool(600)) - { - Vector2 newVelocity = new Vector2(0, Main.rand.NextFloat(0f, 1f)).RotatedByRandom(MathHelper.TwoPi); - Vector2 pos = new Vector2(i, j) * 16; - Vector2 addPos = new Vector2(Main.rand.NextFloat(1f) * 120f, 0).RotatedByRandom(6.283); - addPos.Y = -Math.Abs(addPos.Y) * 4 + 100; - float size = Math.Max(addPos.Y + 500, 0) / 500f; - size *= (130 - Math.Abs(addPos.X)) / 120f; - addPos.X += 16; - pos += addPos; - if (Collision.SolidCollision(pos, 0, 0)) - { - return; - } - var dust = new WhiteTriangle - { - velocity = newVelocity + new Vector2(0, addPos.Y * 0.01f), - Active = true, - Visible = true, - position = pos, - maxTime = Main.rand.Next(50, 192), - scale = 0, - rotation = Main.rand.NextFloat(6.283f), - ai = new float[] { Main.rand.NextFloat(4.0f, 14.5f) * size, Main.rand.NextFloat(-0.03f, 0.03f) }, - }; - Ins.VFXManager.Add(dust); - } - } - } - - public void AddScene(int i, int j) - { - Tile tile = Main.tile[i, j]; - if (tile.TileFrameX == 0 && tile.TileFrameY == 0) - { - OriginalPylon_VFX oPVFX = new OriginalPylon_VFX { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = ModContent.TileType() }; - Ins.VFXManager.Add(oPVFX); - } - } - - public override bool RightClick(int i, int j) - { - Player player = Main.LocalPlayer; - int projectileType = ModContent.ProjectileType(); - if (player.ownedProjectileCounts[projectileType] <= 0) - { - player.AddBuff(BuffID.Shimmer, 30); - Projectile.NewProjectileDirect(WorldGen.GetProjectileSource_PlayerOrWires(i, j, false, player), Main.MouseWorld, Vector2.zeroVector, projectileType, 0, 0, player.whoAmI); - } - return base.RightClick(i, j); - } -} +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.OriginPylon; [Pipeline(typeof(WCSPipeline))] -public class OriginalPylon_VFX : BackgroundVFX +public class OriginalPylon_VFX : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawBG; + public override void OnSpawn() { - texture = ModAsset.StoneBridge_fence.Value; + Texture = ModAsset.StoneBridge_fence.Value; } public override void Update() { - if (!SubworldSystem.IsActive()) - { - Active = false; - } + //if (!SubworldSystem.IsActive()) + //{ + // Active = false; + //} base.Update(); } @@ -177,9 +29,9 @@ public override void Draw() { if (!Ins.VisualQuality.Low) { - float i = position.X / 16f; - float j = position.Y / 16f; - List bars = new List(); + float i = Position.X / 16f; + float j = Position.Y / 16f; + var bars = new List(); Color color0 = Color.White * 0.4f; color0.A = 0; bars = new List() @@ -189,12 +41,10 @@ public override void Draw() new Vertex2D(new Vector2(i - 11, j + 17) * 16, color0, new Vector3(0, 1, 0)), new Vertex2D(new Vector2(i + 21, j + 17) * 16, color0, new Vector3(1, 1, 0)), }; - Ins.Batch.Draw(ModAsset.OriginPylon_hang_glow.Value, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(ModAsset.OriginPylon_glow.Value, bars, PrimitiveType.TriangleStrip); float timeValue = (float)(Main.time * 0.0004f); - Ins.Batch.End(); - Ins.Batch.Begin(BlendState.AlphaBlend, DepthStencilState.Default, SamplerState.PointWrap, RasterizerState.CullNone); - List crack = new List(); + var crack = new List(); for (int k = 0; k < 6; k++) { Vector2 v0 = new Vector2(290, 0).RotatedBy(k); @@ -222,7 +72,7 @@ public override void Draw() Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1)); effect.CurrentTechnique.Passes[0].Apply(); - List chain = new List(); + var chain = new List(); for (int k = 0; k < 6; k++) { Vector2 v0 = new Vector2(290, 0).RotatedBy(k); @@ -274,7 +124,7 @@ public override void Draw() new Vertex2D(new Vector2(i - 11, j + 17) * 16, Color.White, new Vector3(0, 1, 0)), new Vertex2D(new Vector2(i + 21, j + 17) * 16, Color.White, new Vector3(1, 1, 0)), }; - Ins.Batch.Draw(ModAsset.OriginPylon_hang.Value, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(ModAsset.OriginPylon.Value, bars, PrimitiveType.TriangleStrip); } } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon_chain.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon/OriginPylon_chain.png similarity index 100% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon_chain.png rename to Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon/OriginPylon_chain.png diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon_hang_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon/OriginPylon_glow.png similarity index 100% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon_hang_glow.png rename to Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon/OriginPylon_glow.png diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon_halo.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon/OriginPylon_halo.png similarity index 100% rename from Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon_halo.png rename to Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon/OriginPylon_halo.png diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon_glow.png deleted file mode 100644 index 8548d6492..000000000 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/OriginPylon_glow.png and /dev/null differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/PlantSpecimen_Branch.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/PlantSpecimen_Branch.cs new file mode 100644 index 000000000..73d8b7313 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/PlantSpecimen_Branch.cs @@ -0,0 +1,35 @@ +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; + +public class PlantSpecimen_Branch : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileNoAttach[Type] = false; + Main.tileWaterDeath[Type] = false; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3Wall); + TileObjectData.newTile.Height = 4; + TileObjectData.newTile.Width = 3; + TileObjectData.newTile.CoordinateHeights = new int[4]; + Array.Fill(TileObjectData.newTile.CoordinateHeights, 16); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + + TileObjectData.addTile(Type); + DustType = DustID.Glass; + AddMapEntry(new Color(211, 210, 201)); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = fail ? 0 : 1; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/PlantSpecimen_Branch.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/PlantSpecimen_Branch.png new file mode 100644 index 000000000..fa92b842b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/PlantSpecimen_Branch.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/PlantSpecimen_Fern.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/PlantSpecimen_Fern.cs new file mode 100644 index 000000000..e9c546fa2 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/PlantSpecimen_Fern.cs @@ -0,0 +1,35 @@ +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; + +public class PlantSpecimen_Fern : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLighted[Type] = true; + Main.tileLavaDeath[Type] = false; + Main.tileNoAttach[Type] = false; + Main.tileWaterDeath[Type] = false; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3Wall); + TileObjectData.newTile.Height = 3; + TileObjectData.newTile.Width = 3; + TileObjectData.newTile.CoordinateHeights = new int[3]; + Array.Fill(TileObjectData.newTile.CoordinateHeights, 16); + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + + TileObjectData.addTile(Type); + DustType = DustID.Glass; + AddMapEntry(new Color(211, 210, 201)); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = fail ? 0 : 1; + base.NumDust(i, j, fail, ref num); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/PlantSpecimen_Fern.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/PlantSpecimen_Fern.png new file mode 100644 index 000000000..8a4d1b6ac Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/PlantSpecimen_Fern.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon.cs new file mode 100644 index 000000000..efb810ced --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon.cs @@ -0,0 +1,145 @@ +using Everglow.Commons.Templates.Pylon; +using ReLogic.Content; +using Terraria.GameContent; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.Pylons; + +public class HolographicPylon : EverglowPylonBase +{ + public override void SetStaticDefaults() + { + AddMapEntry(new Color(17, 164, 255)); + base.SetStaticDefaults(); + } + + public override bool CanPlacePylon() => true; + + public override bool ValidTeleportCheck_NPCCount(TeleportPylonInfo pylonInfo, int defaultNecessaryNPCCount) => true; + + public override bool ValidTeleportCheck_AnyDanger(TeleportPylonInfo pylonInfo) => true; + + public override bool ValidTeleportCheck_BiomeRequirements(TeleportPylonInfo pylonInfo, SceneMetrics sceneData) => true; + + public override void ValidTeleportCheck_DestinationPostCheck(TeleportPylonInfo destinationPylonInfo, ref bool destinationPylonValid, ref string errorKey) => base.ValidTeleportCheck_DestinationPostCheck(destinationPylonInfo, ref destinationPylonValid, ref errorKey); + + public override void ValidTeleportCheck_NearbyPostCheck(TeleportPylonInfo nearbyPylonInfo, ref bool destinationPylonValid, ref bool anyNearbyValidPylon, ref string errorKey) => base.ValidTeleportCheck_NearbyPostCheck(nearbyPylonInfo, ref destinationPylonValid, ref anyNearbyValidPylon, ref errorKey); + + public override void ModifyTeleportationPosition(TeleportPylonInfo destinationPylonInfo, ref Vector2 teleportationPosition) => base.ModifyTeleportationPosition(destinationPylonInfo, ref teleportationPosition); + + public override void SpecialDraw(int i, int j, SpriteBatch spriteBatch) + { + DrawModPylon(spriteBatch, i, j, CrystalTexture, CrystalHighlightTexture, new Vector2(0, DefaultVerticalOffset), new Color(0f, 0.4f, 0.9f, 0f), new Color(0f, 0.4f, 0.9f, 0f), CrystalVerticalFrameCount, true, PylonSparkDustType); + Lighting.AddLight(i, j, 0f, 0.4f, 0.9f); + } + + public override void DrawModPylon(SpriteBatch spriteBatch, int i, int j, Asset CrystalTexture, Asset CrystalHighlightTexture, Vector2 crystalOffset, Color pylonShadowColor, Color dustColor, int crystalVerticalFrameCount, bool animation = true, int dustType = 43) + { + // Gets offscreen vector for different lighting modes + var offscreenVector = new Vector2(Main.offScreenRange); + if (Main.drawToScreen) + { + offscreenVector = Vector2.Zero; + } + + // Double check that the tile exists + var point = new Point(i, j); + Tile tile = Main.tile[point.X, point.Y]; + if (tile == null || !tile.HasTile) + { + return; + } + + var tileData = TileObjectData.GetTileData(tile); + + // Calculate frame based on vanilla counters in order to line up the animation + int frameY = animation ? Main.tileFrameCounter[TileID.TeleportationPylon] / crystalVerticalFrameCount : 0; + + // Frame our modded crystal sheet accordingly for proper drawing + Rectangle crystalFrame = CrystalTexture.Frame(1, crystalVerticalFrameCount, 0, frameY); + Rectangle smartCursorGlowFrame = CrystalHighlightTexture.Frame(1, crystalVerticalFrameCount, 0, frameY); + + // I have no idea what is happening here; but it fixes the frame bleed issue. All I know is that the vertical sinusoidal motion has something to with it. + // If anyone else has a clue as to why, please do tell. - MutantWafflez + crystalFrame.Height -= 1; + smartCursorGlowFrame.Height -= 1; + + // Calculate positional variables for actually drawing the crystal + Vector2 origin = crystalFrame.Size() / 2f; + var tileOrigin = new Vector2(tileData.CoordinateFullWidth / 2f, tileData.CoordinateFullHeight / 2f); + Vector2 crystalPosition = point.ToWorldCoordinates(tileOrigin.X - 2f, tileOrigin.Y) + crystalOffset; + + // Calculate additional drawing positions with a sine wave movement + float sinusoidalOffset = animation ? (float)Math.Sin(Main.GlobalTimeWrappedHourly * (Math.PI * 2) / 5) : 0; + Vector2 drawingPosition = crystalPosition + offscreenVector + new Vector2(0f, sinusoidalOffset * 4f); + + // Do dust drawing + Rectangle dustBox = Utils.CenteredRectangle(crystalPosition, crystalFrame.Size()); + GenerateDust(dustBox, dustType, dustColor, 0.1f); + + // Get color value and draw the the crystal + Color color = Lighting.GetColor(point.X, point.Y); + color = Color.Lerp(color, Color.White, 0.8f); + spriteBatch.Draw(CrystalTexture.Value, drawingPosition - Main.screenPosition, crystalFrame, color * 0.7f, 0f, origin, 1f, SpriteEffects.None, 0f); + + Texture2D glow = ModAsset.HolographicPylon_Crystal_glow.Value; + spriteBatch.Draw(glow, drawingPosition - Main.screenPosition, crystalFrame, new Color(1f, 1f, 1f, 0), 0f, origin, 1f, SpriteEffects.None, 0f); + + // Draw the shadow effect for the crystal + float scale = animation ? (float)Math.Sin(Main.GlobalTimeWrappedHourly * ((float)Math.PI * 2f) / 1f) * 0.2f + 0.8f : 0.8f; + Color shadowColor = pylonShadowColor * scale; + for (float shadowPos = 0f; shadowPos < 1f; shadowPos += 1f / 6f) + { + spriteBatch.Draw(CrystalTexture.Value, drawingPosition - Main.screenPosition + ((float)Math.PI * 2f * shadowPos).ToRotationVector2() * (6f + sinusoidalOffset * 2f), crystalFrame, shadowColor, 0f, origin, 1f, SpriteEffects.None, 0f); + } + + // Interpret smart cursor outline color & draw it + int selectionLevel = 0; + if (Main.InSmartCursorHighlightArea(point.X, point.Y, out bool actuallySelected)) + { + selectionLevel = 1; + if (actuallySelected) + { + selectionLevel = 2; + } + } + + if (selectionLevel == 0) + { + return; + } + + int averageBrightness = (color.R + color.G + color.B) / 3; + + if (averageBrightness <= 10) + { + return; + } + + Color selectionGlowColor = Colors.GetSelectionGlowColor(selectionLevel == 2, averageBrightness); + spriteBatch.Draw(CrystalHighlightTexture.Value, drawingPosition - Main.screenPosition, smartCursorGlowFrame, selectionGlowColor, 0f, origin, 1f, SpriteEffects.None, 0f); + } + + public override void GenerateDust(Rectangle dustBox, int dustType, Color dustColor, float chance) + { + if (!Main.gamePaused && Main.instance.IsActive && (!Lighting.UpdateEveryFrame || Main.rand.NextBool(4)) && Main.rand.NextFloat() < chance) + { + int numForDust = Dust.NewDust(dustBox.TopLeft(), dustBox.Width, dustBox.Height, dustType, 0f, 0f, 254, dustColor, 0.5f); + Dust obj = Main.dust[numForDust]; + obj.velocity *= 0.1f; + Main.dust[numForDust].velocity.Y -= 0.2f; + } + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + var tile = Main.tile[i, j]; + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + Texture2D tex = ModAsset.HolographicPylon_glow.Value; + spriteBatch.Draw(tex, new Vector2(i * 16, j * 16) - Main.screenPosition + zero, new Rectangle(tile.TileFrameX, tile.TileFrameY, 16, 16), new Color(1f, 1f, 1f, 0), 0, new Vector2(0), 1, SpriteEffects.None, 0); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon.png new file mode 100644 index 000000000..86a974339 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylonTileEntity.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylonTileEntity.cs new file mode 100644 index 000000000..28c56a438 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylonTileEntity.cs @@ -0,0 +1,7 @@ +using Terraria.ModLoader.Default; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.Pylons; + +public class HolographicPylonTileEntity : TEModdedPylon +{ +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon_Crystal.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon_Crystal.png new file mode 100644 index 000000000..c5158ff26 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon_Crystal.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon_Crystal_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon_Crystal_glow.png new file mode 100644 index 000000000..328d1808d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon_Crystal_glow.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon_MapIcon.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon_MapIcon.png new file mode 100644 index 000000000..61880fff4 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon_MapIcon.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon_glow.png new file mode 100644 index 000000000..9c4d77f44 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/HolographicPylon_glow.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon.cs new file mode 100644 index 000000000..86c399214 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon.cs @@ -0,0 +1,135 @@ +using Everglow.Commons.Templates.Pylon; +using ReLogic.Content; +using Terraria.GameContent; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.Pylons; + +public class TownGatePylon : EverglowPylonBase +{ + public override void SetStaticDefaults() + { + AddMapEntry(new Color(60, 61, 118)); + MinPick = int.MaxValue; + base.SetStaticDefaults(); + } + + public override bool CanPlacePylon() => true; + + public override bool ValidTeleportCheck_NPCCount(TeleportPylonInfo pylonInfo, int defaultNecessaryNPCCount) => true; + + public override bool ValidTeleportCheck_AnyDanger(TeleportPylonInfo pylonInfo) => true; + + public override bool ValidTeleportCheck_BiomeRequirements(TeleportPylonInfo pylonInfo, SceneMetrics sceneData) => true; + + public override void ValidTeleportCheck_DestinationPostCheck(TeleportPylonInfo destinationPylonInfo, ref bool destinationPylonValid, ref string errorKey) => base.ValidTeleportCheck_DestinationPostCheck(destinationPylonInfo, ref destinationPylonValid, ref errorKey); + + public override void ValidTeleportCheck_NearbyPostCheck(TeleportPylonInfo nearbyPylonInfo, ref bool destinationPylonValid, ref bool anyNearbyValidPylon, ref string errorKey) => base.ValidTeleportCheck_NearbyPostCheck(nearbyPylonInfo, ref destinationPylonValid, ref anyNearbyValidPylon, ref errorKey); + + public override void ModifyTeleportationPosition(TeleportPylonInfo destinationPylonInfo, ref Vector2 teleportationPosition) => base.ModifyTeleportationPosition(destinationPylonInfo, ref teleportationPosition); + + public override void SpecialDraw(int i, int j, SpriteBatch spriteBatch) + { + DrawModPylon(spriteBatch, i, j, CrystalTexture, CrystalHighlightTexture, new Vector2(0, DefaultVerticalOffset), Color.White * 0.1f, new Color(0.1f, 0.1f, 0.2f, 0.5f), CrystalVerticalFrameCount, true, PylonSparkDustType); + Lighting.AddLight(i, j, 0.6f, 0.3f, 0.4f); + } + + public override void DrawModPylon(SpriteBatch spriteBatch, int i, int j, Asset CrystalTexture, Asset CrystalHighlightTexture, Vector2 crystalOffset, Color pylonShadowColor, Color dustColor, int crystalVerticalFrameCount, bool animation = true, int dustType = 43) + { + // Gets offscreen vector for different lighting modes + var offscreenVector = new Vector2(Main.offScreenRange); + if (Main.drawToScreen) + { + offscreenVector = Vector2.Zero; + } + + // Double check that the tile exists + var point = new Point(i, j); + Tile tile = Main.tile[point.X, point.Y]; + if (tile == null || !tile.HasTile) + { + return; + } + + var tileData = TileObjectData.GetTileData(tile); + + // Calculate frame based on vanilla counters in order to line up the animation + int frameY = animation ? Main.tileFrameCounter[TileID.TeleportationPylon] / crystalVerticalFrameCount : 0; + + // Frame our modded crystal sheet accordingly for proper drawing + Rectangle crystalFrame = CrystalTexture.Frame(1, crystalVerticalFrameCount, 0, frameY); + Rectangle smartCursorGlowFrame = CrystalHighlightTexture.Frame(1, crystalVerticalFrameCount, 0, frameY); + + // I have no idea what is happening here; but it fixes the frame bleed issue. All I know is that the vertical sinusoidal motion has something to with it. + // If anyone else has a clue as to why, please do tell. - MutantWafflez + crystalFrame.Height -= 1; + smartCursorGlowFrame.Height -= 1; + + // Calculate positional variables for actually drawing the crystal + Vector2 origin = crystalFrame.Size() / 2f; + var tileOrigin = new Vector2(tileData.CoordinateFullWidth / 2f, tileData.CoordinateFullHeight / 2f); + Vector2 crystalPosition = point.ToWorldCoordinates(tileOrigin.X - 2f, tileOrigin.Y) + crystalOffset; + + // Calculate additional drawing positions with a sine wave movement + float sinusoidalOffset = animation ? (float)Math.Sin(Main.GlobalTimeWrappedHourly * (Math.PI * 2) / 5) : 0; + Vector2 drawingPosition = crystalPosition + offscreenVector + new Vector2(0f, sinusoidalOffset * 4f); + + // Do dust drawing + Rectangle dustBox = Utils.CenteredRectangle(crystalPosition, crystalFrame.Size()); + GenerateDust(dustBox, dustType, dustColor, 0.1f); + + // Get color value and draw the the crystal + Color color = Lighting.GetColor(point.X, point.Y); + color = Color.Lerp(color, Color.White, 0.2f); + spriteBatch.Draw(CrystalTexture.Value, drawingPosition - Main.screenPosition, crystalFrame, color * 0.7f, 0f, origin, 1f, SpriteEffects.None, 0f); + + Texture2D glow = ModAsset.TownGatePylon_Crystal_glow.Value; + spriteBatch.Draw(glow, drawingPosition - Main.screenPosition, crystalFrame, new Color(1f, 1f, 1f, 0), 0f, origin, 1f, SpriteEffects.None, 0f); + + // Draw the shadow effect for the crystal + float scale = animation ? (float)Math.Sin(Main.GlobalTimeWrappedHourly * ((float)Math.PI * 2f) / 1f) * 0.2f + 0.8f : 0.8f; + Color shadowColor = pylonShadowColor * scale; + for (float shadowPos = 0f; shadowPos < 1f; shadowPos += 1f / 6f) + { + spriteBatch.Draw(CrystalTexture.Value, drawingPosition - Main.screenPosition + ((float)Math.PI * 2f * shadowPos).ToRotationVector2() * (6f + sinusoidalOffset * 2f), crystalFrame, shadowColor, 0f, origin, 1f, SpriteEffects.None, 0f); + } + + // Interpret smart cursor outline color & draw it + int selectionLevel = 0; + if (Main.InSmartCursorHighlightArea(point.X, point.Y, out bool actuallySelected)) + { + selectionLevel = 1; + if (actuallySelected) + { + selectionLevel = 2; + } + } + + if (selectionLevel == 0) + { + return; + } + + int averageBrightness = (color.R + color.G + color.B) / 3; + + if (averageBrightness <= 10) + { + return; + } + + Color selectionGlowColor = Colors.GetSelectionGlowColor(selectionLevel == 2, averageBrightness); + spriteBatch.Draw(CrystalHighlightTexture.Value, drawingPosition - Main.screenPosition, smartCursorGlowFrame, selectionGlowColor, 0f, origin, 1f, SpriteEffects.None, 0f); + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + var tile = Main.tile[i, j]; + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + Texture2D tex = ModAsset.HolographicPylon_glow.Value; + spriteBatch.Draw(tex, new Vector2(i * 16, j * 16) - Main.screenPosition + zero, new Rectangle(tile.TileFrameX, tile.TileFrameY, 16, 16), new Color(1f, 1f, 1f, 0), 0, new Vector2(0), 1, SpriteEffects.None, 0); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon.png new file mode 100644 index 000000000..45468ec67 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylonTileEntity.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylonTileEntity.cs new file mode 100644 index 000000000..04048336e --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylonTileEntity.cs @@ -0,0 +1,7 @@ +using Terraria.ModLoader.Default; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.Pylons; + +public class TownGatePylonTileEntity : TEModdedPylon +{ +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon_Crystal.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon_Crystal.png new file mode 100644 index 000000000..dcfb28f1a Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon_Crystal.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon_Crystal_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon_Crystal_glow.png new file mode 100644 index 000000000..af4b51b11 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon_Crystal_glow.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon_MapIcon.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon_MapIcon.png new file mode 100644 index 000000000..9c370c26f Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon_MapIcon.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon_glow.png new file mode 100644 index 000000000..50baab03a Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/TownGatePylon_glow.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon.cs new file mode 100644 index 000000000..453048bc0 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon.cs @@ -0,0 +1,229 @@ +using Everglow.Commons.Templates.Pylon; +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.YggdrasilTown.VFXs; +using ReLogic.Content; +using Terraria.DataStructures; +using Terraria.GameContent; +using Terraria.Map; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.Pylons; + +public class UnregisteredPylon : EverglowPylonBase +{ + public override void SetStaticDefaults() + { + AddMapEntry(new Color(175, 0, 0)); + base.SetStaticDefaults(); + } + + public override bool CanPlacePylon() => true; + + public override bool ValidTeleportCheck_NPCCount(TeleportPylonInfo pylonInfo, int defaultNecessaryNPCCount) => true; + + public override bool ValidTeleportCheck_AnyDanger(TeleportPylonInfo pylonInfo) => true; + + public override bool ValidTeleportCheck_BiomeRequirements(TeleportPylonInfo pylonInfo, SceneMetrics sceneData) => true; + + public override void ValidTeleportCheck_DestinationPostCheck(TeleportPylonInfo destinationPylonInfo, ref bool destinationPylonValid, ref string errorKey) => base.ValidTeleportCheck_DestinationPostCheck(destinationPylonInfo, ref destinationPylonValid, ref errorKey); + + public override void ValidTeleportCheck_NearbyPostCheck(TeleportPylonInfo nearbyPylonInfo, ref bool destinationPylonValid, ref bool anyNearbyValidPylon, ref string errorKey) => base.ValidTeleportCheck_NearbyPostCheck(nearbyPylonInfo, ref destinationPylonValid, ref anyNearbyValidPylon, ref errorKey); + + public override void ModifyTeleportationPosition(TeleportPylonInfo destinationPylonInfo, ref Vector2 teleportationPosition) => base.ModifyTeleportationPosition(destinationPylonInfo, ref teleportationPosition); + + public override void SpecialDraw(int i, int j, SpriteBatch spriteBatch) + { + DrawModPylon(spriteBatch, i, j, CrystalTexture, CrystalHighlightTexture, new Vector2(0, DefaultVerticalOffset), new Color(0.2f, 0.0f, 0.0f, 0), new Color(0.9f, 0f, 0f, 0f), CrystalVerticalFrameCount, true, PylonSparkDustType); + Lighting.AddLight(i, j, 1f, 0f, 0f); + } + + public override void DrawMapIcon(ref MapOverlayDrawContext context, ref string mouseOverText, TeleportPylonInfo pylonInfo, bool isNearPylon, Color drawColor, float deselectedScale, float selectedScale) + { + } + + public override void DrawModPylon(SpriteBatch spriteBatch, int i, int j, Asset CrystalTexture, Asset CrystalHighlightTexture, Vector2 crystalOffset, Color pylonShadowColor, Color dustColor, int crystalVerticalFrameCount, bool animation = true, int dustType = 43) + { + // Gets offscreen vector for different lighting modes + var offscreenVector = new Vector2(Main.offScreenRange); + if (Main.drawToScreen) + { + offscreenVector = Vector2.Zero; + } + + // Double check that the tile exists + var point = new Point(i, j); + Tile tile = Main.tile[point.X, point.Y]; + if (tile == null || !tile.HasTile) + { + return; + } + + var tileData = TileObjectData.GetTileData(tile); + + // Calculate frame based on vanilla counters in order to line up the animation + int frameY = animation ? Main.tileFrameCounter[TileID.TeleportationPylon] / crystalVerticalFrameCount : 0; + + // Frame our modded crystal sheet accordingly for proper drawing + Rectangle crystalFrame = CrystalTexture.Frame(1, crystalVerticalFrameCount, 0, frameY); + Rectangle smartCursorGlowFrame = CrystalHighlightTexture.Frame(1, crystalVerticalFrameCount, 0, frameY); + + // I have no idea what is happening here; but it fixes the frame bleed issue. All I know is that the vertical sinusoidal motion has something to with it. + // If anyone else has a clue as to why, please do tell. - MutantWafflez + crystalFrame.Height -= 1; + smartCursorGlowFrame.Height -= 1; + + // Calculate positional variables for actually drawing the crystal + Vector2 origin = crystalFrame.Size() / 2f; + var tileOrigin = new Vector2(tileData.CoordinateFullWidth / 2f, tileData.CoordinateFullHeight / 2f); + Vector2 crystalPosition = point.ToWorldCoordinates(tileOrigin.X - 2f, tileOrigin.Y) + crystalOffset; + + // Calculate additional drawing positions with a sine wave movement + float sinusoidalOffset = animation ? (float)Math.Sin(Main.GlobalTimeWrappedHourly * (Math.PI * 2) / 5) : 0; + Vector2 drawingPosition = crystalPosition + offscreenVector + new Vector2(0f, sinusoidalOffset * 4f); + + // Do dust drawing + Rectangle dustBox = Utils.CenteredRectangle(crystalPosition, crystalFrame.Size()); + GenerateDust(dustBox, dustType, dustColor, 0.1f); + + // Get color value and draw the the crystal + Color color = Lighting.GetColor(point.X, point.Y); + color = Color.Lerp(color, Color.White, 0.8f); + spriteBatch.Draw(CrystalTexture.Value, drawingPosition - Main.screenPosition, crystalFrame, color * 0.7f, 0f, origin, 1f, SpriteEffects.None, 0f); + + Texture2D glow = ModAsset.UnregisteredPylon_Crystal_glow.Value; + spriteBatch.Draw(glow, drawingPosition - Main.screenPosition, crystalFrame, new Color(1f, 1f, 1f, 0), 0f, origin, 1f, SpriteEffects.None, 0f); + + // Draw the shadow effect for the crystal + float scale = animation ? (float)Math.Sin(Main.GlobalTimeWrappedHourly * ((float)Math.PI * 2f) / 1f) * 0.2f + 0.8f : 0.8f; + Color shadowColor = pylonShadowColor * scale; + for (float shadowPos = 0f; shadowPos < 1f; shadowPos += 1f / 6f) + { + spriteBatch.Draw(CrystalTexture.Value, drawingPosition - Main.screenPosition + ((float)Math.PI * 2f * shadowPos).ToRotationVector2() * (6f + sinusoidalOffset * 2f), crystalFrame, shadowColor, 0f, origin, 1f, SpriteEffects.None, 0f); + } + + // Interpret smart cursor outline color & draw it + int selectionLevel = 0; + if (Main.InSmartCursorHighlightArea(point.X, point.Y, out bool actuallySelected)) + { + selectionLevel = 1; + if (actuallySelected) + { + selectionLevel = 2; + } + } + + if (selectionLevel == 0) + { + return; + } + + int averageBrightness = (color.R + color.G + color.B) / 3; + + if (averageBrightness <= 10) + { + return; + } + + Color selectionGlowColor = Colors.GetSelectionGlowColor(selectionLevel == 2, averageBrightness); + spriteBatch.Draw(CrystalHighlightTexture.Value, drawingPosition - Main.screenPosition, smartCursorGlowFrame, selectionGlowColor, 0f, origin, 1f, SpriteEffects.None, 0f); + } + + public override void GenerateDust(Rectangle dustBox, int dustType, Color dustColor, float chance) + { + if (!Main.gamePaused && Main.instance.IsActive && (!Lighting.UpdateEveryFrame || Main.rand.NextBool(4)) && Main.rand.NextFloat() < chance) + { + int numForDust = Dust.NewDust(dustBox.TopLeft(), dustBox.Width, dustBox.Height, dustType, 0f, 0f, 254, dustColor, 0.5f); + Dust obj = Main.dust[numForDust]; + obj.velocity *= 0.1f; + Main.dust[numForDust].velocity.Y -= 0.2f; + } + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + var tile = Main.tile[i, j]; + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + Texture2D tex = ModAsset.UnregisteredPylon_glow.Value; + spriteBatch.Draw(tex, new Vector2(i * 16, j * 16) - Main.screenPosition + zero, new Rectangle(tile.TileFrameX, tile.TileFrameY, 16, 16), new Color(1f, 1f, 1f, 0), 0, new Vector2(0), 1, SpriteEffects.None, 0); + } + + public override bool RightClick(int i, int j) + { + var tile = Main.tile[i, j]; + var topLeftTile = new Point(i - tile.TileFrameX / 18, j - tile.TileFrameY / 18); + for (int x = 0; x < 3; x++) + { + for (int y = 0; y < 4; y++) + { + var checkPoint = new Point(topLeftTile.X + x, topLeftTile.Y + y); + var checkTile = WorldGenMisc.SafeGetTile(checkPoint); + if (checkTile.TileType == Type) + { + checkTile.TileType = (ushort)ModContent.TileType(); + checkTile.TileFrameX = (short)(x * 18); + checkTile.TileFrameY = (short)(y * 18); + } + if (x == 0 && y == 0) + { + TileEntity tileEntityOld; + TileEntity.ByPosition.TryGetValue(new Point16(checkPoint.X, checkPoint.Y), out tileEntityOld); + if (tileEntityOld is not null) + { + ModContent.GetInstance().Kill(checkPoint.X, checkPoint.Y); + TileEntity.PlaceEntityNet(checkPoint.X, checkPoint.Y, ModContent.TileEntityType()); + } + } + if (x == 1 && y == 3) + { + UnlockVFX(checkPoint.X, checkPoint.Y); + } + } + } + return false; + } + + public void UnlockVFX(int x, int y) + { + Vector2 worldPos = new Point(x, y).ToWorldCoordinates(); + for (int i = 0; i < 6 + 10; i++) + { + var vel = new Vector2(0, -Main.rand.NextFloat(3.6f, 6.4f)); + Vector2 pos = new Vector2(0, Main.rand.NextFloat(0f, 22.4f)).RotatedByRandom(MathHelper.TwoPi); + pos.Y *= 0.1f; + var dust = new AvariceSuccessDust + { + velocity = vel, + Active = true, + Visible = true, + position = worldPos + pos, + maxTime = Main.rand.Next(60, 120), + scale = Main.rand.NextFloat(1f, 2f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(4.0f, 10.93f) }, + }; + Ins.VFXManager.Add(dust); + } + for (int i = 0; i < 12; i++) + { + var vel = new Vector2(0, -Main.rand.NextFloat(1.6f, 6.4f)); + Vector2 pos = new Vector2(0, Main.rand.NextFloat(0f, 50.4f)).RotatedByRandom(MathHelper.TwoPi); + pos.Y *= 0.1f; + var cube = new AvariceSuccessCube + { + velocity = vel, + Active = true, + Visible = true, + position = worldPos + pos, + maxTime = Main.rand.Next(60, 120), + scale = Main.rand.NextFloat(10f, 20f), + rotation = Main.rand.NextFloat(6.283f), + ai = new float[] { Main.rand.NextFloat(4.0f, 20.93f), 0.06f }, + }; + Ins.VFXManager.Add(cube); + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon.png new file mode 100644 index 000000000..03aa4c832 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylonTileEntity.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylonTileEntity.cs new file mode 100644 index 000000000..e79149fbd --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylonTileEntity.cs @@ -0,0 +1,7 @@ +using Terraria.ModLoader.Default; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.Pylons; + +public class UnregisteredPylonTileEntity : TEModdedPylon +{ +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon_Crystal.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon_Crystal.png new file mode 100644 index 000000000..5bb537d25 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon_Crystal.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon_Crystal_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon_Crystal_glow.png new file mode 100644 index 000000000..8cd717333 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon_Crystal_glow.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon_MapIcon.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon_MapIcon.png new file mode 100644 index 000000000..9d358937e Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon_MapIcon.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon_glow.png new file mode 100644 index 000000000..f576f08bc Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Pylons/UnregisteredPylon_glow.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArena.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArena.cs index f3dc01dfc..68cdf53c7 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArena.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArena.cs @@ -81,7 +81,7 @@ public void AddScene(int i, int j) Tile tile = TileUtils.SafeGetTile(i, j); if (tile.TileFrameX == 0 && tile.TileFrameY == 0) { - RoadSignPost_ToArenaVFX rSV = new RoadSignPost_ToArenaVFX { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + RoadSignPost_ToArenaVFX rSV = new RoadSignPost_ToArenaVFX { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(rSV); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArena.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArena.png index a06120376..e30dcb40e 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArena.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArena.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArenaVFX.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArenaVFX.cs index b5a7df691..e26e50cdd 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArenaVFX.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArenaVFX.cs @@ -1,14 +1,14 @@ using Everglow.Commons.VFX.Scene; using Everglow.SubSpace; using Everglow.SubSpace.Tiles; -using Everglow.Yggdrasil.WorldGeneration; using Everglow.Yggdrasil.YggdrasilTown.Tiles.LampWood.Furniture; using Everglow.Yggdrasil.YggdrasilTown.Walls; +using static Everglow.Commons.Utilities.TileUtils; namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; [Pipeline(typeof(WCSPipeline_PointWrap))] -public class RoadSignPost_ToArenaVFX : BackgroundVFX +public class RoadSignPost_ToArenaVFX : TileVFX { public override CodeLayer DrawLayer => CodeLayer.PostDrawTiles; @@ -17,9 +17,9 @@ public override void Update() base.Update(); float startX = 20; float startY = 4; - if (Main.MouseWorld.X > position.X + startX && Main.MouseWorld.X < position.X + startX + 56) + if (Main.MouseWorld.X > Position.X + startX && Main.MouseWorld.X < Position.X + startX + 56) { - if (Main.MouseWorld.Y > position.Y + startY && Main.MouseWorld.Y < position.Y + startY + 16) + if (Main.MouseWorld.Y > Position.Y + startY && Main.MouseWorld.Y < Position.Y + startY + 16) { Main.instance.MouseText("Rightclick to Enter Arena."); if (Main.mouseRight && Main.mouseRightRelease && !Main.mapFullscreen) @@ -58,7 +58,7 @@ public static void BuildArenaGen() { Tile tile = TileUtils.SafeGetTile(x, y); tile.HasTile = false; - tile.wall = 0; + tile.WallType = 0; } for (int y = 200; y < Main.maxTilesY - 20; y++) { @@ -95,7 +95,7 @@ public static void BuildArenaGen() for (int y = 20; y < 23; y++) { Tile tile = TileUtils.SafeGetTile(x, y); - tile.wall = 1; + tile.WallType = 1; ushort typeChange = (ushort)ModContent.TileType(); if (y == 22) { @@ -126,50 +126,50 @@ public static void BuildArenaGen() { NPC.NewNPCDirect(WorldGen.GetNPCSource_TileBreak(180, 190), new Point(180, 190).ToWorldCoordinates(), msg.Y); } - YggdrasilWorldGeneration.SmoothTile(20, 20, Main.maxTilesX - 20, Main.maxTilesY - 20); + SmoothTile_XXYY(20, 20, Main.maxTilesX - 20, Main.maxTilesY - 20); TileUtils.PlaceFrameImportantTiles(70, 198, 2, 2, ModContent.TileType()); WorldGen.PlaceChest(72, 199, 21, false, 33); } public override void OnSpawn() { - texture = ModAsset.RoadSignPost_ToArenaVFX.Value; + Texture = ModAsset.RoadSignPost_ToArenaVFX.Value; } public override void Draw() { - Color lightColor0 = Lighting.GetColor((int)position.X / 16, (int)position.Y / 16); - Color lightColor1 = Lighting.GetColor((int)(position.X + texture.Width) / 16, (int)position.Y / 16); - Color lightColor2 = Lighting.GetColor((int)position.X / 16, (int)(position.Y + texture.Height) / 16); - Color lightColor3 = Lighting.GetColor((int)(position.X + texture.Width) / 16, (int)(position.Y + texture.Height) / 16); + Color lightColor0 = Lighting.GetColor((int)Position.X / 16, (int)Position.Y / 16); + Color lightColor1 = Lighting.GetColor((int)(Position.X + Texture.Width) / 16, (int)Position.Y / 16); + Color lightColor2 = Lighting.GetColor((int)Position.X / 16, (int)(Position.Y + Texture.Height) / 16); + Color lightColor3 = Lighting.GetColor((int)(Position.X + Texture.Width) / 16, (int)(Position.Y + Texture.Height) / 16); - var drawPos = position + new Vector2(7); + var drawPos = Position + new Vector2(7); List bars = new List() { - new Vertex2D(drawPos + new Vector2(-texture.Width / 2f, 0), lightColor0, new Vector3(0, 0, 0)), - new Vertex2D(drawPos + new Vector2(texture.Width / 2f, 0), lightColor1, new Vector3(1, 0, 0)), + new Vertex2D(drawPos + new Vector2(-Texture.Width / 2f, 0), lightColor0, new Vector3(0, 0, 0)), + new Vertex2D(drawPos + new Vector2(Texture.Width / 2f, 0), lightColor1, new Vector3(1, 0, 0)), - new Vertex2D(drawPos + new Vector2(-texture.Width / 2f, texture.Height / 2f), lightColor2, new Vector3(0, 0.5f, 0)), - new Vertex2D(drawPos + new Vector2(texture.Width / 2f, texture.Height / 2f), lightColor3, new Vector3(1, 0.5f, 0)), + new Vertex2D(drawPos + new Vector2(-Texture.Width / 2f, Texture.Height / 2f), lightColor2, new Vector3(0, 0.5f, 0)), + new Vertex2D(drawPos + new Vector2(Texture.Width / 2f, Texture.Height / 2f), lightColor3, new Vector3(1, 0.5f, 0)), }; - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleStrip); float startX = 20; float startY = 4; - if (Main.MouseWorld.X > position.X + startX && Main.MouseWorld.X < position.X + startX + 56) + if (Main.MouseWorld.X > Position.X + startX && Main.MouseWorld.X < Position.X + startX + 56) { - if (Main.MouseWorld.Y > position.Y + startY && Main.MouseWorld.Y < position.Y + startY + 16) + if (Main.MouseWorld.Y > Position.Y + startY && Main.MouseWorld.Y < Position.Y + startY + 16) { var emphasizeColor = Color.White; bars = new List() { new Vertex2D(drawPos + new Vector2(0, 0), emphasizeColor, new Vector3(0.5f, 0.5f, 0)), - new Vertex2D(drawPos + new Vector2(texture.Width / 2f, 0), emphasizeColor, new Vector3(1, 0.5f, 0)), + new Vertex2D(drawPos + new Vector2(Texture.Width / 2f, 0), emphasizeColor, new Vector3(1, 0.5f, 0)), - new Vertex2D(drawPos + new Vector2(0, texture.Height / 2f), emphasizeColor, new Vector3(0.5f, 1, 0)), - new Vertex2D(drawPos + new Vector2(texture.Width / 2f, texture.Height / 2f), emphasizeColor, new Vector3(1, 1, 0)), + new Vertex2D(drawPos + new Vector2(0, Texture.Height / 2f), emphasizeColor, new Vector3(0.5f, 1, 0)), + new Vertex2D(drawPos + new Vector2(Texture.Width / 2f, Texture.Height / 2f), emphasizeColor, new Vector3(1, 1, 0)), }; - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleStrip); } } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArenaVFX.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArenaVFX.png index 1babc33a5..5b68cfb81 100644 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArenaVFX.png and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/RoadSignPost_ToArenaVFX.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridgeTile.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridgeTile.cs index 624a5753c..6296d07b7 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridgeTile.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridgeTile.cs @@ -48,36 +48,36 @@ public void AddScene(int i, int j) Tile tile = TileUtils.SafeGetTile(i, j); if (tile.TileFrameX == 0 && tile.TileFrameY == 0) { - StoneBridge_fence sBF = new StoneBridge_fence { position = new Vector2(i, j - 3) * 16 - new Vector2(0, 14), Active = true, Visible = true, originTile = new Point(i, j), originType = ModContent.TileType() }; + StoneBridge_fence sBF = new StoneBridge_fence { Position = new Vector2(i, j - 3) * 16 - new Vector2(0, 14), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = ModContent.TileType() }; Ins.VFXManager.Add(sBF); - StoneBridge_foreground sBF2 = new StoneBridge_foreground { position = new Vector2(i, j - 3) * 16 - new Vector2(0, 4), Active = true, Visible = true, originTile = new Point(i, j), originType = ModContent.TileType() }; + StoneBridge_foreground sBF2 = new StoneBridge_foreground { Position = new Vector2(i, j - 3) * 16 - new Vector2(0, 4), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = ModContent.TileType() }; Ins.VFXManager.Add(sBF2); - StoneBridge_Pier_foreground sBF3 = new StoneBridge_Pier_foreground { position = new Vector2(i, j - 3) * 16 + new Vector2(-120, 316), Active = true, Visible = true, originTile = new Point(i, j), originType = ModContent.TileType() }; + StoneBridge_Pier_foreground sBF3 = new StoneBridge_Pier_foreground { Position = new Vector2(i, j - 3) * 16 + new Vector2(-120, 316), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = ModContent.TileType() }; Ins.VFXManager.Add(sBF3); - StoneBridge_Pier2_foreground sBF4 = new StoneBridge_Pier2_foreground { position = new Vector2(i, j - 3) * 16 + new Vector2(-4, 630), Active = true, Visible = true, originTile = new Point(i, j), originType = ModContent.TileType() }; + StoneBridge_Pier2_foreground sBF4 = new StoneBridge_Pier2_foreground { Position = new Vector2(i, j - 3) * 16 + new Vector2(-4, 630), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = ModContent.TileType() }; Ins.VFXManager.Add(sBF4); } if (tile.TileFrameX == 0 && tile.TileFrameY == 18) { - StoneBridge_Leftside_foreground sBF2 = new StoneBridge_Leftside_foreground { position = new Vector2(i, j - 3) * 16 + new Vector2(-272, -4), Active = true, Visible = true, originTile = new Point(i, j), originType = ModContent.TileType() }; + StoneBridge_Leftside_foreground sBF2 = new StoneBridge_Leftside_foreground { Position = new Vector2(i, j - 3) * 16 + new Vector2(-272, -4), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = ModContent.TileType() }; Ins.VFXManager.Add(sBF2); } if (tile.TileFrameX == 0 && tile.TileFrameY == 54) { - StoneBridge_Rightside_foreground sBF2 = new StoneBridge_Rightside_foreground { position = new Vector2(i, j - 3) * 16 + new Vector2(0, -4), Active = true, Visible = true, originTile = new Point(i, j), originType = ModContent.TileType() }; + StoneBridge_Rightside_foreground sBF2 = new StoneBridge_Rightside_foreground { Position = new Vector2(i, j - 3) * 16 + new Vector2(0, -4), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = ModContent.TileType() }; Ins.VFXManager.Add(sBF2); - StoneBridge_Pier_foreground sBF3 = new StoneBridge_Pier_foreground { position = new Vector2(i, j - 3) * 16 + new Vector2(-120, 316), Active = true, Visible = true, originTile = new Point(i, j), originType = ModContent.TileType() }; + StoneBridge_Pier_foreground sBF3 = new StoneBridge_Pier_foreground { Position = new Vector2(i, j - 3) * 16 + new Vector2(-120, 316), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = ModContent.TileType() }; Ins.VFXManager.Add(sBF3); - StoneBridge_Pier2_foreground sBF4 = new StoneBridge_Pier2_foreground { position = new Vector2(i, j - 3) * 16 + new Vector2(-4, 630), Active = true, Visible = true, originTile = new Point(i, j), originType = ModContent.TileType() }; + StoneBridge_Pier2_foreground sBF4 = new StoneBridge_Pier2_foreground { Position = new Vector2(i, j - 3) * 16 + new Vector2(-4, 630), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = ModContent.TileType() }; Ins.VFXManager.Add(sBF4); } if (tile.TileFrameX == 0 && tile.TileFrameY == 72) { - StoneBridge_Middleside_foreground sBF2 = new StoneBridge_Middleside_foreground { position = new Vector2(i, j - 3) * 16 + new Vector2(0, -116), Active = true, Visible = true, originTile = new Point(i, j), originType = ModContent.TileType() }; + StoneBridge_Middleside_foreground sBF2 = new StoneBridge_Middleside_foreground { Position = new Vector2(i, j - 3) * 16 + new Vector2(0, -116), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = ModContent.TileType() }; Ins.VFXManager.Add(sBF2); - StoneBridge_Pier_foreground sBF3 = new StoneBridge_Pier_foreground { position = new Vector2(i + 7, j - 10) * 16 + new Vector2(-112, 316), Active = true, Visible = true, originTile = new Point(i, j), originType = ModContent.TileType() }; + StoneBridge_Pier_foreground sBF3 = new StoneBridge_Pier_foreground { Position = new Vector2(i + 7, j - 10) * 16 + new Vector2(-112, 316), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = ModContent.TileType() }; Ins.VFXManager.Add(sBF3); - StoneBridge_Pier2_foreground sBF4 = new StoneBridge_Pier2_foreground { position = new Vector2(i + 7, j - 10) * 16 + new Vector2(4, 630), Active = true, Visible = true, originTile = new Point(i, j), originType = ModContent.TileType() }; + StoneBridge_Pier2_foreground sBF4 = new StoneBridge_Pier2_foreground { Position = new Vector2(i + 7, j - 10) * 16 + new Vector2(4, 630), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = ModContent.TileType() }; Ins.VFXManager.Add(sBF4); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Leftside_foreground.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Leftside_foreground.cs index 72fa183fc..5121f5b72 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Leftside_foreground.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Leftside_foreground.cs @@ -4,8 +4,9 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; [Pipeline(typeof(WCSPipeline))] -public class StoneBridge_Leftside_foreground : ForegroundVFX +public class StoneBridge_Leftside_foreground : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; public override void Update() { if (!SubworldSystem.IsActive()) @@ -17,6 +18,6 @@ public override void Update() public override void OnSpawn() { - texture = ModAsset.StoneBridge_Leftside.Value; + Texture = ModAsset.StoneBridge_Leftside.Value; } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Middleside_foreground.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Middleside_foreground.cs index 78bc84242..97daf5620 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Middleside_foreground.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Middleside_foreground.cs @@ -4,8 +4,9 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; [Pipeline(typeof(WCSPipeline))] -public class StoneBridge_Middleside_foreground : ForegroundVFX +public class StoneBridge_Middleside_foreground : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; public override void Update() { if (!SubworldSystem.IsActive()) @@ -17,6 +18,6 @@ public override void Update() public override void OnSpawn() { - texture = ModAsset.StoneBridge_Middleside.Value; + Texture = ModAsset.StoneBridge_Middleside.Value; } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Pier2_foreground.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Pier2_foreground.cs index 7575645a3..b7fc957ed 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Pier2_foreground.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Pier2_foreground.cs @@ -4,8 +4,9 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; [Pipeline(typeof(WCSPipeline))] -public class StoneBridge_Pier2_foreground : ForegroundVFX +public class StoneBridge_Pier2_foreground : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; public override void Update() { if (!SubworldSystem.IsActive()) @@ -17,6 +18,6 @@ public override void Update() public override void OnSpawn() { - texture = ModAsset.StoneBridge_Pier2.Value; + Texture = ModAsset.StoneBridge_Pier2.Value; } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Pier_foreground.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Pier_foreground.cs index fd2f7137c..474dedd3e 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Pier_foreground.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Pier_foreground.cs @@ -4,8 +4,9 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; [Pipeline(typeof(WCSPipeline))] -public class StoneBridge_Pier_foreground : ForegroundVFX +public class StoneBridge_Pier_foreground : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; public override void Update() { if (!SubworldSystem.IsActive()) @@ -17,6 +18,6 @@ public override void Update() public override void OnSpawn() { - texture = ModAsset.StoneBridge_Pier.Value; + Texture = ModAsset.StoneBridge_Pier.Value; } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Rightside_foreground.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Rightside_foreground.cs index 589fb968f..18d868b25 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Rightside_foreground.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_Rightside_foreground.cs @@ -4,8 +4,9 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; [Pipeline(typeof(WCSPipeline))] -public class StoneBridge_Rightside_foreground : ForegroundVFX +public class StoneBridge_Rightside_foreground : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; public override void Update() { if (!SubworldSystem.IsActive()) @@ -17,6 +18,6 @@ public override void Update() public override void OnSpawn() { - texture = ModAsset.StoneBridge_Rightside.Value; + Texture = ModAsset.StoneBridge_Rightside.Value; } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_fence.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_fence.cs index 82291a909..5e5feb175 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_fence.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_fence.cs @@ -4,11 +4,12 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; [Pipeline(typeof(WCSPipeline))] -public class StoneBridge_fence : BackgroundVFX +public class StoneBridge_fence : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawBG; public override void OnSpawn() { - texture = ModAsset.StoneBridge_fence.Value; + Texture = ModAsset.StoneBridge_fence.Value; } public override void Update() diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_foreground.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_foreground.cs index cbdd77903..4ee745223 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_foreground.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/StoneBridge_foreground.cs @@ -4,8 +4,9 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; [Pipeline(typeof(WCSPipeline))] -public class StoneBridge_foreground : ForegroundVFX +public class StoneBridge_foreground : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; public override void Update() { if (!SubworldSystem.IsActive()) @@ -17,6 +18,6 @@ public override void Update() public override void OnSpawn() { - texture = ModAsset.StoneBridge.Value; + Texture = ModAsset.StoneBridge.Value; } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/Furnitures/TwilightEucalyptusChest.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/Furnitures/TwilightEucalyptusChest.cs index 5fd29914c..4b2bc4dda 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/Furnitures/TwilightEucalyptusChest.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/Furnitures/TwilightEucalyptusChest.cs @@ -4,6 +4,7 @@ using Terraria.Localization; using Terraria.ObjectData; using Everglow.Yggdrasil.YggdrasilTown.Dusts.TwilightForest; +using Everglow.Yggdrasil.YggdrasilTown.Dusts; namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.Furnitures; @@ -11,7 +12,6 @@ public class TwilightEucalyptusChest : ModTile { public override void SetStaticDefaults() { - // Properties Main.tileSpelunker[Type] = true; Main.tileContainer[Type] = true; Main.tileFrameImportant[Type] = true; @@ -24,39 +24,29 @@ public override void SetStaticDefaults() TileID.Sets.InteractibleByNPCs[Type] = true; TileID.Sets.IsAContainer[Type] = true; TileID.Sets.FriendlyFairyCanLureTo[Type] = true; - TileID.Sets.GeneralPlacementTiles[Type] = false; - DustType = ModContent.DustType(); // You should set a kind of dust manually. + DustType = ModContent.DustType(); AdjTiles = new int[] { TileID.Containers }; - // Other tiles with just one map entry use CreateMapEntryName() to use the default translationkey, "MapEntry" - // Since ExampleChest needs multiple, we register our own MapEntry keys - AddMapEntry(new Color(200, 200, 200), this.GetLocalization("MapEntry0"), MapChestName); - AddMapEntry(new Color(0, 141, 63), this.GetLocalization("MapEntry1"), MapChestName); - - // Style 1 is ExampleChest when locked. We want that tile style to drop the ExampleChest item as well. Use the Chest Lock item to lock this chest. - // No item places ExampleChest in the locked style, so the automatically determined item drop is unknown, this is why RegisterItemDrop is necessary in this situation. - RegisterItemDrop(ModContent.ItemType(), 1); - // Sometimes mods remove content, such as tile styles, or tiles accidentally get corrupted. We can, if desired, register a fallback item for any tile style that doesn't have an automatically determined item drop. This is done by omitting the tileStyles parameter. - RegisterItemDrop(ItemID.Chest); - - // Placement TileObjectData.newTile.CopyFrom(TileObjectData.Style2x2); TileObjectData.newTile.Origin = new Point16(0, 1); TileObjectData.newTile.CoordinateHeights = new[] { 16, 18 }; TileObjectData.newTile.HookCheckIfCanPlace = new PlacementHook(Chest.FindEmptyChest, -1, 0, true); TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(Chest.AfterPlacement_Hook, -1, 0, false); - TileObjectData.newTile.AnchorInvalidTiles = new int[] { + TileObjectData.newTile.AnchorInvalidTiles = new int[] + { TileID.MagicalIceBlock, TileID.Boulder, TileID.BouncyBoulder, TileID.LifeCrystalBoulder, - TileID.RollingCactus + TileID.RollingCactus, }; TileObjectData.newTile.StyleHorizontal = true; TileObjectData.newTile.LavaDeath = false; TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.SolidTile | AnchorType.SolidWithTop | AnchorType.SolidSide, TileObjectData.newTile.Width, 0); TileObjectData.addTile(Type); + + AddMapEntry(new Color(85, 72, 126)); } public override bool TileFrame(int i, int j, ref bool resetFrame, ref bool noBreak) diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/GreenRelicBrick_Trap.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/GreenRelicBrick_Trap.cs index 5d17af811..190185adb 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/GreenRelicBrick_Trap.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/GreenRelicBrick_Trap.cs @@ -45,7 +45,7 @@ public void AddScene(int i, int j) break; } } - ColorLasersTrap trap = new ColorLasersTrap { position = new Point(i, j).ToWorldCoordinates(), Active = true, Visible = true, originTile = new Point(i, j), originType = Type, StartRotation = k * MathHelper.PiOver2, Style = Main.rand.Next(2) }; + ColorLasersTrap trap = new ColorLasersTrap { Position = new Point(i, j).ToWorldCoordinates(), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type, StartRotation = k * MathHelper.PiOver2, Style = Main.rand.Next(2) }; Ins.VFXManager.Add(trap); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/GreenRelicSlotTable.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/GreenRelicSlotTable.cs index bae335416..d8fc552bc 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/GreenRelicSlotTable.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/GreenRelicSlotTable.cs @@ -3,6 +3,7 @@ using Everglow.Yggdrasil.YggdrasilTown.Items.Materials; using Terraria.Audio; using Terraria.ObjectData; +using static Everglow.Commons.Utilities.TileUtils; namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest; @@ -52,7 +53,7 @@ public override bool RightClick(int i, int j) Tile tile = TileUtils.SafeGetTile(i, j); Point topLeftPoint = new Point(i - tile.TileFrameX / 18, j - tile.TileFrameY / 18); YggdrasilWorldGeneration.KillRectangleAreaOfTile(topLeftPoint.X - 1, topLeftPoint.Y, topLeftPoint.X + 3, topLeftPoint.Y + 42); - YggdrasilWorldGeneration.SmoothTile(topLeftPoint.X - 2, topLeftPoint.Y, topLeftPoint.X + 4, topLeftPoint.Y + 42); + SmoothTile_XXYY(topLeftPoint.X - 2, topLeftPoint.Y, topLeftPoint.X + 4, topLeftPoint.Y + 42); for (int x = -2; x < 3; x++) { for (int y = 0; y < 40; y++) diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Liquid_Scene.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Liquid_Scene.cs new file mode 100644 index 000000000..39d4fc501 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Liquid_Scene.cs @@ -0,0 +1,179 @@ +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.WorldGeneration; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +[Pipeline(typeof(WCSPipeline_PointWrap))] +public class BloodChurch_Liquid_Scene : TileVFX +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; + + public bool FlipHorizontally(int i, int j) + { + int leftSolid = 0; + int rightSolid = 0; + for (int x = 1; x < 15; x++) + { + Tile tileLeft = TileUtils.SafeGetTile(i - x, j); + Tile tileRight = TileUtils.SafeGetTile(i + x, j); + if (tileLeft.HasTile && tileLeft.TileType == ModContent.TileType()) + { + leftSolid++; + } + if (tileRight.HasTile && tileRight.TileType == ModContent.TileType()) + { + rightSolid++; + } + } + if (rightSolid > leftSolid) + { + return false; + } + return true; + } + + public List LiquidAreas = new List(); + + public override void Update() + { + if (LiquidAreas.Count <= 0) + { + bool flipH = FlipHorizontally(OriginTilePos.X, OriginTilePos.Y); + int Direction = 1; + int offsetX = 0; + if (flipH) + { + Direction = -1; + offsetX = -176; + } + LiquidAreas.Add(new Rectangle((OriginTilePos.X + 14 * Direction) * 16 + offsetX, (OriginTilePos.Y + 18) * 16, 192, 16)); + } + foreach (Player player in Main.player) + { + if (player != null && player.active && player.velocity.Length() > 1) + { + foreach (Rectangle liquid in LiquidAreas) + { + if (player.Hitbox.Intersects(liquid)) + { + GenerateWaterSplash(liquid, player.Hitbox); + } + } + } + } + base.Update(); + } + + public void GenerateWaterSplash(Rectangle liquidBox, Rectangle entityBox) + { + int splashStart = entityBox.X; + int splashEnd = entityBox.X + entityBox.Width; + splashStart = Math.Max(splashStart, liquidBox.X); + splashEnd = Math.Min(splashEnd, liquidBox.X + liquidBox.Width); + float length = splashEnd - splashStart; + for (int x = 0; x < length / 6; x++) + { + Vector2 pos = new Vector2(splashStart + Main.rand.NextFloat(length), liquidBox.Y); + Dust dust = Dust.NewDustPerfect(Position, ModContent.DustType(), Vector2.zeroVector); + var splash = new BloodChurch_Scene_FakeLiquid_Dust() + { + Position = pos, + Velocity = new Vector2(Main.rand.NextFloat(-2, 2), Main.rand.NextFloat(-2, -1)), + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + Timer = 0, + MaxTime = 150, + MaxPosY = pos.Y + 8, + Frame = new Rectangle(Main.rand.Next(4) * 10, 10, 10, 10), + Scale = Main.rand.NextFloat(0.35f, 0.6f), + Active = true, + Visible = true, + }; + dust.customData = splash; + } + } + + public override void Draw() + { + bool flipH = FlipHorizontally(OriginTilePos.X, OriginTilePos.Y); + int Direction = 1; + if (flipH) + { + Direction = -1; + } + + // Fountain blood liquid + Texture2D liquidTex = ModAsset.BloodChurch_Scene_FakeLiquid_dark.Value; + Texture2D liquidTex_highlight = ModAsset.BloodChurch_Scene_FakeLiquid.Value; + float timeValue = -(float)Main.time / 240f; + List bars = new List(); + List bars_highlight = new List(); + Vector2 liquidSurfacePos = new Vector2(OriginTilePos.X + 13 * Direction, OriginTilePos.Y + 18).ToWorldCoordinates(); + + for (int i = 0; i < 26; i++) + { + Vector2 drawPos = liquidSurfacePos + new Vector2(i * 8 * Direction, 4); + float coordX0 = i / 34f + timeValue * 0.4f; + float coordX1 = (i + 1 * Direction) / 34f + timeValue * 0.4f; + + Color waterEnvLight0 = Lighting.GetColor(drawPos.ToTileCoordinates()) * 0.75f; + Color waterEnvLight1 = Lighting.GetColor((drawPos + new Vector2(8, 0)).ToTileCoordinates()) * 0.75f; + float pureRed0 = (waterEnvLight0.R - Math.Max(waterEnvLight0.G, waterEnvLight0.B)) / 255f; + float pureRed1 = (waterEnvLight1.R - Math.Max(waterEnvLight1.G, waterEnvLight1.B)) / 255f; + pureRed0 = MathF.Pow(pureRed0, 5) * 2; + pureRed1 = MathF.Pow(pureRed1, 5) * 2; + int toCenter = (int)Math.Abs(12.5 - i); + if (i > 5 && i < 21) + { + pureRed0 += 1; + } + if (i > 4 && i < 20) + { + pureRed1 += 1; + } + if (toCenter > 5 && toCenter < 12) + { + bars.Add(drawPos + new Vector2(0, -10 + GetRandomWave(i)), waterEnvLight0, new Vector3(coordX0, 0, 0)); + bars.Add(drawPos + new Vector2(8 * Direction, -10 + GetRandomWave(i + 1)), waterEnvLight1, new Vector3(coordX1, 0, 0)); + bars.Add(drawPos + new Vector2(0, 6), waterEnvLight0, new Vector3(coordX0, 1, 0)); + + bars.Add(drawPos + new Vector2(0, 6), waterEnvLight0, new Vector3(coordX0, 1, 0)); + bars.Add(drawPos + new Vector2(8 * Direction, -10 + GetRandomWave(i + 1)), waterEnvLight1, new Vector3(coordX1, 0, 0)); + bars.Add(drawPos + new Vector2(8 * Direction, 6), waterEnvLight1, new Vector3(coordX1, 1, 0)); + + bars_highlight.Add(drawPos + new Vector2(0, -10 + GetRandomWave(i)), waterEnvLight0 * pureRed0, new Vector3(coordX0, 0, 0)); + bars_highlight.Add(drawPos + new Vector2(8 * Direction, -10 + GetRandomWave(i + 1)), waterEnvLight1 * pureRed1, new Vector3(coordX1, 0, 0)); + bars_highlight.Add(drawPos + new Vector2(0, 6), waterEnvLight0 * pureRed0, new Vector3(coordX0, 1, 0)); + + bars_highlight.Add(drawPos + new Vector2(0, 6), waterEnvLight0 * pureRed0, new Vector3(coordX0, 1, 0)); + bars_highlight.Add(drawPos + new Vector2(8 * Direction, -10 + GetRandomWave(i + 1)), waterEnvLight1 * pureRed1, new Vector3(coordX1, 0, 0)); + bars_highlight.Add(drawPos + new Vector2(8 * Direction, 6), waterEnvLight1 * pureRed1, new Vector3(coordX1, 1, 0)); + } + } + Ins.Batch.Draw(liquidTex, bars, PrimitiveType.TriangleList); + Ins.Batch.Draw(liquidTex_highlight, bars_highlight, PrimitiveType.TriangleList); + + //if(LiquidAreas.Count > 0) + //{ + // var rec = LiquidAreas[0]; + // bars = new List(); + // bars.Add(rec.TopLeft(), Color.White, new Vector3(0, 0, 0)); + // bars.Add(rec.TopRight(), Color.White, new Vector3(1, 0, 0)); + + // bars.Add(rec.BottomLeft(), Color.White, new Vector3(0, 1, 0)); + // bars.Add(rec.BottomRight(), Color.White, new Vector3(1, 1, 0)); + // Ins.Batch.Draw(Commons.ModAsset.TileBlock.Value, bars, PrimitiveType.TriangleStrip); + //} + } + + public float GetRandomWave(float x) + { + float value = 0; + float timeValue = (float)Main.time * 0.06f; + for (int i = 0; i < 8; i++) + { + float rate = MathF.Pow(2, i); + value += MathF.Sin(x * rate + timeValue * rate * 0.5f) / rate; + } + return value; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene.cs new file mode 100644 index 000000000..29b8f22f4 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene.cs @@ -0,0 +1,401 @@ +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.YggdrasilTown.Dusts.TwilightForest; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.LampWood; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class BloodChurch_Scene : ModTile, ISceneTile +{ + public override string Texture => ModAsset.GreenRelicBrick_Mod; + + public bool FlipHorizontally(int i, int j) + { + int leftSolid = 0; + int rightSolid = 0; + for (int x = 1; x < 15; x++) + { + Tile tileLeft = TileUtils.SafeGetTile(i - x, j); + Tile tileRight = TileUtils.SafeGetTile(i + x, j); + if (tileLeft.HasTile && tileLeft.TileType == ModContent.TileType()) + { + leftSolid++; + } + if (tileRight.HasTile && tileRight.TileType == ModContent.TileType()) + { + rightSolid++; + } + } + if (rightSolid > leftSolid) + { + return false; + } + return true; + } + + public override void SetStaticDefaults() + { + Main.tileSolid[Type] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[ModContent.TileType()][Type] = true; + Main.tileBlockLight[Type] = true; + DustType = ModContent.DustType(); + HitSound = SoundID.Dig; + MinPick = int.MaxValue; + AddMapEntry(new Color(35, 58, 58)); + } + + public override bool CanKillTile(int i, int j, ref bool blockDamaged) => false; + + public override bool CanExplode(int i, int j) + { + return false; + } + + public void AddScene(int i, int j) + { + var scene_Close = new TwilightCastle_RoomScene_OverTiles { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; + scene_Close.CustomDraw += DrawBloodyChurchOverTile; + + var scene_Background = new TwilightCastle_RoomScene_Background { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; + scene_Background.CustomDraw += DrawBloodyChurchBackground; + + var liquid_OverPlayer = new BloodChurch_Liquid_Scene { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type, LiquidAreas = new List() }; + + Ins.VFXManager.Add(scene_Close); + Ins.VFXManager.Add(scene_Background); + Ins.VFXManager.Add(liquid_OverPlayer); + + // Ins.VFXManager.Add(scene_Fountain); + } + + public void DrawBloodyChurchOverTile(TwilightCastle_RoomScene_OverTiles otD) + { + bool flipH = otD.FlipHorizontally(otD.OriginTilePos.X, otD.OriginTilePos.Y); + Texture2D tex0 = ModAsset.BloodChurch_Scene_Close.Value; + + List bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(otD.OriginTilePos.X, otD.OriginTilePos.Y, tex0, bars, flipH); + Ins.Batch.Draw(tex0, bars, PrimitiveType.TriangleList); + } + + public void DrawBloodyChurchBackground(TwilightCastle_RoomScene_Background bg) + { + bool flipH = bg.FlipHorizontally(bg.OriginTilePos.X, bg.OriginTilePos.Y); + Texture2D tex0 = ModAsset.BloodChurch_Scene_Background.Value; + + // Texture2D tex1 = ModAsset.BloodChurch_Scene_Far.Value; + Texture2D tex2 = ModAsset.BloodChurch_Scene_Fountain.Value; + Texture2D tex2_red = ModAsset.BloodChurch_Scene_Fountain_Red.Value; + Texture2D tex3_dark = Commons.ModAsset.Noise_flame_2_pure_black.Value; + Texture2D tex3 = Commons.ModAsset.Noise_flame_2_pure.Value; + Texture2D tex4 = Commons.ModAsset.Noise_WaterFallWave.Value; + + List bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(bg.OriginTilePos.X, bg.OriginTilePos.Y, tex0, bars, flipH); + Ins.Batch.Draw(tex0, bars, PrimitiveType.TriangleList); + + // bars = new List(); + // SceneUtils.DrawMultiSceneTowardBottom(bg.OriginTilePos.X, bg.OriginTilePos.Y, tex1, bars, flipH); + // Ins.Batch.Draw(tex1, bars, PrimitiveType.TriangleList); + + // Fountain waterfall background + int direction = 1; + if (flipH) + { + direction = -1; + } + float coordX = 0; + Color oldColor = new Color(1f, 0f, 0.2f, 0); + float timeValue = -(float)Main.time / 240f; + for (int i = 0; i < 11; i++) + { + float addCoordX = MathF.Acos((40f - i * 8) / 41f) / MathHelper.Pi - coordX; + Vector2 drawPos = new Vector2(bg.OriginTilePos.X + 17 * direction, bg.OriginTilePos.Y + 11).ToWorldCoordinates() + new Vector2(i * 8 * direction, 0); + + bars = new List(); + List bars_black = new List(); + for (int j = 0; j < 10; j++) + { + float addYCoord = MathF.Pow(j, 0.5f); + float x0 = -4 + GetOffsetHorizontal(i, j, 6f) * direction; + float x1 = 4 + GetOffsetHorizontal(i + 1 * direction, j, 6f) * direction; + + Vector2 drawPieceLeft = drawPos + new Vector2(x0, j * 16); + Vector2 drawPieceRight = drawPos + new Vector2(x1, j * 16); + + Color leftColor = Lighting.GetColor(drawPieceLeft.ToTileCoordinates(), oldColor); + leftColor.A = 0; + Color rightColor = Lighting.GetColor(drawPieceRight.ToTileCoordinates(), oldColor); + rightColor.A = 0; + + float coordX0 = coordX; + float coordX1 = coordX + addCoordX; + if (flipH) + { + (coordX0, coordX1) = (coordX1, coordX0); + } + + bars.Add(drawPieceLeft, leftColor * 0.15f, new Vector3(coordX0, timeValue + addYCoord * 0.08f, 0)); + bars.Add(drawPieceRight, rightColor * 0.15f, new Vector3(coordX1, timeValue + addYCoord * 0.08f, 0)); + + bars_black.Add(drawPieceLeft, Color.White * 0.35f, new Vector3(coordX0, timeValue + addYCoord * 0.08f, 0)); + bars_black.Add(drawPieceRight, Color.White * 0.35f, new Vector3(coordX1, timeValue + addYCoord * 0.08f, 0)); + } + coordX += addCoordX; + Ins.Batch.Draw(tex3_dark, bars_black, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(tex3, bars, PrimitiveType.TriangleStrip); + } + coordX = 0; + for (int i = 0; i < 3; i++) + { + float addCoordX = MathF.Acos((40f - i * 8) / 41f) / MathHelper.Pi - coordX; + Vector2 drawPos = new Vector2(bg.OriginTilePos.X + 19 * direction, bg.OriginTilePos.Y + 9).ToWorldCoordinates() + new Vector2(i * 8 * direction, 8); + + bars = new List(); + List bars_black = new List(); + for (int j = 0; j < 3; j++) + { + float addYCoord = MathF.Pow(j, 0.5f); + float x0 = -4 + GetOffsetHorizontal(i, j, 1.5f) * direction; + float x1 = 4 + GetOffsetHorizontal(i + 1 * direction, j, 1.5f) * direction; + + Vector2 drawPieceLeft = drawPos + new Vector2(x0, j * 16); + Vector2 drawPieceRight = drawPos + new Vector2(x1, j * 16); + + Color leftColor = Lighting.GetColor(drawPieceLeft.ToTileCoordinates(), oldColor); + leftColor.A = 0; + Color rightColor = Lighting.GetColor(drawPieceRight.ToTileCoordinates(), oldColor); + rightColor.A = 0; + + float coordX0 = coordX; + float coordX1 = coordX + addCoordX; + if (flipH) + { + (coordX0, coordX1) = (coordX1, coordX0); + } + + bars.Add(drawPieceLeft, leftColor * 0.15f, new Vector3(coordX0, timeValue + addYCoord * 0.08f, 0)); + bars.Add(drawPieceRight, rightColor * 0.15f, new Vector3(coordX1, timeValue + addYCoord * 0.08f, 0)); + + bars_black.Add(drawPieceLeft, Color.White * 0.35f, new Vector3(coordX0, timeValue + addYCoord * 0.08f, 0)); + bars_black.Add(drawPieceRight, Color.White * 0.35f, new Vector3(coordX1, timeValue + addYCoord * 0.08f, 0)); + } + coordX += addCoordX; + Ins.Batch.Draw(tex3_dark, bars_black, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(tex3, bars, PrimitiveType.TriangleStrip); + } + + // Fountain + bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(bg.OriginTilePos.X + 17 * direction, bg.OriginTilePos.Y + 10, tex2, bars, flipH); + Ins.Batch.Draw(tex2, bars, PrimitiveType.TriangleList); + + Color envLight = Lighting.GetColor(bg.OriginTilePos.X + 22, bg.OriginTilePos.Y + 14); + bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(bg.OriginTilePos.X + 17 * direction, bg.OriginTilePos.Y + 10, tex2, bars, flipH, (envLight.R - Math.Max(envLight.G, envLight.B)) / 255f); + Ins.Batch.Draw(tex2_red, bars, PrimitiveType.TriangleList); + + // Fountain waterfall front + coordX = 0; + timeValue += 0.5f; + for (int i = 0; i < 11; i++) + { + float addCoordX = MathF.Acos((40f - i * 8) / 41f) / MathHelper.Pi - coordX; + Vector2 drawPos = new Vector2(bg.OriginTilePos.X + 17 * direction, bg.OriginTilePos.Y + 11).ToWorldCoordinates() + new Vector2(i * 8 * direction, 0); + bars = new List(); + List bars_black = new List(); + List bars_reflect = new List(); + for (int j = 0; j < 10; j++) + { + float addYCoord = MathF.Pow(j, 0.5f); + float x0 = -4 + GetOffsetHorizontal(i, j, 6f) * direction; + float x1 = 4 + GetOffsetHorizontal(i + 1 * direction, j, 6f) * direction; + + Vector2 drawPieceLeft = drawPos + new Vector2(x0, j * 16); + Vector2 drawPieceRight = drawPos + new Vector2(x1, j * 16); + + Color leftColor = Lighting.GetColor(drawPieceLeft.ToTileCoordinates(), oldColor); + leftColor.A = 0; + Color rightColor = Lighting.GetColor(drawPieceRight.ToTileCoordinates(), oldColor); + rightColor.A = 0; + + float coordX0 = coordX; + float coordX1 = coordX + addCoordX; + if (flipH) + { + (coordX0, coordX1) = (coordX1, coordX0); + } + + bars.Add(drawPieceLeft, leftColor * 0.15f, new Vector3(coordX0, timeValue + addYCoord * 0.08f, 0)); + bars.Add(drawPieceRight, rightColor * 0.15f, new Vector3(coordX1, timeValue + addYCoord * 0.08f, 0)); + + bars_black.Add(drawPieceLeft, Color.White * 0.25f, new Vector3(coordX0, timeValue + addYCoord * 0.08f, 0)); + bars_black.Add(drawPieceRight, Color.White * 0.25f, new Vector3(coordX1, timeValue + addYCoord * 0.08f, 0)); + + Color reflectLeft = Color.Lerp(leftColor, new Color(1f, 1f, 1f, 0), 0.2f); + Color reflectRight = Color.Lerp(rightColor, new Color(1f, 1f, 1f, 0), 0.2f); + addYCoord = MathF.Pow(j, 0.5f); + bars_reflect.Add(drawPieceLeft, reflectLeft * 0.35f, new Vector3(coordX0, timeValue + addYCoord * 0.08f, 0)); + bars_reflect.Add(drawPieceRight, reflectRight * 0.35f, new Vector3(coordX1, timeValue + addYCoord * 0.08f, 0)); + } + coordX += addCoordX; + Ins.Batch.Draw(tex3_dark, bars_black, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(tex3, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(tex4, bars_reflect, PrimitiveType.TriangleStrip); + } + coordX = 0; + for (int i = 0; i < 3; i++) + { + float addCoordX = MathF.Acos((40f - i * 8) / 41f) / MathHelper.Pi - coordX; + Vector2 drawPos = new Vector2(bg.OriginTilePos.X + 19 * direction, bg.OriginTilePos.Y + 9).ToWorldCoordinates() + new Vector2(i * 8 * direction, 8); + + bars = new List(); + List bars_black = new List(); + List bars_reflect = new List(); + for (int j = 0; j < 4; j++) + { + float addYCoord = MathF.Pow(j, 0.5f); + float x0 = -4 + GetOffsetHorizontal(i, j, 1.5f) * direction; + float x1 = 4 + GetOffsetHorizontal(i + 1 * direction, j, 1.5f) * direction; + float offsetY = j * 8; + + Vector2 drawPieceLeft = drawPos + new Vector2(x0, offsetY); + Vector2 drawPieceRight = drawPos + new Vector2(x1, offsetY); + + Color leftColor = Lighting.GetColor(drawPieceLeft.ToTileCoordinates(), oldColor); + leftColor.A = 0; + Color rightColor = Lighting.GetColor(drawPieceRight.ToTileCoordinates(), oldColor); + rightColor.A = 0; + + float coordX0 = coordX; + float coordX1 = coordX + addCoordX; + if (flipH) + { + (coordX0, coordX1) = (coordX1, coordX0); + } + + bars.Add(drawPos + new Vector2(x0, offsetY), leftColor * 0.15f, new Vector3(coordX0, timeValue + addYCoord * 0.08f, 0)); + bars.Add(drawPos + new Vector2(x1, offsetY), rightColor * 0.15f, new Vector3(coordX1, timeValue + addYCoord * 0.08f, 0)); + + bars_black.Add(drawPos + new Vector2(x0, offsetY), Color.White * 0.35f, new Vector3(coordX0, timeValue + addYCoord * 0.08f, 0)); + bars_black.Add(drawPos + new Vector2(x1, offsetY), Color.White * 0.35f, new Vector3(coordX1, timeValue + addYCoord * 0.08f, 0)); + + Color reflectLeft = Color.Lerp(leftColor, new Color(1f, 1f, 1f, 0), 0.2f); + Color reflectRight = Color.Lerp(rightColor, new Color(1f, 1f, 1f, 0), 0.2f); + addYCoord = MathF.Pow(j, 0.5f); + bars_reflect.Add(drawPos + new Vector2(x0, offsetY), reflectLeft * 0.35f, new Vector3(coordX0, timeValue + addYCoord * 0.08f, 0)); + bars_reflect.Add(drawPos + new Vector2(x1, offsetY), reflectRight * 0.35f, new Vector3(coordX1, timeValue + addYCoord * 0.08f, 0)); + } + coordX += addCoordX; + Ins.Batch.Draw(tex3_dark, bars_black, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(tex3, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(tex4, bars_reflect, PrimitiveType.TriangleStrip); + } + } + + public float GetOffsetHorizontal(float x, float y, float middleX) + { + return -MathF.Sqrt(y) * (middleX - x); + } + + public override void NearbyEffects(int i, int j, bool closer) + { + bool flipH = FlipHorizontally(i, j); + int direction = 1; + if (flipH) + { + direction = -1; + } + if (!Main.gamePaused) + { + for (int k = 0; k < 4; k++) + { + float addX = Main.rand.NextFloat(96); + Vector2 pos = new Vector2(i + 17 * direction, j + 11).ToWorldCoordinates() + new Vector2((addX - 8) * direction, Main.rand.NextFloat(-2, 14)); + var dust = new BloodChurch_Scene_FakeLiquid_Dust() + { + Position = pos, + Velocity = new Vector2((addX - 48) * direction * 0.01f, 1), + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + Timer = 0, + MaxTime = 150, + MaxPosY = (j + 17) * 16, + Frame = new Rectangle(Main.rand.Next(4) * 10, 10, 10, 10), + Scale = Main.rand.NextFloat(0.35f, 0.6f), + Active = true, + Visible = true, + }; + Ins.VFXManager.Add(dust); + } + for (int k = 0; k < 1; k++) + { + float addX = Main.rand.NextFloat(16); + Vector2 pos = new Vector2(i + 19 * direction, j + 9).ToWorldCoordinates() + new Vector2(addX * direction, Main.rand.NextFloat(6, 10)); + var dust = new BloodChurch_Scene_FakeLiquid_Dust() + { + Position = pos, + Velocity = new Vector2((addX - 8) * direction * 0.01f, Main.rand.NextFloat(-0.5f, 0)), + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + Timer = 0, + MaxTime = 150, + MaxPosY = (j + 12) * 16, + Frame = new Rectangle(Main.rand.Next(4) * 10, 10, 10, 10), + Scale = Main.rand.NextFloat(0.35f, 0.6f), + Active = true, + Visible = true, + }; + Ins.VFXManager.Add(dust); + } + + for (int k = 0; k < 4; k++) + { + float addX = Main.rand.NextFloat(136); + Vector2 pos = new Vector2(i + 16 * direction, j + 18).ToWorldCoordinates() + new Vector2((addX - 8) * direction, Main.rand.NextFloat(-8, 0)); + float apartCenter = MathF.Abs(68 - addX); + if (apartCenter < 40) + { + pos.Y -= 8; + } + if (apartCenter < 20) + { + pos.Y -= 8; + } + int frameY = 10; + if (Main.rand.NextBool(3)) + { + frameY = 20; + } + var dust = new BloodChurch_Scene_FakeLiquid_Dust() + { + Position = pos, + Velocity = new Vector2((addX - 68) * direction * 0.01f, Main.rand.NextFloat(-2f, 0f)), + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + Timer = 0, + MaxTime = 150, + MaxPosY = (j + 18) * 16 + 8, + Frame = new Rectangle(Main.rand.Next(4) * 10, frameY, 10, 10), + Scale = Main.rand.NextFloat(0.35f, 0.4f), + Active = true, + Visible = true, + }; + Ins.VFXManager.Add(dust); + } + } + base.NearbyEffects(i, j, closer); + } + + public float GetRandomWave(float x) + { + float value = 0; + float timeValue = (float)Main.time * 0.06f; + for (int i = 0; i < 8; i++) + { + float rate = MathF.Pow(2, i); + value += MathF.Sin(x * rate + timeValue * rate * 0.5f) / rate; + } + return value; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_Background.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_Background.png new file mode 100644 index 000000000..efe8e9a6b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_Background.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_Close.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_Close.png new file mode 100644 index 000000000..04b0074c8 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_Close.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_FakeLiquid.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_FakeLiquid.png new file mode 100644 index 000000000..bbea1e05e Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_FakeLiquid.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_FakeLiquid_Dust.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_FakeLiquid_Dust.cs new file mode 100644 index 000000000..0d3c81439 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_FakeLiquid_Dust.cs @@ -0,0 +1,53 @@ +using Everglow.Commons.VFX.Scene; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +[Pipeline(typeof(WCSPipeline))] +public class BloodChurch_Scene_FakeLiquid_Dust : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawTiles; + + public Vector2 Position; + + public Vector2 Velocity; + + public float Scale; + + public float Timer; + + public float MaxTime; + + public float MaxPosY; + + public float Rotation; + + public Rectangle Frame; + + public override void OnSpawn() + { + } + + public override void Update() + { + Timer++; + if (Timer >= MaxTime) + { + Kill(); + return; + } + if (Position.Y > MaxPosY) + { + Kill(); + return; + } + Position += Velocity; + Velocity += new Vector2(0, 0.15f); + } + + public override void Draw() + { + Texture2D tex = ModAsset.BloodChurch_Scene_FakeLiquid_Dust.Value; + Color drawColor = Lighting.GetColor(Position.ToTileCoordinates()) * 0.5f; + Ins.Batch.Draw(tex, Position, Frame, drawColor, Rotation, Frame.Size() * 0.5f, Scale, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_FakeLiquid_Dust.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_FakeLiquid_Dust.png new file mode 100644 index 000000000..cf4b5489b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_FakeLiquid_Dust.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_FakeLiquid_dark.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_FakeLiquid_dark.png new file mode 100644 index 000000000..ee914eac6 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_FakeLiquid_dark.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_Far.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_Far.png new file mode 100644 index 000000000..3ef3f46aa Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_Far.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_Fountain.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_Fountain.png new file mode 100644 index 000000000..dd4ba33fd Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_Fountain.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_Fountain_Red.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_Fountain_Red.png new file mode 100644 index 000000000..41cf018e3 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/BloodChurch_Scene_Fountain_Red.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DarkDragon_Scene.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DarkDragon_Scene.cs new file mode 100644 index 000000000..2f60f485f --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DarkDragon_Scene.cs @@ -0,0 +1,79 @@ +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.WorldGeneration; +using Everglow.Yggdrasil.YggdrasilTown.Dusts.TwilightForest; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.LampWood; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class DarkDragon_Scene : ModTile, ISceneTile +{ + public override string Texture => ModAsset.GreenRelicBrick_Mod; + + public override void SetStaticDefaults() + { + Main.tileSolid[Type] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[ModContent.TileType()][Type] = true; + Main.tileBlockLight[Type] = true; + DustType = ModContent.DustType(); + HitSound = SoundID.Dig; + MinPick = int.MaxValue; + AddMapEntry(new Color(35, 58, 58)); + } + + public bool FlipHorizontally(int i, int j) + { + int leftSolid = 0; + int rightSolid = 0; + for (int x = 1; x < 15; x++) + { + Tile tileLeft = TileUtils.SafeGetTile(i - x, j); + Tile tileRight = TileUtils.SafeGetTile(i + x, j); + if (tileLeft.HasTile && tileLeft.TileType == ModContent.TileType()) + { + leftSolid++; + } + if (tileRight.HasTile && tileRight.TileType == ModContent.TileType()) + { + rightSolid++; + } + } + if (rightSolid > leftSolid) + { + return false; + } + return true; + } + + public override bool CanKillTile(int i, int j, ref bool blockDamaged) => false; + + public override bool CanExplode(int i, int j) + { + return false; + } + + public void AddScene(int i, int j) + { + var scene_Close = new TwilightCastle_RoomScene_OverTiles { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; + scene_Close.CustomDraw += DrawOverTile; + Ins.VFXManager.Add(scene_Close); + + var scene_Manager = new DarkDragon_Scene_DustManager { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; + Ins.VFXManager.Add(scene_Manager); + } + + public void DrawOverTile(TwilightCastle_RoomScene_OverTiles otD) + { + Texture2D tex0 = ModAsset.DarkDragon_Scene_Background.Value; + bool flipH = otD.FlipHorizontally(otD.OriginTilePos.X, otD.OriginTilePos.Y); + Ins.Batch.Draw(tex0, otD.Position, null, Color.White, 0, flipH ? new Vector2(tex0.Width - 16, 0) : Vector2.zeroVector, 1, flipH ? SpriteEffects.FlipHorizontally : SpriteEffects.None); + } + + public override void NearbyEffects(int i, int j, bool closer) + { + base.NearbyEffects(i, j, closer); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DarkDragon_Scene_Background.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DarkDragon_Scene_Background.png new file mode 100644 index 000000000..641f53268 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DarkDragon_Scene_Background.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DarkDragon_Scene_Dust.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DarkDragon_Scene_Dust.cs new file mode 100644 index 000000000..6160c9d2c --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DarkDragon_Scene_Dust.cs @@ -0,0 +1,82 @@ +using Everglow.Yggdrasil.WorldGeneration; +using Terraria; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +[Pipeline(typeof(WCSPipeline))] +public class DarkDragon_Scene_Dust : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawDusts; + + public Vector2 Position; + + public Vector2 Velocity; + + public float Scale; + + public float Timer; + + public float MaxTime; + + public float MaxPosY; + + public float Rotation; + + public float Fade; + + public Rectangle Frame; + + public int MoveLogic = 0; + + public override void OnSpawn() + { + var tile = TileUtils.SafeGetTile(Position.ToTileCoordinates()); + if (Collision.IsWorldPointSolid(Position) && !Main.tileSolidTop[tile.TileType]) + { + Kill(); + return; + } + } + + public override void Update() + { + Timer++; + if (Timer >= MaxTime) + { + Kill(); + return; + } + if (Position.Y > MaxPosY) + { + Kill(); + return; + } + if (MoveLogic == 0) + { + Rotation += 0.1f; + Scale *= 0.995f; + Velocity *= 0.99f; + Velocity.Y += Scale * 0.01f; + Position += Velocity; + } + if (MoveLogic == 1) + { + Rotation += 0.1f; + Scale *= 0.98f; + Velocity *= 0.98f; + Position += Velocity; + } + if (Scale <= 0.05) + { + Kill(); + return; + } + } + + public override void Draw() + { + Texture2D tex = ModAsset.DarkDragon_Scene_Dust.Value; + Color drawColor = Color.White; + Ins.Batch.Draw(tex, Position, Frame, drawColor * Fade, Rotation, Frame.Size() * 0.5f, Scale, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DarkDragon_Scene_Dust.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DarkDragon_Scene_Dust.png new file mode 100644 index 000000000..8b27f6e78 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DarkDragon_Scene_Dust.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DarkDragon_Scene_DustManager.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DarkDragon_Scene_DustManager.cs new file mode 100644 index 000000000..947b4e839 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DarkDragon_Scene_DustManager.cs @@ -0,0 +1,48 @@ +using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Miscs; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class DarkDragon_Scene_DustManager : TwilightCastle_RoomScene_OverTiles +{ + public int Timer = 0; + + public override void Update() + { + base.Update(); + Timer++; + int direction = 1; + if (FlipHorizontally(OriginTilePos.X, OriginTilePos.Y)) + { + direction = -1; + } + Vector2 p0 = new Vector2(21 * direction, 26); + Vector2 p1 = new Vector2(396 * direction, 26); + if (Main.rand.NextBool(6)) + { + float value = Main.rand.NextFloat(); + Vector2 pos = p0 * value + p1 * (1 - value) + Position; + Dust dust = Dust.NewDustPerfect(Position, ModContent.DustType(), Vector2.zeroVector); + var dark = new DarkDragon_Scene_Dust() + { + Position = pos, + Velocity = new Vector2(Main.rand.NextFloat(2, 2.5f) * direction, Main.rand.NextFloat(1, 1.5f)), + Fade = 1, + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + Timer = 0, + MaxTime = 300, + MaxPosY = OriginTilePos.Y * 16 + 312, + Frame = new Rectangle(Main.rand.Next(4) * 10, 10 + Main.rand.Next(3) * 10, 10, 10), + Scale = Main.rand.NextFloat(1.45f, 3.6f), + Active = true, + Visible = true, + }; + dust.customData = dark; + } + if (Timer % 150 == 0) + { + float value = Main.rand.NextFloat(); + Vector2 pos = p0 * value + p1 * (1 - value) + Position; + Projectile.NewProjectileDirect(WorldGen.GetProjectileSource_PlayerOrWires(OriginTilePos.X, OriginTilePos.Y, false, Main.LocalPlayer), pos, new Vector2(2 * direction, 2), ModContent.ProjectileType(), 30, 2, Main.myPlayer); + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyAnkhBanner.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyAnkhBanner.cs new file mode 100644 index 000000000..07de535b5 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyAnkhBanner.cs @@ -0,0 +1,59 @@ +using Everglow.Commons.TileHelper; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.GameContent.Drawing; +using Terraria.Localization; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class Desert_NavyAnkhBanner : ModTile, ITileFluentlyDrawn +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileLighted[Type] = true; + Main.tileSolid[Type] = false; + Main.tileNoFail[Type] = true; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x2Top); + TileObjectData.newTile.Height = 3; + TileObjectData.newTile.CoordinateHeights = new int[3] + { + 16, + 16, + 16, + }; + + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.AnchorTop = new AnchorData(AnchorType.SolidTile | AnchorType.SolidSide | AnchorType.SolidBottom | AnchorType.PlanterBox, TileObjectData.newTile.Width, 0); + TileObjectData.newTile.StyleWrapLimit = 111; + TileObjectData.newTile.DrawYOffset = -2; + TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile); + TileObjectData.newAlternate.AnchorTop = new AnchorData(AnchorType.Platform, TileObjectData.newTile.Width, 0); + TileObjectData.newAlternate.DrawYOffset = -10; + TileObjectData.addAlternate(0); + TileObjectData.addTile(Type); + + LocalizedText name = CreateMapEntryName(); + AddMapEntry(new Color(13, 88, 130), name); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + return false; + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + FurnitureUtils.BannerFluentDraw(screenPosition, pos, spriteBatch, tileDrawing); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyAnkhBanner.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyAnkhBanner.png new file mode 100644 index 000000000..fcc6bbbe0 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyAnkhBanner.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyBanner.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyBanner.cs new file mode 100644 index 000000000..4d7002a10 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyBanner.cs @@ -0,0 +1,58 @@ +using Everglow.Commons.TileHelper; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.GameContent.Drawing; +using Terraria.Localization; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class Desert_NavyBanner : ModTile, ITileFluentlyDrawn +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileLighted[Type] = true; + Main.tileSolid[Type] = false; + Main.tileNoFail[Type] = true; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x2Top); + TileObjectData.newTile.Height = 3; + TileObjectData.newTile.CoordinateHeights = new int[3] + { + 16, + 16, + 16, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.AnchorTop = new AnchorData(AnchorType.SolidTile | AnchorType.SolidSide | AnchorType.SolidBottom | AnchorType.PlanterBox, TileObjectData.newTile.Width, 0); + TileObjectData.newTile.StyleWrapLimit = 111; + TileObjectData.newTile.DrawYOffset = -2; + TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile); + TileObjectData.newAlternate.AnchorTop = new AnchorData(AnchorType.Platform, TileObjectData.newTile.Width, 0); + TileObjectData.newAlternate.DrawYOffset = -10; + TileObjectData.addAlternate(0); + TileObjectData.addTile(Type); + + LocalizedText name = CreateMapEntryName(); + AddMapEntry(new Color(13, 88, 130), name); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + return false; + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + FurnitureUtils.BannerFluentDraw(screenPosition, pos, spriteBatch, tileDrawing); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyBanner.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyBanner.png new file mode 100644 index 000000000..4870eba45 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyBanner.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyOmegaBanner.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyOmegaBanner.cs new file mode 100644 index 000000000..6522a003f --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyOmegaBanner.cs @@ -0,0 +1,59 @@ +using Everglow.Commons.TileHelper; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.GameContent.Drawing; +using Terraria.Localization; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class Desert_NavyOmegaBanner : ModTile, ITileFluentlyDrawn +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileLighted[Type] = true; + Main.tileSolid[Type] = false; + Main.tileNoFail[Type] = true; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x2Top); + TileObjectData.newTile.Height = 3; + TileObjectData.newTile.CoordinateHeights = new int[3] + { + 16, + 16, + 16, + }; + + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.AnchorTop = new AnchorData(AnchorType.SolidTile | AnchorType.SolidSide | AnchorType.SolidBottom | AnchorType.PlanterBox, TileObjectData.newTile.Width, 0); + TileObjectData.newTile.StyleWrapLimit = 111; + TileObjectData.newTile.DrawYOffset = -2; + TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile); + TileObjectData.newAlternate.AnchorTop = new AnchorData(AnchorType.Platform, TileObjectData.newTile.Width, 0); + TileObjectData.newAlternate.DrawYOffset = -10; + TileObjectData.addAlternate(0); + TileObjectData.addTile(Type); + + LocalizedText name = CreateMapEntryName(); + AddMapEntry(new Color(13, 88, 130), name); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + return false; + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + FurnitureUtils.BannerFluentDraw(screenPosition, pos, spriteBatch, tileDrawing); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyOmegaBanner.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyOmegaBanner.png new file mode 100644 index 000000000..76b49cd4b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavyOmegaBanner.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavySnakeBanner.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavySnakeBanner.cs new file mode 100644 index 000000000..396e3d3d8 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavySnakeBanner.cs @@ -0,0 +1,59 @@ +using Everglow.Commons.TileHelper; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.GameContent.Drawing; +using Terraria.Localization; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class Desert_NavySnakeBanner : ModTile, ITileFluentlyDrawn +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileLighted[Type] = true; + Main.tileSolid[Type] = false; + Main.tileNoFail[Type] = true; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x2Top); + TileObjectData.newTile.Height = 3; + TileObjectData.newTile.CoordinateHeights = new int[3] + { + 16, + 16, + 16, + }; + + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.AnchorTop = new AnchorData(AnchorType.SolidTile | AnchorType.SolidSide | AnchorType.SolidBottom | AnchorType.PlanterBox, TileObjectData.newTile.Width, 0); + TileObjectData.newTile.StyleWrapLimit = 111; + TileObjectData.newTile.DrawYOffset = -2; + TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile); + TileObjectData.newAlternate.AnchorTop = new AnchorData(AnchorType.Platform, TileObjectData.newTile.Width, 0); + TileObjectData.newAlternate.DrawYOffset = -10; + TileObjectData.addAlternate(0); + TileObjectData.addTile(Type); + + LocalizedText name = CreateMapEntryName(); + AddMapEntry(new Color(13, 88, 130), name); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + return false; + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + FurnitureUtils.BannerFluentDraw(screenPosition, pos, spriteBatch, tileDrawing); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavySnakeBanner.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavySnakeBanner.png new file mode 100644 index 000000000..bb61f921d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_NavySnakeBanner.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene.cs new file mode 100644 index 000000000..ff39f34f9 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene.cs @@ -0,0 +1,148 @@ +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.WorldGeneration; +using Everglow.Yggdrasil.YggdrasilTown.Dusts.TwilightForest; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.LampWood; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class Desert_Scene : ModTile, ISceneTile +{ + public override string Texture => ModAsset.GreenRelicBrick_Mod; + + public override void SetStaticDefaults() + { + Main.tileSolid[Type] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[ModContent.TileType()][Type] = true; + Main.tileBlockLight[Type] = true; + DustType = ModContent.DustType(); + HitSound = SoundID.Dig; + MinPick = int.MaxValue; + AddMapEntry(new Color(35, 58, 58)); + } + + public bool FlipHorizontally(int i, int j) + { + int leftSolid = 0; + int rightSolid = 0; + for (int x = 1; x < 15; x++) + { + Tile tileLeft = TileUtils.SafeGetTile(i - x, j); + Tile tileRight = TileUtils.SafeGetTile(i + x, j); + if (tileLeft.HasTile && tileLeft.TileType == ModContent.TileType()) + { + leftSolid++; + } + if (tileRight.HasTile && tileRight.TileType == ModContent.TileType()) + { + rightSolid++; + } + } + if (rightSolid > leftSolid) + { + return false; + } + return true; + } + + public override bool CanKillTile(int i, int j, ref bool blockDamaged) => false; + + public override bool CanExplode(int i, int j) + { + return false; + } + + public void AddScene(int i, int j) + { + var scene_Close = new TwilightCastle_RoomScene_OverTiles { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; + scene_Close.CustomDraw += DrawOverTile; + + var scene_Background = new TwilightCastle_RoomScene_Background { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; + scene_Background.CustomDraw += DrawBackground; + + Ins.VFXManager.Add(scene_Close); + Ins.VFXManager.Add(scene_Background); + } + + public void DrawOverTile(TwilightCastle_RoomScene_OverTiles otD) + { + Texture2D tex0 = ModAsset.Desert_Scene_Close.Value; + bool flipH = otD.FlipHorizontally(otD.OriginTilePos.X, otD.OriginTilePos.Y); + int direction = 1; + if (flipH) + { + direction = -1; + } + + Tile tile_lantern = TileUtils.SafeGetTile(otD.OriginTilePos + new Point(7 * direction, 5)); + if (tile_lantern.TileType == ModContent.TileType() && tile_lantern.TileFrameX == 0) + { + tex0 = ModAsset.Desert_Scene_Close_lightUp.Value; + } + + List bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(otD.OriginTilePos.X, otD.OriginTilePos.Y, tex0, bars, flipH); + Ins.Batch.Draw(tex0, bars, PrimitiveType.TriangleList); + } + + public void DrawBackground(TwilightCastle_RoomScene_Background bg) + { + Texture2D tex0 = ModAsset.Desert_Scene_Background.Value; + Texture2D tex1 = ModAsset.Desert_Scene_Far.Value; + Texture2D tex2 = ModAsset.Desert_Scene_WallGemsReflection.Value; + + bool flipH = bg.FlipHorizontally(bg.OriginTilePos.X, bg.OriginTilePos.Y); + int direction = 1; + if (flipH) + { + direction = -1; + } + List bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(bg.OriginTilePos.X, bg.OriginTilePos.Y, tex0, bars, flipH); + Ins.Batch.Draw(tex0, bars, PrimitiveType.TriangleList); + + bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(bg.OriginTilePos.X, bg.OriginTilePos.Y, tex1, bars, flipH); + Ins.Batch.Draw(tex1, bars, PrimitiveType.TriangleList); + + bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(bg.OriginTilePos.X + 34 * direction, bg.OriginTilePos.Y + 11, tex2, bars, flipH, 2.6f); + Ins.Batch.Draw(tex2, bars, PrimitiveType.TriangleList); + } + + public override void NearbyEffects(int i, int j, bool closer) + { + if (!Main.gamePaused) + { + bool flipH = FlipHorizontally(i, j); + int direction = 1; + if (flipH) + { + direction = -1; + } + if (Main.rand.NextBool(160)) + { + var spark = new Desert_Scene_WallGemsSpark { Position = new Vector2(i, j) * 16 + new Vector2(575 * direction, 209) + new Vector2(Main.rand.NextFloat(13), Main.rand.NextFloat(13)), Active = true, Visible = true, Frame = new Rectangle(0, Main.rand.Next(3) * 14, 14, 14), Scale = Main.rand.NextFloat(0.75f, 1.25f), Color = new Color(0f, 1f, 0.4f), MaxTime = 20, Fade = Main.rand.NextFloat(0.25f, 0.75f) }; + Ins.VFXManager.Add(spark); + } + for (int k = 0; k < 8; k++) + { + if (Main.rand.NextBool(480)) + { + Vector2 offset = new Vector2(22, 0).RotatedBy(k / 8f * MathHelper.TwoPi); + Color color = new Color(1f, 0f, 0.1f); + if (k % 2 == 1) + { + color = new Color(0f, 0f, 1f); + } + var spark = new Desert_Scene_WallGemsSpark { Position = new Vector2(i, j) * 16 + new Vector2(575 * direction, 209) + offset + new Vector2(Main.rand.NextFloat(13), Main.rand.NextFloat(13)), Active = true, Visible = true, Frame = new Rectangle(0, Main.rand.Next(3) * 14, 14, 14), Scale = Main.rand.NextFloat(0.75f, 1.25f), Color = color, MaxTime = 20, Fade = Main.rand.NextFloat(0.25f, 0.75f) }; + Ins.VFXManager.Add(spark); + } + } + } + base.NearbyEffects(i, j, closer); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_Background.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_Background.png new file mode 100644 index 000000000..acad0aa9a Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_Background.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_Close.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_Close.png new file mode 100644 index 000000000..987085487 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_Close.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_Close_lightUp.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_Close_lightUp.png new file mode 100644 index 000000000..2c844afb9 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_Close_lightUp.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_Far.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_Far.png new file mode 100644 index 000000000..5d14753f1 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_Far.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_WallGemsReflection.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_WallGemsReflection.png new file mode 100644 index 000000000..6619df080 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_WallGemsReflection.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_WallGemsSpark.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_WallGemsSpark.cs new file mode 100644 index 000000000..89b93874b --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_WallGemsSpark.cs @@ -0,0 +1,58 @@ +using Everglow.Commons.VFX.Scene; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +[Pipeline(typeof(WCSPipeline))] +public class Desert_Scene_WallGemsSpark : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawDusts; + + public Vector2 Position; + + public float Scale; + + public float Timer; + + public float MaxTime; + + public float Fade; + + public Color Color; + + public Rectangle Frame; + + public override void OnSpawn() + { + if (Collision.IsWorldPointSolid(Position)) + { + Kill(); + return; + } + } + + public override void Update() + { + Timer++; + if (Timer >= MaxTime) + { + Kill(); + return; + } + float duration = Timer / MaxTime; + Lighting.AddLight(Position, Color.ToVector3() * (1 - duration) * 0.3f); + } + + public override void Draw() + { + Texture2D tex = ModAsset.Desert_Scene_WallGemsSpark.Value; + Color drawColor = Color.Lerp(Color, Color.White, 0.3f); + drawColor.A = 0; + float duration = Timer / MaxTime; + Frame.X = 0; + if (duration > 0.5f) + { + Frame.X = 14; + } + Ins.Batch.Draw(tex, Position, Frame, drawColor * Fade, 0, Frame.Size() * 0.5f, Scale, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_WallGemsSpark.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_WallGemsSpark.png new file mode 100644 index 000000000..dee070834 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/Desert_Scene_WallGemsSpark.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DragonChest_DarkDragonRoom.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DragonChest_DarkDragonRoom.cs new file mode 100644 index 000000000..55cf481be --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DragonChest_DarkDragonRoom.cs @@ -0,0 +1,183 @@ +using Everglow.Yggdrasil.YggdrasilTown.Dusts; +using Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.TwilightForest; +using Terraria; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.GameContent.ObjectInteractions; +using Terraria.Localization; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class DragonChest_DarkDragonRoom : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileSpelunker[Type] = true; + Main.tileContainer[Type] = true; + Main.tileFrameImportant[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileOreFinderPriority[Type] = 500; + TileID.Sets.HasOutlines[Type] = true; + TileID.Sets.BasicChest[Type] = true; + TileID.Sets.DisableSmartCursor[Type] = true; + TileID.Sets.AvoidedByNPCs[Type] = true; + TileID.Sets.InteractibleByNPCs[Type] = true; + TileID.Sets.IsAContainer[Type] = true; + TileID.Sets.FriendlyFairyCanLureTo[Type] = true; + + DustType = ModContent.DustType(); + AdjTiles = new int[] { TileID.Containers }; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style2x2); + TileObjectData.newTile.Origin = new Point16(0, 1); + TileObjectData.newTile.CoordinateHeights = new[] { 16, 18 }; + TileObjectData.newTile.HookCheckIfCanPlace = new PlacementHook(Chest.FindEmptyChest, -1, 0, true); + TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(Chest.AfterPlacement_Hook, -1, 0, false); + TileObjectData.newTile.AnchorInvalidTiles = new int[] + { + TileID.MagicalIceBlock, + TileID.Boulder, + TileID.BouncyBoulder, + TileID.LifeCrystalBoulder, + TileID.RollingCactus, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.SolidTile | AnchorType.SolidWithTop | AnchorType.SolidSide, TileObjectData.newTile.Width, 0); + TileObjectData.addTile(Type); + AddMapEntry(new Color(127, 96, 104)); + } + + public override ushort GetMapOption(int i, int j) + { + return (ushort)(Main.tile[i, j].TileFrameX / 36); + } + + public override LocalizedText DefaultContainerName(int frameX, int frameY) + { + int option = frameX / 36; + return this.GetLocalization("MapEntry" + option); + } + + public override bool HasSmartInteract(int i, int j, SmartInteractScanSettings settings) + { + return true; + } + + public static string MapChestName(string name, int i, int j) + { + int left = i; + int top = j; + Tile tile = Main.tile[i, j]; + if (tile.TileFrameX % 36 != 0) + { + left--; + } + + if (tile.TileFrameY != 0) + { + top--; + } + + int chest = Chest.FindChest(left, top); + if (chest < 0) + { + return Language.GetTextValue("LegacyChestType.0"); + } + + if (Main.chest[chest].name == string.Empty) + { + return name; + } + + return name + ": " + Main.chest[chest].name; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 1; + } + + public override bool RightClick(int i, int j) + { + return FurnitureUtils.ChestRightClick(i, j); + } + + public override void MouseOver(int i, int j) + { + Player player = Main.LocalPlayer; + Tile tile = Main.tile[i, j]; + int left = i; + int top = j; + if (tile.TileFrameX % 36 != 0) + { + left--; + } + + if (tile.TileFrameY != 0) + { + top--; + } + + int chest = Chest.FindChest(left, top); + player.cursorItemIconID = -1; + if (chest < 0) + { + player.cursorItemIconText = Language.GetTextValue("LegacyChestType.0"); + } + else + { + string defaultName = TileLoader.DefaultContainerName(tile.TileType, tile.TileFrameX, tile.TileFrameY); // This gets the ContainerName text for the currently selected language + player.cursorItemIconText = Main.chest[chest].name.Length > 0 ? Main.chest[chest].name : defaultName; + if (player.cursorItemIconText == defaultName) + { + player.cursorItemIconID = ModContent.ItemType(); + if (Main.tile[left, top].TileFrameX / 36 == 1) + { + // player.cursorItemIconID = ModContent.ItemType<>(); + } + + player.cursorItemIconText = string.Empty; + } + } + + player.noThrow = 2; + player.cursorItemIconEnabled = true; + } + + public override void MouseOverFar(int i, int j) + { + MouseOver(i, j); + Player player = Main.LocalPlayer; + if (player.cursorItemIconText == string.Empty) + { + player.cursorItemIconEnabled = false; + player.cursorItemIconID = ItemID.None; + } + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + base.PostDraw(i, j, spriteBatch); + Tile tile = Main.tile[i, j]; + int left = i - tile.TileFrameX / 18; + int top = j - tile.TileFrameY / 18; + int chestIndex = Chest.FindChest(left, top); + if (chestIndex >= 0) + { + Chest chest = Main.chest[chestIndex]; + var zero = new Vector2(Main.offScreenRange, Main.offScreenRange); + if (Main.drawToScreen) + { + zero = Vector2.Zero; + } + var texture = ModAsset.DragonChest_DarkDragonRoom_glow.Value; + spriteBatch.Draw(texture, new Vector2(i, j) * 16 - Main.screenPosition + zero, new Rectangle(tile.TileFrameX, tile.TileFrameY + chest.frame * 38, 16, 16), new Color(1f, 1f, 1f, 1f), 0, Vector2.zeroVector, 1, SpriteEffects.None, 0); + if (chest.frame > 0) + { + Lighting.AddLight(i, j, 1.8f * chest.frame, 0.5f * chest.frame, 0.2f * chest.frame); + } + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DragonChest_DarkDragonRoom.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DragonChest_DarkDragonRoom.png new file mode 100644 index 000000000..41e293b27 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DragonChest_DarkDragonRoom.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DragonChest_DarkDragonRoom_Highlight.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DragonChest_DarkDragonRoom_Highlight.png new file mode 100644 index 000000000..6f1aac62d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DragonChest_DarkDragonRoom_Highlight.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DragonChest_DarkDragonRoom_glow.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DragonChest_DarkDragonRoom_glow.png new file mode 100644 index 000000000..fd010d331 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/DragonChest_DarkDragonRoom_glow.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene.cs new file mode 100644 index 000000000..5169eacc3 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene.cs @@ -0,0 +1,122 @@ +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.YggdrasilTown.Dusts.TwilightForest; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.LampWood; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class ForestCastle_Scene : ModTile, ISceneTile +{ + public override string Texture => ModAsset.GreenRelicBrick_Mod; + + public override void SetStaticDefaults() + { + Main.tileSolid[Type] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[ModContent.TileType()][Type] = true; + Main.tileBlockLight[Type] = true; + DustType = ModContent.DustType(); + HitSound = SoundID.Dig; + MinPick = int.MaxValue; + AddMapEntry(new Color(35, 58, 58)); + } + + public override bool CanKillTile(int i, int j, ref bool blockDamaged) => false; + + public override bool CanExplode(int i, int j) + { + return false; + } + + public bool FlipHorizontally(int i, int j) + { + int leftSolid = 0; + int rightSolid = 0; + for (int x = 1; x < 15; x++) + { + Tile tileLeft = TileUtils.SafeGetTile(i - x, j); + Tile tileRight = TileUtils.SafeGetTile(i + x, j); + if (tileLeft.HasTile && tileLeft.TileType == ModContent.TileType()) + { + leftSolid++; + } + if (tileRight.HasTile && tileRight.TileType == ModContent.TileType()) + { + rightSolid++; + } + } + if (rightSolid > leftSolid) + { + return false; + } + return true; + } + + public void AddScene(int i, int j) + { + var scene_Close = new TwilightCastle_RoomScene_OverTiles { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type, Texture = ModAsset.ForestCastle_Scene_Close.Value }; + scene_Close.CustomDraw += DrawForestCastleOverTile; + var scene_Background = new TwilightCastle_RoomScene_Background { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type, Texture = ModAsset.ForestCastle_Scene_Background.Value }; + scene_Background.CustomDraw += DrawForestCastleBackground; + + AddFern(i, j, ModAsset.ForestCastle_Scene_Fern0.Value, new Vector2(528, 16)); + AddFern(i, j, ModAsset.ForestCastle_Scene_Fern1.Value, new Vector2(492, 14)); + AddFern(i, j, ModAsset.ForestCastle_Scene_Fern2.Value, new Vector2(512, 16)); + AddFern(i, j, ModAsset.ForestCastle_Scene_Fern3.Value, new Vector2(482, 14)); + AddFern(i, j, ModAsset.ForestCastle_Scene_Fern4.Value, new Vector2(544, 16)); + AddFern(i, j, ModAsset.ForestCastle_Scene_Fern5.Value, new Vector2(558, 16)); + AddFern(i, j, ModAsset.ForestCastle_Scene_Fern6.Value, new Vector2(570, 16)); + AddFern(i, j, ModAsset.ForestCastle_Scene_Fern7.Value, new Vector2(582, 52)); + AddFern(i, j, ModAsset.ForestCastle_Scene_Fern8.Value, new Vector2(588, 102)); + + Ins.VFXManager.Add(scene_Close); + Ins.VFXManager.Add(scene_Background); + } + + public void AddFern(int i, int j, Texture2D texture, Vector2 offset) + { + bool flip_H = FlipHorizontally(i, j); + Vector2 anchor = offset + new Vector2(-16, -8); + if (flip_H) + { + anchor.X = -offset.X; + } + var flag_Scene = new FlagLikeVFX { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type, Texture = texture, AnchorOffset = anchor, Flip_H = flip_H }; + Ins.VFXManager.Add(flag_Scene); + } + + public void DrawForestCastleOverTile(TwilightCastle_RoomScene_OverTiles otD) + { + Texture2D tex0 = ModAsset.ForestCastle_Scene_Close.Value; + + bool flipH = otD.FlipHorizontally(otD.OriginTilePos.X, otD.OriginTilePos.Y); + List bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(otD.OriginTilePos.X, otD.OriginTilePos.Y, tex0, bars, flipH); + Ins.Batch.Draw(tex0, bars, PrimitiveType.TriangleList); + } + + public void DrawForestCastleBackground(TwilightCastle_RoomScene_Background bg) + { + Texture2D tex0 = ModAsset.ForestCastle_Scene_Background.Value; + Texture2D tex1 = ModAsset.ForestCastle_Scene_Middle.Value; + + bool flipH = bg.FlipHorizontally(bg.OriginTilePos.X, bg.OriginTilePos.Y); + List bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(bg.OriginTilePos.X, bg.OriginTilePos.Y, tex0, bars, flipH); + Ins.Batch.Draw(tex0, bars, PrimitiveType.TriangleList); + + bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(bg.OriginTilePos.X, bg.OriginTilePos.Y, tex1, bars, flipH); + Ins.Batch.Draw(tex1, bars, PrimitiveType.TriangleList); + + Texture2D texFern0 = Commons.ModAsset.TileBlock3x3.Value; // ;ModAsset.ForestCastle_Scene_Fern0.Value; + Texture2D texFern1 = ModAsset.ForestCastle_Scene_Fern1.Value; + } + + public override void NearbyEffects(int i, int j, bool closer) + { + base.NearbyEffects(i, j, closer); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Background.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Background.png new file mode 100644 index 000000000..22701d70f Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Background.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Close.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Close.png new file mode 100644 index 000000000..a37780646 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Close.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern0.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern0.png new file mode 100644 index 000000000..0a8d88c19 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern0.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern1.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern1.png new file mode 100644 index 000000000..c6b7de9d1 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern1.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern2.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern2.png new file mode 100644 index 000000000..f4dd85615 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern2.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern3.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern3.png new file mode 100644 index 000000000..3edec4add Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern3.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern4.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern4.png new file mode 100644 index 000000000..9d4ec5f22 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern4.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern5.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern5.png new file mode 100644 index 000000000..ae6f46e3b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern5.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern6.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern6.png new file mode 100644 index 000000000..142ca1e47 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern6.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern7.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern7.png new file mode 100644 index 000000000..8a2848925 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern7.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern8.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern8.png new file mode 100644 index 000000000..4d2a3c664 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Fern8.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Middle.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Middle.png new file mode 100644 index 000000000..9821d217f Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/ForestCastle_Scene_Middle.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/GenerateSplash.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/GenerateSplash.cs new file mode 100644 index 000000000..e326152ae --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/GenerateSplash.cs @@ -0,0 +1,22 @@ +using Everglow.Commons.VFX.Scene; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class GenerateSplash : ModDust +{ + public override string Texture => Commons.ModAsset.Empty_Mod; + + public override void OnSpawn(Dust dust) + { + } + + public override bool Update(Dust dust) + { + if (dust.customData is Visual) + { + Ins.VFXManager.Add(dust.customData as Visual); + } + dust.active = false; + return base.Update(dust); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/RubyDarkGoldChest_BloodyChurch.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/RubyDarkGoldChest_BloodyChurch.cs new file mode 100644 index 000000000..5eb44f128 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/RubyDarkGoldChest_BloodyChurch.cs @@ -0,0 +1,170 @@ +using Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.TwilightForest; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.GameContent.ObjectInteractions; +using Terraria.Localization; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class RubyDarkGoldChest_BloodyChurch : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileSpelunker[Type] = true; + Main.tileContainer[Type] = true; + Main.tileFrameImportant[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileOreFinderPriority[Type] = 500; + Main.tileLighted[Type] = true; + TileID.Sets.HasOutlines[Type] = true; + TileID.Sets.BasicChest[Type] = true; + TileID.Sets.DisableSmartCursor[Type] = true; + TileID.Sets.AvoidedByNPCs[Type] = true; + TileID.Sets.InteractibleByNPCs[Type] = true; + TileID.Sets.IsAContainer[Type] = true; + TileID.Sets.FriendlyFairyCanLureTo[Type] = true; + + DustType = DustID.Gold; + AdjTiles = new int[] { TileID.Containers }; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style2x2); + TileObjectData.newTile.Origin = new Point16(0, 1); + TileObjectData.newTile.CoordinateHeights = new[] { 16, 18 }; + TileObjectData.newTile.HookCheckIfCanPlace = new PlacementHook(Chest.FindEmptyChest, -1, 0, true); + TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(Chest.AfterPlacement_Hook, -1, 0, false); + TileObjectData.newTile.AnchorInvalidTiles = new int[] + { + TileID.MagicalIceBlock, + TileID.Boulder, + TileID.BouncyBoulder, + TileID.LifeCrystalBoulder, + TileID.RollingCactus, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.SolidTile | AnchorType.SolidWithTop | AnchorType.SolidSide, TileObjectData.newTile.Width, 0); + TileObjectData.addTile(Type); + AddMapEntry(new Color(127, 96, 104)); + } + + public override ushort GetMapOption(int i, int j) + { + return (ushort)(Main.tile[i, j].TileFrameX / 36); + } + + public override LocalizedText DefaultContainerName(int frameX, int frameY) + { + int option = frameX / 36; + return this.GetLocalization("MapEntry" + option); + } + + public override bool HasSmartInteract(int i, int j, SmartInteractScanSettings settings) + { + return true; + } + + public static string MapChestName(string name, int i, int j) + { + int left = i; + int top = j; + Tile tile = Main.tile[i, j]; + if (tile.TileFrameX % 36 != 0) + { + left--; + } + + if (tile.TileFrameY != 0) + { + top--; + } + + int chest = Chest.FindChest(left, top); + if (chest < 0) + { + return Language.GetTextValue("LegacyChestType.0"); + } + + if (Main.chest[chest].name == string.Empty) + { + return name; + } + + return name + ": " + Main.chest[chest].name; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 1; + } + + public override bool RightClick(int i, int j) + { + return FurnitureUtils.ChestRightClick(i, j); + } + + public override void MouseOver(int i, int j) + { + Player player = Main.LocalPlayer; + Tile tile = Main.tile[i, j]; + int left = i; + int top = j; + if (tile.TileFrameX % 36 != 0) + { + left--; + } + + if (tile.TileFrameY != 0) + { + top--; + } + + int chest = Chest.FindChest(left, top); + player.cursorItemIconID = -1; + if (chest < 0) + { + player.cursorItemIconText = Language.GetTextValue("LegacyChestType.0"); + } + else + { + string defaultName = TileLoader.DefaultContainerName(tile.TileType, tile.TileFrameX, tile.TileFrameY); // This gets the ContainerName text for the currently selected language + player.cursorItemIconText = Main.chest[chest].name.Length > 0 ? Main.chest[chest].name : defaultName; + if (player.cursorItemIconText == defaultName) + { + player.cursorItemIconID = ModContent.ItemType(); + if (Main.tile[left, top].TileFrameX / 36 == 1) + { + // player.cursorItemIconID = ModContent.ItemType<>(); + } + + player.cursorItemIconText = string.Empty; + } + } + + player.noThrow = 2; + player.cursorItemIconEnabled = true; + } + + public override void MouseOverFar(int i, int j) + { + MouseOver(i, j); + Player player = Main.LocalPlayer; + if (player.cursorItemIconText == string.Empty) + { + player.cursorItemIconEnabled = false; + player.cursorItemIconID = ItemID.None; + } + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + base.PostDraw(i, j, spriteBatch); + } + + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + r = 2.000f; + g = 0f; + b = 0.400f; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/RubyDarkGoldChest_BloodyChurch.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/RubyDarkGoldChest_BloodyChurch.png new file mode 100644 index 000000000..bc6aef27e Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/RubyDarkGoldChest_BloodyChurch.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/RubyDarkGoldChest_BloodyChurch_Highlight.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/RubyDarkGoldChest_BloodyChurch_Highlight.png new file mode 100644 index 000000000..0858e7adf Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/RubyDarkGoldChest_BloodyChurch_Highlight.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/SandgoldLantern.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/SandgoldLantern.cs new file mode 100644 index 000000000..1e8856008 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/SandgoldLantern.cs @@ -0,0 +1,75 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.YggdrasilTown.Dusts.TwilightForest; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.GameContent.Drawing; +using Terraria.Localization; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class SandgoldLantern : ModTile, ITileFluentlyDrawn +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileLavaDeath[Type] = true; + Main.tileLighted[Type] = true; + Main.tileSolid[Type] = false; + Main.tileNoFail[Type] = true; + + AddToArray(ref TileID.Sets.RoomNeeds.CountsAsTorch); + AdjTiles = new int[] { TileID.HangingLanterns }; + + // Placement + TileObjectData.newTile.CopyFrom(TileObjectData.Style1x2Top); + TileObjectData.newTile.DrawYOffset = -2; + TileObjectData.newAlternate.CopyFrom(TileObjectData.newTile); + TileObjectData.newAlternate.DrawYOffset = -10; + TileObjectData.newAlternate.AnchorTop = new AnchorData(AnchorType.Platform, TileObjectData.newTile.Width, 0); + TileObjectData.addAlternate(0); + TileObjectData.addTile(Type); + + LocalizedText name = CreateMapEntryName(); + AddMapEntry(new Color(251, 235, 127), name); + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 0; + } + + public override void HitWire(int i, int j) + { + FurnitureUtils.LightHitwire(i, j, Type, 1, 2); + } + + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) + { + Tile tile = Main.tile[i, j]; + if (tile.TileFrameX < 18) + { + r = 0.900f; + g = 0.515f; + b = 0.300f; + } + else + { + r = 0f; + g = 0f; + b = 0f; + } + } + + public override bool PreDraw(int i, int j, SpriteBatch spriteBatch) + { + TileFluentDrawManager.AddFluentPoint(this, i, j); + return false; + } + + public void FluentDraw(Vector2 screenPosition, Point pos, SpriteBatch spriteBatch, TileDrawing tileDrawing) + { + FurnitureUtils.LanternFluentDraw(screenPosition, pos, spriteBatch, tileDrawing); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/SandgoldLantern.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/SandgoldLantern.png new file mode 100644 index 000000000..6a9b5786a Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/SandgoldLantern.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/StoneCave_Scene.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/StoneCave_Scene.cs new file mode 100644 index 000000000..f2b0cb021 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/StoneCave_Scene.cs @@ -0,0 +1,68 @@ +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.YggdrasilTown.Dusts.TwilightForest; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.LampWood; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class StoneCave_Scene : ModTile, ISceneTile +{ + public override string Texture => ModAsset.GreenRelicBrick_Mod; + + public override void SetStaticDefaults() + { + Main.tileSolid[Type] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[ModContent.TileType()][Type] = true; + Main.tileBlockLight[Type] = true; + DustType = ModContent.DustType(); + HitSound = SoundID.Dig; + MinPick = int.MaxValue; + AddMapEntry(new Color(35, 58, 58)); + } + + public override bool CanKillTile(int i, int j, ref bool blockDamaged) => false; + + public override bool CanExplode(int i, int j) + { + return false; + } + + public void AddScene(int i, int j) + { + var scene_Close = new TwilightCastle_RoomScene_OverTiles { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type, Texture = ModAsset.StoneCave_Scene_Close.Value }; + scene_Close.CustomDraw += DrawStoneCaveOverTile; + var scene_Background = new TwilightCastle_RoomScene_Background { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type, Texture = ModAsset.StoneCave_Scene_Background.Value }; + scene_Background.CustomDraw += DrawStoneCaveBackground; + + Ins.VFXManager.Add(scene_Close); + Ins.VFXManager.Add(scene_Background); + } + + public void DrawStoneCaveOverTile(TwilightCastle_RoomScene_OverTiles otD) + { + Texture2D tex0 = ModAsset.StoneCave_Scene_Close.Value; + + bool flipH = otD.FlipHorizontally(otD.OriginTilePos.X, otD.OriginTilePos.Y); + List bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(otD.OriginTilePos.X, otD.OriginTilePos.Y, tex0, bars, flipH); + Ins.Batch.Draw(tex0, bars, PrimitiveType.TriangleList); + } + + public void DrawStoneCaveBackground(TwilightCastle_RoomScene_Background bg) + { + Texture2D tex0 = ModAsset.StoneCave_Scene_Background.Value; + Texture2D tex1 = ModAsset.StoneCave_Scene_Far.Value; + + bool flipH = bg.FlipHorizontally(bg.OriginTilePos.X, bg.OriginTilePos.Y); + List bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(bg.OriginTilePos.X, bg.OriginTilePos.Y, tex0, bars, flipH); + Ins.Batch.Draw(tex0, bars, PrimitiveType.TriangleList); + + bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(bg.OriginTilePos.X, bg.OriginTilePos.Y, tex1, bars, flipH); + Ins.Batch.Draw(tex1, bars, PrimitiveType.TriangleList); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/StoneCave_Scene_Background.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/StoneCave_Scene_Background.png new file mode 100644 index 000000000..1c43dc23c Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/StoneCave_Scene_Background.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/StoneCave_Scene_Close.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/StoneCave_Scene_Close.png new file mode 100644 index 000000000..7f83c0708 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/StoneCave_Scene_Close.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/StoneCave_Scene_Far.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/StoneCave_Scene_Far.png new file mode 100644 index 000000000..1d19596ab Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/StoneCave_Scene_Far.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/TwilightCastle_RoomScene_Background.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/TwilightCastle_RoomScene_Background.cs new file mode 100644 index 000000000..c9cd9da79 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/TwilightCastle_RoomScene_Background.cs @@ -0,0 +1,69 @@ +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.WorldGeneration; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +[Pipeline(typeof(WCSPipeline_PointWrap))] +public class TwilightCastle_RoomScene_Background : TileVFX +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawBG; + + public bool FlipHorizontally(int i, int j) + { + int leftSolid = 0; + int rightSolid = 0; + for (int x = 1; x < 15; x++) + { + Tile tileLeft = TileUtils.SafeGetTile(i - x, j); + Tile tileRight = TileUtils.SafeGetTile(i + x, j); + if (tileLeft.HasTile && tileLeft.TileType == ModContent.TileType()) + { + leftSolid++; + } + if (tileRight.HasTile && tileRight.TileType == ModContent.TileType()) + { + rightSolid++; + } + } + if (rightSolid > leftSolid) + { + return false; + } + return true; + } + + public Point Offset = new Point(0, 0); + + /// + /// Allow to make a custon draw for this vfx. + /// + public delegate void CustomDrawVFX(TwilightCastle_RoomScene_Background backgrouond); + + public event CustomDrawVFX CustomDraw; + + public override void OnSpawn() + { + MaxDiatanceOutOfScreen = Main.screenWidth / 2f; + } + + public override void Draw() + { + CustomDraw?.Invoke(this); + } + + public override void Kill() + { + UnregisterCustomDraw(CustomDraw); + base.Kill(); + } + + public void RegisterCustomLogic(CustomDrawVFX customDraw) + { + CustomDraw += customDraw; + } + + public void UnregisterCustomDraw(CustomDrawVFX customDraw) + { + CustomDraw -= customDraw; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/TwilightCastle_RoomScene_OverTiles.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/TwilightCastle_RoomScene_OverTiles.cs new file mode 100644 index 000000000..c7d711af3 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/TwilightCastle_RoomScene_OverTiles.cs @@ -0,0 +1,69 @@ +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.WorldGeneration; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +[Pipeline(typeof(WCSPipeline))] +public class TwilightCastle_RoomScene_OverTiles : TileVFX +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawTiles; + + public Point Offset = new Point(0, 0); + + public bool FlipHorizontally(int i, int j) + { + int leftSolid = 0; + int rightSolid = 0; + for (int x = 1; x < 15; x++) + { + Tile tileLeft = TileUtils.SafeGetTile(i - x, j); + Tile tileRight = TileUtils.SafeGetTile(i + x, j); + if (tileLeft.HasTile && tileLeft.TileType == ModContent.TileType()) + { + leftSolid++; + } + if (tileRight.HasTile && tileRight.TileType == ModContent.TileType()) + { + rightSolid++; + } + } + if (rightSolid > leftSolid) + { + return false; + } + return true; + } + + /// + /// Allow to make a custon draw for this vfx. + /// + public delegate void CustomDrawVFX(TwilightCastle_RoomScene_OverTiles overtileDraw); + + public event CustomDrawVFX CustomDraw; + + public override void OnSpawn() + { + MaxDiatanceOutOfScreen = Main.screenWidth / 2f; + } + + public override void Draw() + { + CustomDraw?.Invoke(this); + } + + public override void Kill() + { + UnregisterCustomDraw(CustomDraw); + base.Kill(); + } + + public void RegisterCustomLogic(CustomDrawVFX customDraw) + { + CustomDraw += customDraw; + } + + public void UnregisterCustomDraw(CustomDrawVFX customDraw) + { + CustomDraw -= customDraw; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Liquid_Scene.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Liquid_Scene.cs new file mode 100644 index 000000000..7f993ac05 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Liquid_Scene.cs @@ -0,0 +1,546 @@ +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.WorldGeneration; +using Everglow.Yggdrasil.YggdrasilTown.Dusts; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +[Pipeline(typeof(WCSPipeline_PointWrap))] +public class WaterSluice_Liquid_Scene : TileVFX +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; + + public bool FlipHorizontally(int i, int j) + { + int leftSolid = 0; + int rightSolid = 0; + for (int x = 1; x < 15; x++) + { + Tile tileLeft = TileUtils.SafeGetTile(i - x, j); + Tile tileRight = TileUtils.SafeGetTile(i + x, j); + if (tileLeft.HasTile && tileLeft.TileType == ModContent.TileType()) + { + leftSolid++; + } + if (tileRight.HasTile && tileRight.TileType == ModContent.TileType()) + { + rightSolid++; + } + } + if (rightSolid > leftSolid) + { + return false; + } + return true; + } + + public override void Update() + { + base.Update(); + } + + public override void Draw() + { + bool flipH = FlipHorizontally(OriginTilePos.X, OriginTilePos.Y); + int Direction = 1; + if (flipH) + { + Direction = -1; + } + Vector2 liquidSurfacePos = new Vector2(OriginTilePos.X + 18 * Direction, OriginTilePos.Y + 6).ToWorldCoordinates() + new Vector2(0, 4); + DrawWaterPierThick(liquidSurfacePos, 0.7f); + liquidSurfacePos = new Vector2(OriginTilePos.X + 23 * Direction, OriginTilePos.Y + 7).ToWorldCoordinates() + new Vector2(0, 6); + DrawWaterPierThick(liquidSurfacePos, 0.4f); + liquidSurfacePos = new Vector2(OriginTilePos.X + 33 * Direction, OriginTilePos.Y + 7).ToWorldCoordinates() + new Vector2(1 * Direction, 0); + DrawWaterPierThin(liquidSurfacePos, 0.1f); + + // liquidSurfacePos = new Vector2(OriginTilePos.X + 34 * Direction, OriginTilePos.Y + 7).ToWorldCoordinates() + new Vector2(9 * Direction, 0); + // DrawWaterPierThin(liquidSurfacePos, 0.8f); + // liquidSurfacePos = new Vector2(OriginTilePos.X + 32 * Direction, OriginTilePos.Y + 7).ToWorldCoordinates() + new Vector2(-7 * Direction, 0); + // DrawWaterPierThin(liquidSurfacePos, 0.5f); + + // liquidSurfacePos = new Vector2(OriginTilePos.X + 33 * Direction, OriginTilePos.Y + 7).ToWorldCoordinates() + new Vector2(12 * Direction, 0); + // DrawWaterPierThinBack(liquidSurfacePos, 0.2f); + // liquidSurfacePos = new Vector2(OriginTilePos.X + 33 * Direction, OriginTilePos.Y + 7).ToWorldCoordinates() + new Vector2(-10 * Direction, 0); + // DrawWaterPierThinBack(liquidSurfacePos, 0.9f); + liquidSurfacePos = new Vector2(OriginTilePos.X + 6 * Direction, OriginTilePos.Y + 9).ToWorldCoordinates() + new Vector2(-2 * Direction, 0); + DrawWaterFallFlow(liquidSurfacePos, 0.6f); + } + + public void DrawWaterPierThinBack(Vector2 worldPos, float offsetY = 0) + { + // Texture2D liquidTex = ModAsset.WaterSluice_Scene_WaterPier_content.Value; + // Texture2D liquidTex_side = ModAsset.WaterSluice_Scene_WaterPier_side.Value; + // float timeValue = -(float)Main.time / 120f; + // List bars = new List(); + // List bars_side = new List(); + // List bars_wave = new List(); + // float fade0 = 0.3f; + // float fade = 0.1f; + // float fade2 = 0.002f; + // float waterWidth = 3; + // for (int i = 0; i < 300; i++) + // { + // Vector2 drawPos = worldPos + new Vector2(0, i * 2); + // var tile = TileUtils.SafeGetTile(drawPos.ToTileCoordinates()); + // float liquidCut = (16 - drawPos.Y % 16) * 16f; + // if ((Collision.IsWorldPointSolid(drawPos) && !Main.tileSolidTop[tile.TileType]) || tile.LiquidAmount > liquidCut) + // { + // GenerateWaterPierDust(worldPos, drawPos, 3, 0.3f, 0.25f, 0.1f); + // break; + // } + // float coordY = timeValue + MathF.Pow(i / 4f + 6, 0.5f) * 0.14f + offsetY; + // AddVertex(bars, drawPos + new Vector2(-waterWidth, 0), new Vector3(0, coordY, 0), fade); + // AddVertex(bars, drawPos + new Vector2(waterWidth, 0), new Vector3(1, coordY, 0), fade); + + // AddVertex(bars_wave, drawPos + new Vector2(-waterWidth, 0), new Vector3(0, coordY * 2.5f, 0), fade2); + // AddVertex(bars_wave, drawPos + new Vector2(waterWidth, 0), new Vector3(1, coordY * 2.5f, 0), fade2); + + // AddVertex(bars_side, drawPos + new Vector2(-waterWidth, 0), new Vector3(0, coordY, 0), fade0); + // AddVertex(bars_side, drawPos + new Vector2(waterWidth, 0), new Vector3(1, coordY, 0), fade0); + // } + // Ins.Batch.Draw(liquidTex, bars, PrimitiveType.TriangleStrip); + // Ins.Batch.Draw(Commons.ModAsset.Noise_flame_2_pure.Value, bars_wave, PrimitiveType.TriangleStrip); + // Ins.Batch.Draw(liquidTex_side, bars_side, PrimitiveType.TriangleStrip); + Texture2D liquidTex = ModAsset.WaterSluice_Scene_WaterPier_thin.Value; + float timeValue = -(float)Main.time / 120f; + List bars = new List(); + float fade = 0.1f; + for (int i = 0; i < 300; i++) + { + Vector2 drawPos = worldPos + new Vector2(0, i * 2); + var tile = TileUtils.SafeGetTile(drawPos.ToTileCoordinates()); + float liquidCut = (16 - drawPos.Y % 16) * 16f; + float waterWidth = 3; + if ((Collision.IsWorldPointSolid(drawPos) && !Main.tileSolidTop[tile.TileType]) || tile.LiquidAmount > liquidCut) + { + GenerateWaterPierDust(worldPos, drawPos, 3, 0.3f, 0.25f, 0.1f); + break; + } + float coordY = timeValue + MathF.Pow(i / 4f + 6, 0.5f) * 0.14f + offsetY; + AddVertex(bars, drawPos + new Vector2(-waterWidth, 0), new Vector3(0, coordY, 0), fade); + AddVertex(bars, drawPos + new Vector2(waterWidth, 0), new Vector3(1, coordY, 0), fade); + } + Ins.Batch.Draw(liquidTex, bars, PrimitiveType.TriangleStrip); + } + + public void DrawWaterPierThin(Vector2 worldPos, float offsetY = 0) + { + Texture2D liquidTex = ModAsset.WaterSluice_Scene_WaterPier_thin_batch.Value; + float timeValue = -(float)Main.time / 120f; + List bars = new List(); + float fade = 0.3f; + for (int i = 0; i < 300; i++) + { + Vector2 drawPos = worldPos + new Vector2(0, i * 2); + var tile = TileUtils.SafeGetTile(drawPos.ToTileCoordinates()); + float liquidCut = (16 - drawPos.Y % 16) * 16f; + float waterWidth = 29; + if ((Collision.IsWorldPointSolid(drawPos) && !Main.tileSolidTop[tile.TileType]) || tile.LiquidAmount > liquidCut) + { + Vector2 offsetWorld = new Vector2(-3, 0); + GenerateWaterPierDust(worldPos + new Vector2(26, 0) + offsetWorld, drawPos + new Vector2(26, 0), 3, 1f, 0.25f, 0.1f); + GenerateWaterPierDust(worldPos + new Vector2(10, 0) + offsetWorld, drawPos + new Vector2(10, 0), 3, 0.3f, 0.25f, 0.1f); + GenerateWaterPierDust(worldPos + offsetWorld, drawPos, 3, 1f, 0.25f, 0.1f); + GenerateWaterPierDust(worldPos + new Vector2(-10, 0) + offsetWorld, drawPos + new Vector2(-10, 0), 3, 0.3f, 0.25f, 0.1f); + GenerateWaterPierDust(worldPos + new Vector2(-26, 0) + offsetWorld, drawPos + new Vector2(-26, 0), 3, 1f, 0.25f, 0.1f); + break; + } + float coordY = timeValue + MathF.Pow(i / 4f + 6, 0.5f) * 0.14f + offsetY; + AddVertex(bars, drawPos + new Vector2(-waterWidth, 0), new Vector3(0, coordY, 0), fade); + AddVertex(bars, drawPos + new Vector2(waterWidth, 0), new Vector3(1, coordY, 0), fade); + } + Ins.Batch.Draw(liquidTex, bars, PrimitiveType.TriangleStrip); + } + + public void DrawWaterPierThick(Vector2 worldPos, float offsetY = 0) + { + Texture2D liquidTex = ModAsset.WaterSluice_Scene_WaterPier_content.Value; + Texture2D liquidTex_side = ModAsset.WaterSluice_Scene_WaterPier_side.Value; + float timeValue = -(float)Main.time / 120f; + List bars = new List(); + List bars_side = new List(); + List bars_wave = new List(); + float fade = 0.3f; + float fade2 = 0.06f; + float waterWidth = 10; + for (int i = 0; i < 300; i++) + { + Vector2 drawPos = worldPos + new Vector2(0, i * 2); + var tile = TileUtils.SafeGetTile(drawPos.ToTileCoordinates()); + float liquidCut = (16 - drawPos.Y % 16) * 16f; + if ((Collision.IsWorldPointSolid(drawPos) && !Main.tileSolidTop[tile.TileType]) || tile.LiquidAmount > liquidCut) + { + GenerateWaterPierDust(worldPos, drawPos, 10, 1f, 0.5f, 0.5f, 1f, 1f); + break; + } + float coordY = timeValue + MathF.Pow(i / 4f + 6, 0.5f) * 0.14f + offsetY; + AddVertex(bars, drawPos + new Vector2(-waterWidth, 0), new Vector3(0, coordY, 0), fade); + AddVertex(bars, drawPos + new Vector2(waterWidth, 0), new Vector3(1, coordY, 0), fade); + + AddVertex(bars_wave, drawPos + new Vector2(-waterWidth, 0), new Vector3(0, coordY * 2.5f, 0), fade2); + AddVertex(bars_wave, drawPos + new Vector2(waterWidth, 0), new Vector3(1, coordY * 2.5f, 0), fade2); + + AddVertex(bars_side, drawPos + new Vector2(-waterWidth, 0), new Vector3(0, coordY, 0)); + AddVertex(bars_side, drawPos + new Vector2(waterWidth, 0), new Vector3(1, coordY, 0)); + } + Ins.Batch.Draw(liquidTex, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Commons.ModAsset.Noise_flame_2_pure.Value, bars_wave, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(liquidTex_side, bars_side, PrimitiveType.TriangleStrip); + } + + public void DrawWaterFallFlow(Vector2 worldPos, float offsetY = 0) + { + Texture2D liquidTex = ModAsset.WaterSluice_Scene_WaterPier_content.Value; + Texture2D liquidTex_side = ModAsset.WaterSluice_Scene_Waterfall_side.Value; + float timeValue = -(float)Main.time / 120f; + bool flipH = FlipHorizontally(OriginTilePos.X, OriginTilePos.Y); + int Direction = 1; + if (flipH) + { + Direction = -1; + } + + // Legacy + // for (int i = 0; i < 14; i++) + // { + // List bars = new List(); + // List bars_side = new List(); + // List bars_wave = new List(); + // List bars_wave2 = new List(); + // float fade = 0.3f; + // float fade2 = 0.06f; + // float waterWidth = 2; + // for (int j = 0; j < 300; j++) + // { + // Vector2 drawPos = worldPos + new Vector2(i * 4 * Direction, j * 2); + // Vector2 offset0 = new Vector2(GetMove(i, j, 7) * Direction, 0); + // Vector2 offset1 = new Vector2(GetMove(i + 1, j, 7) * Direction, 0); + // if (Direction == -1) + // { + // (offset0, offset1) = (offset1, offset0); + // } + // var tile = TileUtils.SafeGetTile(drawPos.ToTileCoordinates()); + // float liquidCut = (16 - drawPos.Y % 16) * 16f; + // if ((Collision.IsWorldPointSolid(drawPos) && !Main.tileSolidTop[tile.TileType]) || tile.LiquidAmount > liquidCut) + // { + // GenerateWaterfallDust(worldPos + new Vector2(i * 4 * Direction, 0), drawPos + offset0, 4, 0.5f, i, 0.5f, 0.15f, 0.1f, 0.5f); + // break; + // } + // float coordY = timeValue + MathF.Pow(j / 4f + 0, 0.5f) * 0.14f + offsetY; + + // AddVertex(bars, drawPos + offset0 + new Vector2(-waterWidth, 0), new Vector3(0.5f, 0, 0), fade); + // AddVertex(bars, drawPos + offset1 + new Vector2(waterWidth, 0), new Vector3(0.5f, 0, 0), fade); + + // AddVertex(bars_wave, drawPos + offset0 + new Vector2(-waterWidth, 0), new Vector3(i / 14f, coordY * 2.5f, 0), fade2 - j * 0.0007f); + // AddVertex(bars_wave, drawPos + offset1 + new Vector2(waterWidth, 0), new Vector3((i + 1) / 14f, coordY * 2.5f, 0), fade2 - j * 0.0007f); + + // AddVertexTransparent(bars_wave2, drawPos + offset0 + new Vector2(-waterWidth, 0), new Vector3(i / 14f, coordY * 1f, 0), 0.2f); + // AddVertexTransparent(bars_wave2, drawPos + offset1 + new Vector2(waterWidth, 0), new Vector3((i + 1) / 14f, coordY * 1f, 0), 0.2f); + + // if (i == 0 || i == 13) + // { + // AddVertex(bars_side, drawPos + offset0 + new Vector2(-waterWidth, 0), new Vector3(i / 14f, 0.6f, 0), fade); + // AddVertex(bars_side, drawPos + offset1 + new Vector2(waterWidth, 0), new Vector3((i + 1) / 14f, 0.6f, 0), fade); + // } + // } + // if (bars.Count > 2) + // { + // Ins.Batch.Draw(liquidTex, bars, PrimitiveType.TriangleStrip); + // Ins.Batch.Draw(Commons.ModAsset.Noise_flame_2_pure.Value, bars_wave, PrimitiveType.TriangleStrip); + // Ins.Batch.Draw(Commons.ModAsset.Noise_WaterFallWave.Value, bars_wave2, PrimitiveType.TriangleStrip); + // } + // if (bars_side.Count > 2) + // { + // Ins.Batch.Draw(liquidTex_side, bars_side, PrimitiveType.TriangleStrip); + // } + // } + List bars = new List(); + List bars_side = new List(); + List bars_wave = new List(); + List bars_wave2 = new List(); + float fade = 0.3f; + float fade2 = 0.06f; + float waterWidth = 2; + for (int j = 0; j < 300; j++) + { + Vector2 drawPos0 = worldPos + new Vector2(14 * 4 * Direction, j * 2); + Vector2 drawPos1 = worldPos + new Vector2(-1 * 4 * Direction, j * 2); + Vector2 offset0 = new Vector2(GetMove(14, j, 7) * Direction, 0); + Vector2 offset1 = new Vector2(GetMove(0, j, 7) * Direction, 0); + if (Direction == -1) + { + (offset0, offset1) = (offset1, offset0); + (drawPos0, drawPos1) = (drawPos1, drawPos0); + } + var tile = TileUtils.SafeGetTile(drawPos0.ToTileCoordinates()); + float liquidCut = (16 - drawPos0.Y % 16) * 16f; + if ((Collision.IsWorldPointSolid(drawPos0) && !Main.tileSolidTop[tile.TileType]) || tile.LiquidAmount > liquidCut) + { + if (Direction == -1) + { + GenerateWaterfallDust(worldPos + new Vector2(0, 0), drawPos0 + offset0, 4, 0.5f, 7, 0.5f, 0f, 1f, 0f); + GenerateWaterfallDust(worldPos + new Vector2(0, 0), drawPos0 + offset0, 4, 0.5f, 7, 0.5f, 0.5f, 1f, 1f); + } + else + { + GenerateWaterfallDust(worldPos + new Vector2(0, 0), drawPos1 + offset1 + new Vector2(2, 0), 4, 0.5f, 7, 0.5f, 0f, 1f, 0f); + GenerateWaterfallDust(worldPos + new Vector2(0, 0), drawPos1 + offset1 + new Vector2(2, 0), 4, 0.5f, 7, 0.5f, 0.5f, 1f, 1f); + } + break; + } + float coordY = timeValue + MathF.Pow(j / 4f + 0, 0.5f) * 0.14f + offsetY; + + AddVertex(bars, drawPos0 + offset0 + new Vector2(-waterWidth, 0), new Vector3(0.5f, 0, 0), fade); + AddVertex(bars, drawPos1 + offset1 + new Vector2(waterWidth, 0), new Vector3(0.5f, 0, 0), fade); + + AddVertex(bars_wave, drawPos0 + offset0 + new Vector2(-waterWidth, 0), new Vector3(0, coordY * 2.5f, 0), fade2 - j * 0.0007f); + AddVertex(bars_wave, drawPos1 + offset1 + new Vector2(waterWidth, 0), new Vector3(1, coordY * 2.5f, 0), fade2 - j * 0.0007f); + + AddVertexTransparent(bars_wave2, drawPos0 + offset0 + new Vector2(-waterWidth, 0), new Vector3(0, coordY * 1f, 0), 0.2f); + AddVertexTransparent(bars_wave2, drawPos1 + offset1 + new Vector2(waterWidth, 0), new Vector3(1, coordY * 1f, 0), 0.2f); + + AddVertex(bars_side, drawPos0 + offset0 + new Vector2(-waterWidth, 0), new Vector3(0, 0.6f, 0), fade); + AddVertex(bars_side, drawPos1 + offset1 + new Vector2(waterWidth, 0), new Vector3(1, 0.6f, 0), fade); + } + if (bars.Count > 2) + { + Ins.Batch.Draw(liquidTex, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Commons.ModAsset.Noise_flame_2_pure.Value, bars_wave, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Commons.ModAsset.Noise_WaterFallWave.Value, bars_wave2, PrimitiveType.TriangleStrip); + } + if (bars_side.Count > 2) + { + Ins.Batch.Draw(liquidTex_side, bars_side, PrimitiveType.TriangleStrip); + } + } + + public float GetMove(int i, int j, float middle) + { + return (middle - i) * MathF.Pow(j, 0.5f) * 0.15f; + } + + public void GenerateWaterPierDust(Vector2 pierStartPos, Vector2 pierEndPos, float width, float fade, float fallingChance = 0.25f, float splashDustChance = 0.25f, float splashDustShockWaveChance = 0.5f, float bubbleChance = 0.5f) + { + if (!Main.gamePaused) + { + // splash dust + if (Main.rand.NextFloat() < splashDustChance) + { + Vector2 pos = new Vector2(pierEndPos.X + Main.rand.NextFloat(-width, width), pierEndPos.Y + Main.rand.NextFloat(-4, 0)); + Dust dust = Dust.NewDustPerfect(Position, ModContent.DustType(), Vector2.zeroVector); + var splash = new WaterSluice_Scene_Dust() + { + Position = pos, + Velocity = new Vector2(Main.rand.NextFloat(-1, 1), Main.rand.NextFloat(-2, -1)), + Fade = fade, + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + Timer = 0, + MaxTime = 150, + MaxPosY = pos.Y + 4, + Frame = new Rectangle(Main.rand.Next(4) * 10, 10 + Main.rand.Next(3) * 10, 10, 10), + Scale = Main.rand.NextFloat(0.25f, 0.4f), + Active = true, + Visible = true, + }; + dust.customData = splash; + if (Main.rand.NextFloat() < bubbleChance) + { + pos = new Vector2(pierEndPos.X + Main.rand.NextFloat(-width, width), pierEndPos.Y + 4); + Dust dust2 = Dust.NewDustPerfect(pos, ModContent.DustType()); + dust2.velocity *= 0.3f; + dust2.velocity.Y = Main.rand.NextFloat(0.5f, 2f); + dust2.scale = Main.rand.NextFloat(0.35f, 0.75f); + } + } + + // shock wave + if (Main.rand.NextFloat() < splashDustShockWaveChance) + { + Vector2 pos = new Vector2(pierEndPos.X + Main.rand.NextFloat(-width - 1, width + 1), pierEndPos.Y + Main.rand.NextFloat(-4, 0)); + Dust dust = Dust.NewDustPerfect(Position, ModContent.DustType(), Vector2.zeroVector); + var splash = new WaterSluice_Scene_shockwave() + { + Position = pos, + Fade = fade * Main.rand.NextFloat(0.75f, 1), + Timer = 0, + MaxTime = 12, + Frame = new Rectangle(0, Main.rand.Next(8) * 16, 8, 16), + Scale = width / 12f * Main.rand.NextFloat(0.75f, 1.25f), + Active = true, + Visible = true, + }; + dust.customData = splash; + } + + // falling dust + if (Main.rand.NextFloat() < fallingChance) + { + Vector2 pos = new Vector2(pierStartPos.X + Main.rand.NextFloat(-width, -(width - 2)), pierStartPos.Y + Main.rand.NextFloat(0, 0)); + Dust dust = Dust.NewDustPerfect(Position, ModContent.DustType(), Vector2.zeroVector); + var splash = new WaterSluice_Scene_Dust() + { + Position = pos, + Velocity = new Vector2(Main.rand.NextFloat(-0.2f, 0.1f), Main.rand.NextFloat(2, 2.5f)), + Fade = fade, + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + Timer = 0, + MaxTime = 150, + MaxPosY = pierEndPos.Y + 4, + Frame = new Rectangle(Main.rand.Next(4) * 10, 10 + Main.rand.Next(3) * 10, 10, 10), + Scale = Main.rand.NextFloat(0.35f, 0.6f) * width / 12f, + Active = true, + Visible = true, + }; + dust.customData = splash; + } + if (Main.rand.NextFloat() < fallingChance) + { + Vector2 pos = new Vector2(pierStartPos.X + Main.rand.NextFloat(width - 2, width), pierStartPos.Y + Main.rand.NextFloat(0, 0)); + Dust dust = Dust.NewDustPerfect(Position, ModContent.DustType(), Vector2.zeroVector); + var splash = new WaterSluice_Scene_Dust() + { + Position = pos, + Velocity = new Vector2(Main.rand.NextFloat(-0.1f, 0.2f), Main.rand.NextFloat(2, 2.5f)), + Fade = fade, + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + Timer = 0, + MaxTime = 150, + MaxPosY = pierEndPos.Y + 4, + Frame = new Rectangle(Main.rand.Next(4) * 10, 10 + Main.rand.Next(3) * 10, 10, 10), + Scale = Main.rand.NextFloat(0.35f, 0.6f), + Active = true, + Visible = true, + }; + dust.customData = splash; + } + } + } + + public void GenerateWaterfallDust(Vector2 waterfallStartPos, Vector2 waterfallEndPos, float width, float fade, float i, float fallingChance = 0.25f, float splashDustChance = 0.25f, float splashDustShockWaveChance = 0.5f, float bubbleChance = 0.5f) + { + if (!Main.gamePaused) + { + // splash dust + bool flipH = FlipHorizontally(OriginTilePos.X, OriginTilePos.Y); + int Direction = 1; + if (flipH) + { + Direction = -1; + } + if (Main.rand.NextFloat() < splashDustChance) + { + Vector2 pos = new Vector2(waterfallEndPos.X + Main.rand.NextFloat(0, 40) * Direction, waterfallEndPos.Y + Main.rand.NextFloat(-4, 0)); + Dust dust = Dust.NewDustPerfect(Position, ModContent.DustType(), Vector2.zeroVector); + var splash = new WaterSluice_Scene_Dust() + { + Position = pos, + Velocity = new Vector2(Main.rand.NextFloat(-1, 1), Main.rand.NextFloat(-3, -1)), + Fade = fade * Main.rand.NextFloat(0.75f, 1.5f), + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + Timer = 0, + MaxTime = 150, + MaxPosY = pos.Y + 4, + Frame = new Rectangle(Main.rand.Next(4) * 10, 10 + Main.rand.Next(3) * 10, 10, 10), + Scale = Main.rand.NextFloat(0.25f, 0.4f), + Active = true, + Visible = true, + }; + dust.customData = splash; + if (Main.rand.NextFloat() < bubbleChance) + { + pos = new Vector2(waterfallEndPos.X + Main.rand.NextFloat(0, 40) * Direction, waterfallEndPos.Y + 4); + Dust dust2 = Dust.NewDustPerfect(pos, ModContent.DustType()); + dust2.velocity *= 0.3f; + dust2.velocity.Y = Main.rand.NextFloat(0.5f, 2f); + dust2.scale = Main.rand.NextFloat(0.35f, 0.75f); + } + } + + // shock wave + if (Main.rand.NextFloat() < splashDustShockWaveChance) + { + Vector2 pos = new Vector2(waterfallEndPos.X + Main.rand.NextFloat(0, 40) * Direction, waterfallEndPos.Y + Main.rand.NextFloat(-4, -10)); + Dust dust = Dust.NewDustPerfect(Position, ModContent.DustType(), Vector2.zeroVector); + var splash = new WaterSluice_Scene_shockwave() + { + Position = pos, + Fade = fade, + Timer = 0, + MaxTime = 12, + Frame = new Rectangle(0, Main.rand.Next(8) * 16, 8, 16), + Scale = Main.rand.NextFloat(0.5f, 1.2f), + Active = true, + Visible = true, + }; + dust.customData = splash; + } + + // falling dust + if (Main.rand.NextFloat() < fallingChance) + { + Vector2 pos = new Vector2(waterfallStartPos.X + Main.rand.NextFloat(-2, 2), waterfallStartPos.Y + Main.rand.NextFloat(0, 4)); + Dust dust = Dust.NewDustPerfect(Position, ModContent.DustType(), Vector2.zeroVector); + var splash = new WaterSluice_Scene_Dust() + { + Position = pos, + Velocity = new Vector2(GetMove(0, 20, 7) * Direction * 0.03f, 0), + Fade = fade, + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + Timer = 0, + MaxTime = 150, + MaxPosY = waterfallEndPos.Y + 4, + Frame = new Rectangle(Main.rand.Next(4) * 10, 10 + Main.rand.Next(3) * 10, 10, 10), + Scale = Main.rand.NextFloat(0.35f, 0.6f), + Active = true, + Visible = true, + }; + dust.customData = splash; + } + + if (Main.rand.NextFloat() < fallingChance) + { + Vector2 pos = new Vector2(waterfallStartPos.X + 13 * 4 * Direction + Main.rand.NextFloat(-2, 2), waterfallStartPos.Y + Main.rand.NextFloat(0, 4)); + Dust dust = Dust.NewDustPerfect(Position, ModContent.DustType(), Vector2.zeroVector); + var splash = new WaterSluice_Scene_Dust() + { + Position = pos, + Velocity = new Vector2(GetMove(13, 20, 7) * Direction * 0.03f, 0), + Fade = fade, + Rotation = Main.rand.NextFloat(MathHelper.TwoPi), + Timer = 0, + MaxTime = 150, + MaxPosY = waterfallEndPos.Y + 4, + Frame = new Rectangle(Main.rand.Next(4) * 10, 10 + Main.rand.Next(3) * 10, 10, 10), + Scale = Main.rand.NextFloat(0.35f, 0.6f), + Active = true, + Visible = true, + }; + dust.customData = splash; + } + } + } + + public void AddVertex(List bars, Vector2 worldPos, Vector3 coord, float mulColor = 1) + { + bars.Add(worldPos, Lighting.GetColor(worldPos.ToTileCoordinates()) * mulColor, coord); + } + + public void AddVertexTransparent(List bars, Vector2 worldPos, Vector3 coord, float mulColor = 1) + { + Color drawColor = Lighting.GetColor(worldPos.ToTileCoordinates()) * mulColor; + drawColor.A = 0; + bars.Add(worldPos, drawColor, coord); + } + + public float GetRandomWave(float x) + { + float value = 0; + float timeValue = (float)Main.time * 0.06f; + for (int i = 0; i < 8; i++) + { + float rate = MathF.Pow(2, i); + value += MathF.Sin(x * rate + timeValue * rate * 0.5f) / rate; + } + return value; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene.cs new file mode 100644 index 000000000..c8c142059 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene.cs @@ -0,0 +1,186 @@ +using System.Reflection; +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.Common; +using Everglow.Yggdrasil.WorldGeneration; +using Everglow.Yggdrasil.YggdrasilTown.Dusts.TwilightForest; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.LampWood; +using MonoMod.Cil; +using Terraria.GameContent.Liquid; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class WaterSluice_Scene : ModTile, ISceneTile +{ + public override string Texture => ModAsset.GreenRelicBrick_Mod; + + public static List JungleWaterAreas = new List(); + + public override void Load() + { + On_WaterfallManager.DrawWaterfall_int_int_int_float_Vector2_Rectangle_Color_SpriteEffects += OnHook_ModifyWaterfallStyle; + Ins.HookManager.AddHook(typeof(LiquidRenderer).GetMethod(nameof(LiquidRenderer.DrawNormalLiquids), BindingFlags.Public | BindingFlags.Instance), ILHook_ModifyWaterStyle); + base.Load(); + } + + private static void OnHook_ModifyWaterfallStyle(On_WaterfallManager.orig_DrawWaterfall_int_int_int_float_Vector2_Rectangle_Color_SpriteEffects orig, WaterfallManager self, int waterfallType, int x, int y, float opacity, Vector2 Position, Rectangle sourceRect, Color color, SpriteEffects effects) + { + if (ModContent.GetInstance().WaterSluiceRoomCount > 0) + { + foreach (var box in JungleWaterAreas) + { + if (box.Contains(x, y)) + { + waterfallType = 4; + } + } + } + orig(self, waterfallType, x, y, opacity, Position, sourceRect, color, effects); + } + + private void ILHook_ModifyWaterStyle(ILContext il) + { + ILCursor cursor = new ILCursor(il); + if (cursor.TryGotoNext( + MoveType.After, + x => x.MatchLdarg2(), + x => x.MatchLdloc3(), + x => x.MatchLdloc(out _))) + { + cursor.Index++; + cursor.EmitLdloc(3); + cursor.EmitLdloc(4); + cursor.EmitLdloc(8); + cursor.EmitDelegate(CalculateWaterStyle); + cursor.EmitStloc(8); + } + } + + private int CalculateWaterStyle(int i, int j, int originStyle) + { + if (ModContent.GetInstance().WaterSluiceRoomCount > 0) + { + foreach (var box in JungleWaterAreas) + { + if (box.Contains(i, j)) + { + return WaterStyleID.Jungle; + } + } + } + return originStyle; + } + + public bool FlipHorizontally(int i, int j) + { + int leftSolid = 0; + int rightSolid = 0; + for (int x = 1; x < 15; x++) + { + Tile tileLeft = TileUtils.SafeGetTile(i - x, j); + Tile tileRight = TileUtils.SafeGetTile(i + x, j); + if (tileLeft.HasTile && tileLeft.TileType == ModContent.TileType()) + { + leftSolid++; + } + if (tileRight.HasTile && tileRight.TileType == ModContent.TileType()) + { + rightSolid++; + } + } + if (rightSolid > leftSolid) + { + return false; + } + return true; + } + + public override void SetStaticDefaults() + { + Main.tileSolid[Type] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[Type][ModContent.TileType()] = true; + + Main.tileMerge[Type][ModContent.TileType()] = true; + Main.tileMerge[ModContent.TileType()][Type] = true; + Main.tileBlockLight[Type] = true; + DustType = ModContent.DustType(); + HitSound = SoundID.Dig; + MinPick = int.MaxValue; + AddMapEntry(new Color(35, 58, 58)); + } + + public override bool CanKillTile(int i, int j, ref bool blockDamaged) => false; + + public override bool CanExplode(int i, int j) + { + return false; + } + + public void AddScene(int i, int j) + { + var scene_Close = new TwilightCastle_RoomScene_OverTiles { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; + scene_Close.CustomDraw += WaterSluiceOverTile; + var liquid = new WaterSluice_Liquid_Scene { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; + + Ins.VFXManager.Add(scene_Close); + Ins.VFXManager.Add(liquid); + } + + public void WaterSluiceOverTile(TwilightCastle_RoomScene_OverTiles otD) + { + bool flipH = otD.FlipHorizontally(otD.OriginTilePos.X, otD.OriginTilePos.Y); + Texture2D tex0 = ModAsset.WaterSluice_Scene_Close.Value; + + List bars = new List(); + SceneUtils.DrawMultiSceneTowardBottom(otD.OriginTilePos.X, otD.OriginTilePos.Y, tex0, bars, flipH); + Ins.Batch.Draw(tex0, bars, PrimitiveType.TriangleList); + } + + public float GetOffsetHorizontal(float x, float y, float middleX) + { + return -MathF.Sqrt(y) * (middleX - x); + } + + public override void NearbyEffects(int i, int j, bool closer) + { + if (JungleWaterAreas is null) + { + JungleWaterAreas = new List(); + } + Rectangle myArea = new Rectangle(i, j, 40, 21); + if (FlipHorizontally(i, j)) + { + myArea = new Rectangle(i - 39, j, 40, 21); + } + + if (!JungleWaterAreas.Contains(myArea)) + { + JungleWaterAreas.Add(myArea); + } + + for (int x = myArea.X; x < myArea.X + myArea.Width; x++) + { + for (int y = myArea.Y; y < myArea.Y + myArea.Height; y++) + { + var tile = TileUtils.SafeGetTile(x, y); + if (tile.LiquidType == LiquidID.Water && tile.LiquidAmount > 0) + { + Lighting.AddLight(x, y, 0.1f, 0.5f, 1f); + } + } + } + base.NearbyEffects(i, j, closer); + } + + public float GetRandomWave(float x) + { + float value = 0; + float timeValue = (float)Main.time * 0.06f; + for (int i = 0; i < 8; i++) + { + float rate = MathF.Pow(2, i); + value += MathF.Sin(x * rate + timeValue * rate * 0.5f) / rate; + } + return value; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_Close.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_Close.png new file mode 100644 index 000000000..2b6a83c5a Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_Close.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_Dust.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_Dust.cs new file mode 100644 index 000000000..45fd0f273 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_Dust.cs @@ -0,0 +1,63 @@ +using Everglow.Yggdrasil.WorldGeneration; +using Terraria; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +[Pipeline(typeof(WCSPipeline))] +public class WaterSluice_Scene_Dust : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawDusts; + + public Vector2 Position; + + public Vector2 Velocity; + + public float Scale; + + public float Timer; + + public float MaxTime; + + public float MaxPosY; + + public float Rotation; + + public float Fade; + + public Rectangle Frame; + + public override void OnSpawn() + { + var tile = TileUtils.SafeGetTile(Position.ToTileCoordinates()); + if (Collision.IsWorldPointSolid(Position) && !Main.tileSolidTop[tile.TileType]) + { + Kill(); + return; + } + } + + public override void Update() + { + Timer++; + if (Timer >= MaxTime) + { + Kill(); + return; + } + if (Position.Y > MaxPosY) + { + Kill(); + return; + } + + Position += Velocity; + Velocity += new Vector2(0, 0.15f); + } + + public override void Draw() + { + Texture2D tex = ModAsset.WaterSluice_Scene_Dust.Value; + Color drawColor = Lighting.GetColor(Position.ToTileCoordinates()) * 0.5f; + Ins.Batch.Draw(tex, Position, Frame, drawColor * Fade, Rotation, Frame.Size() * 0.5f, Scale, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_Dust.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_Dust.png new file mode 100644 index 000000000..fc8abf2fb Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_Dust.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_ShockWave.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_ShockWave.png new file mode 100644 index 000000000..6dfba314d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_ShockWave.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_WaterPier.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_WaterPier.png new file mode 100644 index 000000000..1b970acc8 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_WaterPier.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_WaterPier_content.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_WaterPier_content.png new file mode 100644 index 000000000..b884474eb Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_WaterPier_content.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_WaterPier_side.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_WaterPier_side.png new file mode 100644 index 000000000..49a9b646b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_WaterPier_side.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_WaterPier_thin.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_WaterPier_thin.png new file mode 100644 index 000000000..ae7c38ce2 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_WaterPier_thin.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_WaterPier_thin_batch.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_WaterPier_thin_batch.png new file mode 100644 index 000000000..7d6912fb1 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_WaterPier_thin_batch.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_Waterfall_side.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_Waterfall_side.png new file mode 100644 index 000000000..61994c5d7 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_Waterfall_side.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_shockwave.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_shockwave.cs new file mode 100644 index 000000000..4df2ad5b6 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WaterSluice_Scene_shockwave.cs @@ -0,0 +1,61 @@ +using Everglow.Commons.VFX.Scene; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +[Pipeline(typeof(WCSPipeline))] +public class WaterSluice_Scene_shockwave : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawDusts; + + public Vector2 Position; + + public float Scale; + + public float Timer; + + public float MaxTime; + + public float Fade; + + public Rectangle Frame; + + public override void OnSpawn() + { + if (Collision.IsWorldPointSolid(Position)) + { + Kill(); + return; + } + } + + public override void Update() + { + Timer++; + if (Timer >= MaxTime) + { + Kill(); + return; + } + } + + public override void Draw() + { + Texture2D tex = ModAsset.WaterSluice_Scene_ShockWave.Value; + Color drawColor = Lighting.GetColor(Position.ToTileCoordinates()) * 0.5f; + float duration = Timer / MaxTime; + Frame.X = 0; + if (duration > 0.25f) + { + Frame.X = 8; + } + if (duration > 0.5f) + { + Frame.X = 16; + } + if (duration > 0.75f) + { + Frame.X = 24; + } + Ins.Batch.Draw(tex, Position, Frame, drawColor * Fade, 0, Frame.Size() * 0.5f, Scale, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WoodenChest_ForestCastle.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WoodenChest_ForestCastle.cs new file mode 100644 index 000000000..3df869fd2 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WoodenChest_ForestCastle.cs @@ -0,0 +1,162 @@ +using Everglow.Yggdrasil.YggdrasilTown.Items.Placeables.Furniture.TwilightForest; +using Terraria.DataStructures; +using Terraria.Enums; +using Terraria.GameContent.ObjectInteractions; +using Terraria.Localization; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.RoomScenes; + +public class WoodenChest_ForestCastle : ModTile +{ + public override void SetStaticDefaults() + { + Main.tileSpelunker[Type] = true; + Main.tileContainer[Type] = true; + Main.tileFrameImportant[Type] = true; + Main.tileNoAttach[Type] = true; + Main.tileOreFinderPriority[Type] = 500; + TileID.Sets.HasOutlines[Type] = true; + TileID.Sets.BasicChest[Type] = true; + TileID.Sets.DisableSmartCursor[Type] = true; + TileID.Sets.AvoidedByNPCs[Type] = true; + TileID.Sets.InteractibleByNPCs[Type] = true; + TileID.Sets.IsAContainer[Type] = true; + TileID.Sets.FriendlyFairyCanLureTo[Type] = true; + + DustType = DustID.WoodFurniture; + AdjTiles = new int[] { TileID.Containers }; + + TileObjectData.newTile.CopyFrom(TileObjectData.Style2x2); + TileObjectData.newTile.Origin = new Point16(0, 1); + TileObjectData.newTile.CoordinateHeights = new[] { 16, 18 }; + TileObjectData.newTile.HookCheckIfCanPlace = new PlacementHook(Chest.FindEmptyChest, -1, 0, true); + TileObjectData.newTile.HookPostPlaceMyPlayer = new PlacementHook(Chest.AfterPlacement_Hook, -1, 0, false); + TileObjectData.newTile.AnchorInvalidTiles = new int[] + { + TileID.MagicalIceBlock, + TileID.Boulder, + TileID.BouncyBoulder, + TileID.LifeCrystalBoulder, + TileID.RollingCactus, + }; + TileObjectData.newTile.StyleHorizontal = true; + TileObjectData.newTile.LavaDeath = false; + TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.SolidTile | AnchorType.SolidWithTop | AnchorType.SolidSide, TileObjectData.newTile.Width, 0); + TileObjectData.addTile(Type); + AddMapEntry(new Color(127, 96, 104)); + } + + public override ushort GetMapOption(int i, int j) + { + return (ushort)(Main.tile[i, j].TileFrameX / 36); + } + + public override LocalizedText DefaultContainerName(int frameX, int frameY) + { + int option = frameX / 36; + return this.GetLocalization("MapEntry" + option); + } + + public override bool HasSmartInteract(int i, int j, SmartInteractScanSettings settings) + { + return true; + } + + public static string MapChestName(string name, int i, int j) + { + int left = i; + int top = j; + Tile tile = Main.tile[i, j]; + if (tile.TileFrameX % 36 != 0) + { + left--; + } + + if (tile.TileFrameY != 0) + { + top--; + } + + int chest = Chest.FindChest(left, top); + if (chest < 0) + { + return Language.GetTextValue("LegacyChestType.0"); + } + + if (Main.chest[chest].name == string.Empty) + { + return name; + } + + return name + ": " + Main.chest[chest].name; + } + + public override void NumDust(int i, int j, bool fail, ref int num) + { + num = 1; + } + + public override bool RightClick(int i, int j) + { + return FurnitureUtils.ChestRightClick(i, j); + } + + public override void MouseOver(int i, int j) + { + Player player = Main.LocalPlayer; + Tile tile = Main.tile[i, j]; + int left = i; + int top = j; + if (tile.TileFrameX % 36 != 0) + { + left--; + } + + if (tile.TileFrameY != 0) + { + top--; + } + + int chest = Chest.FindChest(left, top); + player.cursorItemIconID = -1; + if (chest < 0) + { + player.cursorItemIconText = Language.GetTextValue("LegacyChestType.0"); + } + else + { + string defaultName = TileLoader.DefaultContainerName(tile.TileType, tile.TileFrameX, tile.TileFrameY); // This gets the ContainerName text for the currently selected language + player.cursorItemIconText = Main.chest[chest].name.Length > 0 ? Main.chest[chest].name : defaultName; + if (player.cursorItemIconText == defaultName) + { + player.cursorItemIconID = ModContent.ItemType(); + if (Main.tile[left, top].TileFrameX / 36 == 1) + { + // player.cursorItemIconID = ModContent.ItemType<>(); + } + + player.cursorItemIconText = string.Empty; + } + } + + player.noThrow = 2; + player.cursorItemIconEnabled = true; + } + + public override void MouseOverFar(int i, int j) + { + MouseOver(i, j); + Player player = Main.LocalPlayer; + if (player.cursorItemIconText == string.Empty) + { + player.cursorItemIconEnabled = false; + player.cursorItemIconID = ItemID.None; + } + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + base.PostDraw(i, j, spriteBatch); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WoodenChest_ForestCastle.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WoodenChest_ForestCastle.png new file mode 100644 index 000000000..a0fcc45e8 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WoodenChest_ForestCastle.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WoodenChest_ForestCastle_Highlight.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WoodenChest_ForestCastle_Highlight.png new file mode 100644 index 000000000..028e1ac52 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/RoomScenes/WoodenChest_ForestCastle_Highlight.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/Traps/ColorLasersTrap.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/Traps/ColorLasersTrap.cs index 08878413e..c52001d4e 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/Traps/ColorLasersTrap.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/Traps/ColorLasersTrap.cs @@ -5,7 +5,7 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest.Traps; [Pipeline(typeof(WCSPipeline))] -public class ColorLasersTrap : ForegroundVFX +public class ColorLasersTrap : TileVFX { public float Rotation; public float Omega; @@ -13,9 +13,11 @@ public class ColorLasersTrap : ForegroundVFX public int Style; private int length; + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; + public override void OnSpawn() { - texture = ModAsset.ColorLasersTrap.Value; + Texture = ModAsset.ColorLasersTrap.Value; } public Vector3 GetColor() @@ -45,15 +47,15 @@ public Vector3 GetColor() public override void Update() { - Lighting.AddLight(position, GetColor()); - position = originTile.ToWorldCoordinates() + new Vector2(2) + new Vector2(0, -16).RotatedBy(Rotation); + Lighting.AddLight(Position, GetColor()); + Position = OriginTilePos.ToWorldCoordinates() + new Vector2(2) + new Vector2(0, -16).RotatedBy(Rotation); Rotation = StartRotation; Vector2 collisionUnit = new Vector2(0, -8).RotatedBy(Rotation); int count = 0; for (int step = 1; step < 1000; step++) { count++; - if (Collision.SolidCollision(position + step * collisionUnit - new Vector2(4), 8, 8)) + if (Collision.SolidCollision(Position + step * collisionUnit - new Vector2(4), 8, 8)) { break; } @@ -63,7 +65,7 @@ public override void Update() { if (player != null && player.active && player.GetModPlayer().ImmuneStyle != Style) { - if (Collision.CheckAABBvLineCollision(player.Hitbox.TopLeft(), player.Hitbox.Size(), position, position + collisionUnit * length)) + if (Collision.CheckAABBvLineCollision(player.Hitbox.TopLeft(), player.Hitbox.Size(), Position, Position + collisionUnit * length)) { player.Hurt(PlayerDeathReason.ByCustomReason("Try to across in a laser net"), 999, player.velocity.X > 0 ? 1 : -1, false, false, -1, false, 999, 0, 0); } @@ -81,19 +83,19 @@ public override void Draw() var point2 = new Vector2(-frame.Width * 0.5f, frame.Height * 0.5f); var point3 = new Vector2(frame.Width * 0.5f, frame.Height * 0.5f); - Color lightColor0 = Lighting.GetColor((position + point0.RotatedBy(Rotation)).ToTileCoordinates()); - Color lightColor1 = Lighting.GetColor((position + point1.RotatedBy(Rotation)).ToTileCoordinates()); - Color lightColor2 = Lighting.GetColor((position + point2.RotatedBy(Rotation)).ToTileCoordinates()); - Color lightColor3 = Lighting.GetColor((position + point3.RotatedBy(Rotation)).ToTileCoordinates()); + Color lightColor0 = Lighting.GetColor((Position + point0.RotatedBy(Rotation)).ToTileCoordinates()); + Color lightColor1 = Lighting.GetColor((Position + point1.RotatedBy(Rotation)).ToTileCoordinates()); + Color lightColor2 = Lighting.GetColor((Position + point2.RotatedBy(Rotation)).ToTileCoordinates()); + Color lightColor3 = Lighting.GetColor((Position + point3.RotatedBy(Rotation)).ToTileCoordinates()); var bars = new List() { - new Vertex2D(position + point0.RotatedBy(Rotation), lightColor0, new Vector3(frame.X / (float)texture.Width, 0, 0)), - new Vertex2D(position + point1.RotatedBy(Rotation), lightColor1, new Vector3((frame.X + 16) / (float)texture.Width, 0, 0)), - new Vertex2D(position + point2.RotatedBy(Rotation), lightColor2, new Vector3(frame.X / (float)texture.Width, 16f / texture.Height, 0)), + new Vertex2D(Position + point0.RotatedBy(Rotation), lightColor0, new Vector3(frame.X / (float)Texture.Width, 0, 0)), + new Vertex2D(Position + point1.RotatedBy(Rotation), lightColor1, new Vector3((frame.X + 16) / (float)Texture.Width, 0, 0)), + new Vertex2D(Position + point2.RotatedBy(Rotation), lightColor2, new Vector3(frame.X / (float)Texture.Width, 16f / Texture.Height, 0)), - new Vertex2D(position + point2.RotatedBy(Rotation), lightColor2, new Vector3(frame.X / (float)texture.Width, 16f / texture.Height, 0)), - new Vertex2D(position + point1.RotatedBy(Rotation), lightColor1, new Vector3((frame.X + 16) / (float)texture.Width, 0, 0)), - new Vertex2D(position + point3.RotatedBy(Rotation), lightColor3, new Vector3((frame.X + 16) / (float)texture.Width, 16f / texture.Height, 0)), + new Vertex2D(Position + point2.RotatedBy(Rotation), lightColor2, new Vector3(frame.X / (float)Texture.Width, 16f / Texture.Height, 0)), + new Vertex2D(Position + point1.RotatedBy(Rotation), lightColor1, new Vector3((frame.X + 16) / (float)Texture.Width, 0, 0)), + new Vertex2D(Position + point3.RotatedBy(Rotation), lightColor3, new Vector3((frame.X + 16) / (float)Texture.Width, 16f / Texture.Height, 0)), }; Vector2 collisionUnit = new Vector2(0, -8).RotatedBy(Rotation); Vector2 normalUnit = collisionUnit.RotatedBy(MathHelper.PiOver2) * 0.5f; @@ -102,15 +104,15 @@ public override void Draw() { laserColor *= 0.2f; } - bars.Add(position + normalUnit, laserColor, new Vector3(0, 18f / texture.Height, 0)); - bars.Add(position - normalUnit, laserColor, new Vector3(0, 152f / texture.Height, 0)); - bars.Add(position + normalUnit + collisionUnit * length, laserColor, new Vector3(length / 24f, 18f / texture.Height, 0)); + bars.Add(Position + normalUnit, laserColor, new Vector3(0, 18f / Texture.Height, 0)); + bars.Add(Position - normalUnit, laserColor, new Vector3(0, 152f / Texture.Height, 0)); + bars.Add(Position + normalUnit + collisionUnit * length, laserColor, new Vector3(length / 24f, 18f / Texture.Height, 0)); - bars.Add(position + normalUnit + collisionUnit * length, laserColor, new Vector3(length / 24f, 18f / texture.Height, 0)); - bars.Add(position - normalUnit, laserColor, new Vector3(0, 152f / texture.Height, 0)); - bars.Add(position - normalUnit + collisionUnit * length, laserColor, new Vector3(length / 24f, 152f / texture.Height, 0)); + bars.Add(Position + normalUnit + collisionUnit * length, laserColor, new Vector3(length / 24f, 18f / Texture.Height, 0)); + bars.Add(Position - normalUnit, laserColor, new Vector3(0, 152f / Texture.Height, 0)); + bars.Add(Position - normalUnit + collisionUnit * length, laserColor, new Vector3(length / 24f, 152f / Texture.Height, 0)); - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleList); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleList); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_0.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_0.cs index 5fcc7ddc5..7c09e4a92 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_0.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_0.cs @@ -31,7 +31,7 @@ public void AddScene(int i, int j) Tile tile = Main.tile[i, j]; if (tile.TileFrameX == 0 && tile.TileFrameY == 90) { - var mirror = new TwilightBlueCrystal_0_Mirror { position = new Vector2(i, j) * 16 + new Vector2(0, -80), Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + var mirror = new TwilightBlueCrystal_0_Mirror { Position = new Vector2(i, j) * 16 + new Vector2(0, -80), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(mirror); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_0_Mirror.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_0_Mirror.cs index b488cfc95..9e27e082c 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_0_Mirror.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_0_Mirror.cs @@ -7,6 +7,6 @@ public class TwilightBlueCrystal_0_Mirror : Tile_MirrorFaceVFX { public override void OnSpawn() { - texture = ModAsset.TwilightBlueCrystal_0_Mirror.Value; + Texture = ModAsset.TwilightBlueCrystal_0_Mirror.Value; } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_1.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_1.cs index 55b87b1bc..f68a705c8 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_1.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_1.cs @@ -28,7 +28,7 @@ public void AddScene(int i, int j) Tile tile = Main.tile[i, j]; if (tile.TileFrameX == 0 && tile.TileFrameY == 108) { - var mirror = new TwilightBlueCrystal_1_Mirror { position = new Vector2(i, j) * 16 + new Vector2(0, -96), Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + var mirror = new TwilightBlueCrystal_1_Mirror { Position = new Vector2(i, j) * 16 + new Vector2(0, -96), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(mirror); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_1_Mirror.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_1_Mirror.cs index 142cb5472..a2a8466c5 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_1_Mirror.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_1_Mirror.cs @@ -7,6 +7,6 @@ public class TwilightBlueCrystal_1_Mirror : Tile_MirrorFaceVFX { public override void OnSpawn() { - texture = ModAsset.TwilightBlueCrystal_1_Mirror.Value; + Texture = ModAsset.TwilightBlueCrystal_1_Mirror.Value; } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_2.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_2.cs index 7da8f87dc..c1549ed9a 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_2.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_2.cs @@ -20,7 +20,7 @@ public override void SetStaticDefaults() { 16, 16, - 18 + 18, }; TileObjectData.newTile.StyleHorizontal = true; TileObjectData.newTile.LavaDeath = false; @@ -28,6 +28,7 @@ public override void SetStaticDefaults() AddMapEntry(new Color(40, 80, 148)); DustType = ModContent.DustType(); } + public override void ModifyLight(int i, int j, ref float r, ref float g, ref float b) { r = 0.07f; @@ -35,20 +36,22 @@ public override void ModifyLight(int i, int j, ref float r, ref float g, ref flo b = 0.45f; base.ModifyLight(i, j, ref r, ref g, ref b); } + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) { } + public void AddScene(int i, int j) { Tile tile = Main.tile[i, j]; if (tile.TileFrameX == 0 && tile.TileFrameY == 0) { - TwilightBlueCrystal_2_Mirror mirror = new TwilightBlueCrystal_2_Mirror { position = new Vector2(i, j) * 16 + new Vector2(4, 8), Active = true, Visible = true, originTile = new Point(i, j), originType = Type, texture = ModAsset.TwilightBlueCrystal_2_Mirror.Value }; + TwilightBlueCrystal_2_Mirror mirror = new TwilightBlueCrystal_2_Mirror { Position = new Vector2(i, j) * 16 + new Vector2(4, 8), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type, Texture = ModAsset.TwilightBlueCrystal_2_Mirror.Value }; Ins.VFXManager.Add(mirror); } if (tile.TileFrameX == 54 && tile.TileFrameY == 0) { - TwilightBlueCrystal_2_Mirror mirror = new TwilightBlueCrystal_2_Mirror { position = new Vector2(i, j) * 16 + new Vector2(8, 8), Active = true, Visible = true, originTile = new Point(i, j), originType = Type, FlipH = true, texture = ModAsset.TwilightBlueCrystal_2_Mirror_flipH.Value }; + TwilightBlueCrystal_2_Mirror mirror = new TwilightBlueCrystal_2_Mirror { Position = new Vector2(i, j) * 16 + new Vector2(8, 8), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type, FlipH = true, Texture = ModAsset.TwilightBlueCrystal_2_Mirror_flipH.Value }; Ins.VFXManager.Add(mirror); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_6.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_6.cs index ad6241488..c3829ba12 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_6.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_6.cs @@ -28,7 +28,7 @@ public void AddScene(int i, int j) Tile tile = Main.tile[i, j]; if (tile.TileFrameX == 36 && tile.TileFrameY == 36) { - TwilightBlueCrystal_6_Mirror mirror = new TwilightBlueCrystal_6_Mirror { position = new Vector2(i, j) * 16 + new Vector2(-18, -28), Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + TwilightBlueCrystal_6_Mirror mirror = new TwilightBlueCrystal_6_Mirror { Position = new Vector2(i, j) * 16 + new Vector2(-18, -28), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(mirror); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_6_Mirror.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_6_Mirror.cs index b692b2390..8f79fe9de 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_6_Mirror.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightBlueCrystal_6_Mirror.cs @@ -7,6 +7,6 @@ public class TwilightBlueCrystal_6_Mirror : Tile_MirrorFaceVFX { public override void OnSpawn() { - texture = ModAsset.TwilightBlueCrystal_6_Mirror.Value; + Texture = ModAsset.TwilightBlueCrystal_6_Mirror.Value; } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightGrassBlock.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightGrassBlock.cs index 108cd2a1c..539bd0e70 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightGrassBlock.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightGrassBlock.cs @@ -251,7 +251,7 @@ public void PlaceTree(int i, int j, int height) public void AddScene(int i, int j) { - var leaf = new TwilightGrass_grass_fore { position = new Vector2(i, j) * 16, Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + var leaf = new TwilightGrass_grass_fore { Position = new Vector2(i, j) * 16, Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; leaf.scale = 1f; leaf.style = i % 3; Ins.VFXManager.Add(leaf); diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightGrass_grass.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightGrass_grass.cs index 7e03845f0..c155e66c8 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightGrass_grass.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/TwilightForest/TwilightGrass_grass.cs @@ -3,38 +3,39 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles.TwilightForest; [Pipeline(typeof(WCSPipeline))] -public class TwilightGrass_grass_fore : ForegroundVFX +public class TwilightGrass_grass_fore : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; public override void OnSpawn() { - texture = ModAsset.TwilightGrass_grass.Value; + Texture = ModAsset.TwilightGrass_grass.Value; } public override void Update() { - if (originTile.X >= Main.maxTilesX - 1 || originTile.X <= 1) + if (OriginTilePos.X >= Main.maxTilesX - 1 || OriginTilePos.X <= 1) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - if (originTile.Y >= Main.maxTilesY - 1 || originTile.Y <= 1) + if (OriginTilePos.Y >= Main.maxTilesY - 1 || OriginTilePos.Y <= 1) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - if (!VFXManager.InScreen(originTile.ToWorldCoordinates(), 150)) + if (!VFXManager.InScreen(OriginTilePos.ToWorldCoordinates(), 150)) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - Tile tile = Main.tile[originTile]; - if (tile.TileType != originType || !tile.HasTile) + Tile tile = Main.tile[OriginTilePos]; + if (tile.TileType != OriginTileType || !tile.HasTile) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } @@ -44,23 +45,23 @@ public override void Update() public override void Draw() { - if (originTile.X >= Main.maxTilesX - 1 || originTile.X <= 1) + if (OriginTilePos.X >= Main.maxTilesX - 1 || OriginTilePos.X <= 1) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - if (originTile.Y >= Main.maxTilesY - 1 || originTile.Y <= 1) + if (OriginTilePos.Y >= Main.maxTilesY - 1 || OriginTilePos.Y <= 1) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - Tile tile = Main.tile[originTile]; - if (tile.TileType != originType || !tile.HasTile) + Tile tile = Main.tile[OriginTilePos]; + if (tile.TileType != OriginTileType || !tile.HasTile) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } @@ -70,7 +71,7 @@ public override void Draw() // int rectangleX = (int)(Main.screenPosition - deltaPos).X; // int rectangleY = (int)(Main.screenPosition - deltaPos).Y; // Rectangle checkRectangle = new Rectangle(rectangleX, rectangleY, Main.screenWidth - 8, Main.screenHeight - 8); - // if (checkRectangle.Contains((int)position.X, (int)position.Y)) + // if (checkRectangle.Contains((int)Position.X, (int)Position.Y)) // { // return; // } @@ -80,199 +81,199 @@ public override void Draw() { if (tile.TileFrameX >= 18 && tile.TileFrameX <= 54 && tile.TileFrameY == 0) { - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameX >= 18 && tile.TileFrameX <= 54 && tile.TileFrameY == 36) { - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } if (tile.TileFrameX == 0 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) { - AddDrawingFace(bars, new Vector2(-1, 0), position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); } if (tile.TileFrameX == 72 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) { - AddDrawingFace(bars, new Vector2(1, 0), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); } if (tile.TileFrameX == 90 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(-1, 0), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); } if (tile.TileFrameY == 72 && tile.TileFrameX >= 108 && tile.TileFrameX <= 144) { - AddDrawingFace(bars, new Vector2(0, 1), position); - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameY == 0 && tile.TileFrameX >= 108 && tile.TileFrameX <= 144) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(-1, 0), position); - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameY == 54 && tile.TileFrameX >= 108 && tile.TileFrameX <= 144) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(-1, 0), position); - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } if (tile.TileFrameX == 162 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) { - AddDrawingFace(bars, new Vector2(0, 1), position); - AddDrawingFace(bars, new Vector2(0, -1), position); - AddDrawingFace(bars, new Vector2(-1, 0), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); } if (tile.TileFrameX == 216 && tile.TileFrameY <= 36 && tile.TileFrameY >= 0) { - AddDrawingFace(bars, new Vector2(0, 1), position); - AddDrawingFace(bars, new Vector2(0, -1), position); - AddDrawingFace(bars, new Vector2(1, 0), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); + AddDrawingFace(bars, new Vector2(1, 0), Position); } if (tile.TileFrameY == 54 && tile.TileFrameX >= 162 && tile.TileFrameX <= 198) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(-1, 0), position); - AddDrawingFace(bars, new Vector2(0, 1), position); - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameY == 54 && tile.TileFrameX % 36 == 0 && tile.TileFrameX <= 90) { - AddDrawingFace(bars, new Vector2(-1, 0), position); - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameY == 72 && tile.TileFrameX % 36 == 0 && tile.TileFrameX <= 90) { - AddDrawingFace(bars, new Vector2(-1, 0), position); - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } if (tile.TileFrameY == 54 && tile.TileFrameX % 36 == 18 && tile.TileFrameX <= 90) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } if (tile.TileFrameY == 72 && tile.TileFrameX % 36 == 18 && tile.TileFrameX <= 90) { - AddDrawingFace(bars, new Vector2(1, 0), position); - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } } else { if (tile.Slope == SlopeType.SlopeUpLeft) { - AddDrawingFace(bars, new Vector2(1, 1) * 0.85f, position, 1.4143f, new Vector2(-5, -5)); - Tile upTile = Main.tile[originTile + new Point(0, -1)]; + AddDrawingFace(bars, new Vector2(1, 1) * 0.85f, Position, 1.4143f, new Vector2(-5, -5)); + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; if (!upTile.HasTile) { - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } - Tile leftTile = Main.tile[originTile + new Point(-1, 0)]; + Tile leftTile = Main.tile[OriginTilePos + new Point(-1, 0)]; if (!leftTile.HasTile) { - AddDrawingFace(bars, new Vector2(-1, 0), position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); } - Tile downTile = Main.tile[originTile + new Point(0, 1)]; - if (downTile.HasTile && downTile.TileType == originType) + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; + if (downTile.HasTile && downTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(0, -1), position, 1, new Vector2(0, 16)); + AddDrawingFace(bars, new Vector2(0, -1), Position, 1, new Vector2(0, 16)); } } if (tile.Slope == SlopeType.SlopeDownLeft) { - AddDrawingFace(bars, new Vector2(1, -1) * 0.85f, position, 1.4143f, new Vector2(-5, 5)); - Tile downTile = Main.tile[originTile + new Point(0, 1)]; + AddDrawingFace(bars, new Vector2(1, -1) * 0.85f, Position, 1.4143f, new Vector2(-5, 5)); + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; if (!downTile.HasTile) { - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } - Tile leftTile = Main.tile[originTile + new Point(-1, 0)]; + Tile leftTile = Main.tile[OriginTilePos + new Point(-1, 0)]; if (!leftTile.HasTile) { - AddDrawingFace(bars, new Vector2(-1, 0), position); + AddDrawingFace(bars, new Vector2(-1, 0), Position); } - Tile upTile = Main.tile[originTile + new Point(0, -1)]; - if (upTile.HasTile && upTile.TileType == originType) + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; + if (upTile.HasTile && upTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(0, 1), position, 1, new Vector2(0, -16)); + AddDrawingFace(bars, new Vector2(0, 1), Position, 1, new Vector2(0, -16)); } } if (tile.Slope == SlopeType.SlopeUpRight) { - AddDrawingFace(bars, new Vector2(-1, 1) * 0.85f, position, 1.4143f, new Vector2(5, -5)); - Tile upTile = Main.tile[originTile + new Point(0, -1)]; + AddDrawingFace(bars, new Vector2(-1, 1) * 0.85f, Position, 1.4143f, new Vector2(5, -5)); + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; if (!upTile.HasTile) { - AddDrawingFace(bars, new Vector2(0, -1), position); + AddDrawingFace(bars, new Vector2(0, -1), Position); } - Tile rightTile = Main.tile[originTile + new Point(1, 0)]; + Tile rightTile = Main.tile[OriginTilePos + new Point(1, 0)]; if (!rightTile.HasTile) { - AddDrawingFace(bars, new Vector2(1, 0), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); } - Tile downTile = Main.tile[originTile + new Point(0, 1)]; - if (downTile.HasTile && downTile.TileType == originType) + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; + if (downTile.HasTile && downTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(0, -1), position, 1, new Vector2(0, 16)); + AddDrawingFace(bars, new Vector2(0, -1), Position, 1, new Vector2(0, 16)); } } if (tile.Slope == SlopeType.SlopeDownRight) { - AddDrawingFace(bars, new Vector2(-1, -1) * 0.85f, position, 1.4143f, new Vector2(5, 5)); - Tile downTile = Main.tile[originTile + new Point(0, 1)]; + AddDrawingFace(bars, new Vector2(-1, -1) * 0.85f, Position, 1.4143f, new Vector2(5, 5)); + Tile downTile = Main.tile[OriginTilePos + new Point(0, 1)]; if (!downTile.HasTile) { - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } - Tile rightTile = Main.tile[originTile + new Point(1, 0)]; + Tile rightTile = Main.tile[OriginTilePos + new Point(1, 0)]; if (!rightTile.HasTile) { - AddDrawingFace(bars, new Vector2(1, 0), position); + AddDrawingFace(bars, new Vector2(1, 0), Position); } - Tile upTile = Main.tile[originTile + new Point(0, -1)]; - if (upTile.HasTile && upTile.TileType == originType) + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; + if (upTile.HasTile && upTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(0, 1), position, 1, new Vector2(0, -16)); + AddDrawingFace(bars, new Vector2(0, 1), Position, 1, new Vector2(0, -16)); } } if (tile.halfBrick()) { - AddDrawingFace(bars, new Vector2(0, -1), position, 1, new Vector2(0, 6)); - if (!Main.tile[originTile + new Point(0, 1)].HasTile) + AddDrawingFace(bars, new Vector2(0, -1), Position, 1, new Vector2(0, 6)); + if (!Main.tile[OriginTilePos + new Point(0, 1)].HasTile) { - AddDrawingFace(bars, new Vector2(0, 1), position); + AddDrawingFace(bars, new Vector2(0, 1), Position); } - Tile upTile = Main.tile[originTile + new Point(0, -1)]; - if (upTile.HasTile && upTile.TileType == originType) + Tile upTile = Main.tile[OriginTilePos + new Point(0, -1)]; + if (upTile.HasTile && upTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(0, 1), position, 1, new Vector2(0, -16)); + AddDrawingFace(bars, new Vector2(0, 1), Position, 1, new Vector2(0, -16)); } - Tile leftTile = Main.tile[originTile + new Point(-1, 0)]; - if (leftTile.HasTile && leftTile.TileType == originType) + Tile leftTile = Main.tile[OriginTilePos + new Point(-1, 0)]; + if (leftTile.HasTile && leftTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(1, 0), position, 0.5f, new Vector2(-14, -4)); + AddDrawingFace(bars, new Vector2(1, 0), Position, 0.5f, new Vector2(-14, -4)); } if (!leftTile.HasTile) { - AddDrawingFace(bars, new Vector2(-1, 0), position, 0.5f, new Vector2(0, 4)); + AddDrawingFace(bars, new Vector2(-1, 0), Position, 0.5f, new Vector2(0, 4)); } - Tile rightTile = Main.tile[originTile + new Point(1, 0)]; - if (rightTile.HasTile && rightTile.TileType == originType) + Tile rightTile = Main.tile[OriginTilePos + new Point(1, 0)]; + if (rightTile.HasTile && rightTile.TileType == OriginTileType) { - AddDrawingFace(bars, new Vector2(-1, 0), position, 0.5f, new Vector2(14, -4)); + AddDrawingFace(bars, new Vector2(-1, 0), Position, 0.5f, new Vector2(14, -4)); } if (!rightTile.HasTile) { - AddDrawingFace(bars, new Vector2(1, 0), position, 0.5f, new Vector2(0, 4)); + AddDrawingFace(bars, new Vector2(1, 0), Position, 0.5f, new Vector2(0, 4)); } } } - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleList); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleList); } - public void AddDrawingFace(List bars, Vector2 direction, Vector2 position, float length = 1, Vector2 offset = default) + public void AddDrawingFace(List bars, Vector2 Direction, Vector2 Position, float length = 1, Vector2 offset = default) { - Vector2 drawCenter = position + new Vector2(8) + offset; - var directionN = Vector2.Normalize(direction); + Vector2 drawCenter = Position + new Vector2(8) + offset; + var directionN = Vector2.Normalize(Direction); float rot = -MathF.Asin(Vector3.Cross(new Vector3(directionN, 0), new Vector3(0, -1, 0)).Z); float cos = Vector2.Dot(directionN, new Vector2(0, -1)); if (cos < 0) @@ -281,10 +282,10 @@ public void AddDrawingFace(List bars, Vector2 direction, Vector2 posit } float dLength = 16 / 52f; - Vector2 point0 = drawCenter + new Vector2(-8 * length, -8).RotatedBy(rot) + direction * 8; - Vector2 point1 = drawCenter + new Vector2(8 * length, -8).RotatedBy(rot) + direction * 8; - Vector2 point2 = drawCenter + new Vector2(-8 * length, 8).RotatedBy(rot) + direction * 12; - Vector2 point3 = drawCenter + new Vector2(8 * length, 8).RotatedBy(rot) + direction * 12; + Vector2 point0 = drawCenter + new Vector2(-8 * length, -8).RotatedBy(rot) + Direction * 8; + Vector2 point1 = drawCenter + new Vector2(8 * length, -8).RotatedBy(rot) + Direction * 8; + Vector2 point2 = drawCenter + new Vector2(-8 * length, 8).RotatedBy(rot) + Direction * 12; + Vector2 point3 = drawCenter + new Vector2(8 * length, 8).RotatedBy(rot) + Direction * 12; Color color0 = Lighting.GetColor(point0.ToTileCoordinates()); Color color1 = Lighting.GetColor(point1.ToTileCoordinates()); diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/UnionWallLamp_Style0.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/UnionWallLamp_Style0.cs index bbce88341..e541404c0 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/UnionWallLamp_Style0.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/UnionWallLamp_Style0.cs @@ -16,12 +16,11 @@ public override void SetStaticDefaults() Main.tileWaterDeath[Type] = false; TileObjectData.newTile.CopyFrom(TileObjectData.Style3x3Wall); - TileObjectData.newTile.Origin = new(0, 0); TileObjectData.newTile.Height = 7; TileObjectData.newTile.Width = 5; TileObjectData.newTile.AnchorTop = new AnchorData(AnchorType.None, 0, 0); TileObjectData.newTile.AnchorBottom = new AnchorData(AnchorType.None, 0, 0); - TileObjectData.newTile.CoordinateHeights = new int[12]; + TileObjectData.newTile.CoordinateHeights = new int[7]; Array.Fill(TileObjectData.newTile.CoordinateHeights, 16); TileObjectData.newTile.StyleHorizontal = true; TileObjectData.newTile.LavaDeath = false; diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs.cs index 94b3132b2..ac667034b 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs.cs @@ -91,10 +91,12 @@ public void AddScene(int i, int j) Tile tile = TileUtils.SafeGetTile(i, j); if (tile.TileFrameX == 900 && tile.TileFrameY == 900) { - Union_Y_Stairs_Front uYSF = new Union_Y_Stairs_Front { position = new Vector2(i, j) * 16 + new Vector2(0, -70), Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + Union_Y_Stairs_Front uYSF = new Union_Y_Stairs_Front { Position = new Vector2(i, j) * 16 + new Vector2(0, -70), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(uYSF); - Union_Y_Stairs_Back uYSB = new Union_Y_Stairs_Back { position = new Vector2(i, j) * 16 + new Vector2(0, -70), Active = true, Visible = true, originTile = new Point(i, j), originType = Type }; + Union_Y_Stairs_Back uYSB = new Union_Y_Stairs_Back { Position = new Vector2(i, j) * 16 + new Vector2(0, -70), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; Ins.VFXManager.Add(uYSB); + Union_Y_Stairs_ban_2nd_floor uYSB2F = new Union_Y_Stairs_ban_2nd_floor { Position = new Vector2(i, j) * 16 + new Vector2(303, 140), Active = true, Visible = true, OriginTilePos = new Point(i, j), OriginTileType = Type }; + Ins.VFXManager.Add(uYSB2F); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_Back.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_Back.cs index 7aed06b4a..cec663dc3 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_Back.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_Back.cs @@ -3,7 +3,7 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; [Pipeline(typeof(WCSPipeline))] -public class Union_Y_Stairs_Back : BackgroundVFX +public class Union_Y_Stairs_Back : TileVFX { public override CodeLayer DrawLayer => CodeLayer.PostDrawTiles; @@ -14,7 +14,7 @@ public override void Update() public override void OnSpawn() { - texture = ModAsset.Union_Y_Stairs_Back.Value; + Texture = ModAsset.Union_Y_Stairs_Back.Value; } public override void Draw() @@ -26,31 +26,31 @@ public override void Draw() { for (int j = 0; j < height; j++) { - Color lightColor0 = Lighting.GetColor((int)position.X / 16 + i, (int)position.Y / 16 + j); - Color lightColor1 = Lighting.GetColor((int)position.X / 16 + i + 1, (int)position.Y / 16 + j); - Color lightColor2 = Lighting.GetColor((int)position.X / 16 + i, (int)position.Y / 16 + j + 1); - Color lightColor3 = Lighting.GetColor((int)position.X / 16 + i + 1, (int)position.Y / 16 + j + 1); - - bars.Add(position + new Vector2(i, j) * 16, lightColor0, new Vector3(i / width, j / height, 0)); - bars.Add(position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); - bars.Add(position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); - - bars.Add(position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); - bars.Add(position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); - bars.Add(position + new Vector2(i + 1, j + 1) * 16, lightColor3, new Vector3((i + 1) / width, (j + 1) / height, 0)); + Color lightColor0 = Lighting.GetColor((int)Position.X / 16 + i, (int)Position.Y / 16 + j); + Color lightColor1 = Lighting.GetColor((int)Position.X / 16 + i + 1, (int)Position.Y / 16 + j); + Color lightColor2 = Lighting.GetColor((int)Position.X / 16 + i, (int)Position.Y / 16 + j + 1); + Color lightColor3 = Lighting.GetColor((int)Position.X / 16 + i + 1, (int)Position.Y / 16 + j + 1); + + bars.Add(Position + new Vector2(i, j) * 16, lightColor0, new Vector3(i / width, j / height, 0)); + bars.Add(Position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); + bars.Add(Position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); + + bars.Add(Position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); + bars.Add(Position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); + bars.Add(Position + new Vector2(i + 1, j + 1) * 16, lightColor3, new Vector3((i + 1) / width, (j + 1) / height, 0)); } } if (bars.Count <= 0) { - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); } - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleStrip); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_Front.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_Front.cs index 4d5f7e014..267aa5cae 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_Front.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_Front.cs @@ -4,63 +4,64 @@ namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; [Pipeline(typeof(WCSPipeline))] -public class Union_Y_Stairs_Front : ForegroundVFX +public class Union_Y_Stairs_Front : TileVFX { + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; public override void Update() { - if (originTile.X > 0 && originTile.X < Main.maxTilesX) + if (OriginTilePos.X > 0 && OriginTilePos.X < Main.maxTilesX) { - if (originTile.Y > 0 && originTile.Y < Main.maxTilesY) + if (OriginTilePos.Y > 0 && OriginTilePos.Y < Main.maxTilesY) { - Tile tile = Main.tile[originTile.X, originTile.Y]; + Tile tile = Main.tile[OriginTilePos.X, OriginTilePos.Y]; if (tile != null) { if (TileLoader.GetTile(tile.TileType) is ISceneTile) { - if (tile.TileType == originType) + if (tile.TileType == OriginTileType) { if (!tile.HasTile) { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } - Vector2 checkPos = position; + Vector2 checkPos = Position; if (VFXManager.InScreen(checkPos, 1500)) { Visible = true; @@ -68,14 +69,14 @@ public override void Update() else { Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; + SceneVFXSystem.TilePointHasScene[(OriginTilePos.X, OriginTilePos.Y)] = false; return; } } public override void OnSpawn() { - texture = ModAsset.Union_Y_Stairs_Front.Value; + Texture = ModAsset.Union_Y_Stairs_Front.Value; } public override void Draw() @@ -87,31 +88,31 @@ public override void Draw() { for (int j = 0; j < height; j++) { - Color lightColor0 = Lighting.GetColor((int)position.X / 16 + i, (int)position.Y / 16 + j); - Color lightColor1 = Lighting.GetColor((int)position.X / 16 + i + 1, (int)position.Y / 16 + j); - Color lightColor2 = Lighting.GetColor((int)position.X / 16 + i, (int)position.Y / 16 + j + 1); - Color lightColor3 = Lighting.GetColor((int)position.X / 16 + i + 1, (int)position.Y / 16 + j + 1); + Color lightColor0 = Lighting.GetColor((int)Position.X / 16 + i, (int)Position.Y / 16 + j); + Color lightColor1 = Lighting.GetColor((int)Position.X / 16 + i + 1, (int)Position.Y / 16 + j); + Color lightColor2 = Lighting.GetColor((int)Position.X / 16 + i, (int)Position.Y / 16 + j + 1); + Color lightColor3 = Lighting.GetColor((int)Position.X / 16 + i + 1, (int)Position.Y / 16 + j + 1); - bars.Add(position + new Vector2(i, j) * 16, lightColor0, new Vector3(i / width, j / height, 0)); - bars.Add(position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); - bars.Add(position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); + bars.Add(Position + new Vector2(i, j) * 16, lightColor0, new Vector3(i / width, j / height, 0)); + bars.Add(Position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); + bars.Add(Position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); - bars.Add(position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); - bars.Add(position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); - bars.Add(position + new Vector2(i + 1, j + 1) * 16, lightColor3, new Vector3((i + 1) / width, (j + 1) / height, 0)); + bars.Add(Position + new Vector2(i, j + 1) * 16, lightColor2, new Vector3(i / width, (j + 1) / height, 0)); + bars.Add(Position + new Vector2(i + 1, j) * 16, lightColor1, new Vector3((i + 1) / width, j / height, 0)); + bars.Add(Position + new Vector2(i + 1, j + 1) * 16, lightColor3, new Vector3((i + 1) / width, (j + 1) / height, 0)); } } if (bars.Count <= 0) { - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); - bars.Add(position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); } - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleList); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleList); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_ban.pdn b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_ban.pdn new file mode 100644 index 000000000..9a8683dff Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_ban.pdn differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_ban_2nd_floor.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_ban_2nd_floor.cs new file mode 100644 index 000000000..f617d61d7 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_ban_2nd_floor.cs @@ -0,0 +1,36 @@ +using Everglow.Commons.VFX.Scene; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; + +[Pipeline(typeof(WCSPipeline))] +public class Union_Y_Stairs_ban_2nd_floor : TileVFX +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawTiles; + + public override void OnSpawn() + { + Texture = ModAsset.Union_Y_Stairs_ban_2nd_floor.Value; + } + + public override void Update() + { + Rectangle rectangle = new Rectangle((int)(Position.X - Texture.Width / 2f), (int)(Position.Y - Texture.Height / 2f), Texture.Width, Texture.Height); + foreach (var player in Main.player) + { + // TODO: Enough score in mission system to enter 2nd floor + if (player.Hitbox.Intersects(rectangle)) + { + player.Top = new Vector2(player.Top.X, rectangle.Bottom().Y); + player.velocity.Y = 0; + } + } + base.Update(); + } + + public override void Draw() + { + Texture2D texBlack = ModAsset.Union_Y_Stairs_ban_2nd_floor_black.Value; + Ins.Batch.Draw(texBlack, Position, null, new Color(1f, 1f, 1f, 1f), 0, texBlack.Size() * 0.5f, 1f, SpriteEffects.None); + Ins.Batch.Draw(Texture, Position, null, new Color(1f, 1f, 1f, 0), 0, Texture.Size() * 0.5f, 1f, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_ban_2nd_floor.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_ban_2nd_floor.png new file mode 100644 index 000000000..5586b1968 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_ban_2nd_floor.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_ban_2nd_floor_black.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_ban_2nd_floor_black.png new file mode 100644 index 000000000..b658bd7da Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/Union_Y_Stairs_ban_2nd_floor_black.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilCommandBlock.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilCommandBlock.cs index c63a6f7f3..9aba30ad4 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilCommandBlock.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilCommandBlock.cs @@ -1,5 +1,9 @@ +using Everglow.Commons.Utilities.BackgroundHelper; +using Everglow.Commons.VFX.Scene; +using Everglow.Yggdrasil.YggdrasilTown.Background; using Everglow.Yggdrasil.YggdrasilTown.Dusts; using Everglow.Yggdrasil.YggdrasilTown.NPCs.TownNPCs; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; using SubworldLibrary; using Terraria.DataStructures; using Terraria.Enums; @@ -42,4 +46,64 @@ public override void RandomUpdate(int i, int j) YggdrasilTownCentralSystem.CheckNPC(ModContent.NPCType()); } } + + public override void NearbyEffects(int i, int j, bool closer) + { + var tile = Main.tile[i, j]; + if (tile.TileFrameX == 0 && tile.TileFrameY == 0) + { + BackgroundSystem bgSystem = ModContent.GetInstance(); + if (!bgSystem.HasBgSlide("Everglow.Yggdrasil.YggdrasilTown.Background.YggdrasilTown_Construct")) + { + AddBackground(bgSystem, i, j); + } + } + } + + public void AddBackground(BackgroundSystem bgSystem, int i, int j) + { + List polygon = new List(); + Vector2 centerPosWorld = new Point(i, j).ToWorldCoordinates() + new Vector2(260, -464); + polygon.Add(centerPosWorld + new Vector2(-210, 0) * 16); + polygon.Add(centerPosWorld + new Vector2(-210, -30) * 16); + polygon.Add(centerPosWorld + new Vector2(-150, -60) * 16); + polygon.Add(centerPosWorld + new Vector2(-50, -89) * 16); + polygon.Add(centerPosWorld + new Vector2(-20, -89) * 16); + polygon.Add(centerPosWorld + new Vector2(60, -50) * 16); + polygon.Add(centerPosWorld + new Vector2(120, -65) * 16); + polygon.Add(centerPosWorld + new Vector2(170, -60) * 16); + polygon.Add(centerPosWorld + new Vector2(210, -20) * 16); + polygon.Add(centerPosWorld + new Vector2(210, 0) * 16); + List bgArea = TileUtils.GetPolygonAreaOfTilePos(polygon); + + YggdrasilTown_Construct ytc = new YggdrasilTown_Construct(); + ytc.WorldAnchor = centerPosWorld + new Vector2(0, 704); + ytc.BgTiles = bgArea; + ytc.TileAnchor = new Point(i, j); + bgSystem.AddBackgroundSlide(ytc); + + GiantFurnace_Construct gfc = new GiantFurnace_Construct(); + gfc.WorldAnchor = centerPosWorld + new Vector2(181, 63) * 16 + new Vector2(4, 24); + gfc.BgTiles = TileUtils.GetAABBAreaOfTile((int)centerPosWorld.X / 16 + 134, (int)centerPosWorld.Y / 16 + 32, 92, 60); + gfc.TileAnchor = new Point(i, j); + bgSystem.AddBackgroundSlide(gfc); + + GiantFurnace_Construct_far gfcf = new GiantFurnace_Construct_far(); + gfcf.WorldAnchor = centerPosWorld + new Vector2(181, 63) * 16 + new Vector2(-264, -164); + gfcf.BgTiles = TileUtils.GetAABBAreaOfTile((int)centerPosWorld.X / 16 + 106, (int)centerPosWorld.Y / 16 + 34, 112, 60); + gfcf.TileAnchor = new Point(i, j); + bgSystem.AddBackgroundSlide(gfcf); + + GiantFurnace_Construct_sky gfcs = new GiantFurnace_Construct_sky(); + gfcs.WorldAnchor = centerPosWorld + new Vector2(0, -240); + gfcs.BgTiles = TileUtils.GetAABBAreaOfTile((int)centerPosWorld.X / 16 + 106, (int)centerPosWorld.Y / 16 + 4, 112, 90); + gfcs.TileAnchor = new Point(i, j); + bgSystem.AddBackgroundSlide(gfcs); + + FurnaceScoreShop fSS = new FurnaceScoreShop(); + fSS.WorldAnchor = centerPosWorld + new Vector2(-156, 920); + fSS.BgTiles = TileUtils.GetAABBAreaOfTile((int)centerPosWorld.X / 16 + 100, (int)centerPosWorld.Y / 16 + 78, 20, 14); + fSS.TileAnchor = new Point(i, j); + bgSystem.AddBackgroundSlide(fSS); + } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilGravelStoreGate.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilGravelStoreGate.cs new file mode 100644 index 000000000..4c2500845 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilGravelStoreGate.cs @@ -0,0 +1,76 @@ +using Everglow.Commons.TileHelper; +using Everglow.SubSpace; +using Everglow.SubSpace.Tiles; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; + +public class YggdrasilGravelStoreGate : RoomDoorTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = false; + TileUtils.DefaultToMultiTileWall(5, 5); + TileObjectData.addTile(Type); + AddMapEntry(new Color(86, 62, 44)); + } + + public void BuildPlayerRoomGen() + { + var mapIO = new MapIO(130, 130); + + mapIO.Read(ModIns.Mod.GetFileStream(ModAsset.GravelStore114x36_Path)); + + var it = mapIO.GetEnumerator(); + while (it.MoveNext()) + { + WorldGen.SquareTileFrame(it.CurrentCoord.X, it.CurrentCoord.Y); + WorldGen.SquareWallFrame(it.CurrentCoord.X, it.CurrentCoord.Y); + } + + for (int x = 20; x < 22; x++) + { + for (int y = 20; y < 23; y++) + { + Tile tile = TileUtils.SafeGetTile(x, y); + tile.WallType = 1; + ushort typeChange = (ushort)ModContent.TileType(); + if (y == 22) + { + typeChange = 0; + } + else + { + tile.TileFrameX = (short)((x - 20) * 18); + tile.TileFrameY = (short)((y - 20) * 18); + } + tile.TileType = typeChange; + tile.HasTile = true; + } + } + } + + public override bool RightClick(int i, int j) + { + Tile tile = Main.tile[i, j]; + var point = new Point(i - tile.TileFrameX / 18, j - tile.TileFrameY / 18); + RoomManager.EnterNextLevelRoom(point, new Point(150, 150), BuildPlayerRoomGen); + return false; + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + //var zero = new Vector2(Main.offScreenRange); + //if (Main.drawToScreen) + //{ + // zero = Vector2.Zero; + //} + //var color = new Color(55, 55, 55, 0); + //var tile = Main.tile[i, j]; + //int frameX = tile.TileFrameX; + //int frameY = tile.TileFrameY; + //Texture2D glow = ModAsset.YggdrasilGravelStoreGate.Value; + //spriteBatch.Draw(glow, new Vector2(i, j) * 16 - Main.screenPosition + zero, new Rectangle(frameX, frameY, 16, 18), color, 0f, Vector2.zeroVector, 1f, SpriteEffects.None, 0f); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilGravelStoreGate.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilGravelStoreGate.png new file mode 100644 index 000000000..9cdbd5a8b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilGravelStoreGate.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilGravelStoreGate_Exit.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilGravelStoreGate_Exit.cs new file mode 100644 index 000000000..4b8ba8450 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilGravelStoreGate_Exit.cs @@ -0,0 +1,38 @@ +using Everglow.SubSpace; +using Everglow.SubSpace.Tiles; +using Terraria.ObjectData; + +namespace Everglow.Yggdrasil.YggdrasilTown.Tiles; + +public class YggdrasilGravelStoreGate_Exit : RoomDoorTile +{ + public override void SetStaticDefaults() + { + Main.tileFrameImportant[Type] = true; + Main.tileLavaDeath[Type] = false; + TileUtils.DefaultToMultiTileWall(5, 5); + TileObjectData.addTile(Type); + AddMapEntry(new Color(86, 62, 44)); + } + + public override bool CanExplode(int i, int j) + { + return false; + } + + public override bool CanKillTile(int i, int j, ref bool blockDamaged) + { + return false; + } + + public override bool RightClick(int i, int j) + { + RoomManager.ExitALevelOfRoom(); + return true; + } + + public override void MouseOver(int i, int j) + { + Main.instance.MouseText("Exit Union."); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilGravelStoreGate_Exit.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilGravelStoreGate_Exit.png new file mode 100644 index 000000000..c03a99a13 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilGravelStoreGate_Exit.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilPlayerRoomDoor.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilPlayerRoomDoor.cs index 3f05c4ec9..47132e5fd 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilPlayerRoomDoor.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/YggdrasilPlayerRoomDoor.cs @@ -25,7 +25,7 @@ public void BuildPlayerRoomGen() for (int y = 20; y < 23; y++) { Tile tile = TileUtils.SafeGetTile(x, y); - tile.wall = 1; + tile.WallType = 1; ushort typeChange = (ushort)ModContent.TileType(); if (y == 22) { diff --git "a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/\347\262\276\347\201\265-0001-535x1332-21x8.png" "b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/\347\262\276\347\201\265-0001-535x1332-21x8.png" deleted file mode 100644 index ad6a3d2ca..000000000 Binary files "a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/\347\262\276\347\201\265-0001-535x1332-21x8.png" and /dev/null differ diff --git "a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/\347\262\276\347\201\265-0003-194x144-16x6.png" "b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/\347\262\276\347\201\265-0003-194x144-16x6.png" deleted file mode 100644 index 93e6519cf..000000000 Binary files "a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/\347\262\276\347\201\265-0003-194x144-16x6.png" and /dev/null differ diff --git "a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/\347\262\276\347\201\265-0003-218x142-24x8.png" "b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/\347\262\276\347\201\265-0003-218x142-24x8.png" deleted file mode 100644 index 51fd4253c..000000000 Binary files "a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/\347\262\276\347\201\265-0003-218x142-24x8.png" and /dev/null differ diff --git "a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/\347\262\276\347\201\265-0003-370x118-42x28.png" "b/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/\347\262\276\347\201\265-0003-370x118-42x28.png" deleted file mode 100644 index 53586fb40..000000000 Binary files "a/Sources/Modules/Yggdrasil/YggdrasilTown/Tiles/\347\262\276\347\201\265-0003-370x118-42x28.png" and /dev/null differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/TownMap.png b/Sources/Modules/Yggdrasil/YggdrasilTown/TownMap.png new file mode 100644 index 000000000..0eb9c321d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/TownMap.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreIcon.png b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreIcon.png new file mode 100644 index 000000000..bceed9d24 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreIcon.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI.cs new file mode 100644 index 000000000..15e3a5bf3 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI.cs @@ -0,0 +1,244 @@ +using Everglow.Commons.UI.UIElements; +using Everglow.Yggdrasil.YggdrasilTown.Items.Accessories.Furnace; +using Everglow.Yggdrasil.YggdrasilTown.Items.Fishing.FishingRods; +using Everglow.Yggdrasil.YggdrasilTown.Items.Weapons; +using Spine; + +namespace Everglow.Yggdrasil.YggdrasilTown.UI; + +public class FurnaceScoreMilestoneRewardUI : UIBlock +{ + // ==================== UI elements ==================== // + public FurnaceScoreMilestoneRewardUI_Itemslot[] FurnaceScoreMilestoneRewardSlots; + + public FurnaceScoreMilestoneRewardUI_VerticalScrollbar FurnaceScoreMilestoneRewardScrollbar; + + public static List MilestoneRewards = new List { 1000, 2000, 5000, 7000, 10000, 14000, 18000, 22000, 26000, 35000, 45000, 60000, 80000, 100000 }; + + public float WheelValue => FurnaceScoreMilestoneRewardScrollbar.WheelValue; + + public bool ShouldSetupItemSlots => FurnaceScoreMilestoneRewardSlots.Any(slot => (slot.ContainedItem.type == ItemID.None && slot.GetIndex() >= 0 && !Main.LocalPlayer.GetModPlayer().ReceivedReward[slot.GetIndex()])); + + public override void OnInitialization() + { + base.OnInitialization(); + Info.HiddenOverflow = true; + FurnaceScoreMilestoneRewardSlots = new FurnaceScoreMilestoneRewardUI_Itemslot[14]; + for (int i = 0; i < FurnaceScoreMilestoneRewardSlots.Length; i++) + { + int rewardType = 1; + int rewardStack = 1; + switch (i) + { + case 0: + rewardType = ModContent.ItemType(); + break; + case 1: + rewardType = ModContent.ItemType(); + break; + case 2: + rewardType = ModContent.ItemType(); + break; + case 3: + rewardType = ModContent.ItemType(); + break; + case 4: + rewardType = ModContent.ItemType(); + break; + case 5: + rewardType = ModContent.ItemType(); + break; + case 6: + rewardType = ModContent.ItemType(); + break; + case 7: + rewardType = ModContent.ItemType(); + break; + case 8: + rewardType = ItemID.PlatinumCoin; + break; + case 9: + rewardType = ItemID.PlatinumCoin; + rewardStack = 2; + break; + case 10: + rewardType = ItemID.PlatinumCoin; + rewardStack = 3; + break; + case 11: + rewardType = ItemID.PlatinumCoin; + rewardStack = 5; + break; + case 12: + rewardType = ItemID.PlatinumCoin; + rewardStack = 10; + break; + case 13: + rewardType = ItemID.PlatinumCoin; + rewardStack = 15; + break; + } + + Item item = new Item(); + item.SetDefaults(rewardType); + item.stack = rewardStack; + FurnaceScoreMilestoneRewardSlots[i] = new FurnaceScoreMilestoneRewardUI_Itemslot() + { + SlotBackTexture = ModAsset.FurnaceShop_Normal.Value, + ContainedItem = item, + CanPutInSlot = (item) => false, + CanTakeOutSlot = (item) => false, + CornerSize = new Vector2(10, 10), + DrawColor = Color.White, + Tooltip = "Furnace Score Milestone Reward Slot", + }; + Register(FurnaceScoreMilestoneRewardSlots[i]); + } + FurnaceScoreMilestoneRewardScrollbar = new FurnaceScoreMilestoneRewardUI_VerticalScrollbar(); + Register(FurnaceScoreMilestoneRewardScrollbar); + } + + public override void Calculation() + { + base.Calculation(); + Info.Left.SetValue(314, 0f); + Info.Top.SetValue(20, 0f); + Info.Width.SetValue(180, 0f); + Info.Height.SetValue(166, 0f); + for (int i = 0; i < FurnaceScoreMilestoneRewardSlots.Length; i++) + { + FurnaceScoreMilestoneRewardSlots[i].Info.Left.SetValue(110, 0f); + FurnaceScoreMilestoneRewardSlots[i].Info.Top.SetValue(10 + (13 - i) * 60 - FurnaceScoreMilestoneRewardScrollbar.WheelValue * 720, 0f); + FurnaceScoreMilestoneRewardSlots[i].Info.Width.SetValue(40, 0f); + FurnaceScoreMilestoneRewardSlots[i].Info.Height.SetValue(40, 0f); + if (YggdrasilTownFurnaceSystem.CurrentScore >= MilestoneRewards[i]) + { + FurnaceScoreMilestoneRewardSlots[i].SlotBackTexture = ModAsset.FurnaceScoreMilestoneRewardUI_Enable.Value; + } + else + { + FurnaceScoreMilestoneRewardSlots[i].SlotBackTexture = ModAsset.FurnaceScoreMilestoneRewardUI_Lock.Value; + } + } + } + + public override void Update(GameTime gt) + { + base.Update(gt); + Calculation(); + if (ShouldSetupItemSlots) + { + SetupItemSlots(); + } + } + + public void SetupItemSlots() + { + for (int i = 0; i < FurnaceScoreMilestoneRewardSlots.Length; i++) + { + int rewardType = 1; + int rewardStack = 1; + switch (i) + { + case 0: + rewardType = ModContent.ItemType(); + break; + case 1: + rewardType = ModContent.ItemType(); + break; + case 2: + rewardType = ModContent.ItemType(); + break; + case 3: + rewardType = ModContent.ItemType(); + break; + case 4: + rewardType = ModContent.ItemType(); + break; + case 5: + rewardType = ModContent.ItemType(); + break; + case 6: + rewardType = ModContent.ItemType(); + break; + case 7: + rewardType = ModContent.ItemType(); + break; + case 8: + rewardType = ItemID.PlatinumCoin; + break; + case 9: + rewardType = ItemID.PlatinumCoin; + rewardStack = 2; + break; + case 10: + rewardType = ItemID.PlatinumCoin; + rewardStack = 3; + break; + case 11: + rewardType = ItemID.PlatinumCoin; + rewardStack = 5; + break; + case 12: + rewardType = ItemID.PlatinumCoin; + rewardStack = 10; + break; + case 13: + rewardType = ItemID.PlatinumCoin; + rewardStack = 15; + break; + } + if (Main.LocalPlayer.GetModPlayer().ReceivedReward[i]) + { + rewardType = 0; + rewardStack = 1; + } + if (FurnaceScoreMilestoneRewardSlots[i].ContainedItem.type == ItemID.None) + { + Item item = new Item(); + item.SetDefaults(rewardType); + item.stack = rewardStack; + FurnaceScoreMilestoneRewardSlots[i].ContainedItem = item; + } + } + } + + public override void Draw(SpriteBatch sb) + { + base.Draw(sb); + } + + protected override void DrawSelf(SpriteBatch sb) + { + Rectangle destRec = Info.HitBox; + destRec.Y -= 2; + destRec.Height += 2; + Draw9Piece_Board(sb, destRec, new Color(0.66f, 0.66f, 0.66f, 0.66f)); + + // Texture2D tex = ModAsset.FurnaceScoreMilestoneRewardUI_RewardTree.Value; + // Rectangle bar_background_frame = new Rectangle(12, 1, 3, 5); + // Rectangle bar_value_frame = new Rectangle(12, 9, 3, 5); + // int bar_x = (int)(Info.Left.Pixel + 80); + // int bar_y = (int)(Info.Top.Pixel + Info.Width.Pixel + 80 - FurnaceScoreMilestoneRewardScrollbar.WheelValue * 720); + // int value = Math.Clamp((int)((100000 - Main.LocalPlayer.GetModPlayer().TotalFurnaceScore) * 900f), 0, 900); + // sb.Draw(tex, new Rectangle(bar_x - 3, bar_y, 6, 900), bar_background_frame, Color.White, 0f, Vector2.Zero, SpriteEffects.None, 0f); + // sb.Draw(tex, new Rectangle(bar_x - 3, bar_y + value, 6, 900 - value), bar_value_frame, Color.White, 0f, Vector2.Zero, SpriteEffects.None, 0f); + } + + public void Draw9Piece_Board(SpriteBatch spriteBatch, Rectangle destinationBox, Color drawColor) + { + Texture2D tex = ModAsset.FurnaceShop_Normal.Value; + int margin = 4; + spriteBatch.Draw(tex, new Rectangle(destinationBox.X, destinationBox.Y, margin, margin), new Rectangle(0, 0, margin, margin), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + margin, destinationBox.Y, destinationBox.Width - margin * 2, margin), new Rectangle(margin, 0, 2, margin), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + destinationBox.Width - margin, destinationBox.Y, margin, margin), new Rectangle(tex.Width - margin, 0, margin, margin), drawColor); + + spriteBatch.Draw(tex, new Rectangle(destinationBox.X, destinationBox.Y + margin, margin, destinationBox.Height - margin * 2), new Rectangle(0, margin, margin, 2), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + margin, destinationBox.Y + margin, destinationBox.Width - margin * 2, destinationBox.Height - margin * 2), new Rectangle(margin, margin, 2, 2), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + destinationBox.Width - margin, destinationBox.Y + margin, margin, destinationBox.Height - margin * 2), new Rectangle(tex.Width - margin, margin, margin, 2), drawColor); + + spriteBatch.Draw(tex, new Rectangle(destinationBox.X, destinationBox.Y + destinationBox.Height - margin, margin, margin), new Rectangle(0, tex.Height - margin, margin, margin), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + margin, destinationBox.Y + destinationBox.Height - margin, destinationBox.Width - margin * 2, margin), new Rectangle(margin, tex.Height - margin, 2, margin), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + destinationBox.Width - margin, destinationBox.Y + destinationBox.Height - margin, margin, margin), new Rectangle(tex.Width - margin, tex.Height - margin, margin, margin), drawColor); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Enable.png b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Enable.png new file mode 100644 index 000000000..e27a2a2f1 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Enable.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Itemslot.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Itemslot.cs new file mode 100644 index 000000000..7480d63dc --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Itemslot.cs @@ -0,0 +1,142 @@ +using Everglow.Commons.UI.UIElements; +using Terraria.GameContent; +using Terraria.UI.Chat; + +namespace Everglow.Yggdrasil.YggdrasilTown.UI; + +public class FurnaceScoreMilestoneRewardUI_Itemslot : UIItemSlot +{ + public override void OnInitialization() + { + base.OnInitialization(); + CanTakeOutSlot += CanTakeOut; + OnPickItem += (target) => + { + if (ParentElement is FurnaceScoreMilestoneRewardUI rewardUI) + { + int index = GetIndex(); + if (index >= 0 && index < FurnaceScoreMilestoneRewardUI.MilestoneRewards.Count) + { + int milestoneScore = FurnaceScoreMilestoneRewardUI.MilestoneRewards[index]; + if (Main.LocalPlayer.GetModPlayer().TotalFurnaceScore >= milestoneScore) + { + Main.LocalPlayer.GetModPlayer().ReceivedReward[index] = true; + } + } + } + }; + } + + public bool CanTakeOut(Item item) + { + if (ParentElement is FurnaceScoreMilestoneRewardUI rewardUI) + { + int index = GetIndex(); + if (index >= 0 && index < FurnaceScoreMilestoneRewardUI.MilestoneRewards.Count) + { + int milestoneScore = FurnaceScoreMilestoneRewardUI.MilestoneRewards[index]; + return Main.LocalPlayer.GetModPlayer().TotalFurnaceScore >= milestoneScore; + } + } + return false; + } + + public override void Update(GameTime gameTime) + { + if (ContainedItem.type > ItemID.None && Main.LocalPlayer.GetModPlayer().ReceivedReward[GetIndex()]) + { + ContainedItem = new Item(); + ContainedItem.SetDefaults(ItemID.None, true); + } + base.Update(gameTime); + } + + protected override void DrawSelf(SpriteBatch sb) + { + int index = GetIndex(); + FurnacePlayer fPlayer = Main.LocalPlayer.GetModPlayer(); + int score = fPlayer.TotalFurnaceScore; + int rewardThreod = FurnaceScoreMilestoneRewardUI.MilestoneRewards[index]; + if (score > rewardThreod) + { + SlotBackTexture = ModAsset.FurnaceScoreMilestoneRewardUI_Enable.Value; + if (fPlayer.ReceivedReward[index]) + { + SlotBackTexture = ModAsset.FurnaceScoreMilestoneRewardUI_Used.Value; + } + } + base.DrawSelf(sb); + + if (ParentElement is FurnaceScoreMilestoneRewardUI rewardUI) + { + Texture2D tex = ModAsset.FurnaceScoreMilestoneRewardUI_RewardTree.Value; + Rectangle bar_background_frame = new Rectangle(12, 1, 3, 5); + Rectangle bar_value_frame = new Rectangle(12, 9, 3, 5); + Rectangle bar_top_frame = new Rectangle(12, 7, 3, 1); + Rectangle joint = new Rectangle(0, 1, 11, 5); + Rectangle connectLine = new Rectangle(0, 16, 15, 1); + int revertIndex = 13 - index; + int bar_x = Info.TotalHitBox.Left - 30; + int bar_y = Info.TotalHitBox.Top + 15; + int min = 0; + if (index >= 1) + { + min = FurnaceScoreMilestoneRewardUI.MilestoneRewards[index - 1]; + } + int max = rewardThreod; + int range = max - min; + int value = Math.Clamp((int)((score - min) / (float)range * 60f), 0, 60); + sb.Draw(tex, new Rectangle(bar_x - 3, bar_y, 6, 56), bar_background_frame, Color.White, 0f, Vector2.Zero, SpriteEffects.None, 0f); + sb.Draw(tex, new Rectangle(bar_x - 3, bar_y + 56 - value, 6, Math.Max(value, 0)), bar_value_frame, Color.White, 0f, Vector2.Zero, SpriteEffects.None, 0f); + if (value is > 0 and < 60) + { + sb.Draw(tex, new Rectangle(bar_x - 3, bar_y + 56 - value, 6, 2), bar_top_frame, Color.White, 0f, Vector2.Zero, SpriteEffects.None, 0f); + } + if (score >= rewardThreod) + { + joint = new Rectangle(0, 9, 11, 5); + connectLine = new Rectangle(0, 19, 15, 1); + if (fPlayer.ReceivedReward[index]) + { + connectLine = new Rectangle(0, 22, 15, 1); + } + } + sb.Draw(tex, new Rectangle(bar_x - 11, bar_y - 5, 22, 10), joint, Color.White, 0f, Vector2.Zero, SpriteEffects.None, 0f); + sb.Draw(tex, new Rectangle(bar_x + 12, bar_y - 1, 18, 2), connectLine, Color.White, 0f, Vector2.Zero, SpriteEffects.None, 0f); + + Texture2D tick = ModAsset.FurnaceScoreMilestoneRewardUI_Used_Icon.Value; + sb.Draw(tick, Info.TotalHitBox.Center(), null, Color.White, 0f, tick.Size() * 0.5f, 1f, SpriteEffects.None, 0f); + } + + Color texColor = Color.White; + Color texBoundColor = Color.Black; + if (score < rewardThreod) + { + Texture2D texLock = ModAsset.FurnaceScoreMilestoneRewardUI_Lock.Value; + var DrawRectangle = Info.TotalHitBox; + DrawAdvBox(sb, DrawRectangle.X, DrawRectangle.Y, + DrawRectangle.Width, DrawRectangle.Height, + DrawColor * 0.75f, ModAsset.FurnaceScoreMilestoneRewardUI_Lock.Value, CornerSize, 1f); + texColor = new Color(0.24f, 0.2f, 0.2f, 1); + texBoundColor = new Color(0.12f, 0.12f, 0.12f, 1f); + } + string neededScore = FurnaceScoreMilestoneRewardUI.MilestoneRewards[GetIndex()].ToString(); + Vector2 textSize = ChatManager.GetStringSize(FontAssets.MouseText.Value, neededScore, Vector2.One, -1f); + Utils.DrawBorderStringFourWay(Main.spriteBatch, FontAssets.MouseText.Value, neededScore, Info.TotalHitBox.X - 40 - textSize.X, Info.TotalHitBox.Center().Y - 15, texColor, texBoundColor, Vector2.Zero, 1f); + } + + public int GetIndex() + { + if (ParentElement is FurnaceScoreMilestoneRewardUI rewardUI) + { + for (int i = 0; i < rewardUI.FurnaceScoreMilestoneRewardSlots.Length; i++) + { + if (rewardUI.FurnaceScoreMilestoneRewardSlots[i] == this) + { + return i; + } + } + } + return -1; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Lock.png b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Lock.png new file mode 100644 index 000000000..aab0d9c96 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Lock.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_RewardTree.png b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_RewardTree.png new file mode 100644 index 000000000..2ae622fea Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_RewardTree.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Scrollbar.png b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Scrollbar.png new file mode 100644 index 000000000..c6eb1747e Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Scrollbar.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Used.png b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Used.png new file mode 100644 index 000000000..2674e5750 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Used.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Used_Icon.png b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Used_Icon.png new file mode 100644 index 000000000..697dae624 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_Used_Icon.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_VerticalScrollbar.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_VerticalScrollbar.cs new file mode 100644 index 000000000..49a07b4a4 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreMilestoneRewardUI_VerticalScrollbar.cs @@ -0,0 +1,146 @@ +using Everglow.Commons.UI.UIElements; + +namespace Everglow.Yggdrasil.YggdrasilTown.UI +{ + public class FurnaceScoreMilestoneRewardUI_VerticalScrollbar : UIVerticalScrollbar + { + public override float Scale => 1f; + + public override float TopMax => -7f * Scale; + + public override float TopMin => -7f * Scale; + + private bool _mouseOver = false; + + /// + /// 上下箭头 + /// + private UIBlock _scrollbarArrow = new UIBlock(); + + /// + /// è½¨é“ + /// + private UIBlock _scrollbarTrack = new UIBlock(); + + /// + /// æ»‘å— + /// + private UIBlock _scrollbarThumb = new UIBlock(); + + public FurnaceScoreMilestoneRewardUI_VerticalScrollbar() + { + Info.Width.SetValue(2f, 0f); + _innerScale = new Vector2(22f, 50f); + AlwaysOnLight = true; + + Events.OnMouseHover += e => + { + _mouseOver = true; + }; + Events.OnMouseOut += e => + { + _mouseOver = false; + }; + + _scrollbarArrow.ShowBorder = _scrollbarTrack.ShowBorder = _scrollbarThumb.ShowBorder = (false, false, false, false); + _scrollbarArrow.PanelColor = Color.Transparent; + _scrollbarTrack.PanelColor = Color.Transparent; + _scrollbarThumb.PanelColor = Color.Transparent; + + var mask = new UIBlock(); + mask.Info.Width.SetValue(4f, 0f); + mask.Info.Height.SetValue(1f, 0f); + mask.Info.CanBeInteract = false; + mask.Info.SetToCenter(); + mask.Info.Top.SetValue(1f, 0f); + mask.ShowBorder = (false, false, false, false); + mask.PanelColor = _scrollbarArrow.PanelColor; + Register(mask); + + mask = new UIBlock(); + mask.Info.Width.SetValue(4f, 0f); + mask.Info.Height.SetValue(1f, 0f); + mask.Info.CanBeInteract = false; + mask.Info.SetToCenter(); + mask.Info.Top.SetValue(-2f, 1f); + mask.ShowBorder = (false, false, false, false); + mask.PanelColor = _scrollbarArrow.PanelColor; + Register(mask); + + _wheelValue = 1f; + } + + public override void Update(GameTime gt) + { + ChildrenElements.ForEach(child => + { + if (child != null && child.IsVisible) + { + child.Update(gt); + } + }); + + if (IsVisible) + { + Events.Update(this, gt); + } + + var innerHeight = 1f * _innerScale.Y; + float height = Info.TotalSize.Y - TopMax - TopMin - innerHeight; + if (_isMouseDown) + { + WheelValue = (Main.mouseY - + Info.TotalLocation.Y - TopMin - innerHeight / 2f) / height; + } + + if (_wheelValue != _waitToWheelValue) + { + _wheelValue += (_waitToWheelValue - _wheelValue) / 4f; + Calculation(); + } + } + + public override bool ContainsPoint(Point point) + { + Rectangle containBar = Info.HitBox; + containBar.X -= 10; + containBar.Width += 20; + return base.ContainsPoint(point) || containBar.Contains(point.X, point.Y); + } + + public override void Calculation() + { + base.Calculation(); + _scrollbarArrow.Info.TotalHitBox = _scrollbarTrack.Info.TotalHitBox = Info.TotalHitBox; + + var innerHeight = _innerScale.Y; + float height = Info.TotalSize.Y - TopMax - TopMin - innerHeight; + var top = TopMin + height * WheelValue; + _scrollbarThumb.Info.TotalHitBox = new Rectangle( + (int)(Info.TotalLocation.X - (UIScrollbarInnerTexture.Width * _innerScale.X - Info.TotalSize.X) / 2f), + (int)(Info.TotalLocation.Y + top), + (int)_innerScale.X, + (int)_innerScale.Y); + _scrollbarArrow.Info.TotalHitBox.Height = Math.Max(2, _scrollbarThumb.Info.TotalHitBox.Y - Info.TotalHitBox.Y - 1); + _scrollbarTrack.Info.TotalHitBox.Y = Math.Max( + _scrollbarTrack.Info.TotalHitBox.Bottom - Info.TotalHitBox.Height - 2, + _scrollbarThumb.Info.TotalHitBox.Bottom + 1); + _scrollbarTrack.Info.TotalHitBox.Height = Math.Max(2, Info.TotalHitBox.Bottom - _scrollbarTrack.Info.TotalHitBox.Y); + } + + protected override void DrawSelf(SpriteBatch sb) + { + var tex = ModAsset.FurnaceScoreMilestoneRewardUI_Scrollbar.Value; + var trackScale = new Vector2(1, Info.TotalHitBox.Height / (float)tex.Height); + sb.Draw(tex, Info.TotalHitBox.Top() + new Vector2(0, 0), new Rectangle(0, 0, 4, 3), Color.White, 0, new Vector2(2, 3), 2, SpriteEffects.None, 0); + sb.Draw(tex, new Rectangle(Info.TotalHitBox.Center.X - 4, Info.TotalHitBox.Top + 4, 8, Info.TotalHitBox.Height - 10), new Rectangle(0, 4, 4, 16), Color.White); + sb.Draw(tex, Info.TotalHitBox.Top() + new Vector2(0, Info.TotalHitBox.Height), new Rectangle(0, 21, 4, 3), Color.White, 0, new Vector2(2, 0), 2, SpriteEffects.None, 0); + var thumbFrame = new Rectangle(7, 0, 6, 16); + if (_mouseOver || _isMouseDown) + { + thumbFrame = new Rectangle(21, 0, 6, 16); + } + sb.Draw(tex, _scrollbarThumb.Info.TotalHitBox.Center(), thumbFrame, Color.White, 0, thumbFrame.Size() * 0.5f, 2f, SpriteEffects.None, 0); + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreShopUI.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreShopUI.cs new file mode 100644 index 000000000..3dac402b1 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreShopUI.cs @@ -0,0 +1,123 @@ +using Everglow.Commons.UI; +using Everglow.Commons.UI.UIElements; +using Everglow.Yggdrasil.YggdrasilTown.Items.Weapons; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; +using Terraria.GameContent; + +namespace Everglow.Yggdrasil.YggdrasilTown.UI; + +public class FurnaceScoreShopUI : UIContainerElement +{ + public static FurnaceScoreShopUI Instance => (FurnaceScoreShopUI)UISystem.EverglowUISystem.Elements[typeof(FurnaceScoreShopUI).FullName]; + + // ==================== UI elements ==================== // + public FurnaceScoreShop_Itemslot[] FurnaceScoreShopItemSlots; + + public FurnaceScoreMilestoneRewardUI _mileStoneRewardUI; + + public bool ShouldSetupShopItems = true; + + public override void OnInitialization() + { + base.OnInitialization(); + FurnaceScoreShopItemSlots = new FurnaceScoreShop_Itemslot[28]; + for (int i = 0; i < FurnaceScoreShopItemSlots.Length; i++) + { + FurnaceScoreShopItemSlots[i] = new FurnaceScoreShop_Itemslot() + { + SlotBackTexture = ModAsset.FurnaceShop_Normal.Value, + ContainedItem = new Item(0, 1), + CanPutInSlot = (item) => false, + CanTakeOutSlot = (item) => false, + CornerSize = new Vector2(10, 10), + DrawColor = Color.White, + Tooltip = "Furnace Score Shop Item Slot", + }; + Register(FurnaceScoreShopItemSlots[i]); + } + _mileStoneRewardUI = new FurnaceScoreMilestoneRewardUI() + { + CanDrag = false, + }; + Register(_mileStoneRewardUI); + } + + public override void Calculation() + { + base.Calculation(); + Info.Left.SetValue(0, 0f); + Info.Top.SetValue(240, 0f); + Info.Width.SetValue(480, 0f); + Info.Height.SetValue(300, 0f); + for (int i = 0; i < FurnaceScoreShopItemSlots.Length; i++) + { + FurnaceScoreShopItemSlots[i].Info.Left.SetValue(20 + i % 7 * 42, 0f); + FurnaceScoreShopItemSlots[i].Info.Top.SetValue(20 + i / 7 * 42, 0f); + FurnaceScoreShopItemSlots[i].Info.Width.SetValue(38, 0f); + FurnaceScoreShopItemSlots[i].Info.Height.SetValue(38, 0f); + } + } + + public override void Update(GameTime gt) + { + base.Update(gt); + if (Main.LocalPlayer.chest > -1 || Main.LocalPlayer.talkNPC > -1) + { + Instance.Close(); + } + Calculation(); + if (ShouldSetupShopItems) + { + SetupShopItems(); + } + } + + public void SetupShopItems() + { + FurnaceScoreShop.SellPricesInFurnaceScore = new Dictionary(); + for (int i = 0; i < FurnaceScoreShopItemSlots.Length; i++) + { + int rewardType = 0; + switch (i) + { + case 0: + rewardType = ModContent.ItemType(); + FurnaceScoreShop.SellPricesInFurnaceScore[rewardType] = 14500; + FurnaceScoreShopItemSlots[i].ShopSlot = true; + break; + case 1: + rewardType = ModContent.ItemType(); + FurnaceScoreShop.SellPricesInFurnaceScore[rewardType] = 15500; + FurnaceScoreShopItemSlots[i].ShopSlot = true; + break; + case 2: + rewardType = ModContent.ItemType(); + FurnaceScoreShop.SellPricesInFurnaceScore[rewardType] = 17000; + FurnaceScoreShopItemSlots[i].ShopSlot = true; + break; + case 3: + rewardType = ModContent.ItemType(); + FurnaceScoreShop.SellPricesInFurnaceScore[rewardType] = 14000; + FurnaceScoreShopItemSlots[i].ShopSlot = true; + break; + } + Item item = new Item(); + item.SetDefaults(rewardType); + + // TODO: Need a modded itemTooltip allocating feature. Now use 36 for Furnace Score Shop Itemslot. + item.tooltipContext = 36; + FurnaceScoreShopItemSlots[i].ContainedItem = item; + } + ShouldSetupShopItems = false; + } + + public override void Draw(SpriteBatch sb) + { + int score = Main.LocalPlayer.GetModPlayer().CurrentFurnaceScore; + Utils.DrawBorderStringFourWay(Main.spriteBatch, FontAssets.MouseText.Value, "Furnace Score Shop & Milestone Reward", 504f, Info.Top.Pixel + 18, Color.White * (Main.mouseTextColor / 255f), Color.Black, Vector2.Zero, 1f); + Texture2D tex = ModAsset.FurnaceScoreIcon.Value; + sb.Draw(tex, new Vector2(30f, Info.TotalHitBox.Bottom - 100), null, Color.White, 0, tex.Size() * 0.5f, 1f, SpriteEffects.None, 0); + Utils.DrawBorderStringFourWay(Main.spriteBatch, FontAssets.MouseText.Value, " : " + score, 20f, Info.TotalHitBox.Bottom - 110, Color.White * (Main.mouseTextColor / 255f), Color.Black, Vector2.Zero, 1f); + base.Draw(sb); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreShop_Itemslot.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreShop_Itemslot.cs new file mode 100644 index 000000000..69284e56e --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceScoreShop_Itemslot.cs @@ -0,0 +1,71 @@ +using Everglow.Commons.UI.UIElements; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; + +namespace Everglow.Yggdrasil.YggdrasilTown.UI; + +public class FurnaceScoreShop_Itemslot : UIItemSlot +{ + public override void OnInitialization() + { + base.OnInitialization(); + Info.Left.SetValue(20, 0f); + Info.Top.SetValue(20, 0f); + Info.Width.SetValue(36, 0f); + Info.Height.SetValue(36, 0f); + DrawColor = new Color(0.66f, 0.66f, 0.66f, 0.66f); + CanTakeOutSlot = CanTakeOut; + CanPutInSlot = CanPutIn; + OnPickItem += (target) => + { + int value = 0; + if (FurnaceScoreShop.SellPricesInFurnaceScore.ContainsKey(Main.mouseItem.type)) + { + value = FurnaceScoreShop.SellPricesInFurnaceScore[Main.mouseItem.type]; + } + Main.LocalPlayer.GetModPlayer().CurrentFurnaceScore -= value; + }; + OnPutItem += (target) => + { + int value = 0; + if (FurnaceScoreShop.SellPricesInFurnaceScore.ContainsKey(ContainedItem.type)) + { + value = FurnaceScoreShop.SellPricesInFurnaceScore[ContainedItem.type]; + } + Main.LocalPlayer.GetModPlayer().CurrentFurnaceScore += value; + ContainedItem = new Item(); + ContainedItem.SetDefaults(ItemID.None, true); + }; + } + + public int GetIndex(UIItemSlot slot) + { + for (int i = 0; i < FurnaceScoreShopUI.Instance.FurnaceScoreShopItemSlots.Length; i++) + { + if (FurnaceScoreShopUI.Instance.FurnaceScoreShopItemSlots[i] == slot) + { + return i; + } + } + return -1; + } + + public bool CanTakeOut(Item item) + { + int value = 0; + if (FurnaceScoreShop.SellPricesInFurnaceScore.ContainsKey(item.type)) + { + value = FurnaceScoreShop.SellPricesInFurnaceScore[item.type]; + } + return Main.LocalPlayer.GetModPlayer().CurrentFurnaceScore >= value; + } + + public bool CanPutIn(Item item) + { + return false; + } + + public override void Update(GameTime gameTime) + { + base.Update(gameTime); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceShop_Normal.png b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceShop_Normal.png new file mode 100644 index 000000000..f96a57b18 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/FurnaceShop_Normal.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/UI/LuggageStorageSlot.png b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/LuggageStorageSlot.png new file mode 100644 index 000000000..efd97ae88 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/UI/LuggageStorageSlot.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/Arena/NPCBossTagsSystem.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/Arena/NPCBossTagsSystem.cs index 02314cd25..e50ed2a08 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/Arena/NPCBossTagsSystem.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/Arena/NPCBossTagsSystem.cs @@ -5,7 +5,7 @@ namespace Everglow.Yggdrasil.YggdrasilTown.VFXs.Arena; [Pipeline(typeof(WCSPipeline))] -public class NPCBossTagsSystem : ForegroundVFX +public class NPCBossTagsSystem : TileVFX { public override CodeLayer DrawLayer => CodeLayer.PreDrawFilter; @@ -34,13 +34,13 @@ public class NPCBossTagsSystem : ForegroundVFX public override void OnSpawn() { - texture = ModAsset.NPCBossTagsSystem.Value; - OutScreenDistanceMax = 18000; + Texture = ModAsset.NPCBossTagsSystem.Value; + MaxDiatanceOutOfScreen = 18000; } public override void Update() { - OutScreenDistanceMax = 18000; + MaxDiatanceOutOfScreen = 18000; AnimationCoroutine.Update(); if (TargetBoss == null || !TargetBoss.active) { @@ -170,7 +170,7 @@ public override void Draw() } } int rowCount = (int)MathF.Sqrt(tagCount) + 1; - var topLeftPos = position + new Vector2(-rowCount * 80 / 2 + 40 + 16, -rowCount * 80 - 200 + 40 + 16); + var topLeftPos = Position + new Vector2(-rowCount * 80 / 2 + 40 + 16, -rowCount * 80 - 200 + 40 + 16); var tNLIY = TargetBoss.ModNPC as TownNPC_LiveInYggdrasil; if (tNLIY != null) @@ -232,7 +232,7 @@ public override void Draw() new Vertex2D(backgroundPos + new Vector2(0, backgroundHeight), backGroundColor, new Vector3(0, 0, 0)), new Vertex2D(backgroundPos + new Vector2(backgroundWidth, backgroundHeight), backGroundColor, new Vector3(0, 0, 0)), }; - Ins.Batch.Draw(texture, blackBackground, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, blackBackground, PrimitiveType.TriangleStrip); if (StartFighting) { @@ -310,13 +310,13 @@ public override void Draw() Color orColor = drawColor * 0.5f; var orTag = new List() { - new Vertex2D(drawPos + new Vector2(-24, -16), orColor, new Vector3(294f / texture.Width, 0, 0)), - new Vertex2D(drawPos + new Vector2(24, -16), orColor, new Vector3(358f / texture.Width, 0, 0)), + new Vertex2D(drawPos + new Vector2(-24, -16), orColor, new Vector3(294f / Texture.Width, 0, 0)), + new Vertex2D(drawPos + new Vector2(24, -16), orColor, new Vector3(358f / Texture.Width, 0, 0)), - new Vertex2D(drawPos + new Vector2(-24, 16), orColor, new Vector3(294f / texture.Width, 38f / texture.Height, 0)), - new Vertex2D(drawPos + new Vector2(24, 16), orColor, new Vector3(358f / texture.Width, 38f / texture.Height, 0)), + new Vertex2D(drawPos + new Vector2(-24, 16), orColor, new Vector3(294f / Texture.Width, 38f / Texture.Height, 0)), + new Vertex2D(drawPos + new Vector2(24, 16), orColor, new Vector3(358f / Texture.Width, 38f / Texture.Height, 0)), }; - Ins.Batch.Draw(texture, orTag, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, orTag, PrimitiveType.TriangleStrip); drawPos += new Vector2(19); } } @@ -345,10 +345,10 @@ public override void Draw() } Main.instance.MouseText(tag.DisplayContents); } - float coordX0 = iType % 6 * 36 / (float)texture.Width; - float coordY0 = (iType - iType % 6) / 6f * 36 / texture.Height; - float coordX1 = (iType % 6 * 36 + 38) / (float)texture.Width; - float coordY1 = ((iType - iType % 6) / 6f * 36 + 38) / texture.Height; + float coordX0 = iType % 6 * 36 / (float)Texture.Width; + float coordY0 = (iType - iType % 6) / 6f * 36 / Texture.Height; + float coordX1 = (iType % 6 * 36 + 38) / (float)Texture.Width; + float coordY1 = ((iType - iType % 6) / 6f * 36 + 38) / Texture.Height; var bars = new List() { @@ -358,13 +358,13 @@ public override void Draw() new Vertex2D(drawPos + new Vector2(-iconWidth / 2f, iconWidth / 2f), drawColor, new Vector3(coordX0, coordY1, 0)), new Vertex2D(drawPos + new Vector2(iconWidth / 2f, iconWidth / 2f), drawColor, new Vector3(coordX1, coordY1, 0)), }; - Ins.Batch.Draw(texture, bars, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, bars, PrimitiveType.TriangleStrip); drawPosIndex++; } // Start Button var startButtonColor = new Color(50, 50, 50, 0); - var startButtonPos = position + new Vector2(-35 + 16, -80); + var startButtonPos = Position + new Vector2(-35 + 16, -80); if (MouseInArea(startButtonPos, new Vector2(70, 38))) { startButtonColor = Color.Lerp(startButtonColor, new Color(255, 220, 125, 0), 0.5f); @@ -387,17 +387,17 @@ public override void Draw() } var startButton = new List() { - new Vertex2D(startButtonPos, startButtonColor, new Vector3(222f / texture.Width, 0, 0)), - new Vertex2D(startButtonPos + new Vector2(70, 0), startButtonColor, new Vector3(292f / texture.Width, 0, 0)), + new Vertex2D(startButtonPos, startButtonColor, new Vector3(222f / Texture.Width, 0, 0)), + new Vertex2D(startButtonPos + new Vector2(70, 0), startButtonColor, new Vector3(292f / Texture.Width, 0, 0)), - new Vertex2D(startButtonPos + new Vector2(0, 38), startButtonColor, new Vector3(222f / texture.Width, 38f / texture.Height, 0)), - new Vertex2D(startButtonPos + new Vector2(70, 38), startButtonColor, new Vector3(292f / texture.Width, 38f / texture.Height, 0)), + new Vertex2D(startButtonPos + new Vector2(0, 38), startButtonColor, new Vector3(222f / Texture.Width, 38f / Texture.Height, 0)), + new Vertex2D(startButtonPos + new Vector2(70, 38), startButtonColor, new Vector3(292f / Texture.Width, 38f / Texture.Height, 0)), }; - Ins.Batch.Draw(texture, startButton, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, startButton, PrimitiveType.TriangleStrip); // All Enable Button var allEnableButtonColor = new Color(50, 50, 110, 0); - var allEnableButtonPos = position + new Vector2(-35 + 16 - 60, -80); + var allEnableButtonPos = Position + new Vector2(-35 + 16 - 60, -80); if (MouseInArea(allEnableButtonPos, new Vector2(70, 38))) { allEnableButtonColor = Color.Lerp(allEnableButtonColor, new Color(255, 220, 125, 0), 0.5f); @@ -409,17 +409,17 @@ public override void Draw() } var allEnableButton = new List() { - new Vertex2D(allEnableButtonPos, allEnableButtonColor, new Vector3(36f / texture.Width, 180f / texture.Height, 0)), - new Vertex2D(allEnableButtonPos + new Vector2(38, 0), allEnableButtonColor, new Vector3(74f / texture.Width, 180f / texture.Height, 0)), + new Vertex2D(allEnableButtonPos, allEnableButtonColor, new Vector3(36f / Texture.Width, 180f / Texture.Height, 0)), + new Vertex2D(allEnableButtonPos + new Vector2(38, 0), allEnableButtonColor, new Vector3(74f / Texture.Width, 180f / Texture.Height, 0)), - new Vertex2D(allEnableButtonPos + new Vector2(0, 38), allEnableButtonColor, new Vector3(36f / texture.Width, 218f / texture.Height, 0)), - new Vertex2D(allEnableButtonPos + new Vector2(38, 38), allEnableButtonColor, new Vector3(74f / texture.Width, 218f / texture.Height, 0)), + new Vertex2D(allEnableButtonPos + new Vector2(0, 38), allEnableButtonColor, new Vector3(36f / Texture.Width, 218f / Texture.Height, 0)), + new Vertex2D(allEnableButtonPos + new Vector2(38, 38), allEnableButtonColor, new Vector3(74f / Texture.Width, 218f / Texture.Height, 0)), }; - Ins.Batch.Draw(texture, allEnableButton, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, allEnableButton, PrimitiveType.TriangleStrip); // All Disable Button var allDisableButtonColor = new Color(60, 5, 20, 0); - var allDisableButtonPos = position + new Vector2(-35 + 16 + 95, -80); + var allDisableButtonPos = Position + new Vector2(-35 + 16 + 95, -80); if (MouseInArea(allDisableButtonPos, new Vector2(70, 38))) { allDisableButtonColor = Color.Lerp(allDisableButtonColor, new Color(255, 220, 125, 0), 0.5f); @@ -431,17 +431,17 @@ public override void Draw() } var allDisableButton = new List() { - new Vertex2D(allDisableButtonPos, allDisableButtonColor, new Vector3(36f / texture.Width, 180f / texture.Height, 0)), - new Vertex2D(allDisableButtonPos + new Vector2(38, 0), allDisableButtonColor, new Vector3(74f / texture.Width, 180f / texture.Height, 0)), + new Vertex2D(allDisableButtonPos, allDisableButtonColor, new Vector3(36f / Texture.Width, 180f / Texture.Height, 0)), + new Vertex2D(allDisableButtonPos + new Vector2(38, 0), allDisableButtonColor, new Vector3(74f / Texture.Width, 180f / Texture.Height, 0)), - new Vertex2D(allDisableButtonPos + new Vector2(0, 38), allDisableButtonColor, new Vector3(36f / texture.Width, 218f / texture.Height, 0)), - new Vertex2D(allDisableButtonPos + new Vector2(38, 38), allDisableButtonColor, new Vector3(74f / texture.Width, 218f / texture.Height, 0)), + new Vertex2D(allDisableButtonPos + new Vector2(0, 38), allDisableButtonColor, new Vector3(36f / Texture.Width, 218f / Texture.Height, 0)), + new Vertex2D(allDisableButtonPos + new Vector2(38, 38), allDisableButtonColor, new Vector3(74f / Texture.Width, 218f / Texture.Height, 0)), }; - Ins.Batch.Draw(texture, allDisableButton, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, allDisableButton, PrimitiveType.TriangleStrip); // Score Display var scoreColor = new Color(150, 150, 150, 0); - var scorePos = position + new Vector2(0, -110); + var scorePos = Position + new Vector2(0, -110); int offSetX = 18; int vScore = (int)VisualScore; DrawNumber(vScore, scorePos + new Vector2(0 + offSetX, -40), 1f, scoreColor); @@ -456,11 +456,11 @@ public void DrawNumber(int number, Vector2 centerPos, float size, Color color) Vector2 numberTopLeft = new Vector2(2 + 52 * (number % 10), 254); Vector2 drawPos = centerPos; scoreDraw = new List(); - scoreDraw.Add(drawPos - numberSize * 0.5f, color, new Vector3(numberTopLeft / texture.Size(), 0)); - scoreDraw.Add(drawPos + new Vector2(numberSize.X, -numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(numberSize.X, 0)) / texture.Size(), 0)); - scoreDraw.Add(drawPos + new Vector2(-numberSize.X, numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(0, numberSize.Y)) / texture.Size(), 0)); - scoreDraw.Add(drawPos + numberSize * 0.5f, color, new Vector3((numberTopLeft + numberSize) / texture.Size(), 0)); - Ins.Batch.Draw(texture, scoreDraw, PrimitiveType.TriangleStrip); + scoreDraw.Add(drawPos - numberSize * 0.5f, color, new Vector3(numberTopLeft / Texture.Size(), 0)); + scoreDraw.Add(drawPos + new Vector2(numberSize.X, -numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(numberSize.X, 0)) / Texture.Size(), 0)); + scoreDraw.Add(drawPos + new Vector2(-numberSize.X, numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(0, numberSize.Y)) / Texture.Size(), 0)); + scoreDraw.Add(drawPos + numberSize * 0.5f, color, new Vector3((numberTopLeft + numberSize) / Texture.Size(), 0)); + Ins.Batch.Draw(Texture, scoreDraw, PrimitiveType.TriangleStrip); } if (number.ToString().Length == 2) { @@ -469,20 +469,20 @@ public void DrawNumber(int number, Vector2 centerPos, float size, Color color) Vector2 numberTopLeft = new Vector2(2 + 52 * firstNumber, 254); Vector2 drawPos = centerPos + new Vector2(27 * size, 0); scoreDraw = new List(); - scoreDraw.Add(drawPos - numberSize * 0.5f, color, new Vector3(numberTopLeft / texture.Size(), 0)); - scoreDraw.Add(drawPos + new Vector2(numberSize.X, -numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(numberSize.X, 0)) / texture.Size(), 0)); - scoreDraw.Add(drawPos + new Vector2(-numberSize.X, numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(0, numberSize.Y)) / texture.Size(), 0)); - scoreDraw.Add(drawPos + numberSize * 0.5f, color, new Vector3((numberTopLeft + numberSize) / texture.Size(), 0)); - Ins.Batch.Draw(texture, scoreDraw, PrimitiveType.TriangleStrip); + scoreDraw.Add(drawPos - numberSize * 0.5f, color, new Vector3(numberTopLeft / Texture.Size(), 0)); + scoreDraw.Add(drawPos + new Vector2(numberSize.X, -numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(numberSize.X, 0)) / Texture.Size(), 0)); + scoreDraw.Add(drawPos + new Vector2(-numberSize.X, numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(0, numberSize.Y)) / Texture.Size(), 0)); + scoreDraw.Add(drawPos + numberSize * 0.5f, color, new Vector3((numberTopLeft + numberSize) / Texture.Size(), 0)); + Ins.Batch.Draw(Texture, scoreDraw, PrimitiveType.TriangleStrip); numberTopLeft = new Vector2(2 + 52 * secondNumber, 254); drawPos = centerPos + new Vector2(-27 * size, 0); scoreDraw = new List(); - scoreDraw.Add(drawPos - numberSize * 0.5f, color, new Vector3(numberTopLeft / texture.Size(), 0)); - scoreDraw.Add(drawPos + new Vector2(numberSize.X, -numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(numberSize.X, 0)) / texture.Size(), 0)); - scoreDraw.Add(drawPos + new Vector2(-numberSize.X, numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(0, numberSize.Y)) / texture.Size(), 0)); - scoreDraw.Add(drawPos + numberSize * 0.5f, color, new Vector3((numberTopLeft + numberSize) / texture.Size(), 0)); - Ins.Batch.Draw(texture, scoreDraw, PrimitiveType.TriangleStrip); + scoreDraw.Add(drawPos - numberSize * 0.5f, color, new Vector3(numberTopLeft / Texture.Size(), 0)); + scoreDraw.Add(drawPos + new Vector2(numberSize.X, -numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(numberSize.X, 0)) / Texture.Size(), 0)); + scoreDraw.Add(drawPos + new Vector2(-numberSize.X, numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(0, numberSize.Y)) / Texture.Size(), 0)); + scoreDraw.Add(drawPos + numberSize * 0.5f, color, new Vector3((numberTopLeft + numberSize) / Texture.Size(), 0)); + Ins.Batch.Draw(Texture, scoreDraw, PrimitiveType.TriangleStrip); } if (number.ToString().Length == 3) { @@ -492,29 +492,29 @@ public void DrawNumber(int number, Vector2 centerPos, float size, Color color) Vector2 numberTopLeft = new Vector2(2 + 52 * firstNumber, 254); Vector2 drawPos = centerPos + new Vector2(54 * size, 0); scoreDraw = new List(); - scoreDraw.Add(drawPos - numberSize * 0.5f, color, new Vector3(numberTopLeft / texture.Size(), 0)); - scoreDraw.Add(drawPos + new Vector2(numberSize.X, -numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(numberSize.X, 0)) / texture.Size(), 0)); - scoreDraw.Add(drawPos + new Vector2(-numberSize.X, numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(0, numberSize.Y)) / texture.Size(), 0)); - scoreDraw.Add(drawPos + numberSize * 0.5f, color, new Vector3((numberTopLeft + numberSize) / texture.Size(), 0)); - Ins.Batch.Draw(texture, scoreDraw, PrimitiveType.TriangleStrip); + scoreDraw.Add(drawPos - numberSize * 0.5f, color, new Vector3(numberTopLeft / Texture.Size(), 0)); + scoreDraw.Add(drawPos + new Vector2(numberSize.X, -numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(numberSize.X, 0)) / Texture.Size(), 0)); + scoreDraw.Add(drawPos + new Vector2(-numberSize.X, numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(0, numberSize.Y)) / Texture.Size(), 0)); + scoreDraw.Add(drawPos + numberSize * 0.5f, color, new Vector3((numberTopLeft + numberSize) / Texture.Size(), 0)); + Ins.Batch.Draw(Texture, scoreDraw, PrimitiveType.TriangleStrip); numberTopLeft = new Vector2(2 + 52 * secondNumber, 254); drawPos = centerPos + new Vector2(0, 0); scoreDraw = new List(); - scoreDraw.Add(drawPos - numberSize * 0.5f, color, new Vector3(numberTopLeft / texture.Size(), 0)); - scoreDraw.Add(drawPos + new Vector2(numberSize.X, -numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(numberSize.X, 0)) / texture.Size(), 0)); - scoreDraw.Add(drawPos + new Vector2(-numberSize.X, numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(0, numberSize.Y)) / texture.Size(), 0)); - scoreDraw.Add(drawPos + numberSize * 0.5f, color, new Vector3((numberTopLeft + numberSize) / texture.Size(), 0)); - Ins.Batch.Draw(texture, scoreDraw, PrimitiveType.TriangleStrip); + scoreDraw.Add(drawPos - numberSize * 0.5f, color, new Vector3(numberTopLeft / Texture.Size(), 0)); + scoreDraw.Add(drawPos + new Vector2(numberSize.X, -numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(numberSize.X, 0)) / Texture.Size(), 0)); + scoreDraw.Add(drawPos + new Vector2(-numberSize.X, numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(0, numberSize.Y)) / Texture.Size(), 0)); + scoreDraw.Add(drawPos + numberSize * 0.5f, color, new Vector3((numberTopLeft + numberSize) / Texture.Size(), 0)); + Ins.Batch.Draw(Texture, scoreDraw, PrimitiveType.TriangleStrip); numberTopLeft = new Vector2(2 + 52 * thirdNumber, 254); drawPos = centerPos + new Vector2(-54 * size, 0); scoreDraw = new List(); - scoreDraw.Add(drawPos - numberSize * 0.5f, color, new Vector3(numberTopLeft / texture.Size(), 0)); - scoreDraw.Add(drawPos + new Vector2(numberSize.X, -numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(numberSize.X, 0)) / texture.Size(), 0)); - scoreDraw.Add(drawPos + new Vector2(-numberSize.X, numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(0, numberSize.Y)) / texture.Size(), 0)); - scoreDraw.Add(drawPos + numberSize * 0.5f, color, new Vector3((numberTopLeft + numberSize) / texture.Size(), 0)); - Ins.Batch.Draw(texture, scoreDraw, PrimitiveType.TriangleStrip); + scoreDraw.Add(drawPos - numberSize * 0.5f, color, new Vector3(numberTopLeft / Texture.Size(), 0)); + scoreDraw.Add(drawPos + new Vector2(numberSize.X, -numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(numberSize.X, 0)) / Texture.Size(), 0)); + scoreDraw.Add(drawPos + new Vector2(-numberSize.X, numberSize.Y) * 0.5f, color, new Vector3((numberTopLeft + new Vector2(0, numberSize.Y)) / Texture.Size(), 0)); + scoreDraw.Add(drawPos + numberSize * 0.5f, color, new Vector3((numberTopLeft + numberSize) / Texture.Size(), 0)); + Ins.Batch.Draw(Texture, scoreDraw, PrimitiveType.TriangleStrip); } } @@ -539,7 +539,7 @@ public void DrawRemovingPlatformEffect(string type) removePlatform.Add(new Vector2(left, posY + height), drawColor, new Vector3(0, 0, 0)); removePlatform.Add(new Vector2(right, posY + height), drawColor, new Vector3(0, 0, 0)); - Ins.Batch.Draw(texture, removePlatform, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, removePlatform, PrimitiveType.TriangleStrip); } if (type == "RemoveLeftPlatform" || type == "RemoveRightPlatform") @@ -565,7 +565,7 @@ public void DrawRemovingPlatformEffect(string type) removePlatform.Add(new Vector2(left, posY + height), drawColor, new Vector3(0, 0, 0)); removePlatform.Add(new Vector2(right, posY + height), drawColor, new Vector3(0, 0, 0)); - Ins.Batch.Draw(texture, removePlatform, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, removePlatform, PrimitiveType.TriangleStrip); posY = 185 * 16; removePlatform = new List(); @@ -574,7 +574,7 @@ public void DrawRemovingPlatformEffect(string type) removePlatform.Add(new Vector2(left, posY + height), drawColor, new Vector3(0, 0, 0)); removePlatform.Add(new Vector2(right, posY + height), drawColor, new Vector3(0, 0, 0)); - Ins.Batch.Draw(texture, removePlatform, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, removePlatform, PrimitiveType.TriangleStrip); } } @@ -623,7 +623,7 @@ public void DrawHealthBar(int backgroundWidth, int backgroundHeight, Vector2 bac new Vertex2D(healthBarPos + new Vector2(-innerGridSize / 2f, innerGridSize / 2f) * scaleFactor, healthColorOld, new Vector3(0, 0, 0)), new Vertex2D(healthBarPos + new Vector2(innerGridSize / 2f, innerGridSize / 2f) * scaleFactor, healthColorOld, new Vector3(0, 0, 0)), }; - Ins.Batch.Draw(texture, healthBar, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, healthBar, PrimitiveType.TriangleStrip); scaleFactor = 1f; @@ -645,7 +645,7 @@ public void DrawHealthBar(int backgroundWidth, int backgroundHeight, Vector2 bac new Vertex2D(healthBarPos + new Vector2(-innerGridSize / 2f, innerGridSize / 2f) * scaleFactor, healthColor, new Vector3(0, 0, 0)), new Vertex2D(healthBarPos + new Vector2(innerGridSize / 2f, innerGridSize / 2f) * scaleFactor, healthColor, new Vector3(0, 0, 0)), }; - Ins.Batch.Draw(texture, healthBar, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Texture, healthBar, PrimitiveType.TriangleStrip); } } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/BackgroundPipeline.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/BackgroundPipeline.cs new file mode 100644 index 000000000..d29b00b92 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/BackgroundPipeline.cs @@ -0,0 +1,31 @@ +namespace Everglow.Yggdrasil.YggdrasilTown.VFXs; + +/// +/// If some VFX binding with background, use this make sure the matrix is correct. +/// +public class BackgroundPipeline : Pipeline +{ + public override void BeginRender() + { + Ins.Batch.Begin(); + var projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1); + if (Main.LocalPlayer.gravDir == -1) + { + projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, 0, Main.screenHeight, 0, 1); + } + effect.Value.Parameters["uTransform"].SetValue( + Matrix.CreateTranslation(new Vector3(-Main.screenPosition, 0)) * + projection); + effect.Value.CurrentTechnique.Passes[0].Apply(); + } + + public override void EndRender() + { + Ins.Batch.End(); + } + + public override void Load() + { + effect = VFXManager.DefaultEffect; + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/DarkSludge_Liquid.png b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/DarkSludge_Liquid.png deleted file mode 100644 index 2c3d5cb69..000000000 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/DarkSludge_Liquid.png and /dev/null differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/DarkSludge_Scene.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/DarkSludge_Scene.cs deleted file mode 100644 index f627ff344..000000000 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/DarkSludge_Scene.cs +++ /dev/null @@ -1,119 +0,0 @@ -using Everglow.Commons.VFX.Scene; -using Everglow.Yggdrasil.WorldGeneration; -using Everglow.Yggdrasil.YggdrasilTown.Tiles; - -namespace Everglow.Yggdrasil.YggdrasilTown.VFXs; - -[Pipeline(typeof(WCSPipeline), typeof(BloomPipeline))] -public class DarkSludge_Scene : ForegroundVFX -{ - public float[] ai; - public int MinX; - public int MaxX; - - public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; - - public override void OnSpawn() - { - } - - public override void Update() - { - if (Ins.VisualQuality.Low) - { - Active = false; - SceneVFXSystem.TilePointHasScene[(originTile.X, originTile.Y)] = false; - return; - } - if (MaxX == 0) - { - MinX = originTile.X; - MaxX = originTile.X; - while (MinX > 0) - { - if (TileUtils.SafeGetTile(MinX, originTile.Y).TileType == ModContent.TileType() && TileUtils.SafeGetTile(MinX, originTile.Y - 1).TileType != ModContent.TileType()) - { - MinX--; - } - else - { - break; - } - } - while (MaxX < Main.maxTilesX) - { - if (TileUtils.SafeGetTile(MaxX, originTile.Y).TileType == ModContent.TileType() && TileUtils.SafeGetTile(MaxX, originTile.Y - 1).TileType != ModContent.TileType()) - { - MaxX++; - } - else - { - break; - } - } - } - } - - public override void Draw() - { - List bars = []; - List bars2 = []; - if (MinX >= MaxX) - { - for (int x = 0; x < 4; x++) - { - bars.Add(Vector2.zeroVector, Color.Transparent, new Vector3(0, 0, 1)); - bars2.Add(Vector2.zeroVector, Color.Transparent, new Vector3(0, 0, 1)); - } - } - int coeDistance = 12; - for (int i = MinX; i <= MaxX; i += coeDistance) - { - Vector2 position = new Point(i, originTile.Y).ToVector2() * 16; - Color color = Lighting.GetColor(new Point(i, originTile.Y)); - for (int x = 0; x < 4; x++) - { - bars.Add(position + new Vector2(0 + x * 4 * coeDistance, NoiseWave(x * 4 * coeDistance + i * 16) * 12), color, new Vector3(0, 0, 1)); - bars.Add(position + new Vector2(4 * coeDistance + x * 4 * coeDistance, NoiseWave(x * 4 * coeDistance + 4 * coeDistance + i * 16) * 12), color, new Vector3(0, 0, 1)); - - bars.Add(position + new Vector2(0 + x * 4 * coeDistance, NoiseWave(x * 4 * coeDistance + i * 16) * 12 + 4), color, new Vector3(0, 0.4f, 1)); - bars.Add(position + new Vector2(4 * coeDistance + x * 4 * coeDistance, NoiseWave(x * 4 * coeDistance + 4 * coeDistance + i * 16) * 12 + 4), color, new Vector3(0, 0.4f, 1)); - } - - for (int x = 0; x < 4; x++) - { - bars2.Add(position + new Vector2(0 + x * 4 * coeDistance, NoiseWave(x * 4 * coeDistance + i * 16) * 12 + 4), color, new Vector3(0, 0.4f, 1)); - bars2.Add(position + new Vector2(4 * coeDistance + x * 4 * coeDistance, NoiseWave(x * 4 * coeDistance + 4 * coeDistance + i * 16) * 12 + 4), color, new Vector3(0, 0.4f, 1)); - - bars2.Add(position + new Vector2(0 + x * 4 * coeDistance, 16), color, new Vector3(0, 1f, 1)); - bars2.Add(position + new Vector2(4 * coeDistance + x * 4 * coeDistance, 16), color, new Vector3(0, 1f, 1)); - } - } - Ins.Batch.Draw(ModAsset.DarkSludge_Liquid.Value, bars, PrimitiveType.TriangleStrip); - Ins.Batch.Draw(ModAsset.DarkSludge_Liquid.Value, bars2, PrimitiveType.TriangleStrip); - } - - public float NoiseWave(float x) - { - x *= 0.012f; - //x += ; - float value = 0; - - int octaves = 4; - float lacunarity = 2f; - float gain = 0.5f; - - // Initial values - float amplitude = 0.5f; - float frequency = 1; - - // Loop of octaves - for (int i = 0; i < octaves; i++) - { - value += amplitude * MathF.Sin(frequency * x + (float)Main.time * 0.04f * MathF.Sin(i * MathHelper.PiOver2)); - frequency *= lacunarity; - amplitude *= gain; - } - return value; - } -} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/IntroductiontoThermalElectricity_Plasma.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/IntroductiontoThermalElectricity_Plasma.cs new file mode 100644 index 000000000..2d293b05f --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/IntroductiontoThermalElectricity_Plasma.cs @@ -0,0 +1,70 @@ +using Everglow.Commons.Graphics; +using Terraria.Map; + +namespace Everglow.Yggdrasil.YggdrasilTown.VFXs; + +[Pipeline(typeof(WCSPipeline), typeof(BloomPipeline))] +public class IntroductiontoThermalElectricity_Plasma : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawNPCs; + + public float Timer; + public float MaxTime; + public float Rotation; + public float Scale; + public Vector2 Position; + public Vector2 Velocity; + public GradientColor PlasmaColor = new(); + + public void AddGradientColor() + { + PlasmaColor.colorList.Add((new Color(255, 255, 255, 255), 0)); + PlasmaColor.colorList.Add((new Color(255, 255, 255, 255), 0.2f)); + PlasmaColor.colorList.Add((new Color(56, 155, 255, 255), 0.3f)); + PlasmaColor.colorList.Add((new Color(255, 105, 91, 255), 0.8f)); + PlasmaColor.colorList.Add((new Color(0, 0, 0, 0), 1f)); + } + + public override void Update() + { + if (PlasmaColor.colorList.Count <= 0) + { + AddGradientColor(); + } + Timer++; + if (Timer > MaxTime) + { + Active = false; + return; + } + Position += Velocity; + Velocity *= 0.96f; + Scale *= 0.99f; + float timeLeftValue = Timer / MaxTime; + Color lightColor = PlasmaColor.GetColor(timeLeftValue); + Lighting.AddLight(Position, lightColor.ToVector3() * Scale * 0.1f); + } + + public override void Draw() + { + if (PlasmaColor.colorList.Count <= 0) + { + AddGradientColor(); + } + Vector2 drawPos = Position; + Vector2 toCorner = new Vector2(0, Scale).RotatedBy(Rotation); + float timeLeftValue = Timer / MaxTime; + var drawColor = PlasmaColor.GetColor(timeLeftValue); + + var bars = new List(); + bars.Add(drawPos + toCorner, drawColor, new Vector3(0, 0, 0)); + bars.Add(drawPos + toCorner.RotatedBy(MathHelper.PiOver2), drawColor, new Vector3(1, 0, 0)); + bars.Add(drawPos + toCorner.RotatedBy(MathHelper.Pi), drawColor, new Vector3(0, 1, 0)); + + bars.Add(drawPos + toCorner, drawColor, new Vector3(0, 0, 0)); + bars.Add(drawPos + toCorner.RotatedBy(MathHelper.Pi), drawColor, new Vector3(0, 1, 0)); + bars.Add(drawPos + toCorner.RotatedBy(-MathHelper.PiOver2), drawColor, new Vector3(1, 1, 0)); + + Ins.Batch.Draw(ModAsset.IntroductiontoThermalElectricity_Plasma.Value, bars, PrimitiveType.TriangleList); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/IntroductiontoThermalElectricity_Plasma.png b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/IntroductiontoThermalElectricity_Plasma.png new file mode 100644 index 000000000..676e51eaa Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/IntroductiontoThermalElectricity_Plasma.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/IntroductiontoThermalElectricity_Plasma_Trail.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/IntroductiontoThermalElectricity_Plasma_Trail.cs new file mode 100644 index 000000000..6f5e04f88 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/IntroductiontoThermalElectricity_Plasma_Trail.cs @@ -0,0 +1,87 @@ +using Everglow.Commons.Graphics; + +namespace Everglow.Yggdrasil.YggdrasilTown.VFXs; + +[Pipeline(typeof(WCSPipeline), typeof(BloomPipeline))] +public class IntroductiontoThermalElectricity_Plasma_Trail : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawNPCs; + + public float Timer; + public float MaxTime; + public float Rotation; + public float Scale; + public Vector2 Position; + public Vector2 Velocity; + public GradientColor PlasmaColor = new(); + public Queue Trails = new Queue(); + + public void AddGradientColor() + { + PlasmaColor.colorList.Add((new Color(255, 255, 255, 255), 0)); + PlasmaColor.colorList.Add((new Color(255, 255, 255, 255), 0.2f)); + PlasmaColor.colorList.Add((new Color(56, 155, 255, 255), 0.3f)); + PlasmaColor.colorList.Add((new Color(255, 105, 91, 255), 0.8f)); + PlasmaColor.colorList.Add((new Color(0, 0, 0, 0), 1f)); + } + + public override void Update() + { + if (PlasmaColor.colorList.Count <= 0) + { + AddGradientColor(); + } + Timer++; + if (Timer > MaxTime) + { + Active = false; + return; + } + Trails.Enqueue(Position); + if (Trails.Count > 20) + { + Trails.Dequeue(); + } + Position += Velocity; + Velocity *= 0.96f; + Scale *= 0.99f; + float timeLeftValue = Timer / MaxTime; + Color lightColor = PlasmaColor.GetColor(timeLeftValue); + Lighting.AddLight(Position, lightColor.ToVector3() * Scale * 0.1f); + } + + public override void Draw() + { + if (PlasmaColor.colorList.Count <= 0) + { + AddGradientColor(); + } + Vector2 drawPos; + float timeLeftValue = Timer / MaxTime; + Color drawColor; + var bars = new List(); + + for (int k = 0; k < Trails.Count; k++) + { + drawPos = Trails.ToArray()[k]; + drawColor = PlasmaColor.GetColor(timeLeftValue - k / 20f + 1); + AddVertexs(bars, drawPos, drawColor * 0.5f); + } + drawColor = PlasmaColor.GetColor(timeLeftValue); + AddVertexs(bars, Position, drawColor); + + Ins.Batch.Draw(ModAsset.IntroductiontoThermalElectricity_Plasma.Value, bars, PrimitiveType.TriangleList); + } + + public void AddVertexs(List bars, Vector2 position, Color color) + { + Vector2 toCorner = new Vector2(0, Scale).RotatedBy(Rotation); + bars.Add(position + toCorner, color, new Vector3(0, 0, 0)); + bars.Add(position + toCorner.RotatedBy(MathHelper.PiOver2), color, new Vector3(1, 0, 0)); + bars.Add(position + toCorner.RotatedBy(MathHelper.Pi), color, new Vector3(0, 1, 0)); + + bars.Add(position + toCorner, color, new Vector3(0, 0, 0)); + bars.Add(position + toCorner.RotatedBy(MathHelper.Pi), color, new Vector3(0, 1, 0)); + bars.Add(position + toCorner.RotatedBy(-MathHelper.PiOver2), color, new Vector3(1, 1, 0)); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MagicalBoomerangDust.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MagicalBoomerangDust.cs index b34cadd9a..2dbd02924 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MagicalBoomerangDust.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MagicalBoomerangDust.cs @@ -1,3 +1,5 @@ +using Everglow.Commons.Graphics; + namespace Everglow.Yggdrasil.YggdrasilTown.VFXs; [Pipeline(typeof(WCSPipeline))] @@ -15,6 +17,8 @@ public class MagicalBoomerangDust : Visual public float rotation; public int Frame = 0; + public bool gravity = false; + public override void Update() { timer++; @@ -36,9 +40,20 @@ public override void Update() return; } position += velocity; - velocity *= 0.9f; + if (!gravity) + { + velocity *= 0.9f; + scale *= 0.9f; + } + else + { + velocity *= 0.95f; + velocity.Y += 0.05f; + scale *= 0.98f; + } Frame = (int)(timer / maxTime * 3f); - Lighting.AddLight(position, new Vector3(0f, 0.3f, 0.7f) * scale / 8f); + float value = (maxTime - timer) / maxTime; + Lighting.AddLight(position, Vector3.Lerp(new Vector3(1f, 1.5f, 2.2f), new Vector3(0f, 0f, 2.2f), 1 - value) * value); } public override void Draw() @@ -46,7 +61,16 @@ public override void Draw() float frameCount = 3; float frameY = Frame; Vector2 toCorner = new Vector2(0, scale).RotatedBy(rotation); - var drawColor = new Color(1f, 1f, 1f, 0); + float value = (maxTime - timer) / maxTime; + GradientColor gradientColor = new GradientColor(); + if (gradientColor.colorList.Count <= 0) + { + gradientColor.colorList.Add((new Color(1f, 1f, 1f, 0), 0)); + gradientColor.colorList.Add((new Color(0f, 0.5f, 1f, 0), 0.4f)); + gradientColor.colorList.Add((new Color(0f, 0f, 1f, 0), 0.5f)); + gradientColor.colorList.Add((new Color(0f, 0f, 0f, 0), 1f)); + } + var drawColor = gradientColor.GetColor(1 - value); var bars = new List() { new Vertex2D(position + toCorner, drawColor, new Vector3(0, frameY / frameCount, 0)), diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MagicalBoomerangDust.png b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MagicalBoomerangDust.png deleted file mode 100644 index d6a03727d..000000000 Binary files a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MagicalBoomerangDust.png and /dev/null differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MidnightBayouBackgroundCloud.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MidnightBayouBackgroundCloud.cs new file mode 100644 index 000000000..9d289a415 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MidnightBayouBackgroundCloud.cs @@ -0,0 +1,63 @@ +using Everglow.Yggdrasil.YggdrasilTown.Background; + +namespace Everglow.Yggdrasil.YggdrasilTown.VFXs; + +[Pipeline(typeof(BackgroundPipeline))] +public class MidnightBayouBackgroundCloud : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawBG; + + public Texture2D CloudTexture = null; + public Vector2 Velocity; + public Vector2 Position; + public Vector2 AnchorPos; + public float Fade; + public float Timer; + public float MaxTime; + public float Distance = 6f; + public float Scale; + + public override void Update() + { + // Movement + Velocity = new Vector2(Main.windSpeedCurrent * 0.6f, 0); + Position += Velocity; + + // Timer + Timer++; + if (Timer >= MaxTime) + { + Active = false; + return; + } + + // Color + Fade = 0.4f; + float timeLeft = MaxTime - Timer; + float thretholdTime = 120; + if (timeLeft < thretholdTime) + { + Fade *= timeLeft / thretholdTime; + } + if (Timer < thretholdTime) + { + Fade *= Timer / thretholdTime; + } + var background = ModContent.GetInstance(); + if (background is not null) + { + Fade *= background.BackgroundAlphaMidnightBayou; + } + } + + public override void Draw() + { + if (CloudTexture is null) + { + return; + } + Vector2 offsetedPos = Position + (Main.screenPosition - AnchorPos) * (1 - 1 / Distance); + Color drawColor = new Color(1f, 1f, 1f, 0) * Fade; + Ins.Batch.Draw(CloudTexture, offsetedPos, null, drawColor, 0, CloudTexture.Size() * 0.5f, Scale, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MidnightBayouBackgroundCloud_0.png b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MidnightBayouBackgroundCloud_0.png new file mode 100644 index 000000000..50ee1b9b5 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MidnightBayouBackgroundCloud_0.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MidnightBayouBackgroundCloud_1.png b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MidnightBayouBackgroundCloud_1.png new file mode 100644 index 000000000..598a4061b Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MidnightBayouBackgroundCloud_1.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MidnightBayouBackgroundCloud_2.png b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MidnightBayouBackgroundCloud_2.png new file mode 100644 index 000000000..3bae1b01d Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MidnightBayouBackgroundCloud_2.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MidnightBayouBackgroundCloud_3.png b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MidnightBayouBackgroundCloud_3.png new file mode 100644 index 000000000..f66ee4862 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/MidnightBayouBackgroundCloud_3.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/PearShapedNeedle_Dust.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/PearShapedNeedle_Dust.cs new file mode 100644 index 000000000..319b79e89 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/PearShapedNeedle_Dust.cs @@ -0,0 +1,48 @@ +namespace Everglow.Yggdrasil.YggdrasilTown.VFXs; + +[Pipeline(typeof(WCSPipeline), typeof(BloomPipeline))] +public class PearShapedNeedle_Dust : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawNPCs; + + public float Timer; + public float MaxTime; + public float Rotation; + public float Scale; + public float RanSeed; + public Vector2 Position; + public Vector2 Velocity; + + public override void Update() + { + Timer++; + if (Timer > MaxTime) + { + Active = false; + return; + } + Position += Velocity; + Velocity *= 0.6f; + Scale *= 0.95f; + } + + public override void Draw() + { + Vector2 drawPos = Position; + Vector2 toCorner = new Vector2(0, Scale).RotatedBy(Rotation); + float shineValue = (MathF.Sin(Timer * 0.1f + RanSeed) + 1) / 2f; + shineValue = MathF.Pow(shineValue, 8) * 6; + var drawColor = Lighting.GetColor(Position.ToTileCoordinates()); + drawColor *= shineValue; + var bars = new List(); + bars.Add(drawPos + toCorner, drawColor, new Vector3(0, 0, 0)); + bars.Add(drawPos + toCorner.RotatedBy(MathHelper.PiOver2), drawColor, new Vector3(1, 0, 0)); + bars.Add(drawPos + toCorner.RotatedBy(MathHelper.Pi), drawColor, new Vector3(0, 1, 0)); + + bars.Add(drawPos + toCorner, drawColor, new Vector3(0, 0, 0)); + bars.Add(drawPos + toCorner.RotatedBy(MathHelper.Pi), drawColor, new Vector3(0, 1, 0)); + bars.Add(drawPos + toCorner.RotatedBy(-MathHelper.PiOver2), drawColor, new Vector3(1, 1, 0)); + + Ins.Batch.Draw(ModAsset.IntroductiontoThermalElectricity_Plasma.Value, bars, PrimitiveType.TriangleList); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/PearShapedNeedle_Dust.png b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/PearShapedNeedle_Dust.png new file mode 100644 index 000000000..676e51eaa Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/PearShapedNeedle_Dust.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/PearShapedNeedle_HitStar.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/PearShapedNeedle_HitStar.cs new file mode 100644 index 000000000..7962900eb --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/PearShapedNeedle_HitStar.cs @@ -0,0 +1,33 @@ +namespace Everglow.Yggdrasil.YggdrasilTown.VFXs; + +[Pipeline(typeof(WCSPipeline))] +public class PearShapedNeedle_HitStar : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawNPCs; + + public float Timer; + public float MaxTime; + public float Rotation; + public Vector2 Position; + + public override void Update() + { + Timer++; + if (Timer > MaxTime) + { + Active = false; + return; + } + } + + public override void Draw() + { + float timeValue = 1 - Timer / MaxTime; + Color drawColor = Lighting.GetColor(Position.ToTileCoordinates()) * 2.5f; + drawColor.A = 0; + float scale = 0.25f; + Texture2D tex = Commons.ModAsset.StarSlash.Value; + Ins.Batch.Draw(tex, Position, null, drawColor, Rotation, tex.Size() * 0.5f, new Vector2(timeValue, 1f) * scale, SpriteEffects.None); + Ins.Batch.Draw(tex, Position, null, drawColor, Rotation + MathHelper.PiOver2, tex.Size() * 0.5f, new Vector2(timeValue, 1.5f) * scale, SpriteEffects.None); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/PearShapedNeedle_Trail.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/PearShapedNeedle_Trail.cs new file mode 100644 index 000000000..ee13e5d5a --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/PearShapedNeedle_Trail.cs @@ -0,0 +1,50 @@ +using Everglow.Commons.Graphics; +using Terraria.Map; + +namespace Everglow.Yggdrasil.YggdrasilTown.VFXs; + +[Pipeline(typeof(WCSPipeline))] +public class PearShapedNeedle_Trail : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawNPCs; + + public float Timer; + public float MaxTime; + public Vector2 Position_Start; + public Vector2 Position_End; + + public override void Update() + { + Timer++; + if (Timer > MaxTime) + { + Active = false; + return; + } + } + + public override void Draw() + { + float timeValue = Timer / MaxTime; + Vector2 direction_V = (Position_Start - Position_End).NormalizeSafe().RotatedBy(MathHelper.PiOver2); + Vector2 width = direction_V * (1 - timeValue) * 30; + Color darkColor = Color.White * 0.8f; + var bars_dark = new List(); + var bars = new List(); + for (int i = 0; i <= 10; i++) + { + float valueLerp = i / 10f; + Vector2 currentPos = Vector2.Lerp(Position_Start, Position_End, valueLerp); + Color drawColor = Lighting.GetColor(currentPos.ToTileCoordinates()) * 2.5f; + drawColor.A = 0; + bars_dark.Add(currentPos + width, darkColor, new Vector3(0, valueLerp * 0.8f, 0)); + bars_dark.Add(currentPos - width, darkColor, new Vector3(1, valueLerp * 0.8f, 0)); + + bars.Add(currentPos + width, drawColor, new Vector3(0, valueLerp * 0.8f, 0)); + bars.Add(currentPos - width, drawColor, new Vector3(1, valueLerp * 0.8f, 0)); + } + + Ins.Batch.Draw(Commons.ModAsset.StarSlash_black.Value, bars_dark, PrimitiveType.TriangleStrip); + Ins.Batch.Draw(Commons.ModAsset.StarSlash.Value, bars, PrimitiveType.TriangleStrip); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/QuenchingBlade_SmashVFX.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/QuenchingBlade_SmashVFX.cs new file mode 100644 index 000000000..c0f219e7a --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/QuenchingBlade_SmashVFX.cs @@ -0,0 +1,37 @@ +namespace Everglow.Yggdrasil.YggdrasilTown.VFXs; + +[Pipeline(typeof(WCSPipeline), typeof(BloomPipeline))] +public class QuenchingBlade_SmashVFX : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawPlayers; + + public int Timer; + + public int MaxTime = 28; + + public int Direction; + + public Vector2 Position; + + public override void Update() + { + Timer++; + if (Timer >= MaxTime) + { + Active = false; + return; + } + float timeValue = 1 - Timer / (float)MaxTime; + Lighting.AddLight(Position, new Vector3(1.4f * MathF.Sqrt(timeValue), timeValue * timeValue * 1f, timeValue * timeValue * timeValue * 2) * 2f); + } + + public override void Draw() + { + float frameCount = 7; + float timeValue = Timer / (float)MaxTime; + int frameNumber = (int)(timeValue * frameCount); + Rectangle frame = new Rectangle(0, frameNumber * 610, 720, 610); + SpriteEffects effects = Direction == 1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally; + Ins.Batch.Draw(ModAsset.QuenchingBlade_SmashVFX.Value, Position, frame, Color.White, 0, new Vector2(frame.Width * 0.5f, frame.Height), 1f, effects); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/QuenchingBlade_SmashVFX.png b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/QuenchingBlade_SmashVFX.png new file mode 100644 index 000000000..7c48ebbbe Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/QuenchingBlade_SmashVFX.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/QuenchingSmashVFX.png b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/QuenchingSmashVFX.png new file mode 100644 index 000000000..e3bd7e205 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/QuenchingSmashVFX.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/RandomNPC/VFXPerson.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/RandomNPC/VFXPerson.cs new file mode 100644 index 000000000..3c456f0c3 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/RandomNPC/VFXPerson.cs @@ -0,0 +1,306 @@ +using Everglow.Yggdrasil.YggdrasilTown.Items.Tools.Developer; + +namespace Everglow.Yggdrasil.YggdrasilTown.VFXs.RandomNPC; + +[Pipeline(typeof(WCSPipeline))] +public class VFXPerson : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawDusts; + + public enum MoveState + { + Stand, + Walk, + Jump, + } + + public Vector2 Position; + + public Vector2 Velocity; + + public float Timer; + + public float MaxTime; + + public int State; + + public int Direction; + + public int Frame; + + public int HairStyle; + + public int Sex; + + public int ShoeStyle; + + public bool Blocked; + + public Color EyeColor; + + public Color SkinColor; + + public Color HairColor; + + public Color ClothColor; + + public Color ShoeColor; + + public override void OnSpawn() + { + } + + public override void Update() + { + CheckEliminate(); + UpdateFrame(); + AI(); + + Timer++; + if (Timer > MaxTime) + { + Active = false; + } + } + + public void AI() + { + if (TileUtils.PlatformCollision(Position + new Vector2(-8, 0), 16, 48)) + { + if (!Blocked) + { + Velocity.Y *= 0; + for (int t = 0; t < 16; t++) + { + if (!TileUtils.PlatformCollision(Position + new Vector2(-8, -1), 16, 48)) + { + break; + } + Position.Y -= 1; + if (t == 15) + { + Position.Y += 16; + Velocity.X *= -1; + Direction *= -1; + Blocked = true; + } + } + } + else + { + Velocity.Y *= 0; + for (int t = 0; t < 32; t++) + { + if (!TileUtils.PlatformCollision(Position + new Vector2(-8, -1), 16, 48)) + { + break; + } + Position.Y -= 16; + if (t == 31) + { + Position.Y += 16 * 32; + } + } + for (int t = 0; t < 16; t++) + { + if (!TileUtils.PlatformCollision(Position + new Vector2(-8, -1), 16, 48)) + { + break; + } + Position.Y += 16; + if (t == 15) + { + Position.Y -= 16 * 16; + Active = false; + return; + } + } + Blocked = false; + } + } + else + { + Blocked = false; + Velocity.Y += 0.25f; + if (Velocity.Y > 8) + { + Velocity.Y = 8; + } + } + if (State == (int)MoveState.Walk) + { + Velocity.X = 1.5f * Direction; + if (Main.rand.NextBool(240)) + { + State = (int)MoveState.Stand; + } + } + if (State == (int)MoveState.Stand) + { + Velocity.X = 0; + if (Main.rand.NextBool(240)) + { + State = (int)MoveState.Walk; + if (Main.rand.NextBool()) + { + Direction *= -1; + } + } + } + Position += Velocity; + } + + public void CheckEliminate() + { + if (Main.mouseMiddle && Main.mouseMiddleRelease && Main.LocalPlayer.HeldItem.type == ModContent.ItemType()) + { + Active = false; + return; + } + } + + public void UpdateFrame() + { + if (Timer % 3 == 0) + { + Frame++; + switch (State) + { + case (int)MoveState.Stand: + { + Frame = 0; + break; + } + case (int)MoveState.Walk: + { + if (Frame >= 20) + { + Frame = 6; + } + break; + } + } + } + } + + public override void Draw() + { + // Eye and Head + SpriteEffects flip = Direction == 1 ? SpriteEffects.None : SpriteEffects.FlipHorizontally; + Texture2D head = Terraria.GameContent.TextureAssets.Players[0, 0].Value; + Rectangle headFrame = new Rectangle(0, Frame * 56, 40, 56); + Ins.Batch.Draw(head, Position + new Vector2(0, 52), headFrame, Lighting.GetColor(Position.ToTileCoordinates(), SkinColor), 0, new Vector2(headFrame.Width * 0.5f, headFrame.Height), 1f, flip); + Texture2D sclera = Terraria.GameContent.TextureAssets.Players[0, 1].Value; + Ins.Batch.Draw(sclera, Position + new Vector2(0, 52), headFrame, Lighting.GetColor(Position.ToTileCoordinates(), Color.White), 0, new Vector2(headFrame.Width * 0.5f, headFrame.Height), 1f, flip); + Texture2D pupil = Terraria.GameContent.TextureAssets.Players[0, 2].Value; + Ins.Batch.Draw(pupil, Position + new Vector2(0, 52), headFrame, Lighting.GetColor(Position.ToTileCoordinates(), EyeColor), 0, new Vector2(headFrame.Width * 0.5f, headFrame.Height), 1f, flip); + + float bodyOffset = 0; + if (Frame is >= 14 and <= 16 || Frame is >= 7 and <= 9) + { + bodyOffset = -2; + } + + // Chest + Texture2D chest = Terraria.GameContent.TextureAssets.Players[0, 3].Value; + Rectangle chestFrame = new Rectangle(0, 0, 40, 56); + Ins.Batch.Draw(chest, Position + new Vector2(0, 24 + bodyOffset), chestFrame, Lighting.GetColor(Position.ToTileCoordinates(), SkinColor), 0, chestFrame.Size() * 0.5f, 1f, flip); + + // Armx and hands + Texture2D arm = Terraria.GameContent.TextureAssets.Players[0, 4].Value; + Texture2D hand = Terraria.GameContent.TextureAssets.Players[0, 5].Value; + Rectangle armFrame = new Rectangle(120, 56, 40, 56); + int offsetFrame = Frame + 2; + offsetFrame -= 6; + offsetFrame %= 14; + offsetFrame += 6; + if (offsetFrame is 6 or 7 or 19) + { + armFrame.X = 160; + } + if (offsetFrame is 8 or 9 or 17 or 18) + { + armFrame.X = 120; + } + if (offsetFrame is 10 or 11 or 15 or 16) + { + armFrame.X = 200; + } + if (offsetFrame is 12 or 13 or 14) + { + armFrame.X = 240; + } + if (State == (int)MoveState.Stand) + { + armFrame = new Rectangle(80, 0, 40, 56); + } + Rectangle armFrame_back = armFrame; + armFrame_back.Y += 112; + Rectangle handFrame = armFrame; + Rectangle handFrame_back = armFrame; + handFrame_back.Y += 112; + Ins.Batch.Draw(hand, Position + new Vector2(0, 24 + bodyOffset), handFrame_back, Lighting.GetColor(Position.ToTileCoordinates(), SkinColor), 0, handFrame_back.Size() * 0.5f, 1f, flip); + Ins.Batch.Draw(arm, Position + new Vector2(0, 24 + bodyOffset), armFrame_back, Lighting.GetColor(Position.ToTileCoordinates(), SkinColor), 0, armFrame_back.Size() * 0.5f, 1f, flip); + + // Clothes + Texture2D innerCloth = Terraria.GameContent.TextureAssets.Players[0, 6].Value; + Texture2D sleeve = Terraria.GameContent.TextureAssets.Players[0, 8].Value; + Rectangle innerClothFrame = chestFrame; + if (Sex == 1) + { + innerClothFrame.Y += 112; + } + Ins.Batch.Draw(innerCloth, Position + new Vector2(0, 24 + bodyOffset), innerClothFrame, Lighting.GetColor(Position.ToTileCoordinates(), ClothColor), 0, innerClothFrame.Size() * 0.5f, 1f, flip); + Ins.Batch.Draw(sleeve, Position + new Vector2(0, 24 + bodyOffset), armFrame_back, Lighting.GetColor(Position.ToTileCoordinates(), ClothColor), 0, armFrame_back.Size() * 0.5f, 1f, flip); + Ins.Batch.Draw(hand, Position + new Vector2(0, 24 + bodyOffset), handFrame, Lighting.GetColor(Position.ToTileCoordinates(), SkinColor), 0, handFrame.Size() * 0.5f, 1f, flip); + Ins.Batch.Draw(arm, Position + new Vector2(0, 24 + bodyOffset), armFrame, Lighting.GetColor(Position.ToTileCoordinates(), SkinColor), 0, armFrame.Size() * 0.5f, 1f, flip); + Ins.Batch.Draw(sleeve, Position + new Vector2(0, 24 + bodyOffset), armFrame, Lighting.GetColor(Position.ToTileCoordinates(), ClothColor), 0, armFrame.Size() * 0.5f, 1f, flip); + + // Foot + Texture2D foot = Terraria.GameContent.TextureAssets.Players[0, 10].Value; + Rectangle footFrame = new Rectangle(0, Frame * 56, 40, 56); + Ins.Batch.Draw(foot, Position + new Vector2(0, -4), footFrame, Lighting.GetColor(Position.ToTileCoordinates(), ShoeStyle % 2 == 0 ? ShoeColor : SkinColor), 0, new Vector2(footFrame.Width * 0.5f, 0), 1f, flip); + + // Shoes + Texture2D shoe = Terraria.GameContent.TextureAssets.Players[0, 11].Value; + switch (ShoeStyle) + { + case 0: + shoe = Terraria.GameContent.TextureAssets.Players[0, 11].Value; + break; + case 1: + shoe = Terraria.GameContent.TextureAssets.Players[0, 12].Value; + break; + case 2: + shoe = Terraria.GameContent.TextureAssets.Players[1, 11].Value; + break; + case 3: + shoe = Terraria.GameContent.TextureAssets.Players[1, 12].Value; + break; + case 4: + shoe = Terraria.GameContent.TextureAssets.Players[2, 11].Value; + break; + case 5: + shoe = Terraria.GameContent.TextureAssets.Players[2, 12].Value; + break; + case 6: + shoe = Terraria.GameContent.TextureAssets.Players[3, 11].Value; + break; + case 7: + shoe = Terraria.GameContent.TextureAssets.Players[3, 12].Value; + break; + } + + Ins.Batch.Draw(shoe, Position + new Vector2(0, -4), footFrame, Lighting.GetColor(Position.ToTileCoordinates(), ShoeColor), 0, new Vector2(footFrame.Width * 0.5f, 0), 1f, flip); + + // Hair + Main.instance.LoadHair(HairStyle); + Texture2D hair = Terraria.GameContent.TextureAssets.PlayerHair[HairStyle].Value; + Rectangle hairFrame = new Rectangle(0, (Frame - 6) * 56, 40, 56); + if (Frame < 6) + { + hairFrame.Y = 0; + } + Ins.Batch.Draw(hair, Position + new Vector2(0, 24), hairFrame, Lighting.GetColor(Position.ToTileCoordinates(), HairColor), 0, hairFrame.Size() * 0.5f, 1f, flip); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/RandomNPC/YggdrasilTownPersonManager.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/RandomNPC/YggdrasilTownPersonManager.cs new file mode 100644 index 000000000..3fd7a2ee0 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/RandomNPC/YggdrasilTownPersonManager.cs @@ -0,0 +1,65 @@ +namespace Everglow.Yggdrasil.YggdrasilTown.VFXs.RandomNPC; + +public class YggdrasilTownPersonManager +{ + public static List People = new List(); + + public static void AddRandomPerson() + { + VFXPerson person = new VFXPerson() + { + Active = true, + Visible = true, + Position = Main.MouseWorld, + Velocity = Vector2.Zero, + Timer = 0, + MaxTime = 3000000, + State = (int)VFXPerson.MoveState.Walk, + SkinColor = ChooseSkinColor(), + HairColor = new Vector3(Main.rand.NextFloat(360), MathF.Pow(Main.rand.NextFloat(), 0.25f), MathF.Pow(Main.rand.NextFloat(), 0.5f)).HSVToRGB_Color(1f), + ClothColor = new Vector3(Main.rand.NextFloat(360), MathF.Pow(Main.rand.NextFloat(), 2f), MathF.Pow(Main.rand.NextFloat(), 1.2f)).HSVToRGB_Color(1f), + ShoeColor = new Vector3(Main.rand.NextFloat(-30, 60), MathF.Pow(Main.rand.NextFloat(), 2f), MathF.Pow(Main.rand.NextFloat(), 2.5f)).HSVToRGB_Color(1f), + EyeColor = new Vector3(Main.rand.NextFloat(360), MathF.Pow(Main.rand.NextFloat(), 0.5f), Main.rand.NextFloat()).HSVToRGB_Color(1f), + HairStyle = Main.rand.Next(165), + Direction = Main.rand.NextBool() ? -1 : 1, + Sex = Main.rand.NextBool() ? 0 : 1, + ShoeStyle = Main.rand.Next(8), + }; + Ins.VFXManager.Add(person); + People.Add(person); + } + + public static Color ChooseSkinColor() + { + switch (Main.rand.Next(7)) + { + case 0: + return new Color(209, 160, 156); + case 1: + return new Color(255, 221, 221); + case 2: + return new Color(255, 221, 193); + case 3: + return new Color(206, 135, 111); + case 4: + return new Color(104, 66, 75); + case 5: + return new Color(232, 205, 176); + case 6: + return new Color(232, 202, 194); + } + + return new Color(209, 160, 156); + } + + public static void Update() + { + for (int k = People.Count - 1; k >= 0; k--) + { + if (!People[k].Active) + { + People.RemoveAt(k); + } + } + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_Dust.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_Dust.cs new file mode 100644 index 000000000..f454c6339 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_Dust.cs @@ -0,0 +1,48 @@ +namespace Everglow.Yggdrasil.YggdrasilTown.VFXs; + +[Pipeline(typeof(WCSPipeline), typeof(BloomPipeline))] +public class SpringOfQuicksand_Dust : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawDusts; + + public float Timer; + public float MaxTime; + public float Rotation; + public float Scale; + public float RanSeed; + public Vector2 Position; + public Vector2 Velocity; + + public override void Update() + { + Timer++; + if (Timer > MaxTime) + { + Active = false; + return; + } + Position += Velocity; + Velocity.Y += 0.15f * Scale / 2f; + Velocity *= 0.995f; + } + + public override void Draw() + { + Vector2 drawPos = Position; + Vector2 toCorner = new Vector2(0, Scale).RotatedBy(Rotation); + float shineValue = (MathF.Sin(Timer * 0.1f + RanSeed) + 1) / 2f; + shineValue = MathF.Pow(shineValue, 8) * 6; + var drawColor = Lighting.GetColor(Position.ToTileCoordinates()); + drawColor *= shineValue; + var bars = new List(); + bars.Add(drawPos + toCorner, drawColor, new Vector3(0, 0, 0)); + bars.Add(drawPos + toCorner.RotatedBy(MathHelper.PiOver2), drawColor, new Vector3(1, 0, 0)); + bars.Add(drawPos + toCorner.RotatedBy(MathHelper.Pi), drawColor, new Vector3(0, 1, 0)); + + bars.Add(drawPos + toCorner, drawColor, new Vector3(0, 0, 0)); + bars.Add(drawPos + toCorner.RotatedBy(MathHelper.Pi), drawColor, new Vector3(0, 1, 0)); + bars.Add(drawPos + toCorner.RotatedBy(-MathHelper.PiOver2), drawColor, new Vector3(1, 1, 0)); + + Ins.Batch.Draw(ModAsset.SpringOfQuicksand_Dust.Value, bars, PrimitiveType.TriangleList); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_Dust.png b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_Dust.png new file mode 100644 index 000000000..0ba82e152 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_Dust.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_SandTrail.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_SandTrail.cs new file mode 100644 index 000000000..19f65c400 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_SandTrail.cs @@ -0,0 +1,93 @@ +namespace Everglow.Yggdrasil.YggdrasilTown.VFXs; + +[Pipeline(typeof(SpringOfQuicksand_SandTrail_Pipeline))] +public class SpringOfQuicksand_SandTrail : Visual +{ + public override CodeLayer DrawLayer => CodeLayer.PostDrawNPCs; + + public Vector2 Position; + public Vector2 Velocity; + public float[] ai; + public float Timer; + public float MaxTime; + public float Fade = 0; + public float Scale; + private Queue trails = new Queue(); + + public override void Update() + { + if (Position.X <= 320 || Position.X >= Main.maxTilesX * 16 - 320) + { + Timer = MaxTime; + Active = false; + return; + } + if (Position.Y <= 320 || Position.Y >= Main.maxTilesY * 16 - 320) + { + Timer = MaxTime; + Active = false; + return; + } + trails.Enqueue(Position); + if (trails.Count > 60) + { + trails.Dequeue(); + } + if (Collision.IsWorldPointSolid(Position)) + { + Fade += 0.1f; + if (Fade > 1f) + { + Active = false; + return; + } + } + Position += Velocity; + Velocity.Y += 0.25f * Scale / 20f; + Velocity *= 0.95f; + + Timer++; + if (Timer > MaxTime) + { + Active = false; + } + } + + public override void Draw() + { + float timeValue = Timer / 30f; + float timeFade = timeValue < 1 ? timeValue : 1f; + if (MaxTime - Timer < 30f) + { + timeFade *= (MaxTime - Timer) / 30f; + } + List bars = new List(); + if (trails.Count <= 2) + { + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + bars.Add(Position, Color.Transparent, new Vector3(0, 0, 0)); + + Ins.Batch.Draw(Commons.ModAsset.Trail_12.Value, bars, PrimitiveType.TriangleStrip); + return; + } + for (int i = 0; i < trails.Count; i++) + { + Vector2 pos = trails.ToArray()[i]; + Vector2 dir = Velocity.NormalizeSafe(); + if (i > 0) + { + dir = (trails.ToArray()[i - 1] - trails.ToArray()[i]).NormalizeSafe(); + } + dir = dir.RotatedBy(MathHelper.PiOver2) * Scale; + Color envLight = Lighting.GetColor(pos.ToTileCoordinates()) * (1 - Fade) * timeFade; + float zCoord = i / ((float)trails.Count - 1); + zCoord = MathF.Sin(zCoord * MathHelper.Pi); + bars.Add(pos + dir, envLight, new Vector3(i / 40f - timeValue, 0, zCoord)); + bars.Add(pos - dir, envLight, new Vector3(i / 40f - timeValue, 1, zCoord)); + } + Ins.Batch.Draw(Commons.ModAsset.Noise_flame_3.Value, bars, PrimitiveType.TriangleStrip); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_SandTrail_Pipeline.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_SandTrail_Pipeline.cs new file mode 100644 index 000000000..4dbd8383e --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_SandTrail_Pipeline.cs @@ -0,0 +1,28 @@ +namespace Everglow.Yggdrasil.YggdrasilTown.VFXs; + +public class SpringOfQuicksand_SandTrail_Pipeline : Pipeline +{ + public override void Load() + { + effect = ModAsset.SpringOfQuicksand_SandTrail_Shader; + effect.Value.Parameters["uNoise"].SetValue(Commons.ModAsset.Noise_Sand.Value); + effect.Value.Parameters["uHeatMap"].SetValue(ModAsset.SpringOfQuicksand_Sandflow_HeatMap.Value); + } + + public override void BeginRender() + { + var effect = this.effect.Value; + var projection = Matrix.CreateOrthographicOffCenter(0, Main.screenWidth, Main.screenHeight, 0, 0, 1); + var model = Matrix.CreateTranslation(new Vector3(-Main.screenPosition, 0)) * Main.GameViewMatrix.TransformationMatrix; + effect.Parameters["uTransform"].SetValue(model * projection); + + Main.graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointWrap; + Ins.Batch.Begin(BlendState.AlphaBlend, DepthStencilState.None, SamplerState.PointWrap, RasterizerState.CullNone); + effect.CurrentTechnique.Passes[0].Apply(); + } + + public override void EndRender() + { + Ins.Batch.End(); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_SandTrail_Shader.fx b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_SandTrail_Shader.fx new file mode 100644 index 000000000..3fd50b0d1 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_SandTrail_Shader.fx @@ -0,0 +1,75 @@ +sampler2D uImage : register(s0); +texture uHeatMap; +sampler uHeatMapSampler = +sampler_state +{ + Texture = ; + MipFilter = LINEAR; + MinFilter = LINEAR; + MagFilter = LINEAR; + AddressU = CLAMP; + AddressV = CLAMP; +}; +texture uNoise; +sampler uNoiseSampler = +sampler_state +{ + Texture = ; + MipFilter = LINEAR; + MinFilter = LINEAR; + MagFilter = LINEAR; + AddressU = WRAP; + AddressV = WRAP; +}; + +float4x4 uTransform; + +struct VSInput +{ + float2 Pos : POSITION0; + float4 Color : COLOR0; + float3 Texcoord : TEXCOORD0; +}; + +struct PSInput +{ + float4 Pos : SV_POSITION; + float4 Color : COLOR0; + float3 Texcoord : TEXCOORD0; +}; + +PSInput VertexShaderFunction(VSInput input) +{ + PSInput output; + output.Color = input.Color; + output.Texcoord = input.Texcoord; + output.Pos = mul(float4(input.Pos, 0, 1), uTransform); + return output; +} + +float4 PixelShaderFunction(PSInput input) : COLOR0 +{ + float2 origCoord = input.Texcoord.xy - float2(0.5, 0.5); + origCoord.y /= input.Texcoord.z; + origCoord += float2(0.5, 0.5); + float2 modifiedCoord = origCoord; + if (modifiedCoord.y < 0 || modifiedCoord.y > 1) + { + return float4(0, 0, 0, 0); + } + + float4 colorNoise = tex2D(uNoiseSampler, modifiedCoord); + float4 origColor = tex2D(uImage, modifiedCoord) * colorNoise; + float4 colorHeatMap = tex2D(uHeatMapSampler, float2(origColor.r, 0.5)); + float4 finalColor = colorHeatMap * input.Color; + return finalColor; +} + +technique Technique1 +{ + pass Test + { + VertexShader = compile vs_3_0 VertexShaderFunction(); + PixelShader = compile ps_3_0 PixelShaderFunction(); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_Sandflow_HeatMap.png b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_Sandflow_HeatMap.png new file mode 100644 index 000000000..e0165d43a Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/SpringOfQuicksand_Sandflow_HeatMap.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/WhiteTriangle.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/WhiteTriangle.cs index c223adb8b..127b66d00 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/WhiteTriangle.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/VFXs/WhiteTriangle.cs @@ -56,6 +56,7 @@ public override void Draw() { Vector2 toCorner = new Vector2(0, scale).RotatedBy(rotation); Color lightColor = Color.White; + // lightColor = Color.Lerp(color2, color1, Math.Clamp((606 * 16 - position.X) / (8f * 16),0, 1)); int maxLength = 15; for (int y = 0; y < maxLength; y++) diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/GravelStoreWall_Thick.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/GravelStoreWall_Thick.cs new file mode 100644 index 000000000..f5618ef1b --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/GravelStoreWall_Thick.cs @@ -0,0 +1,24 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.YggdrasilTown.Dusts; + +namespace Everglow.Yggdrasil.YggdrasilTown.Walls; + +public class GravelStoreWall_Thick : ModWall +{ + public override void SetStaticDefaults() + { + Main.wallHouse[Type] = true; + DustType = ModContent.DustType(); + AddMapEntry(new Color(169, 178, 175)); + } + + public override bool WallFrame(int i, int j, bool randomizeFrame, ref int style, ref int frameNumber) + { + //Tile tileBelow = WorldGenMisc.SafeGetTile(i, j + 1); + //if (tileBelow.WallType == ModContent.WallType()) + //{ + // style = 4; + //} + return base.WallFrame(i, j, randomizeFrame, ref style, ref frameNumber); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/GravelStoreWall_Thick.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/GravelStoreWall_Thick.png new file mode 100644 index 000000000..cf8579c94 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/GravelStoreWall_Thick.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/GravelStoreWall_Thin.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/GravelStoreWall_Thin.cs new file mode 100644 index 000000000..4bb962192 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/GravelStoreWall_Thin.cs @@ -0,0 +1,24 @@ +using Everglow.Commons.TileHelper; +using Everglow.Yggdrasil.YggdrasilTown.Dusts; + +namespace Everglow.Yggdrasil.YggdrasilTown.Walls; + +public class GravelStoreWall_Thin : ModWall +{ + public override void SetStaticDefaults() + { + Main.wallHouse[Type] = true; + DustType = ModContent.DustType(); + AddMapEntry(new Color(169, 178, 175)); + } + + public override bool WallFrame(int i, int j, bool randomizeFrame, ref int style, ref int frameNumber) + { + //Tile tileBelow = WorldGenMisc.SafeGetTile(i, j - 1); + //if (tileBelow.WallType == ModContent.WallType()) + //{ + // style = 4; + //} + return base.WallFrame(i, j, randomizeFrame, ref style, ref frameNumber); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/GravelStoreWall_Thin.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/GravelStoreWall_Thin.png new file mode 100644 index 000000000..0ea0487f3 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/GravelStoreWall_Thin.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/TwilightForest/GreenRelicWall_Style2.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/TwilightForest/GreenRelicWall_Style2.cs new file mode 100644 index 000000000..dda8f67d1 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/TwilightForest/GreenRelicWall_Style2.cs @@ -0,0 +1,31 @@ +using Everglow.Yggdrasil.YggdrasilTown.Dusts.TwilightForest; + +namespace Everglow.Yggdrasil.YggdrasilTown.Walls.TwilightForest; + +public class GreenRelicWall_Style2 : ModWall +{ + public override void SetStaticDefaults() + { + Main.wallHouse[Type] = true; + DustType = ModContent.DustType(); + AddMapEntry(new Color(10, 31, 31)); + } + + public override bool WallFrame(int i, int j, bool randomizeFrame, ref int style, ref int frameNumber) + { + return base.WallFrame(i, j, randomizeFrame, ref style, ref frameNumber); + } + + public override void PostDraw(int i, int j, SpriteBatch spriteBatch) + { + var texture = ModContent.Request(Texture).Value; + var offsetScreen = new Vector2(Main.offScreenRange); + if (Main.drawToScreen) + { + offsetScreen = Vector2.Zero; + } + Vector2 drawPos = new Point(i, j).ToWorldCoordinates() - Main.screenPosition + offsetScreen; + var frame = new Rectangle(0 + i % 12 * 16 - 4, 204 + j % 12 * 16 - 4, 28, 28); + spriteBatch.Draw(texture, drawPos, frame, Lighting.GetColor(i, j), 0, frame.Size() * 0.5f, 1, SpriteEffects.None, 0); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/TwilightForest/GreenRelicWall_Style2.png b/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/TwilightForest/GreenRelicWall_Style2.png new file mode 100644 index 000000000..d85851c33 Binary files /dev/null and b/Sources/Modules/Yggdrasil/YggdrasilTown/Walls/TwilightForest/GreenRelicWall_Style2.png differ diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/YggdrasilTownCentralSystem.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/YggdrasilTownCentralSystem.cs index 9635342f1..4d68f487c 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/YggdrasilTownCentralSystem.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/YggdrasilTownCentralSystem.cs @@ -1,14 +1,13 @@ using Everglow.SubSpace; -using Everglow.Yggdrasil.WorldGeneration; using Everglow.Yggdrasil.YggdrasilTown.Biomes; using Everglow.Yggdrasil.YggdrasilTown.Kitchen.Tiles; using Everglow.Yggdrasil.YggdrasilTown.NPCs.TownNPCs; using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Miscs.PlayerArena; using Everglow.Yggdrasil.YggdrasilTown.Tiles; -using Microsoft.Xna.Framework.Graphics; +using Everglow.Yggdrasil.YggdrasilTown.VFXs.RandomNPC; using SubworldLibrary; -using Terraria; using Terraria.DataStructures; +using Terraria.GameContent; namespace Everglow.Yggdrasil.YggdrasilTown; @@ -40,6 +39,28 @@ public static Vector2 TownPos(Vector2 position_Orig) public static int ArenaScore; + public override void Load() + { + Ins.HookManager.AddHook(CodeLayer.PostDrawMapIcons, DrawMap_YggdrasilTown); + base.Load(); + } + + private void DrawMap_YggdrasilTown(Vector2 mapTopLeft, Vector2 mapX2Y2AndOff, Rectangle? mapRect, float mapScale) + { + if (!SubworldSystem.IsActive()) + { + return; + } + Vector2 center = TownTopLeftWorldCoord + new Vector2(268, 162) * 16; + Vector2 position = (center / 16f - mapTopLeft) * mapScale + mapX2Y2AndOff; + var destination = new Rectangle((int)position.X - 1, (int)position.Y - 1, 2, 2); + if (mapRect != null ? destination.Intersects(mapRect.Value) : true) + { + Texture2D tex = ModAsset.TownMap.Value; + Main.spriteBatch.Draw(tex, position, null, Color.White * 0.5f, 0, tex.Size() * new Vector2(0.5f, 1f), mapScale * 0.5f, SpriteEffects.None, 0); + } + } + public override void OnWorldLoad() { if (SubworldSystem.Current is YggdrasilWorld) @@ -97,6 +118,7 @@ public override void PostUpdateNPCs() RoadSignPost_ToArenaVFX.BuildArenaGen(); ResetedArena = true; } + YggdrasilTownPersonManager.Update(); base.PostUpdateNPCs(); } @@ -180,6 +202,15 @@ public static bool InArena_YggdrasilTown() return false; } + public static bool InGravelStore_YggdrasilTown() + { + if (SubworldSystem.Current is RoomWorld) + { + return TileUtils.SafeGetTile(20, 20).TileType == ModContent.TileType(); + } + return false; + } + public static bool InFurnace_YggdrasilTown() { if (Main.dedServ) diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/YggdrasilTownFurnaceGlobalItem.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/YggdrasilTownFurnaceGlobalItem.cs new file mode 100644 index 000000000..a7ab63be7 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/YggdrasilTownFurnaceGlobalItem.cs @@ -0,0 +1,55 @@ +using System.Collections.ObjectModel; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; +using Everglow.Yggdrasil.YggdrasilTown.UI; +using Terraria.GameContent; +using Terraria.UI.Chat; + +namespace Everglow.Yggdrasil.YggdrasilTown; + +public class YggdrasilTownFurnaceGlobalItem : GlobalItem +{ + public override void ModifyTooltips(Item item, List tooltips) + { + if (!FurnaceScoreShopUI.Instance.IsVisible || item.type == ItemID.None) + { + base.ModifyTooltips(item, tooltips); + return; + } + + // TODO: Need a modded itemTooltip allocating feature. Now use 36 for Furnace Score Shop Itemslot. + if (FurnaceScoreShop.SellPricesInFurnaceScore.ContainsKey(item.type) && item.tooltipContext == 36) + { + tooltips.Add(new TooltipLine(Mod, "FurnaceScoreShopItem", $"Sell Price: {FurnaceScoreShop.SellPricesInFurnaceScore[item.type]}") { OverrideColor = new Color(1f, 0.4f, 0.05f, 1f) }); + } + } + + public override bool PreDrawTooltip(Item item, ReadOnlyCollection lines, ref int x, ref int y) + { + //if (!FurnaceScoreShopUI.Instance.IsVisible || item.type == ItemID.None) + //{ + // return base.PreDrawTooltip(item, lines, ref x, ref y); + //} + //if (FurnaceScoreShop.SellPricesInFurnaceScore.ContainsKey(item.type) && item.tooltipContext == 36) + //{ + // Vector2 size = ChatManager.GetStringSize(FontAssets.MouseText.Value, lines[^1].Text, Vector2.One); + // Texture2D tex = ModAsset.FurnaceScoreIcon.Value; + // Main.spriteBatch.Draw(tex, new Vector2(x + size.X, y), null, Color.White, 0, tex.Size() * 0.5f, 1f, SpriteEffects.None, 0); + //} + return base.PreDrawTooltip(item, lines, ref x, ref y); + } + + public override bool PreDrawTooltipLine(Item item, DrawableTooltipLine line, ref int yOffset) + { + if (!FurnaceScoreShopUI.Instance.IsVisible || item.type == ItemID.None) + { + return base.PreDrawTooltipLine(item, line, ref yOffset); + } + if (FurnaceScoreShop.SellPricesInFurnaceScore.ContainsKey(item.type) && item.tooltipContext == 36 && line.Text.Contains("Price")) + { + Vector2 size = ChatManager.GetStringSize(line.Font, "Sell Price:", Vector2.One); + Texture2D tex = ModAsset.FurnaceScoreIcon.Value; + Main.spriteBatch.Draw(tex, new Vector2(line.X + size.X + 10, line.Y + 8), null, Color.White, 0, tex.Size() * 0.5f, 1f, SpriteEffects.None, 0); + } + return base.PreDrawTooltipLine(item, line, ref yOffset); + } +} diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/YggdrasilTownFurnaceSystem.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/YggdrasilTownFurnaceSystem.cs index a1950d01f..75f3f0ae8 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilTown/YggdrasilTownFurnaceSystem.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilTown/YggdrasilTownFurnaceSystem.cs @@ -1,4 +1,6 @@ -using Terraria.ModLoader.IO; +using Everglow.Commons.UI; +using Everglow.Yggdrasil.YggdrasilTown.Tiles.FurnaceTiles; +using Terraria.GameContent; namespace Everglow.Yggdrasil.YggdrasilTown; @@ -10,20 +12,187 @@ public class YggdrasilTownFurnaceSystem : ModSystem public static int CurrentEnergy = 0; + public static List MeltingAnimationTimer = new List(); + public static int EnergtMax = 100000; - public static int SwitchPlayerCooling = 0; + public static int PlayerDropInFloorScaleTimer = 0; - public override void PostUpdateEverything() + public static int PlayerLeaveFloorScaleTimer = 0; + + public static bool EnquiryMeltingDown = false; + + public static bool MeltingDownButtonClicked = false; + + public static bool FurnaceScoreShopOpen = false; + + public override void Load() { - if (Main.netMode != NetmodeID.Server) + base.Load(); + UISystem.Instance.PostDrawChestUI += DrawFurnaceMeltingChest; + } + + public void DrawFurnaceMeltingChest(UISystem system, SpriteBatch spriteBatch) + { + Player player = Main.LocalPlayer; + if (player.chest >= 0) { - CurrentPlayer = Main.LocalPlayer; + int i = Main.chest[player.chest].x; + int j = Main.chest[player.chest].y; + var tile = TileUtils.SafeGetTile(i, j); + if (tile.TileType == ModContent.TileType()) + { + // Point panel + Draw9Piece_ChatBack(spriteBatch, new Rectangle(70, 426, 340, 40), new Color(1f, 0.3f, 0.2f, 0.6f)); + Chest chest = Main.chest[player.chest]; + int totalValue = 0; + for (int k = 0; k < chest.item.Length; k++) + { + Item item = chest.item[k]; + if (item != null) + { + float itemValue = 1 + item.value / (100 + MathF.Sqrt(item.value * 10)); + int rare = Math.Min(10, item.rare); + float rareValue = 6f - (rare - 10) * (rare - 10) / 20f; + int value = (int)(rareValue * itemValue * item.stack); + totalValue += value; + } + } + if (EnquiryMeltingDown) + { + Utils.DrawBorderStringFourWay(spriteBatch, FontAssets.MouseText.Value, "Clear the chest and get points?", 86, 436, Color.White, Color.Black, Vector2.zeroVector); + } + else + { + Utils.DrawBorderStringFourWay(spriteBatch, FontAssets.MouseText.Value, "Furnace Points: " + totalValue, 86, 436, Color.White, Color.Black, Vector2.zeroVector); + } + + // Meltdown button + var iconFrame = new Rectangle(0, 0, 14, 24); + var buttonColor = new Color(1f, 0f, 0f, 0.75f); + bool mouseOver = false; + if (CurrentPlayer is null) + { + buttonColor = new Color(0.25f, 0.25f, 0.25f, 0.5f); + EnquiryMeltingDown = false; + MeltingDownButtonClicked = false; + } + else + { + if (new Rectangle(410, 426, 40, 40).Contains(Main.MouseScreen.ToPoint())) + { + buttonColor = new Color(1f, 0.1f, 0.35f, 0.95f); + Main.instance.MouseText("Meltdown", ItemRarityID.Red); + mouseOver = true; + if (Main.mouseLeft && Main.mouseLeftRelease) + { + MeltingDownButtonClicked = !MeltingDownButtonClicked; + EnquiryMeltingDown = MeltingDownButtonClicked; + } + } + } + Draw9Piece_ChatBack(spriteBatch, new Rectangle(410, 426, 40, 40), buttonColor); + if (mouseOver || MeltingDownButtonClicked) + { + Draw9Piece_ChatBack_Highlight(spriteBatch, new Rectangle(410, 426, 40, 40)); + iconFrame = new Rectangle(16, 0, 14, 24); + } + Texture2D icon = ModAsset.FurnaceMeltingChest_MeltingIcon.Value; + spriteBatch.Draw(icon, new Vector2(430, 446), iconFrame, Color.White, 0, iconFrame.Size() * 0.5f, 1f, SpriteEffects.None, 0); + + // Confirmation panel + Rectangle yes_button = new Rectangle(20, 258, 46, 82); + Rectangle no_button = new Rectangle(20, 342, 46, 82); + Color yesColor = new Color(0.25f, 0.25f, 0.25f, 0.5f); + Color noColor = new Color(0.25f, 0.25f, 0.25f, 0.5f); + bool mouseOverYes = false; + bool mouseOverNo = false; + Color yesTextColor = new Color(0.2f, 0.2f, 0.2f, 1f); + Color noTextColor = new Color(0.2f, 0.2f, 0.2f, 1f); + if (EnquiryMeltingDown) + { + yesTextColor = new Color(0.45f, 0.45f, 0.45f, 1f); + noTextColor = new Color(0.45f, 0.45f, 0.45f, 1f); + yesColor = new Color(1f, 0f, 0f, 0.75f); + if (yes_button.Contains(Main.MouseScreen.ToPoint())) + { + mouseOverYes = true; + if (Main.mouseLeft && Main.mouseLeftRelease) + { + player.chest = -1; + MeltingButton.MeltDown(i, j); + } + } + + noColor = new Color(0.6f, 0.6f, 0.6f, 0.75f); + if (no_button.Contains(Main.MouseScreen.ToPoint())) + { + mouseOverNo = true; + if (Main.mouseLeft && Main.mouseLeftRelease) + { + MeltingDownButtonClicked = !MeltingDownButtonClicked; + EnquiryMeltingDown = MeltingDownButtonClicked; + } + } + } + Draw9Piece_ChatBack(spriteBatch, yes_button, yesColor); + Draw9Piece_ChatBack(spriteBatch, no_button, noColor); + if (mouseOverYes) + { + yesTextColor = new Color(1f, 1f, 1f, 1f); + Draw9Piece_ChatBack_Highlight(spriteBatch, yes_button); + } + if (mouseOverNo) + { + noTextColor = new Color(1f, 1f, 1f, 1f); + Draw9Piece_ChatBack_Highlight(spriteBatch, no_button); + } + Vector2 yesPos = yes_button.Center() - new Vector2(12, 12); + Vector2 noPos = no_button.Center() - new Vector2(12, 12); + Utils.DrawBorderStringFourWay(spriteBatch, FontAssets.MouseText.Value, "Yes", yesPos.X, yesPos.Y, yesTextColor, Color.Black, Vector2.zeroVector); + Utils.DrawBorderStringFourWay(spriteBatch, FontAssets.MouseText.Value, "No", noPos.X, noPos.Y, noTextColor, Color.Black, Vector2.zeroVector); + } } + } + + public void Draw9Piece_ChatBack(SpriteBatch spriteBatch, Rectangle destinationBox, Color drawColor) + { + Texture2D tex = TextureAssets.ChatBack.Value; + spriteBatch.Draw(tex, new Rectangle(destinationBox.X, destinationBox.Y, 8, 8), new Rectangle(0, 0, 8, 8), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + 8, destinationBox.Y, destinationBox.Width - 16, 8), new Rectangle(8, 0, 2, 8), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + destinationBox.Width - 8, destinationBox.Y, 8, 8), new Rectangle(tex.Width - 8, 0, 8, 8), drawColor); + + spriteBatch.Draw(tex, new Rectangle(destinationBox.X, destinationBox.Y + 8, 8, destinationBox.Height - 16), new Rectangle(0, 8, 8, 2), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + 8, destinationBox.Y + 8, destinationBox.Width - 16, destinationBox.Height - 16), new Rectangle(8, 8, 2, 2), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + destinationBox.Width - 8, destinationBox.Y + 8, 8, destinationBox.Height - 16), new Rectangle(tex.Width - 8, 8, 8, 2), drawColor); + + spriteBatch.Draw(tex, new Rectangle(destinationBox.X, destinationBox.Y + destinationBox.Height - 8, 8, 8), new Rectangle(0, tex.Height - 8, 8, 8), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + 8, destinationBox.Y + destinationBox.Height - 8, destinationBox.Width - 16, 8), new Rectangle(8, tex.Height - 8, 2, 8), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + destinationBox.Width - 8, destinationBox.Y + destinationBox.Height - 8, 8, 8), new Rectangle(tex.Width - 8, tex.Height - 8, 8, 8), drawColor); + } + + public void Draw9Piece_ChatBack_Highlight(SpriteBatch spriteBatch, Rectangle destinationBox) + { + Color drawColor = Color.White; + Texture2D tex = Commons.ModAsset.Vanilla_Chat_Back_Highlight.Value; + spriteBatch.Draw(tex, new Rectangle(destinationBox.X, destinationBox.Y, 8, 8), new Rectangle(0, 0, 8, 8), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + 8, destinationBox.Y, destinationBox.Width - 16, 8), new Rectangle(8, 0, 2, 8), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + destinationBox.Width - 8, destinationBox.Y, 8, 8), new Rectangle(tex.Width - 8, 0, 8, 8), drawColor); + + spriteBatch.Draw(tex, new Rectangle(destinationBox.X, destinationBox.Y + 8, 8, destinationBox.Height - 16), new Rectangle(0, 8, 8, 2), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + destinationBox.Width - 8, destinationBox.Y + 8, 8, destinationBox.Height - 16), new Rectangle(tex.Width - 8, 8, 8, 2), drawColor); + + spriteBatch.Draw(tex, new Rectangle(destinationBox.X, destinationBox.Y + destinationBox.Height - 8, 8, 8), new Rectangle(0, tex.Height - 8, 8, 8), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + 8, destinationBox.Y + destinationBox.Height - 8, destinationBox.Width - 16, 8), new Rectangle(8, tex.Height - 8, 2, 8), drawColor); + spriteBatch.Draw(tex, new Rectangle(destinationBox.X + destinationBox.Width - 8, destinationBox.Y + destinationBox.Height - 8, 8, 8), new Rectangle(tex.Width - 8, tex.Height - 8, 8, 8), drawColor); + } + + public override void PostUpdateEverything() + { if (CurrentPlayer != null) { FurnacePlayer fPlayer = CurrentPlayer.GetModPlayer(); - CurrentScore = fPlayer.FurnaceScore; + CurrentScore = fPlayer.TotalFurnaceScore; } if (CurrentEnergy >= 1000) { @@ -37,60 +206,26 @@ public override void PostUpdateEverything() { CurrentEnergy = EnergtMax; } - if (SwitchPlayerCooling > 0) + if (PlayerDropInFloorScaleTimer > 0) { - SwitchPlayerCooling--; + PlayerDropInFloorScaleTimer--; } - else + if (PlayerLeaveFloorScaleTimer > 0) { - SwitchPlayerCooling = 0; + PlayerLeaveFloorScaleTimer--; } - base.PostUpdateEverything(); - } -} - -public class FurnacePlayer : ModPlayer -{ - public int FurnaceScore; - - public override void SyncPlayer(int toWho, int fromWho, bool newPlayer) - { - //ModPacket packet = Mod.GetPacket(); - //packet.Write(MessageID.PlayerLifeMana); - //packet.Write((byte)Player.whoAmI); - //packet.Write((byte)FurnaceScore); - //packet.Send(toWho, fromWho); - } - - // Called in ExampleMod.Networking.cs - public void ReceivePlayerSync(BinaryReader reader) - { - FurnaceScore = reader.ReadByte(); - } - public override void CopyClientState(ModPlayer targetCopy) - { - var clone = (FurnacePlayer)targetCopy; - clone.FurnaceScore = FurnaceScore; - } - - public override void SendClientChanges(ModPlayer clientPlayer) - { - var clone = (FurnacePlayer)clientPlayer; - - if (FurnaceScore != clone.FurnaceScore) + for (int k = MeltingAnimationTimer.Count - 1; k >= 0; k--) { - SyncPlayer(toWho: -1, fromWho: Main.myPlayer, newPlayer: false); + if (MeltingAnimationTimer[k] > 0) + { + MeltingAnimationTimer[k]--; + } + else + { + MeltingAnimationTimer.RemoveAt(k); + } } - } - - public override void SaveData(TagCompound tag) - { - tag["FurnaceScore"] = FurnaceScore; - } - - public override void LoadData(TagCompound tag) - { - FurnaceScore = tag.GetInt("FurnaceScore"); + base.PostUpdateEverything(); } } diff --git a/Sources/Modules/Yggdrasil/YggdrasilWorld.cs b/Sources/Modules/Yggdrasil/YggdrasilWorld.cs index 345a1bf06..d1a5235d2 100644 --- a/Sources/Modules/Yggdrasil/YggdrasilWorld.cs +++ b/Sources/Modules/Yggdrasil/YggdrasilWorld.cs @@ -5,8 +5,10 @@ namespace Everglow.Yggdrasil; -internal class YggdrasilWorld : Subworld +public class YggdrasilWorld : Subworld { + public static Point KelpCurtain_IsleOfBloom_CaveCenter; + public static bool InYggdrasil => SubworldSystem.IsActive(); public static float YggdrasilTimer = 0; @@ -78,23 +80,3 @@ private static void WorldGen_setWorldSize(On_WorldGen.orig_setWorldSize orig) Main.maxSectionsY = (Main.maxTilesY - 1) / 150 + 1; } } - -public class YggdrasilWorldSystem : ModSystem -{ - public override void PostUpdateEverything() - { - if (YggdrasilWorld.InYggdrasil) - { - YggdrasilWorld.YggdrasilTimer++; - - if (Main.bloodMoon) - { - Main.bloodMoon = false; - } - if (Main.slimeRain) - { - Main.slimeRain = false; - } - } - } -} diff --git a/Sources/Modules/Yggdrasil/YggdrasilWorldSystem.cs b/Sources/Modules/Yggdrasil/YggdrasilWorldSystem.cs new file mode 100644 index 000000000..ea20a1287 --- /dev/null +++ b/Sources/Modules/Yggdrasil/YggdrasilWorldSystem.cs @@ -0,0 +1,22 @@ +namespace Everglow.Yggdrasil; + +public class YggdrasilWorldSystem : ModSystem +{ + public override void PostUpdateEverything() + { + if (YggdrasilWorld.InYggdrasil) + { + YggdrasilWorld.YggdrasilTimer++; + + if (Main.bloodMoon) + { + Main.bloodMoon = false; + } + if (Main.slimeRain) + { + Main.slimeRain = false; + } + } + base.PostUpdateEverything(); + } +}