forked from MadYeling/Fargowiltas
-
Notifications
You must be signed in to change notification settings - Fork 0
/
FargoPlayerBuffDrawLayer.cs
158 lines (137 loc) · 7.48 KB
/
FargoPlayerBuffDrawLayer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using Terraria;
using Terraria.DataStructures;
using Terraria.GameContent;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.UI.Chat;
namespace Fargowiltas
{
public class FargoPlayerBuffDrawLayer : PlayerDrawLayer
{
public override bool IsHeadLayer => false;
private readonly int[] debuffsToIgnore = {
BuffID.Campfire,
BuffID.HeartLamp,
BuffID.Sunflower,
BuffID.PeaceCandle,
BuffID.StarInBottle,
BuffID.Tipsy,
BuffID.MonsterBanner,
BuffID.Werewolf,
BuffID.Merfolk,
BuffID.CatBast,
BuffID.BrainOfConfusionBuff,
BuffID.NeutralHunger
};
public override bool GetDefaultVisibility(PlayerDrawSet drawInfo)
=> !Main.hideUI
&& drawInfo.drawPlayer.whoAmI == Main.myPlayer
&& drawInfo.drawPlayer.active
&& !drawInfo.drawPlayer.dead
&& !drawInfo.drawPlayer.ghost
&& drawInfo.shadow == 0
&& ModContent.GetInstance<FargoConfig>().DebuffOpacity > 0
&& drawInfo.drawPlayer.buffType.Count(d => Main.debuff[d] && !debuffsToIgnore.Contains(d)) > 0;
public override Position GetDefaultPosition() => new Between();
//key is buff id
//value is <old duration, max duration>
//purpose of knowing old duration: get debuffed for 15sec, it decrease to 4sec, debuffed again for 10sec, recalculate ratio to match
private Dictionary<int, Tuple<int, int>> memorizedDebuffDurations = new Dictionary<int, Tuple<int, int>>();
protected override void Draw(ref PlayerDrawSet drawInfo)
{
Player player = drawInfo.drawPlayer;
List<int> debuffs = player.buffType.Where(d => Main.debuff[d] && !debuffsToIgnore.Contains(d)).ToList();
const int maxPerLine = 10;
int yOffset = 0;
for (int j = 0; j < debuffs.Count; j += maxPerLine)
{
int maxForThisLine = Math.Min(maxPerLine, debuffs.Count - j);
float midpoint = maxForThisLine / 2f - 0.5f;
for (int i = 0; i < maxForThisLine; i++)
{
int debuffID = debuffs[j + i];
Vector2 drawPos = (player.gravDir > 0 ? player.Top : player.Bottom);
drawPos.Y -= (32f + yOffset) * player.gravDir;
drawPos.X += 32f * (i - midpoint);
drawPos -= player.MountedCenter; //turn it into just the offset from player center
drawPos = drawPos.RotatedBy(-player.fullRotation); //correct for player rotation????
drawPos += player.MountedCenter;
drawPos -= Main.screenPosition;
if (!TextureAssets.Buff[debuffID].IsLoaded)
continue;
Texture2D buffIcon = TextureAssets.Buff[debuffID].Value;
Color buffColor = Color.White * ModContent.GetInstance<FargoConfig>().DebuffOpacity;
int index = Array.FindIndex(player.buffType, id => id == debuffID);
int currentDuration = player.buffTime[index];
float rotation = (player.gravDir > 0 ? 0 : MathHelper.Pi) - player.fullRotation;
SpriteEffects effects = player.gravDir > 0 ? SpriteEffects.None : SpriteEffects.FlipHorizontally;
float faderRatio = ModContent.GetInstance<FargoConfig>().DebuffFaderRatio;
if (faderRatio > 0 && !Main.buffNoTimeDisplay[debuffID])
{
if (currentDuration <= 1) //probably either a persistent debuff or one that will clear soon
{
if (memorizedDebuffDurations.TryGetValue(debuffID, out Tuple<int, int> knownDurations))
{
memorizedDebuffDurations.Remove(debuffID); //remove it
buffColor *= 1f - faderRatio; //like drawing 0% ratio so it doesnt jumpscare full opacity for 1 tick
}
}
else //is longer
{
//draw part of the rectangle to represent time remaining
if (memorizedDebuffDurations.TryGetValue(debuffID, out Tuple<int, int> knownDurations)
&& knownDurations.Item1 >= currentDuration && knownDurations.Item2 > currentDuration)
{
int maxDuration = knownDurations.Item2;
float ratio = (float)currentDuration / maxDuration;
int x = 0;
int y = (int)(buffIcon.Bounds.Height * (1f - ratio));
int width = buffIcon.Bounds.Width;
int height = (int)(buffIcon.Bounds.Height * ratio);
if (y + height > buffIcon.Bounds.Height) //just in case
y = buffIcon.Bounds.Height - height;
Rectangle buffIconPortion = new Rectangle(x, y, width, height);
Vector2 drawPortion = drawPos + y * Vector2.UnitY.RotatedBy(rotation);
Color portionColor = buffColor * faderRatio;
drawInfo.DrawDataCache.Add(new DrawData(
buffIcon, drawPortion, buffIconPortion, buffColor,
rotation, buffIcon.Bounds.Size() / 2,
1f, effects, 0));
buffColor *= 1f - faderRatio;
//update known duration
memorizedDebuffDurations[debuffID] = new Tuple<int, int>(currentDuration, maxDuration);
}
else //if just got this debuff for the first time or it reapplied for longer, update max duration and draw at 100% opacity ratio
{
memorizedDebuffDurations[debuffID] = new Tuple<int, int>(currentDuration, currentDuration);
}
}
}
drawInfo.DrawDataCache.Add(new DrawData(
buffIcon, drawPos, buffIcon.Bounds, buffColor,
rotation, buffIcon.Bounds.Size() / 2,
1f, effects, 0));
//if (ModContent.GetInstance<FargoConfig>().DebuffCountdown)
//{
// Vector2 textPos = drawPos;
// ChatManager.DrawColorCodedStringWithShadow(
// Main.spriteBatch,
// FontAssets.ItemStack.Value,
// Math.Round(currentDuration / 60.0, MidpointRounding.AwayFromZero).ToString(),
// textPos,
// Color.White,
// 0f,
// Vector2.Zero,
// Vector2.One);
//}
}
yOffset += (int)(32 * player.gravDir);
}
}
}
}