TModLoader v1.4.4.9
TModLoader source code documentation
Loading...
Searching...
No Matches
EmoteBubble.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using Microsoft.Xna.Framework;
4using Microsoft.Xna.Framework.Graphics;
6using Terraria.ID;
8
10
11public class EmoteBubble : IEntityWithGlobals<GlobalEmoteBubble>
12{
13 internal static int[] CountNPCs = new int[NPCID.Count];
14
16
17 private static List<int> toClean = new List<int>();
18
19 private static int NextID;
20
21 internal int ID;
22
24
25 public int lifeTime;
26
27 public int lifeTimeStart;
28
32 public int emote;
33
34 public int metadata;
35
36 public int frameSpeed = 8;
37
38 public int frameCounter;
39
40 public int frame;
41
42 public const int EMOTE_SHEET_HORIZONTAL_FRAMES = 8;
43
44 public const int EMOTE_SHEET_EMOTES_PER_ROW = 4;
45
46 public static readonly int EMOTE_SHEET_VERTICAL_FRAMES = 2 + (EmoteID.Count - 1) / 4;
47
49
50 public ModEmoteBubble ModEmoteBubble { get; internal set; }
51
53
55
59 public int WhoAmI => ID;
60
65 public bool IsFullyDisplayed
66 {
67 get
68 {
69 if (lifeTime >= 6)
70 {
71 return lifeTimeStart - lifeTime >= 6;
72 }
73 return false;
74 }
75 }
76
77 public static void UpdateAll()
78 {
79 lock (byID)
80 {
81 toClean.Clear();
82 foreach (KeyValuePair<int, EmoteBubble> item in byID)
83 {
84 item.Value.Update();
85 if (item.Value.lifeTime <= 0)
86 {
87 toClean.Add(item.Key);
88 }
89 }
90 foreach (int item2 in toClean)
91 {
92 byID.Remove(item2);
93 }
94 toClean.Clear();
95 }
96 }
97
98 public static void DrawAll(SpriteBatch sb)
99 {
100 lock (byID)
101 {
102 foreach (KeyValuePair<int, EmoteBubble> item in byID)
103 {
104 item.Value.Draw(sb);
105 }
106 }
107 }
108
110 {
111 if (anch.type == WorldUIAnchor.AnchorType.Entity)
112 {
113 int item = 0;
114 if (anch.entity is NPC)
115 {
116 item = 0;
117 }
118 else if (anch.entity is Player)
119 {
120 item = 1;
121 }
122 else if (anch.entity is Projectile)
123 {
124 item = 2;
125 }
126 int whoAmI = anch.entity.whoAmI;
127 if (!ModNet.AllowVanillaClients && anch.entity is Projectile projectile)
128 {
129 whoAmI = projectile.identity;
130 item = (projectile.owner << 8) | item;
131 }
132 return Tuple.Create(item, whoAmI);
133 }
134 return Tuple.Create(0, 0);
135 }
136
137 public static WorldUIAnchor DeserializeNetAnchor(int type, int meta)
138 {
139 int packedOwnerType = type;
140 type = packedOwnerType & 0xFF;
141 switch (type)
142 {
143 case 0:
144 return new WorldUIAnchor((Entity)Main.npc[meta]);
145 case 1:
146 return new WorldUIAnchor((Entity)Main.player[meta]);
147 case 2:
149 {
150 int owner = packedOwnerType >> 8;
151 int whoAmI = Main.maxProjectiles;
152 for (int i = 0; i < Main.maxProjectiles; i++)
153 {
154 Projectile projectile = Main.projectile[i];
155 if (projectile.owner == owner && projectile.identity == meta && projectile.active)
156 {
157 whoAmI = i;
158 break;
159 }
160 }
161 return new WorldUIAnchor((Entity)Main.projectile[whoAmI]);
162 }
164 default:
165 throw new Exception("How did you end up getting this?");
166 }
167 }
168
169 public static int AssignNewID()
170 {
171 return NextID++;
172 }
173
181 public static int NewBubble(int emoticon, WorldUIAnchor bubbleAnchor, int time)
182 {
183 if (Main.netMode == 1)
184 {
185 return -1;
186 }
188 emoteBubble.ID = AssignNewID();
190 if (Main.netMode == 2)
191 {
193 NetMessage.SendData(91, -1, -1, null, emoteBubble.ID, tuple.Item1, tuple.Item2, time, emoticon);
194 }
197 return emoteBubble.ID;
198 }
199
207 public static int NewBubbleNPC(WorldUIAnchor bubbleAnchor, int time, WorldUIAnchor other = null)
208 {
209 if (Main.netMode == 1)
210 {
211 return -1;
212 }
214 emoteBubble.PickNPCEmote(other);
215 if (emoteBubble.emote < 0)
216 {
217 return -1;
218 }
219 emoteBubble.ID = AssignNewID();
221 if (Main.netMode == 2)
222 {
224 NetMessage.SendData(91, -1, -1, null, emoteBubble.ID, tuple.Item1, tuple.Item2, time, emoteBubble.emote, emoteBubble.metadata);
225 }
227 return emoteBubble.ID;
228 }
229
235 public static void CheckForNPCsToReactToEmoteBubble(int emoteID, Player player)
236 {
237 //IL_0065: Unknown result type (might be due to invalid IL or missing references)
238 //IL_006d: Unknown result type (might be due to invalid IL or missing references)
239 //IL_0053: Unknown result type (might be due to invalid IL or missing references)
240 for (int i = 0; i < 200; i++)
241 {
242 NPC nPC = Main.npc[i];
243 if (nPC != null && nPC.active && nPC.aiStyle == 7 && nPC.townNPC && !(nPC.ai[0] >= 2f) && ((player.CanBeTalkedTo && player.Distance(nPC.Center) < 200f) || !Collision.CanHitLine(nPC.Top, 0, 0, player.Top, 0, 0)))
244 {
245 int direction = (nPC.position.X < player.position.X).ToDirectionInt();
246 nPC.ai[0] = 19f;
247 nPC.ai[1] = 220f;
248 nPC.ai[2] = player.whoAmI;
249 nPC.direction = direction;
250 nPC.netUpdate = true;
251 }
252 }
253 }
254
255 public EmoteBubble(int emotion, WorldUIAnchor bubbleAnchor, int time = 180)
256 {
258 emote = emotion;
259 lifeTime = time;
260 lifeTimeStart = time;
261 }
262
263 private void Update()
264 {
265 lifeTime--;
267 {
268 frameCounter = 0;
269 if (++frame >= 2)
270 {
271 frame = 0;
272 }
273 }
274 }
275
276 private void Draw(SpriteBatch sb)
277 {
278 //IL_000f: Unknown result type (might be due to invalid IL or missing references)
279 //IL_0013: Unknown result type (might be due to invalid IL or missing references)
280 //IL_0018: Unknown result type (might be due to invalid IL or missing references)
281 //IL_0019: Unknown result type (might be due to invalid IL or missing references)
282 //IL_001a: Unknown result type (might be due to invalid IL or missing references)
283 //IL_001f: Unknown result type (might be due to invalid IL or missing references)
284 //IL_004e: Unknown result type (might be due to invalid IL or missing references)
285 //IL_0053: Unknown result type (might be due to invalid IL or missing references)
286 //IL_0057: Unknown result type (might be due to invalid IL or missing references)
287 //IL_0061: Unknown result type (might be due to invalid IL or missing references)
288 //IL_0091: Unknown result type (might be due to invalid IL or missing references)
289 //IL_0093: Unknown result type (might be due to invalid IL or missing references)
290 //IL_0094: Unknown result type (might be due to invalid IL or missing references)
291 //IL_0095: Unknown result type (might be due to invalid IL or missing references)
292 //IL_009b: Unknown result type (might be due to invalid IL or missing references)
293 //IL_00a0: Unknown result type (might be due to invalid IL or missing references)
294 //IL_00bd: Unknown result type (might be due to invalid IL or missing references)
295 //IL_00ea: Unknown result type (might be due to invalid IL or missing references)
296 //IL_00e5: Unknown result type (might be due to invalid IL or missing references)
297 //IL_00f5: Unknown result type (might be due to invalid IL or missing references)
298 //IL_00f6: Unknown result type (might be due to invalid IL or missing references)
299 //IL_0175: Unknown result type (might be due to invalid IL or missing references)
300 //IL_0176: Unknown result type (might be due to invalid IL or missing references)
301 //IL_0178: Unknown result type (might be due to invalid IL or missing references)
302 //IL_017a: Unknown result type (might be due to invalid IL or missing references)
303 //IL_019f: Unknown result type (might be due to invalid IL or missing references)
304 //IL_01a0: Unknown result type (might be due to invalid IL or missing references)
305 //IL_01a7: Unknown result type (might be due to invalid IL or missing references)
306 //IL_01b1: Unknown result type (might be due to invalid IL or missing references)
307 //IL_01b8: Unknown result type (might be due to invalid IL or missing references)
308 //IL_0185: Unknown result type (might be due to invalid IL or missing references)
309 //IL_0186: Unknown result type (might be due to invalid IL or missing references)
310 //IL_0188: Unknown result type (might be due to invalid IL or missing references)
311 //IL_018a: Unknown result type (might be due to invalid IL or missing references)
312 //IL_016b: Unknown result type (might be due to invalid IL or missing references)
313 //IL_0162: Unknown result type (might be due to invalid IL or missing references)
314 //IL_010e: Unknown result type (might be due to invalid IL or missing references)
315 //IL_0119: Unknown result type (might be due to invalid IL or missing references)
316 //IL_011e: Unknown result type (might be due to invalid IL or missing references)
317 //IL_0123: Unknown result type (might be due to invalid IL or missing references)
318 //IL_0170: Unknown result type (might be due to invalid IL or missing references)
319 //IL_02df: Unknown result type (might be due to invalid IL or missing references)
320 //IL_02e0: Unknown result type (might be due to invalid IL or missing references)
321 //IL_02e2: Unknown result type (might be due to invalid IL or missing references)
322 //IL_02e4: Unknown result type (might be due to invalid IL or missing references)
323 //IL_01e4: Unknown result type (might be due to invalid IL or missing references)
324 //IL_020e: Unknown result type (might be due to invalid IL or missing references)
325 //IL_020f: Unknown result type (might be due to invalid IL or missing references)
326 //IL_0216: Unknown result type (might be due to invalid IL or missing references)
327 //IL_0220: Unknown result type (might be due to invalid IL or missing references)
328 //IL_0227: Unknown result type (might be due to invalid IL or missing references)
329 //IL_01f7: Unknown result type (might be due to invalid IL or missing references)
330 //IL_01fa: Unknown result type (might be due to invalid IL or missing references)
331 //IL_01fb: Unknown result type (might be due to invalid IL or missing references)
332 //IL_02a7: Unknown result type (might be due to invalid IL or missing references)
333 //IL_02b2: Unknown result type (might be due to invalid IL or missing references)
334 //IL_02ca: Unknown result type (might be due to invalid IL or missing references)
335 //IL_02d1: Unknown result type (might be due to invalid IL or missing references)
336 Texture2D value = TextureAssets.Extra[48].Value;
337 SpriteEffects effect = (SpriteEffects)0;
338 Vector2 position = GetPosition(out effect);
339 position = position.Floor();
340 bool flag = lifeTime < 6 || lifeTimeStart - lifeTime < 6;
341 Rectangle value2 = value.Frame(8, EMOTE_SHEET_VERTICAL_FRAMES, (!flag) ? 1 : 0);
342 Vector2 origin = default(Vector2);
343 ((Vector2)(ref origin))._002Ector((float)(value2.Width / 2), (float)value2.Height);
344 if (Main.player[Main.myPlayer].gravDir == -1f)
345 {
346 origin.Y = 0f;
347 effect = (SpriteEffects)(effect | 2);
348 position = Main.ReverseGravitySupport(position);
349 }
350 Rectangle emoteFrame = (Rectangle)((emote >= 0 && emote < EmoteID.Count) ? value.Frame(8, 39, emote * 2 % 8 + frame, 1 + emote / 4) : new Rectangle(0, 0, 34, 28));
351 if (emote == -1)
352 {
353 position += new Vector2((float)(((Enum)effect).HasFlag((Enum)(object)(SpriteEffects)1) ? 1 : (-1)), (float)(-emoteFrame.Height + 3));
354 }
355 else
356 {
357 if (ModEmoteBubble != null)
358 {
359 value = ModContent.Request<Texture2D>(ModEmoteBubble.Texture).Value;
360 emoteFrame = (Rectangle)(((_003F?)EmoteBubbleLoader.GetFrame(this)) ?? value.Frame(2, 1, frame));
361 }
362 if (!EmoteBubbleLoader.PreDraw(this, sb, value, position, emoteFrame, origin, effect))
363 {
364 EmoteBubbleLoader.PostDraw(this, sb, value, position, emoteFrame, origin, effect);
365 return;
366 }
367 }
368 sb.Draw(TextureAssets.Extra[48].Value, position, (Rectangle?)value2, Color.White, 0f, origin, 1f, effect, 0f);
369 if (flag)
370 {
371 return;
372 }
373 if (emote >= 0)
374 {
375 if ((emote == 87 || emote == 89) && ((Enum)effect).HasFlag((Enum)(object)(SpriteEffects)1))
376 {
377 effect = (SpriteEffects)(effect & -2);
378 position.X += 4f;
379 }
380 sb.Draw(value, position, (Rectangle?)emoteFrame, Color.White, 0f, origin, 1f, effect, 0f);
381 }
382 else if (emote == -1)
383 {
384 value = TextureAssets.NpcHead[metadata].Value;
385 float num = 1f;
386 if ((float)value.Width / 22f > 1f)
387 {
388 num = 22f / (float)value.Width;
389 }
390 if ((float)value.Height / 16f > 1f / num)
391 {
392 num = 16f / (float)value.Height;
393 }
394 sb.Draw(value, position, (Rectangle?)null, Color.White, 0f, new Vector2((float)(value.Width / 2), 0f), num, effect, 0f);
395 }
396 EmoteBubbleLoader.PostDraw(this, sb, value, position, emoteFrame, origin, effect);
397 }
398
399 private Vector2 GetPosition(out SpriteEffects effect)
400 {
401 //IL_00d0: Unknown result type (might be due to invalid IL or missing references)
402 //IL_00d5: Unknown result type (might be due to invalid IL or missing references)
403 //IL_00da: Unknown result type (might be due to invalid IL or missing references)
404 //IL_0100: Unknown result type (might be due to invalid IL or missing references)
405 //IL_0105: Unknown result type (might be due to invalid IL or missing references)
406 //IL_00b7: Unknown result type (might be due to invalid IL or missing references)
407 //IL_00bc: Unknown result type (might be due to invalid IL or missing references)
408 //IL_00c1: Unknown result type (might be due to invalid IL or missing references)
409 //IL_011a: Unknown result type (might be due to invalid IL or missing references)
410 //IL_0124: Unknown result type (might be due to invalid IL or missing references)
411 //IL_0047: Unknown result type (might be due to invalid IL or missing references)
412 //IL_005c: Unknown result type (might be due to invalid IL or missing references)
413 //IL_0066: Unknown result type (might be due to invalid IL or missing references)
414 //IL_0099: Unknown result type (might be due to invalid IL or missing references)
415 //IL_009e: Unknown result type (might be due to invalid IL or missing references)
416 //IL_00a3: Unknown result type (might be due to invalid IL or missing references)
417 //IL_00a8: Unknown result type (might be due to invalid IL or missing references)
418 switch (anchor.type)
419 {
420 case WorldUIAnchor.AnchorType.Entity:
421 effect = (SpriteEffects)(anchor.entity.direction != -1);
422 return new Vector2(anchor.entity.Top.X, anchor.entity.VisualPosition.Y) + new Vector2((float)(-anchor.entity.direction * anchor.entity.width) * 0.75f, 2f) - Main.screenPosition;
423 case WorldUIAnchor.AnchorType.Pos:
424 effect = (SpriteEffects)0;
425 return anchor.pos - Main.screenPosition;
426 case WorldUIAnchor.AnchorType.Tile:
427 effect = (SpriteEffects)0;
428 return anchor.pos - Main.screenPosition + new Vector2(0f, (0f - anchor.size.Y) / 2f);
429 default:
430 effect = (SpriteEffects)0;
431 return new Vector2((float)Main.screenWidth, (float)Main.screenHeight) / 2f;
432 }
433 }
434
435 public static void OnBubbleChange(int bubbleID)
436 {
438 if (emoteBubble.anchor.type != 0 || !(emoteBubble.anchor.entity is Player player))
439 {
440 return;
441 }
442 foreach (EmoteBubble value in byID.Values)
443 {
444 if (value.anchor.type == WorldUIAnchor.AnchorType.Entity && value.anchor.entity == player && value.ID != bubbleID)
445 {
446 value.lifeTime = 6;
447 }
448 }
449 }
450
455 public static void MakeLocalPlayerEmote(int emoteId)
456 {
457 if (Main.netMode == 0)
458 {
461 }
462 else
463 {
464 NetMessage.SendData(120, -1, -1, null, Main.myPlayer, emoteId);
465 }
466 }
467
468 public void PickNPCEmote(WorldUIAnchor other = null)
469 {
470 //IL_0015: Unknown result type (might be due to invalid IL or missing references)
471 Player plr = Main.player[Player.FindClosest(((NPC)anchor.entity).Center, 0, 0)];
472 List<int> list = new List<int>();
473 bool flag = false;
474 for (int i = 0; i < 200; i++)
475 {
476 if (Main.npc[i].active && Main.npc[i].boss)
477 {
478 flag = true;
479 }
480 }
481 if (!flag)
482 {
483 if (Main.rand.Next(3) == 0)
484 {
485 ProbeTownNPCs(list);
486 }
487 if (Main.rand.Next(3) == 0)
488 {
489 ProbeEmotions(list);
490 }
491 if (Main.rand.Next(3) == 0)
492 {
493 ProbeBiomes(list, plr);
494 }
495 if (Main.rand.Next(2) == 0)
496 {
497 ProbeCritters(list);
498 }
499 if (Main.rand.Next(2) == 0)
500 {
501 ProbeItems(list, plr);
502 }
503 if (Main.rand.Next(5) == 0)
504 {
505 ProbeBosses(list);
506 }
507 if (Main.rand.Next(2) == 0)
508 {
509 ProbeDebuffs(list, plr);
510 }
511 if (Main.rand.Next(2) == 0)
512 {
513 ProbeEvents(list);
514 }
515 if (Main.rand.Next(2) == 0)
516 {
517 ProbeWeather(list, plr);
518 }
519 ProbeExceptions(list, plr, other);
520 }
521 else
522 {
523 ProbeCombat(list);
524 }
525 if (other == null)
526 {
527 other = new WorldUIAnchor();
528 }
530 if (modPickedEmote == -1)
531 {
532 emote = -1;
533 }
534 else if (modPickedEmote.HasValue)
535 {
536 emote = modPickedEmote.Value;
537 }
538 else if (list.Count > 0)
539 {
540 emote = list[Main.rand.Next(list.Count)];
541 }
542 }
543
544 private void ProbeCombat(List<int> list)
545 {
546 list.Add(16);
547 list.Add(1);
548 list.Add(2);
549 list.Add(91);
550 list.Add(93);
551 list.Add(84);
552 list.Add(84);
553 }
554
555 private void ProbeWeather(List<int> list, Player plr)
556 {
557 if (Main.cloudBGActive > 0f)
558 {
559 list.Add(96);
560 }
561 if (Main.cloudAlpha > 0f)
562 {
563 if (!Main.dayTime)
564 {
565 list.Add(5);
566 }
567 list.Add(4);
568 if (plr.ZoneSnow)
569 {
570 list.Add(98);
571 }
572 if (plr.position.X < 4000f || (plr.position.X > (float)(Main.maxTilesX * 16 - 4000) && (double)plr.position.Y < Main.worldSurface / 16.0))
573 {
574 list.Add(97);
575 }
576 }
577 else
578 {
579 list.Add(95);
580 }
581 if (plr.ZoneHallow)
582 {
583 list.Add(6);
584 }
585 }
586
587 private void ProbeEvents(List<int> list)
588 {
589 if (BirthdayParty.PartyIsUp && Main.rand.Next(3) == 0)
590 {
591 list.Add(Utils.SelectRandom<int>(Main.rand, 127, 128, 129, 126));
592 }
593 if (Main.bloodMoon || (!Main.dayTime && Main.rand.Next(4) == 0))
594 {
595 list.Add(18);
596 }
597 if (Main.eclipse || (Main.hardMode && Main.rand.Next(4) == 0))
598 {
599 list.Add(19);
600 }
602 {
603 list.Add(99);
604 }
606 {
607 list.Add(20);
608 }
610 {
611 list.Add(21);
612 }
614 {
615 list.Add(133);
616 }
617 }
618
619 private void ProbeDebuffs(List<int> list, Player plr)
620 {
621 //IL_0001: Unknown result type (might be due to invalid IL or missing references)
622 if (plr.Center.Y > (float)(Main.maxTilesY * 16 - 3200) || plr.onFire || ((NPC)anchor.entity).onFire || plr.onFire2)
623 {
624 list.Add(9);
625 }
626 if (Main.rand.Next(2) == 0)
627 {
628 list.Add(11);
629 }
630 if (plr.poisoned || ((NPC)anchor.entity).poisoned || plr.ZoneJungle)
631 {
632 list.Add(8);
633 }
634 if (plr.inventory[plr.selectedItem].type == 215 || Main.rand.Next(3) == 0)
635 {
636 list.Add(10);
637 }
638 }
639
640 private void ProbeItems(List<int> list, Player plr)
641 {
642 list.Add(7);
643 list.Add(73);
644 list.Add(74);
645 list.Add(75);
646 list.Add(78);
647 list.Add(90);
648 if (plr.statLife < plr.statLifeMax2 / 2)
649 {
650 list.Add(84);
651 }
652 }
653
654 private void ProbeTownNPCs(List<int> list)
655 {
656 for (int i = 0; i < NPCLoader.NPCCount; i++)
657 {
658 CountNPCs[i] = 0;
659 }
660 for (int j = 0; j < 200; j++)
661 {
662 if (Main.npc[j].active)
663 {
664 CountNPCs[Main.npc[j].type]++;
665 }
666 }
667 int type = ((NPC)anchor.entity).type;
668 for (int k = 0; k < NPCLoader.NPCCount; k++)
669 {
670 if (NPCID.Sets.FaceEmote[k] > 0 && CountNPCs[k] > 0 && k != type)
671 {
672 list.Add(NPCID.Sets.FaceEmote[k]);
673 }
674 }
675 }
676
677 private void ProbeBiomes(List<int> list, Player plr)
678 {
679 if ((double)(plr.position.Y / 16f) < Main.worldSurface * 0.45)
680 {
681 list.Add(22);
682 }
683 else if ((double)(plr.position.Y / 16f) > Main.rockLayer + (double)(Main.maxTilesY / 2) - 100.0)
684 {
685 list.Add(31);
686 }
687 else if ((double)(plr.position.Y / 16f) > Main.rockLayer)
688 {
689 list.Add(30);
690 }
691 else if (plr.ZoneHallow)
692 {
693 list.Add(27);
694 }
695 else if (plr.ZoneCorrupt)
696 {
697 list.Add(26);
698 }
699 else if (plr.ZoneCrimson)
700 {
701 list.Add(25);
702 }
703 else if (plr.ZoneJungle)
704 {
705 list.Add(24);
706 }
707 else if (plr.ZoneSnow)
708 {
709 list.Add(32);
710 }
711 else if ((double)(plr.position.Y / 16f) < Main.worldSurface && (plr.position.X < 4000f || plr.position.X > (float)(16 * (Main.maxTilesX - 250))))
712 {
713 list.Add(29);
714 }
715 else if (plr.ZoneDesert)
716 {
717 list.Add(28);
718 }
719 else if (plr.ZoneForest)
720 {
721 list.Add(23);
722 }
723 }
724
725 private void ProbeCritters(List<int> list)
726 {
727 //IL_000b: Unknown result type (might be due to invalid IL or missing references)
728 Vector2 center = anchor.entity.Center;
729 float num = 1f;
730 float num2 = 1f;
731 if ((double)center.Y < Main.rockLayer * 16.0)
732 {
733 num2 = 0.2f;
734 }
735 else
736 {
737 num = 0.2f;
738 }
739 if (Main.rand.NextFloat() <= num)
740 {
741 if (Main.dayTime)
742 {
743 list.Add(13);
744 list.Add(12);
745 list.Add(68);
746 list.Add(62);
747 list.Add(63);
748 list.Add(69);
749 list.Add(70);
750 }
751 if (!Main.dayTime || (Main.dayTime && (Main.time < 5400.0 || Main.time > 48600.0)))
752 {
753 list.Add(61);
754 }
755 if (NPC.downedGoblins)
756 {
757 list.Add(64);
758 }
759 if (NPC.downedFrost)
760 {
761 list.Add(66);
762 }
763 if (NPC.downedPirates)
764 {
765 list.Add(65);
766 }
768 {
769 list.Add(71);
770 }
771 if (WorldGen.crimson)
772 {
773 list.Add(67);
774 }
775 }
776 if (Main.rand.NextFloat() <= num2)
777 {
778 list.Add(72);
779 list.Add(69);
780 }
781 }
782
783 private void ProbeEmotions(List<int> list)
784 {
785 list.Add(0);
786 list.Add(1);
787 list.Add(2);
788 list.Add(3);
789 list.Add(15);
790 list.Add(16);
791 list.Add(17);
792 list.Add(87);
793 list.Add(91);
794 list.Add(136);
795 list.Add(134);
796 list.Add(135);
797 list.Add(137);
798 list.Add(138);
799 list.Add(139);
800 if (Main.bloodMoon && !Main.dayTime)
801 {
802 int item = Utils.SelectRandom<int>(Main.rand, 16, 1, 138);
803 list.Add(item);
804 list.Add(item);
805 list.Add(item);
806 }
807 }
808
809 private void ProbeBosses(List<int> list)
810 {
811 int num = 0;
813 {
814 num = 1;
815 }
816 if (NPC.downedBoss2)
817 {
818 num = 2;
819 }
821 {
822 num = 3;
823 }
824 if (Main.hardMode)
825 {
826 num = 4;
827 }
829 {
830 num = 5;
831 }
833 {
834 num = 6;
835 }
837 {
838 num = 7;
839 }
841 {
842 num = 8;
843 }
844 int maxValue = 10;
846 {
847 maxValue = 1;
848 }
849 if ((num >= 1 && num <= 2) || (num >= 1 && Main.rand.Next(maxValue) == 0))
850 {
851 list.Add(39);
852 if (WorldGen.crimson)
853 {
854 list.Add(41);
855 }
856 else
857 {
858 list.Add(40);
859 }
860 list.Add(51);
861 }
862 if ((num >= 2 && num <= 3) || (num >= 2 && Main.rand.Next(maxValue) == 0))
863 {
864 list.Add(43);
865 list.Add(42);
866 }
867 if ((num >= 4 && num <= 5) || (num >= 4 && Main.rand.Next(maxValue) == 0))
868 {
869 list.Add(44);
870 list.Add(47);
871 list.Add(45);
872 list.Add(46);
873 }
874 if ((num >= 5 && num <= 6) || (num >= 5 && Main.rand.Next(maxValue) == 0))
875 {
876 if (!NPC.downedMechBoss1)
877 {
878 list.Add(47);
879 }
880 if (!NPC.downedMechBoss2)
881 {
882 list.Add(45);
883 }
884 if (!NPC.downedMechBoss3)
885 {
886 list.Add(46);
887 }
888 list.Add(48);
889 }
890 if (num == 6 || (num >= 6 && Main.rand.Next(maxValue) == 0))
891 {
892 list.Add(48);
893 list.Add(49);
894 list.Add(50);
895 }
896 if (num == 7 || (num >= 7 && Main.rand.Next(maxValue) == 0))
897 {
898 list.Add(49);
899 list.Add(50);
900 list.Add(52);
901 }
902 if (num == 8 || (num >= 8 && Main.rand.Next(maxValue) == 0))
903 {
904 list.Add(52);
905 list.Add(53);
906 }
908 {
909 list.Add(59);
910 }
912 {
913 list.Add(60);
914 }
916 {
917 list.Add(57);
918 }
920 {
921 list.Add(58);
922 }
924 {
925 list.Add(56);
926 }
928 {
929 list.Add(55);
930 }
932 {
933 list.Add(54);
934 }
936 {
937 list.Add(143);
938 }
940 {
941 list.Add(144);
942 }
944 {
945 list.Add(150);
946 }
947 }
948
950 {
952 if (nPC.type == 17)
953 {
954 list.Add(80);
955 list.Add(85);
956 list.Add(85);
957 list.Add(85);
958 list.Add(85);
959 }
960 else if (nPC.type == 18)
961 {
962 list.Add(73);
963 list.Add(73);
964 list.Add(84);
965 list.Add(75);
966 }
967 else if (nPC.type == 19)
968 {
969 if (other != null && ((NPC)other.entity).type == 22)
970 {
971 list.Add(1);
972 list.Add(1);
973 list.Add(93);
974 list.Add(92);
975 }
976 else if (other != null && ((NPC)other.entity).type == 22)
977 {
978 list.Add(1);
979 list.Add(1);
980 list.Add(93);
981 list.Add(92);
982 }
983 else
984 {
985 list.Add(82);
986 list.Add(82);
987 list.Add(85);
988 list.Add(85);
989 list.Add(77);
990 list.Add(93);
991 }
992 }
993 else if (nPC.type == 20)
994 {
995 if (list.Contains(121))
996 {
997 list.Add(121);
998 list.Add(121);
999 }
1000 list.Add(14);
1001 list.Add(14);
1002 }
1003 else if (nPC.type == 22)
1004 {
1005 if (!Main.bloodMoon)
1006 {
1007 if (other != null && ((NPC)other.entity).type == 19)
1008 {
1009 list.Add(1);
1010 list.Add(1);
1011 list.Add(93);
1012 list.Add(92);
1013 }
1014 else
1015 {
1016 list.Add(79);
1017 }
1018 }
1019 if (!Main.dayTime)
1020 {
1021 list.Add(16);
1022 list.Add(16);
1023 list.Add(16);
1024 }
1025 }
1026 else if (nPC.type == 37)
1027 {
1028 list.Add(43);
1029 list.Add(43);
1030 list.Add(43);
1031 list.Add(72);
1032 list.Add(72);
1033 }
1034 else if (nPC.type == 38)
1035 {
1036 if (Main.bloodMoon)
1037 {
1038 list.Add(77);
1039 list.Add(77);
1040 list.Add(77);
1041 list.Add(81);
1042 }
1043 else
1044 {
1045 list.Add(77);
1046 list.Add(77);
1047 list.Add(81);
1048 list.Add(81);
1049 list.Add(81);
1050 list.Add(90);
1051 list.Add(90);
1052 }
1053 }
1054 else if (nPC.type == 54)
1055 {
1056 if (Main.bloodMoon)
1057 {
1058 list.Add(43);
1059 list.Add(72);
1060 list.Add(1);
1061 }
1062 else
1063 {
1064 if (list.Contains(111))
1065 {
1066 list.Add(111);
1067 }
1068 list.Add(17);
1069 }
1070 }
1071 else if (nPC.type == 107)
1072 {
1073 if (other != null && ((NPC)other.entity).type == 124)
1074 {
1075 list.Remove(111);
1076 list.Add(0);
1077 list.Add(0);
1078 list.Add(0);
1079 list.Add(17);
1080 list.Add(17);
1081 list.Add(86);
1082 list.Add(88);
1083 list.Add(88);
1084 }
1085 else
1086 {
1087 if (list.Contains(111))
1088 {
1089 list.Add(111);
1090 list.Add(111);
1091 list.Add(111);
1092 }
1093 list.Add(91);
1094 list.Add(92);
1095 list.Add(91);
1096 list.Add(92);
1097 }
1098 }
1099 else if (nPC.type == 108)
1100 {
1101 list.Add(100);
1102 list.Add(89);
1103 list.Add(11);
1104 }
1105 if (nPC.type == 124)
1106 {
1107 if (other != null && ((NPC)other.entity).type == 107)
1108 {
1109 list.Remove(111);
1110 list.Add(0);
1111 list.Add(0);
1112 list.Add(0);
1113 list.Add(17);
1114 list.Add(17);
1115 list.Add(88);
1116 list.Add(88);
1117 return;
1118 }
1119 if (list.Contains(109))
1120 {
1121 list.Add(109);
1122 list.Add(109);
1123 list.Add(109);
1124 }
1125 if (list.Contains(108))
1126 {
1127 list.Remove(108);
1128 if (Main.hardMode)
1129 {
1130 list.Add(108);
1131 list.Add(108);
1132 }
1133 else
1134 {
1135 list.Add(106);
1136 list.Add(106);
1137 }
1138 }
1139 list.Add(43);
1140 list.Add(2);
1141 }
1142 else if (nPC.type == 142)
1143 {
1144 list.Add(32);
1145 list.Add(66);
1146 list.Add(17);
1147 list.Add(15);
1148 list.Add(15);
1149 }
1150 else if (nPC.type == 160)
1151 {
1152 list.Add(10);
1153 list.Add(89);
1154 list.Add(94);
1155 list.Add(8);
1156 }
1157 else if (nPC.type == 178)
1158 {
1159 list.Add(83);
1160 list.Add(83);
1161 }
1162 else if (nPC.type == 207)
1163 {
1164 list.Add(28);
1165 list.Add(95);
1166 list.Add(93);
1167 }
1168 else if (nPC.type == 208)
1169 {
1170 list.Add(94);
1171 list.Add(17);
1172 list.Add(3);
1173 list.Add(77);
1174 }
1175 else if (nPC.type == 209)
1176 {
1177 list.Add(48);
1178 list.Add(83);
1179 list.Add(5);
1180 list.Add(5);
1181 }
1182 else if (nPC.type == 227)
1183 {
1184 list.Add(63);
1185 list.Add(68);
1186 }
1187 else if (nPC.type == 228)
1188 {
1189 list.Add(24);
1190 list.Add(24);
1191 list.Add(95);
1192 list.Add(8);
1193 }
1194 else if (nPC.type == 229)
1195 {
1196 list.Add(93);
1197 list.Add(9);
1198 list.Add(65);
1199 list.Add(120);
1200 list.Add(59);
1201 }
1202 else if (nPC.type == 353)
1203 {
1204 if (list.Contains(104))
1205 {
1206 list.Add(104);
1207 list.Add(104);
1208 }
1209 if (list.Contains(111))
1210 {
1211 list.Add(111);
1212 list.Add(111);
1213 }
1214 list.Add(67);
1215 }
1216 else if (nPC.type == 368)
1217 {
1218 list.Add(85);
1219 list.Add(7);
1220 list.Add(79);
1221 }
1222 else if (nPC.type == 369)
1223 {
1224 if (!Main.bloodMoon)
1225 {
1226 list.Add(70);
1227 list.Add(70);
1228 list.Add(76);
1229 list.Add(76);
1230 list.Add(79);
1231 list.Add(79);
1232 if ((double)nPC.position.Y < Main.worldSurface)
1233 {
1234 list.Add(29);
1235 }
1236 }
1237 }
1238 else if (nPC.type == 453)
1239 {
1240 list.Add(72);
1241 list.Add(69);
1242 list.Add(87);
1243 list.Add(3);
1244 }
1245 else if (nPC.type == 441)
1246 {
1247 list.Add(100);
1248 list.Add(100);
1249 list.Add(1);
1250 list.Add(1);
1251 list.Add(1);
1252 list.Add(87);
1253 }
1254 }
1255
1261 public static EmoteBubble GetExistingEmoteBubble(int whoAmI)
1262 {
1263 return byID.GetValueOrDefault(whoAmI);
1264 }
1265
1272 public static void MakePlayerEmote(Player player, int emoteId, bool syncBetweenClients = true)
1273 {
1274 int netMode = Main.netMode;
1275 if (netMode == 2 || netMode == 0 || !syncBetweenClients)
1276 {
1277 NewBubble(emoteId, new WorldUIAnchor((Entity)player), 360);
1279 }
1280 else
1281 {
1282 NetMessage.SendData(120, -1, -1, null, player.whoAmI, emoteId);
1283 }
1284 }
1285}
static bool CanHitLine(Vector2 Position1, int Width1, int Height1, Vector2 Position2, int Width2, int Height2)
Definition Collision.cs:815
Vector2 Center
Definition Entity.cs:70
int whoAmI
The index of this Entity within its specific array. These arrays track the entities in the world....
Definition Entity.cs:16
Vector2 Top
Definition Entity.cs:121
float Distance(Vector2 Other)
Definition Entity.cs:275
Vector2 position
The position of this Entity in world coordinates.
Definition Entity.cs:28
int width
The width of this Entity's hitbox, in pixels.
Definition Entity.cs:46
virtual Vector2 VisualPosition
Definition Entity.cs:67
bool active
If true, the Entity actually exists within the game world. Within the specific entity array,...
Definition Entity.cs:21
static Asset< Texture2D >[] Extra
static Asset< Texture2D >[] NpcHead
int WhoAmI
The whoAmI indicator that indicates this T:Terraria.GameContent.UI.EmoteBubble, can be used in M:Terr...
void ProbeEvents(List< int > list)
static int NewBubbleNPC(WorldUIAnchor bubbleAnchor, int time, WorldUIAnchor other=null)
Use this method to make NPCs use a random emote based on the pick emote table.
void ProbeExceptions(List< int > list, Player plr, WorldUIAnchor other)
static void MakeLocalPlayerEmote(int emoteId)
Send a emote from P:Terraria.Main.LocalPlayer. Should never be called on server.
static void CheckForNPCsToReactToEmoteBubble(int emoteID, Player player)
Try to find a NPC close enough (less than 200 pixels) to react to the emote sent by the player.
void ProbeWeather(List< int > list, Player plr)
static Dictionary< int, EmoteBubble > byID
void PickNPCEmote(WorldUIAnchor other=null)
static EmoteBubble GetExistingEmoteBubble(int whoAmI)
Gets the emote bubble that exists in the world by P:Terraria.GameContent.UI.EmoteBubble....
EmoteBubble(int emotion, WorldUIAnchor bubbleAnchor, int time=180)
void ProbeDebuffs(List< int > list, Player plr)
Vector2 GetPosition(out SpriteEffects effect)
static WorldUIAnchor DeserializeNetAnchor(int type, int meta)
void ProbeItems(List< int > list, Player plr)
void ProbeCritters(List< int > list)
static Tuple< int, int > SerializeNetAnchor(WorldUIAnchor anch)
void ProbeTownNPCs(List< int > list)
void ProbeEmotions(List< int > list)
bool IsFullyDisplayed
Whether or not this emote is fully displayed The first and the last 6 frames are for bubble-popping ...
static void MakePlayerEmote(Player player, int emoteId, bool syncBetweenClients=true)
Send a emote from the player.
static int NewBubble(int emoticon, WorldUIAnchor bubbleAnchor, int time)
Use this method to spawn a emote bubble.
static void DrawAll(SpriteBatch sb)
static void OnBubbleChange(int bubbleID)
void ProbeCombat(List< int > list)
RefReadOnlyArray< GlobalEmoteBubble > EntityGlobals
void ProbeBiomes(List< int > list, Player plr)
void ProbeBosses(List< int > list)
int emote
This is the internal ID of this EmoteBubble.
static readonly int EMOTE_SHEET_VERTICAL_FRAMES
static readonly int Count
Definition EmoteID.cs:50
static int[] FaceEmote
Associates a town NPC's NPC type (F:Terraria.NPC.type) with its corresponding T:Terraria....
Definition NPCID.cs:439
static readonly short Count
Definition NPCID.cs:12909
static double time
The time that has passed since it last became day/night. Increased by F:Terraria....
Definition Main.cs:1375
static int maxTilesY
The height of the currently-loaded world in tiles.
Definition Main.cs:1191
static float cloudAlpha
Definition Main.cs:1393
static double worldSurface
The y-coordinate of the top of the dirt layer, in tile coordinates. Corresponds to 0' on the Depth Me...
Definition Main.cs:1351
static int myPlayer
The index in F:Terraria.Main.player of this client's Player. If this is 255, this client is the ser...
Definition Main.cs:1958
static Vector2 ReverseGravitySupport(Vector2 pos, float height=0f)
Definition Main.cs:3198
static int netMode
Denotes the current network mode: 0 for single player client, 1 for multiplayer client,...
Definition Main.cs:2182
static double rockLayer
The y-coordinate of the top of the caverns layer, in tile coordinates.
Definition Main.cs:1357
static bool expertMode
Definition Main.cs:2898
static bool dayTime
Definition Main.cs:1365
static readonly int maxProjectiles
Definition Main.cs:1217
static bool bloodMoon
Definition Main.cs:1387
static int screenHeight
Definition Main.cs:1870
static Vector2 screenPosition
The position of the top left corner of the screen in world coordinates. Modify in M:Terraria....
Definition Main.cs:1864
static int maxTilesX
The width of the currently-loaded world in tiles.
Definition Main.cs:1186
static bool eclipse
Definition Main.cs:1403
static Projectile[] projectile
Definition Main.cs:1836
static UnifiedRandom rand
Definition Main.cs:2758
static NPC[] npc
Definition Main.cs:1830
static int screenWidth
Definition Main.cs:1868
static float cloudBGActive
Definition Main.cs:656
static bool snowMoon
Definition Main.cs:1391
static bool pumpkinMoon
Definition Main.cs:1389
static Player LocalPlayer
Retrieves the T:Terraria.Player object for the local user. Shorthand for F:Terraria....
Definition Main.cs:3001
static bool hardMode
Definition Main.cs:1091
static Player[] player
Definition Main.cs:1960
static bool UpdateFrame(EmoteBubble emoteBubble)
static void PostDraw(EmoteBubble emoteBubble, SpriteBatch spriteBatch, Texture2D texture, Vector2 position, Rectangle frame, Vector2 origin, SpriteEffects spriteEffects)
static ? Rectangle GetFrame(EmoteBubble emoteBubble)
static void OnSpawn(EmoteBubble emoteBubble)
static bool PreDraw(EmoteBubble emoteBubble, SpriteBatch spriteBatch, Texture2D texture, Vector2 position, Rectangle frame, Vector2 origin, SpriteEffects spriteEffects)
Manages content added by mods. Liasons between mod content and Terraria's arrays and oversees the Loa...
Definition ModContent.cs:38
virtual string Texture
The file name of this emote's texture file in the mod loader's file space.
Represents an emote. Emotes are typically used by players or NPC. Players can use the emotes menu or ...
static bool AllowVanillaClients
Definition ModNet.cs:109
static ? int PickEmote(NPC npc, Player closestPlayer, List< int > emoteList, WorldUIAnchor anchor)
Definition NPCLoader.cs:870
This serves as the central class from which NPC-related functions are carried out....
Definition NPCLoader.cs:26
static bool downedChristmasSantank
Denotes whether or not at least one Santa-NK1 has been defeated in the current world.
Definition NPC.cs:877
static bool downedFrost
Denotes whether or not the Frost Legion has been defeated at least once in the current world.
Definition NPC.cs:821
static bool downedMechBoss2
Denotes whether or not the Twins have been defeated at least once in the current world.
Definition NPC.cs:959
static bool downedBoss2
Denotes whether or not the Eater of Worlds OR the Brain of Cthulhu have been defeated at least once i...
Definition NPC.cs:796
static bool downedMechBossAny
Denotes whether or not ANY Mechanical Boss has been defeated at least once in the current world.
Definition NPC.cs:949
static bool downedEmpressOfLight
Denotes whether or not the Empress of Light has been defeated at least once in the current world.
Definition NPC.cs:912
static bool downedHalloweenKing
Denotes whether or not at least one Pumpking has been defeated in the current world.
Definition NPC.cs:862
static bool downedBoss1
Denotes whether or not the Eye of Cthulhu has been defeated at least once in the current world.
Definition NPC.cs:790
static bool downedMechBoss3
Denotes whether or not Skeletron Prime has been defeated at least once in the current world.
Definition NPC.cs:964
static bool downedPirates
Denotes whether or not at least one Pirate Invasion has been defeated in the current world.
Definition NPC.cs:826
static bool downedMoonlord
Denotes whether or not the Moon Lord has been defeated at least once in the current world.
Definition NPC.cs:887
static bool downedQueenBee
Denotes whether or not at least one Queen Bee has been defeated in the current world.
Definition NPC.cs:806
static bool downedHalloweenTree
Denotes whether or not at least one Mourning Wood has been defeated in the current world.
Definition NPC.cs:857
static bool downedChristmasTree
Denotes whether or not at least one Everscream has been defeated in the current world.
Definition NPC.cs:872
static bool downedGoblins
Denotes whether or not at least one Goblin Army has been defeated in the current world.
Definition NPC.cs:816
static bool downedGolemBoss
Denotes whether or not Golem has been defeated at least once in the current world.
Definition NPC.cs:842
static bool downedMartians
Denotes whether or not at least one Martian Madness event has been cleared in the current world.
Definition NPC.cs:847
static bool downedChristmasIceQueen
Denotes whether or not at least one Ice Queen has been defeated in the current world.
Definition NPC.cs:867
static bool downedAncientCultist
Denotes whether or not the Lunatic Cultist has been defeated at least once in the current world.
Definition NPC.cs:882
static bool downedBoss3
Denotes whether or not Skeletron has been defeated at least once in the current world.
Definition NPC.cs:801
static bool downedPlantBoss
Denotes whether or not Plantera has been defeated at least once in the current world.
Definition NPC.cs:837
static bool downedMechBoss1
Denotes whether or not the Destroyer has been defeated at least once in the current world.
Definition NPC.cs:954
static bool downedDeerclops
Denotes whether or not the Deerclops has been defeated at least once in the current world.
Definition NPC.cs:922
static bool downedQueenSlime
Denotes whether or not Queen Slime has been defeated at least once in the current world.
Definition NPC.cs:917
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)
bool CanBeTalkedTo
Definition Player.cs:4227
static byte FindClosest(Vector2 Position, int Width, int Height)
Definition Player.cs:5246
int owner
The index of the player who owns this projectile. In Multiplayer, Clients "own" projectiles that they...
int identity
The projectile's universal unique identifier, which is the same on all clients and the server....
static bool crimson
Definition WorldGen.cs:1170
static bool spawnMeteor
Definition WorldGen.cs:1218