// Because we want the damage tooltip to show our custom damage, we need to modify it public override void ModifyTooltips(List <TooltipLine> tooltips) { // Get the vanilla damage tooltip TooltipLine tt = tooltips.FirstOrDefault(x => x.Name == "Damage" && x.mod == "Terraria"); if (tt != null) { // We want to grab the last word of the tooltip, which is the translated word for 'damage' (depending on what language the player is using) // So we split the string by whitespace, and grab the last word from the returned arrays to get the damage word, and the first to get the damage shown in the tooltip string[] splitText = tt.text.Split(' '); string damageValue = splitText.First(); string damageWord = splitText.Last(); // Change the tooltip text tt.text = damageValue + ' ' + Language.GetTextValue("Mods.Entrogic.ArcaneDamage") + damageWord; } bool hasGlove = false; foreach (Item it in Main.LocalPlayer.inventory) { if (it.type != ItemID.None && Entrogic.ItemSafe(it) && it.GetGlobalItem <EntrogicItem>().glove) { hasGlove = true; break; } } if (!hasGlove && !glove) { TooltipLine line = new TooltipLine(mod, mod.Name, $"你似乎还无法使用这张卡牌,请" + $"{(NPC.AnyNPCs(NPCType<CardMerchant>()) ? "" : "等待卡牌商的到来并")}从卡牌商处购买一个手套以使用") { overrideColor = Color.Red }; tooltips.Add(line); } if (AEntrogicConfigClient.Instance.ShowUsefulInformations) { TooltipLine line = new TooltipLine(mod, mod.Name, $"抽取概率:{item.GetGlobalItem<EntrogicItem>().cardProb * 100f}%") { overrideColor = Color.Gray }; tooltips.Add(line); } ModifySafeTooltips(tooltips); }
public override void AI() { Player player = Main.player[npc.target]; npc.spriteDirection = -npc.direction; if (State != (int)NPCState.Dead && State != (int)NPCState.PlayerDead) { npc.velocity = (player.Center - npc.Center).ToRotation().ToRotationVector2() * 1.8f; } if (!player.active || player.dead) { npc.TargetClosest(); if (!player.active || player.dead) { SwitchState((int)NPCState.PlayerDead); } } switch ((NPCState)State) { // 正常状态下 case NPCState.Normal: { npc.TargetClosest(); Timer++; if (Timer >= 60 && player.active) { if (npc.Distance(player.Center) >= 40f * 16f) { SwitchState((int)NPCState.Teleport); } else if (Collision.CanHit(npc.Center, npc.width, npc.height, player.Center, player.width, player.height)) { SwitchState((int)NPCState.Attack); } } break; } // 攻击状态下 case NPCState.Attack: { // 帧数=计时器/4 Timer++; // 第九帧攻击 (也就是此阶段第32帧) if (Timer == 32 && Main.netMode != NetmodeID.MultiplayerClient) { // 来点二分法 Vector2 shootPos = new Vector2(npc.Center.X, npc.Center.Y + npc.height / 2f - 30f); // min, max和mid都表示射击角度 float min = -MathHelper.Pi, max = MathHelper.Pi; float mid = (min + max) * 0.5f; while (Math.Abs(max - min) > 0.005f) { Vector2 dirtProj = shootPos; Vector2 plrMovement = player.Center; mid = (min + max) * 0.5f; float beyond = 0f; Vector2 velo = mid.ToRotationVector2() * 15f; for (int i = 0; i < 1000; i++) { dirtProj += velo; plrMovement += player.velocity; if (npc.Distance(dirtProj) > npc.Distance(plrMovement)) { beyond = (dirtProj - npc.Center).ToRotation() - (plrMovement - npc.Center).ToRotation(); break; } } if (beyond > 0f) { max = mid; } else { min = mid; } } Projectile.NewProjectile(shootPos, mid.ToRotationVector2() * 15f, ProjectileType <DirtHostile>(), npc.damage / 2, 1f, Main.myPlayer); npc.netUpdate = true; } // 第12帧结束 (4*11=44) if (Timer >= 44) { SwitchState((int)NPCState.Normal); } break; } // 传送状态下 case NPCState.Teleport: { // 随机传送到以玩家为中心的六十格的矩形内任意松软类物块 Timer++; // 帧数=计时器/4 // 第16帧传送 (4*15=60) if (Timer == 60) { npc.TargetClosest(); if (player.active) { List <Point> findTile = new List <Point>(); for (int i = -30; i <= 30; i++) { for (int j = -30; j <= 30; j++) { Point pos = new Point(i + (int)(player.Center.X / 16f), j + (int)(player.Center.Y / 16f)); if (WorldGen.InWorld(pos.X, pos.Y) && Entrogic.TileDirt(Main.tile[pos.X, pos.Y])) { bool rsafe = true; for (int k = -1; k <= 1; k++) { for (int l = -1; l >= -3; l--) { Point posSafe = new Point(k + pos.X, l + pos.Y); if (WorldGen.InWorld(posSafe.X, posSafe.Y) && Main.tile[posSafe.X, posSafe.Y].active() && Main.tileSolid[Main.tile[posSafe.X, posSafe.Y].type]) { rsafe = false; } } } if (rsafe) { findTile.Add(pos); } } } } if (findTile.Count > 0) { int random = Main.rand.Next(0, findTile.Count); Point randomTile = findTile[random]; npc.position = randomTile.ToWorldCoordinates(8 - npc.width * 0.5f, -npc.height); } } } // 传送之后倒放帧图,倒放完了返回普通模式 if (Timer == 120) { SwitchState((int)NPCState.Normal); } break; } // 死亡状态下 case NPCState.Dead: { drawOffsetY = 0; npc.height = 138; npc.velocity.X *= 0.88f; npc.noGravity = false; npc.noTileCollide = false; // 不断下降直到碰到物块 // 第9帧最后落下动画 (6*8=48) if (Timer <= 48) { Timer++; } else if (npc.position.Y == npc.oldPosition.Y) { // 帧数=计时器/6 Timer++; } // 第13帧最后动画 (6*12=72) if (Timer >= 72) { Timer = 72; npc.ai[2]++; npc.alpha = (int)npc.ai[2] * 3; if (npc.ai[2] >= 90) { npc.life = 0; npc.HitEffect(0, 0); npc.checkDead(); // This will trigger ModNPC.CheckDead the second time, causing the real death. } } npc.netUpdate = true; break; } // 玩家死亡状态下 case NPCState.PlayerDead: { npc.noGravity = false; npc.noTileCollide = true; npc.TargetClosest(); if (player.active && !player.dead) { SwitchState((int)NPCState.Normal); } Timer++; if (Timer >= 130) { npc.life = 0; npc.active = false; npc.netUpdate = true; } break; } } }
public override void Draw(SpriteBatch spriteBatch) { Player player = Main.LocalPlayer; EntrogicPlayer ePlayer = player.GetModPlayer <EntrogicPlayer>(); if (IsActive) { base.Draw(spriteBatch); Vector2 bookPos = new Vector2((Main.screenWidth - bookSize.X) / 2, (Main.screenHeight - bookSize.Y) / 2); Rectangle rectLeft = new Rectangle((int)bookPos.X, (int)(bookPos.Y + bookSize.Y - 117), 72, 117); Rectangle rectRight = new Rectangle((int)(bookPos.X + bookSize.X - 72), (int)(bookPos.Y + bookSize.Y - 117), 72, 117); if (mouseRect.Intersects(rectLeft) && ePlayer.PageNum > 1) { spriteBatch.Draw(Entrogic.Instance.GetTexture("UI/Books/书本_03"), new Vector2(rectLeft.X, rectLeft.Y), null, Color.White, 0f, Vector2.Zero, Vector2.One, SpriteEffects.None, 0f); } else { string page = (ePlayer.PageNum * 2 - 1).ToString(); Vector2 size = Main.fontMouseText.MeasureString(page) * 0.5f; ChatManager.DrawColorCodedStringWithShadow(spriteBatch, Main.fontItemStack, page, new Vector2(bookPos.X + 34 - size.X, bookPos.Y + bookSize.Y - 86 - size.Y), Color.White, 0f, Vector2.Zero, new Vector2(1f)); } int MaxPage = 1; if (ePlayer.GetHoldItem() != null) { if (ePlayer.GetHoldItem().GetGlobalItem <EntrogicItem>().book) { MaxPage = ((ModBook)ePlayer.GetHoldItem().modItem).MaxPage; } } if (mouseRect.Intersects(rectRight) && ePlayer.PageNum < MaxPage) { spriteBatch.Draw(Entrogic.Instance.GetTexture("UI/Books/书本_02"), new Vector2(rectRight.X, rectRight.Y), null, Color.White, 0f, Vector2.Zero, Vector2.One, SpriteEffects.None, 0f); } else { string page = (ePlayer.PageNum * 2).ToString(); Vector2 size = Main.fontMouseText.MeasureString(page) * 0.5f; ChatManager.DrawColorCodedStringWithShadow(spriteBatch, Main.fontItemStack, page, new Vector2(bookPos.X + bookSize.X - 34 - size.X, bookPos.Y + bookSize.Y - 86 - size.Y), Color.White, 0f, Vector2.Zero, new Vector2(1f)); } #region Draw Text Vector2 space = new Vector2((Main.screenWidth - bookSize.X) / 2 + 38, (Main.screenHeight - bookSize.Y) / 2 + 46); //Main.spriteBatch.Draw(Main.magicPixel, space.ToRectangle(), Color.Yellow * .7f); //Main.spriteBatch.Draw(Main.magicPixel, GetOuterDimensions().ToRectangle(), Color.Red * .7f); DynamicSpriteFont font = Entrogic.PixelFont; float scale = 1f; string text = " "; Color baseColor = Color.White; float lineDistance = 0f; Item playerHeldItem = player.HeldItem; if (Entrogic.ItemSafe(playerHeldItem)) { if (playerHeldItem.GetGlobalItem <EntrogicItem>().book) { ModBook itemBook = (ModBook)playerHeldItem.modItem; if (itemBook.PageText[ePlayer.PageNum * 2 - 1] != null) { text = itemBook.PageText[ePlayer.PageNum * 2 - 1]; } //if (((ModBook)ePlayer.GetHoldItem().modItem).font != null) // font = ((ModBook)ePlayer.GetHoldItem().modItem).font; if (itemBook.textBaseColor != null) { baseColor = itemBook.textBaseColor; } lineDistance = itemBook.lineDistance[ePlayer.PageNum * 2 - 1]; scale = itemBook.textScale[ePlayer.PageNum * 2 - 1]; } } float baseLineDistance = 46f * scale; { // 左书页文字 List <List <TextSnippet> > drawTextSnippets = WordwrapStringSmart(text, scale, baseColor, font, (int)(bookSize.X * 0.5f) - 72, -1); float position = 0f; TextSnippet[] texts; foreach (var snippetList in drawTextSnippets) { texts = snippetList.ToArray(); //float snippetListHeight = ChatManager.GetStringSize(font, texts, new Vector2(scale)).Y + lineDistance; //Main.NewText($"Y: {ChatManager.GetStringSize(font, texts, Vector2.One).X}"); if (position > -baseLineDistance + lineDistance /*snippetListHeight*/) { //foreach (var snippet in snippetList) //{ int hoveredSnippet = -1; ChatManager.ConvertNormalSnippets(texts); ChatManager.DrawColorCodedString(spriteBatch, font, texts, new Vector2(space.X, space.Y + position /*+ offset*/), baseColor, 0f, Vector2.Zero, new Vector2(scale), out hoveredSnippet, -1f); //offset += 20; //offset += texts.Max(t => (int)ChatManager.GetStringSize(Main.fontMouseText, texts, Vector2.One).X); //if (hoveredSnippet > -1 && IsMouseHovering) //{ // BossChecklist.instance.BossLog.hoveredTextSnippet = texts[hoveredSnippet]; // // BossChecklist change: Use hoveredTextSnippet to bypass clippingRectangle and draw order issues. // //texts[hoveredSnippet].OnHover(); // //if (Main.mouseLeft && Main.mouseLeftRelease/* && Terraria.GameInput.PlayerInput.Triggers.JustReleased.MouseLeft*/) { // // texts[hoveredSnippet].OnClick(); // //} //} } position += baseLineDistance + lineDistance /*snippetListHeight*/; if (position > bookSize.Y - 48) { break; } //} } } { // 右书页文字 if (ePlayer.GetHoldItem() != null) { if (ePlayer.GetHoldItem().GetGlobalItem <EntrogicItem>().book) { if (((ModBook)ePlayer.GetHoldItem().modItem).PageText[ePlayer.PageNum * 2] != null) { text = ((ModBook)ePlayer.GetHoldItem().modItem).PageText[ePlayer.PageNum * 2]; } lineDistance = ((ModBook)ePlayer.GetHoldItem().modItem).lineDistance[ePlayer.PageNum * 2]; scale = ((ModBook)ePlayer.GetHoldItem().modItem).textScale[ePlayer.PageNum * 2]; } } List <List <TextSnippet> > drawTextSnippets = WordwrapStringSmart(text, scale, baseColor, font, (int)(bookSize.X * 0.5f) - 78, -1); float position = 0f; TextSnippet[] texts; foreach (var snippetList in drawTextSnippets) { texts = snippetList.ToArray(); //float snippetListHeight = ChatManager.GetStringSize(font, texts, new Vector2(scale)).Y + lineDistance; //Main.NewText($"Y: {ChatManager.GetStringSize(font, texts, Vector2.One).X}"); if (position > -baseLineDistance + lineDistance /*snippetListHeight*/) { //foreach (var snippet in snippetList) //{ int hoveredSnippet = -1; ChatManager.ConvertNormalSnippets(texts); ChatManager.DrawColorCodedString(spriteBatch, font, texts, new Vector2(space.X + bookSize.X * 0.5f, space.Y + position /*+ offset*/), baseColor, 0f, Vector2.Zero, new Vector2(scale), out hoveredSnippet, -1f); //offset += 20; //offset += texts.Max(t => (int)ChatManager.GetStringSize(Main.fontMouseText, texts, Vector2.One).X); //if (hoveredSnippet > -1 && IsMouseHovering) //{ // BossChecklist.instance.BossLog.hoveredTextSnippet = texts[hoveredSnippet]; // // BossChecklist change: Use hoveredTextSnippet to bypass clippingRectangle and draw order issues. // //texts[hoveredSnippet].OnHover(); // //if (Main.mouseLeft && Main.mouseLeftRelease/* && Terraria.GameInput.PlayerInput.Triggers.JustReleased.MouseLeft*/) { // // texts[hoveredSnippet].OnClick(); // //} //} } position += baseLineDistance + lineDistance /*snippetListHeight*/; if (position > bookSize.Y - 48) { break; } //} } } #endregion } }