Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
CoinLossRevengeSystem.cs
Go to the documentation of this file.
1using System;
3using System.IO;
4using System.Linq;
9using Terraria.ID;
10using Terraria.UI;
11
12namespace Terraria.GameContent;
13
15{
16 public class RevengeMarker
17 {
18 private static int _uniqueIDCounter = 0;
19
20 private static readonly int _expirationCompCopper = Item.buyPrice(0, 0, 0, 1);
21
22 private static readonly int _expirationCompSilver = Item.buyPrice(0, 0, 1);
23
24 private static readonly int _expirationCompGold = Item.buyPrice(0, 1);
25
26 private static readonly int _expirationCompPlat = Item.buyPrice(1);
27
28 private const int ONE_MINUTE = 3600;
29
30 private const int ENEMY_BOX_WIDTH = 2160;
31
32 private const int ENEMY_BOX_HEIGHT = 1440;
33
34 public static readonly Vector2 EnemyBoxSize = new Vector2(2160f, 1440f);
35
36 private readonly Vector2 _location;
37
38 private readonly Rectangle _hitbox;
39
40 private readonly int _npcNetID;
41
42 private readonly float _npcHPPercent;
43
44 private readonly float _baseValue;
45
46 private readonly int _coinsValue;
47
48 private readonly int _npcTypeAgainstDiscouragement;
49
51
52 private readonly int _expirationTime;
53
54 private readonly bool _spawnedFromStatue;
55
56 private readonly int _uniqueID;
57
58 private bool _forceExpire;
59
60 private bool _attemptedRespawn;
61
63
64 public int UniqueID => _uniqueID;
65
66 public void SetToExpire()
67 {
68 _forceExpire = true;
69 }
70
71 public void SetRespawnAttemptLock(bool state)
72 {
74 }
75
97
98 public bool IsInvalid()
99 {
101 switch (nPCInvasionGroup)
102 {
103 case 1:
104 case 2:
105 case 3:
106 case 4:
108 case -3:
109 return !DD2Event.Ongoing;
110 case -2:
111 if (Main.pumpkinMoon)
112 {
113 return Main.dayTime;
114 }
115 return true;
116 case -1:
117 if (Main.snowMoon)
118 {
119 return Main.dayTime;
120 }
121 return true;
122 default:
124 {
125 case 158:
126 case 159:
127 case 162:
128 case 166:
129 case 251:
130 case 253:
131 case 460:
132 case 461:
133 case 462:
134 case 463:
135 case 466:
136 case 467:
137 case 468:
138 case 469:
139 case 477:
140 case 478:
141 case 479:
142 if (!Main.eclipse || !Main.dayTime)
143 {
144 return true;
145 }
146 break;
147 }
148 return false;
149 }
150 }
151
152 public bool IsExpired(int gameTime)
153 {
154 if (!_forceExpire)
155 {
156 return _expirationTime <= gameTime;
157 }
158 return true;
159 }
160
161 private int CalculateExpirationTime(int gameCacheTime, int coinValue)
162 {
163 int num = 0;
164 num = ((coinValue < _expirationCompSilver) ? ((int)MathHelper.Lerp(0f, 3600f, Utils.GetLerpValue(_expirationCompCopper, _expirationCompSilver, coinValue))) : ((coinValue < _expirationCompGold) ? ((int)MathHelper.Lerp(36000f, 108000f, Utils.GetLerpValue(_expirationCompSilver, _expirationCompGold, coinValue))) : ((coinValue >= _expirationCompPlat) ? 432000 : ((int)MathHelper.Lerp(108000f, 216000f, Utils.GetLerpValue(_expirationCompSilver, _expirationCompGold, coinValue))))));
165 num += 18000;
166 return gameCacheTime + num;
167 }
168
170 {
171 return rectOuter.Intersects(_hitbox);
172 }
173
174 public void SpawnEnemy()
175 {
176 int num = NPC.NewNPC(new EntitySource_RevengeSystem(), (int)_location.X, (int)_location.Y, _npcNetID);
177 NPC nPC = Main.npc[num];
178 if (_npcNetID < 0)
179 {
180 nPC.SetDefaults(_npcNetID);
181 }
182 if (NPCID.Sets.SpecialSpawningRules.TryGetValue(_npcNetID, out var value) && value == 0)
183 {
184 Point point = nPC.position.ToTileCoordinates();
185 nPC.ai[0] = point.X;
186 nPC.ai[1] = point.Y;
187 nPC.netUpdate = true;
188 }
189 nPC.timeLeft += 3600;
190 nPC.extraValue = _coinsValue;
191 nPC.value = _baseValue;
192 nPC.SpawnedFromStatue = _spawnedFromStatue;
193 float num2 = Math.Max(0.5f, _npcHPPercent);
194 nPC.life = (int)((float)nPC.lifeMax * num2);
195 if (num < 200)
196 {
197 if (Main.netMode == 0)
198 {
199 nPC.moneyPing(_location);
200 }
201 else
202 {
203 NetMessage.SendData(23, -1, -1, null, num);
204 NetMessage.SendData(92, -1, -1, null, num, _coinsValue, _location.X, _location.Y);
205 }
206 }
207 if (DisplayCaching)
208 {
209 Main.NewText("Spawned " + nPC.GivenOrTypeName);
210 }
211 }
212
214 {
216 {
217 case 2:
219 case 3:
221 case 6:
222 {
223 bool flag = false;
225 {
226 case 513:
227 flag = !playerTarget.ZoneUndergroundDesert;
228 break;
229 case 10:
230 case 39:
231 case 95:
232 case 117:
233 case 510:
234 flag = true;
235 break;
236 }
237 if (flag)
238 {
239 return (double)playerTarget.position.Y < Main.worldSurface * 16.0;
240 }
241 return false;
242 }
243 default:
244 return _npcNetID switch
245 {
246 253 => !Main.eclipse,
247 490 => Main.dayTime,
248 _ => false,
249 };
250 }
251 }
252
254 {
256 vector *= mapScale;
258 if (mapRect.HasValue && !mapRect.Value.Contains(vector.ToPoint()))
259 {
260 return false;
261 }
263 value = ((_coinsValue < 100) ? TextureAssets.Coin[0].Value : ((_coinsValue < 10000) ? TextureAssets.Coin[1].Value : ((_coinsValue >= 1000000) ? TextureAssets.Coin[3].Value : TextureAssets.Coin[2].Value)));
264 Rectangle rectangle = value.Frame(1, 8);
265 spriteBatch.Draw(value, vector, rectangle, Color.White, 0f, rectangle.Size() / 2f, drawScale, SpriteEffects.None, 0f);
267 }
268
269 public void UseMouseOver(SpriteBatch spriteBatch, ref string mouseTextString, float drawScale = 1f)
270 {
271 mouseTextString = "";
272 Vector2 vector = Main.MouseScreen / drawScale + new Vector2(-28f) + new Vector2(4f, 0f);
273 ItemSlot.DrawMoney(spriteBatch, "", vector.X, vector.Y, Utils.CoinsSplit(_coinsValue), horizontal: true);
274 }
275
277 {
278 writer.Write(_uniqueID);
279 writer.WriteVector2(_location);
280 writer.Write(_npcNetID);
281 writer.Write(_npcHPPercent);
284 writer.Write(_coinsValue);
285 writer.Write(_baseValue);
287 }
288 }
289
290 public static bool DisplayCaching = false;
291
292 public static int MinimumCoinsForCaching = Item.buyPrice(0, 0, 10);
293
294 private const int PLAYER_BOX_WIDTH_INNER = 1968;
295
296 private const int PLAYER_BOX_HEIGHT_INNER = 1200;
297
298 private const int PLAYER_BOX_WIDTH_OUTER = 2608;
299
300 private const int PLAYER_BOX_HEIGHT_OUTER = 1840;
301
302 private static readonly Vector2 _playerBoxSizeInner = new Vector2(1968f, 1200f);
303
304 private static readonly Vector2 _playerBoxSizeOuter = new Vector2(2608f, 1840f);
305
307
308 private readonly object _markersLock = new object();
309
310 private int _gameTime;
311
313 {
314 int uniqueID = reader.ReadInt32();
315 Vector2 coords = reader.ReadVector2();
316 int npcNetId = reader.ReadInt32();
317 float npcHPPercent = reader.ReadSingle();
318 int npcType = reader.ReadInt32();
319 int npcAiStyle = reader.ReadInt32();
320 int coinValue = reader.ReadInt32();
321 float baseValue = reader.ReadSingle();
322 bool spawnedFromStatue = reader.ReadBoolean();
325 }
326
328 {
330 {
332 }
333 }
334
336 {
338 {
339 _markers.RemoveAll((RevengeMarker x) => x.UniqueID == markerUniqueID);
340 }
341 }
342
344 {
346 }
347
348 public void CacheEnemy(NPC npc)
349 {
350 if (npc.boss || npc.realLife != -1 || npc.rarity > 0 || npc.extraValue < MinimumCoinsForCaching || npc.position.X < Main.leftWorld + 640f + 16f || npc.position.X + (float)npc.width > Main.rightWorld - 640f - 32f || npc.position.Y < Main.topWorld + 640f + 16f || npc.position.Y > Main.bottomWorld - 640f - 32f - (float)npc.height)
351 {
352 return;
353 }
354 int num = npc.netID;
355 if (NPCID.Sets.RespawnEnemyID.TryGetValue(num, out var value))
356 {
357 num = value;
358 }
359 if (num != 0)
360 {
363 if (Main.netMode == 2)
364 {
366 }
367 if (DisplayCaching)
368 {
369 Main.NewText("Cached " + npc.GivenOrTypeName);
370 }
371 }
372 }
373
374 public void Reset()
375 {
377 {
378 _markers.Clear();
379 }
380 _gameTime = 0;
381 }
382
383 public void Update()
384 {
385 _gameTime++;
386 if (Main.netMode == 1 && _gameTime % 60 == 0)
387 {
389 }
390 }
391
392 public void CheckRespawns()
393 {
395 {
396 if (_markers.Count == 0)
397 {
398 return;
399 }
400 }
402 for (int i = 0; i < 255; i++)
403 {
404 Player player = Main.player[i];
405 if (player.active && !player.dead)
406 {
408 }
409 }
410 if (list.Count == 0)
411 {
412 return;
413 }
416 {
418 for (int j = 0; j < _markers.Count; j++)
419 {
421 bool flag = false;
424 {
425 if (revengeMarker.Intersects(item.Item2, item.Item3))
426 {
427 tuple = item;
428 flag = true;
429 break;
430 }
431 }
432 if (!flag)
433 {
434 revengeMarker.SetRespawnAttemptLock(state: false);
435 }
436 else
437 {
438 if (revengeMarker.RespawnAttemptLocked)
439 {
440 continue;
441 }
442 revengeMarker.SetRespawnAttemptLock(state: true);
443 if (revengeMarker.WouldNPCBeDiscouraged(Main.player[tuple.Item1]))
444 {
445 revengeMarker.SetToExpire();
446 continue;
447 }
448 revengeMarker.SpawnEnemy();
450 if (Main.dedServ)
451 {
452 NetMessage.SendData(127, -1, -1, null, revengeMarker.UniqueID);
453 }
454 }
455 }
456 _markers = _markers.Except(list2).ToList();
457 }
458 }
459
461 {
463 {
466 _markers.RemoveAll((RevengeMarker x) => x.IsInvalid());
467 _markers.RemoveAll((RevengeMarker x) => x.IsExpired(_gameTime));
468 if (!Main.dedServ)
469 {
470 return;
471 }
472 foreach (RevengeMarker item in enumerable)
473 {
474 NetMessage.SendData(127, -1, -1, null, item.UniqueID);
475 }
476 foreach (RevengeMarker item2 in enumerable2)
477 {
478 NetMessage.SendData(127, -1, -1, null, item2.UniqueID);
479 }
480 }
481 }
482
484 {
485 RevengeMarker result = null;
487 {
488 foreach (RevengeMarker marker in _markers)
489 {
490 if (marker.DrawMapIcon(spriteBatch, mapTopLeft, mapX2Y2AndOff, mapRect, mapScale, drawScale, _gameTime))
491 {
492 result = marker;
493 }
494 }
495 return result;
496 }
497 }
498
500 {
502 {
503 foreach (RevengeMarker marker in _markers)
504 {
506 }
507 }
508 }
509}
void Draw(Texture2D texture, Vector2 position, Color color)
static float Lerp(float value1, float value2, float amount)
Definition MathHelper.cs:53
bool ICollection< KeyValuePair< TKey, TValue > >. Contains(KeyValuePair< TKey, TValue > keyValuePair)
void Add(TKey key, TValue value)
virtual bool ReadBoolean()
virtual float ReadSingle()
virtual int ReadInt32()
static byte Max(byte val1, byte val2)
Definition Math.cs:738
Vector2 Center
Definition Entity.cs:43
Vector2 position
Definition Entity.cs:14
bool DrawMapIcon(SpriteBatch spriteBatch, Vector2 mapTopLeft, Vector2 mapX2Y2AndOff, Rectangle? mapRect, float mapScale, float drawScale, int gameTime)
bool Intersects(Rectangle rectInner, Rectangle rectOuter)
int CalculateExpirationTime(int gameCacheTime, int coinValue)
void UseMouseOver(SpriteBatch spriteBatch, ref string mouseTextString, float drawScale=1f)
RevengeMarker(Vector2 coords, int npcNetId, float npcHPPercent, int npcType, int npcAiStyle, int coinValue, float baseValue, bool spawnedFromStatue, int gameTime, int uniqueID=-1)
RevengeMarker DrawMapIcons(SpriteBatch spriteBatch, Vector2 mapTopLeft, Vector2 mapX2Y2AndOff, Rectangle? mapRect, float mapScale, float drawScale, ref string unused)
static Asset< Texture2D > MapDeath
static Asset< Texture2D >[] Coin
static Dictionary< int, int > SpecialSpawningRules
Definition NPCID.cs:96
static Dictionary< int, int > RespawnEnemyID
Definition NPCID.cs:4115
static int buyPrice(int platinum=0, int gold=0, int silver=0, int copper=0)
Definition Item.cs:47979
static float bottomWorld
Definition Main.cs:1112
static int netMode
Definition Main.cs:2095
static bool dayTime
Definition Main.cs:1282
static bool dedServ
Definition Main.cs:1226
static Vector2 MouseScreen
Definition Main.cs:2773
static void NewText(string newText, byte R=byte.MaxValue, byte G=byte.MaxValue, byte B=byte.MaxValue)
Definition Main.cs:61429
static float topWorld
Definition Main.cs:1110
static bool eclipse
Definition Main.cs:1312
static int invasionType
Definition Main.cs:1970
static float rightWorld
Definition Main.cs:1108
static NPC[] npc
Definition Main.cs:1685
static bool snowMoon
Definition Main.cs:1300
static bool pumpkinMoon
Definition Main.cs:1298
static float leftWorld
Definition Main.cs:1106
static Player[] player
Definition Main.cs:1803
bool boss
Definition NPC.cs:515
int aiStyle
Definition NPC.cs:453
float GetLifePercent()
Definition NPC.cs:1484
string GivenOrTypeName
Definition NPC.cs:749
bool SpawnedFromStatue
Definition NPC.cs:85
int extraValue
Definition NPC.cs:525
static int GetNPCInvasionGroup(int npcID)
Definition NPC.cs:70596
float value
Definition NPC.cs:523
static bool DespawnEncouragement_AIStyle2_FloatingEye_IsDiscouraged(int npcID, Vector2 npcPosition, int target=255)
Definition NPC.cs:46056
int type
Definition NPC.cs:445
static int NewNPC(IEntitySource source, int X, int Y, int Type, int Start=0, float ai0=0f, float ai1=0f, float ai2=0f, float ai3=0f, int Target=255)
Definition NPC.cs:77654
int netID
Definition NPC.cs:531
int rarity
Definition NPC.cs:109
static bool DespawnEncouragement_AIStyle3_Fighters_NotDiscouraged(int npcID, Vector2 position, NPC npcInstance)
Definition NPC.cs:53251
int realLife
Definition NPC.cs:173
static void SendData(int msgType, int remoteClient=-1, int ignoreClient=-1, NetworkText text=null, int number=0, float number2=0f, float number3=0f, float number4=0f, int number5=0, int number6=0, int number7=0)
Definition NetMessage.cs:88
static void SendCoinLossRevengeMarker(CoinLossRevengeSystem.RevengeMarker marker, int remoteClient=-1, int ignoreClient=-1)
static void DrawMoney(SpriteBatch sb, string text, float shopx, float shopy, int[] coinsArray, bool horizontal=false)
Definition ItemSlot.cs:2829
static int[] CoinsSplit(long count)
Definition Utils.cs:665
static float GetLerpValue(float from, float to, float t, bool clamped=false)
Definition Utils.cs:203
static Rectangle CenteredRectangle(Vector2 center, Vector2 size)
Definition Utils.cs:604