using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using System.Reflection;
using TAPI;
using Terraria;
namespace PostHardModeJungle.Items
{
public class Aether_Wraith_Summoning_Wand : ModItem
{
public override bool? UseItem(Player p)
{
if (Main.netMode != 1)
{
int j = p.whoAmI;
int spawnRangeX = (int)typeof(NPC).GetField("spawnRangeX", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null);
int spawnRangeY = (int)typeof(NPC).GetField("spawnRangeX", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null);
int spawnSpaceX = (int)typeof(NPC).GetField("spawnSpaceX", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null);
int spawnSpaceY = (int)typeof(NPC).GetField("spawnSpaceY", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null);
#region set xmin,xmax,ymin,ymax,safe_xmin,safe_xmax,safe_ymin,safe_ymax
int xmin = (int)(Main.player[j].position.X / 16f) - spawnRangeX;
int xmax = (int)(Main.player[j].position.X / 16f) + spawnRangeX;
int ymin = (int)(Main.player[j].position.Y / 16f) - spawnRangeY;
int ymax = (int)(Main.player[j].position.Y / 16f) + spawnRangeY;
int safe_xmin = (int)(Main.player[j].position.X / 16f) - NPC.safeRangeX;
int safe_xmax = (int)(Main.player[j].position.X / 16f) + NPC.safeRangeX;
int safe_ymin = (int)(Main.player[j].position.Y / 16f) - NPC.safeRangeY;
int safe_ymax = (int)(Main.player[j].position.Y / 16f) + NPC.safeRangeY;
if (xmin < 0)
xmin = 0;
if (xmax > Main.maxTilesX)
xmax = Main.maxTilesX;
if (ymin < 0)
ymin = 0;
if (ymax > Main.maxTilesY)
ymax = Main.maxTilesY;
#endregion
bool spawn_valid = false;
int x_pos_out = 0;
int y_pos_out = 0;
int k = 0;
while (k < 50) // try 50 times
{
#region look for valid spawn point
int x_pos = Main.rand.Next(xmin, xmax);
int y_pos = Main.rand.Next(ymin, ymax);
if (Main.tile[x_pos, y_pos].active() && TileDef.solid[(int)Main.tile[x_pos, y_pos].type]) // solid block
goto IL_C34; // spawn failed
if (!TileDef.wallHouse[(int)Main.tile[x_pos, y_pos].wall]) // not inside a house
{
#region trace down to find a tile with solid ground, away from player (x_pos_out,y_pos_out)
int l = y_pos;
while (l < Main.maxTilesY) // trace downwards
{
if (Main.tile[x_pos, l].active() && TileDef.solid[(int)Main.tile[x_pos, l].type]) // hit a solid tile
{
if (x_pos < safe_xmin || x_pos > safe_xmax || l < safe_ymin || l > safe_ymax) // away from spawning player
{
//byte arg_B5A_0 = Main.tile[x_pos, l].type;
x_pos_out = x_pos;
y_pos_out = l;
spawn_valid = true;
break; // found a candidate - stop tracing down
}
break; // hit a solid tile - stop tracing down
}
else // keep tracing down
l++;
} // END trace downwards
#endregion
if (!spawn_valid)
goto IL_C34;
#region set cavity_xmin,cavity_xmax,cavity_ymin,cavity_ymax; check if there is space for npc
int cavity_x_min = x_pos_out - spawnSpaceX / 2;
int cavity_x_max = x_pos_out + spawnSpaceX / 2;
int cavity_y_min = y_pos_out - spawnSpaceY;
int cavity_y_max = y_pos_out;
if (cavity_x_min < 0)
spawn_valid = false;
if (cavity_x_max > Main.maxTilesX)
spawn_valid = false;
if (cavity_y_min < 0)
spawn_valid = false;
if (cavity_y_max > Main.maxTilesY)
spawn_valid = false;
if (spawn_valid)
{
for (int m = cavity_x_min; m < cavity_x_max; m++)
{
for (int n = cavity_y_min; n < cavity_y_max; n++)
{
if (Main.tile[m, n].active() && TileDef.solid[(int)Main.tile[m, n].type])
{
spawn_valid = false;
break;
}
if (Main.tile[m, n].lava())
{
spawn_valid = false;
break;
}
}
}
goto IL_C34;
}
#endregion
goto IL_C34;
}
#region dont spawn on other players' screens either
if (spawn_valid)
{
Rectangle spawn_rect = new Rectangle(x_pos_out * 16, y_pos_out * 16, 16, 16);
for (int other_player = 0; other_player < 255; other_player++)
{
if (Main.player[other_player].active)
{
Rectangle other_player_rect = new Rectangle((int)(Main.player[other_player].position.X + (float)(Main.player[other_player].width / 2) - (float)(NPC.sWidth / 2) - (float)NPC.safeRangeX), (int)(Main.player[other_player].position.Y + (float)(Main.player[other_player].height / 2) - (float)(NPC.sHeight / 2) - (float)NPC.safeRangeY), NPC.sWidth + NPC.safeRangeX * 2, NPC.sHeight + NPC.safeRangeY * 2);
if (spawn_rect.Intersects(other_player_rect))
spawn_valid = false;
}
}
}
#endregion
IL_C3A:
k++;
continue; // try again
IL_C34:
if (!spawn_valid)
goto IL_C3A; // try again
break; // found legal spot
#endregion
} // END try 50 times
if (spawn_valid)
{
int new_npc = 255;
new_npc = NPC.NewNPC(x_pos_out * 16 + 8, y_pos_out * 16, NPCDef.byName["PostHardModeJungle:Aether_Wraith"].type, 0);
if (Main.netMode == 2 && new_npc < 200)
NetMessage.SendData(23, -1, -1, "", new_npc, 0f, 0f, 0f, 0);
}
}
if (Main.netMode != 2)
{
Main.PlaySound(2, (int)p.Center.X, (int)p.Center.Y, 37);
Vector2 npcPos = p.position - new Vector2(0, 200);
for (int m = 0; m < 15; m++)
{
int dustID = Dust.NewDust(npcPos, p.width, p.height, 60, Main.rand.Next(-10, 10) * 1f, Main.rand.Next(-10, 10) * 1f, 100, Color.White, 3.5f);
Main.dust[dustID].noGravity = true;
}
}
return true;
}
}
}