📄 world.cs
字号:
using System;
using System.Reflection;
using System.Collections;
namespace CO_Full_Server
{
/// <summary>
/// Summary description for World.
/// </summary>
public class World
{
public enum Maps : uint
{
TwinCity = 1002,
MapleForest = 1011
}
public enum ChatType : uint
{
Talk = 0x7d0,
Whisper = 0x7d1,
Team = 0x7d3,
Guild = 0x7d4,
Top = 0x7d5,
Friends = 0x7d9,
Center = 0x7db
}
public static Hashtable ClientHash = new Hashtable(20, .7f);
public static ArrayList[,] TCLocHash = new ArrayList[1000,1000];
public static ArrayList[,] MFLocHash = new ArrayList[1000,1000];
public static Hashtable Chatrooms = new Hashtable(10, .8f);
public static Random RND = new Random();
public World()
{
//
// TODO: Add constructor logic here
//
}
public const int VIEWTHRESHOLD = 14;
public static Location StagingLoc = new Location(0x01b6, 0x0179);
public static void SpawnCharacter(COClient Client)
{
Character Char = Client.Char;
COClient Cli;
ArrayList[,] Target;
byte[] SpawnData = PacketBuilder.SpawnEntity(Char);
if (Client.Char.Map == Maps.TwinCity)
{
Target = TCLocHash;
}
else if (Client.Char.Map == Maps.MapleForest)
{
Target = MFLocHash;
}
else
{
return;
}
for (int x = Char.CurrentLoc.X - VIEWTHRESHOLD; x < Char.CurrentLoc.X + VIEWTHRESHOLD; x++)
{
for (int y = Char.CurrentLoc.Y - VIEWTHRESHOLD; y < Char.CurrentLoc.Y + VIEWTHRESHOLD; y++)
{
for (int z = 0; z < Target[x,y].Count; z++)
{
if (Target[x,y][z].GetType().Name == "COClient")
{
Cli = (COClient)Target[x,y][z];
Cli.SendData(SpawnData);
}
}
}
}
Target[Char.CurrentLoc.X,Char.CurrentLoc.Y].Add(Client);
}
public static void GetSurroundings(COClient Client)
{
Character Char = Client.Char;
COClient Cli;
ArrayList[,] Target = GetTarget(Client.Char.Map);
byte[] SpawnData = PacketBuilder.SpawnEntity(Char);
for (int x = Char.CurrentLoc.X - VIEWTHRESHOLD; x < Char.CurrentLoc.X + VIEWTHRESHOLD; x++)
{
for (int y = Char.CurrentLoc.Y - VIEWTHRESHOLD; y < Char.CurrentLoc.Y + VIEWTHRESHOLD; y++)
{
for (int z = 0; z < Target[x,y].Count; z++)
{
if (Target[x,y][z].GetType().Name == "COClient")
{
Cli = (COClient)Target[x,y][z];
Client.SendData(PacketBuilder.SpawnEntity(Cli.Char));
}
}
}
}
}
public static void InitWorld()
{
for (int x = 0; x < 1000; x++)
{
for (int y = 0; y < 1000; y++)
{
TCLocHash[x,y] = new ArrayList(2);
}
}
for (int x = 0; x < 1000; x++)
{
for (int y = 0; y < 1000; y++)
{
MFLocHash[x,y] = new ArrayList(2);
}
}
}
public static void Jump(COClient Client, byte[] Packet)
{
int PrevX = (Packet[0x0d] << 8) + Packet[0x0c];
int PrevY = (Packet[0x0f] << 8) + Packet[0x0e];
int NewX = (Packet[0x15] << 8) + Packet[0x14];
int NewY = (Packet[0x17] << 8) + Packet[0x016];
Console.WriteLine("dX = " + (NewX - PrevX) + " dY = " + (NewY - PrevY));
Character Char = Client.Char;
COClient Cli;
ArrayList[,] Target = GetTarget(Client.Char.Map);
if (!Target[PrevX, PrevY].Contains(Client))
{
DropClient(Client,"Client was not at stated location.");
throw new Exception("Client was not at stated location.");
}
if (Math.Abs(NewX - PrevX) > VIEWTHRESHOLD + 3 || Math.Abs(NewY - PrevY) > VIEWTHRESHOLD + 3)
{
DropClient(Client,"Jump too large");
throw new Exception("Jump too large");
}
if (Math.Abs(NewX - PrevX) > VIEWTHRESHOLD - 1 || Math.Abs(NewY - PrevY) > VIEWTHRESHOLD - 1)
{
World.DisapperClient(Client);
Char.CurrentLoc = new Location(NewX, NewY);
Target[PrevX, PrevY].Remove(Client);
Target[NewX, NewY].Add(Client);
World.SpawnCharacter(Client);
return;
}
Char.CurrentLoc = new Location(NewX, NewY);
Target[PrevX, PrevY].Remove(Client);
Target[NewX, NewY].Add(Client);
//Update the clients
//1 - Clients here cannot see the jumper. A spawn must occur on both sides
int StepX = NewX > PrevX ? 1 : -1;
int StepY = NewY > PrevY ? 1 : -1;
int StartX;
int EndX;
int StartY;
int EndY;
if (StepX > 0)
{
StartX = PrevX + VIEWTHRESHOLD;
EndX = NewX + VIEWTHRESHOLD;
}
else
{
StartX = PrevX - VIEWTHRESHOLD;
EndX = NewX - VIEWTHRESHOLD;
}
if (StepY > 0)
{
StartY = NewY - VIEWTHRESHOLD;
EndY = NewY + VIEWTHRESHOLD;
}
else
{
StartY = NewY + VIEWTHRESHOLD;
EndY = NewY - VIEWTHRESHOLD;
}
for (int x = StartX - StepX; x != EndX; x += StepX)
{
for (int y = StartY - StepY; y != EndY; y += StepY)
{
for (int z = 0; z < Target[x,y].Count; z++)
{
if (Target[x,y][z].GetType().Name == "COClient")
{
Cli = (COClient)Target[x,y][z];
Cli.SendData(PacketBuilder.SpawnEntity(Client.Char));
Client.SendData(PacketBuilder.SpawnEntity(Cli.Char));
}
}
}
}
//Console.WriteLine("Step 1 complete");
//2 - Clients here cannot see the jumper. A spawn must occur on both sides
if (StepX > 0)
{
StartX = NewX - VIEWTHRESHOLD;
EndX = PrevX + VIEWTHRESHOLD;
}
else
{
StartX = NewX + VIEWTHRESHOLD;
EndX = PrevX - VIEWTHRESHOLD;
}
if (StepY > 0)
{
StartY = PrevY + VIEWTHRESHOLD;
EndY = NewY + VIEWTHRESHOLD;
}
else
{
StartY = PrevY - VIEWTHRESHOLD;
EndY = NewY - VIEWTHRESHOLD;
}
for (int x = StartX - StepX; x != EndX; x += StepX)
{
for (int y = StartY - StepY; y != EndY; y += StepY)
{
for (int z = 0; z < Target[x,y].Count; z++)
{
if (Target[x,y][z].GetType().Name == "COClient")
{
Cli = (COClient)Target[x,y][z];
Cli.SendData(PacketBuilder.SpawnEntity(Client.Char));
Client.SendData(PacketBuilder.SpawnEntity(Cli.Char));
}
}
}
}
//Console.WriteLine("Step 2 complete");
//3 - Clients here will not be able to see the jumper after the jump. A remove entity must be sent.
if (StepX > 0)
{
StartX = PrevX - VIEWTHRESHOLD;
EndX = NewX - VIEWTHRESHOLD;
}
else
{
StartX = PrevX + VIEWTHRESHOLD;
EndX = NewX + VIEWTHRESHOLD;
}
if (StepY > 0)
{
StartY = PrevY - VIEWTHRESHOLD;
EndY = PrevY + VIEWTHRESHOLD;
}
else
{
StartY = PrevY + VIEWTHRESHOLD;
EndY = PrevY - VIEWTHRESHOLD;
}
for (int x = StartX - StepX; x != EndX; x += StepX)
{
for (int y = StartY - StepY; y != EndY; y += StepY)
{
for (int z = 0; z < Target[x,y].Count; z++)
{
if (Target[x,y][z].GetType().Name == "COClient")
{
Cli = (COClient)Target[x,y][z];
Cli.SendData(PacketBuilder.RemoveEntity(Char.CharID));
}
}
}
}
//Console.WriteLine("Step 3 complete");
//4 - Clients here will not be able to see the jumper after the jump. A remove entity must be sent.
if (StepX > 0)
{
StartX = NewX - VIEWTHRESHOLD;
EndX = PrevX + VIEWTHRESHOLD;
}
else
{
StartX = NewX + VIEWTHRESHOLD;
EndX = PrevX - VIEWTHRESHOLD;
}
if (StepY > 0)
{
StartY = PrevY - VIEWTHRESHOLD;
EndY = NewY - VIEWTHRESHOLD;
}
else
{
StartY = PrevY + VIEWTHRESHOLD;
EndY = NewY + VIEWTHRESHOLD;
}
for (int x = StartX - StepX; x != EndX; x += StepX)
{
for (int y = StartY - StepY; y != EndY; y += StepY)
{
for (int z = 0; z < Target[x,y].Count; z++)
{
if (Target[x,y][z].GetType().Name == "COClient")
{
Cli = (COClient)Target[x,y][z];
Cli.SendData(PacketBuilder.RemoveEntity(Char.CharID));
}
}
}
}
//Console.WriteLine("Step 4 complete");
//5 - Last, clients that will see the jump
if (StepX > 0)
{
StartX = NewX - VIEWTHRESHOLD;
EndX = PrevX + VIEWTHRESHOLD;
}
else
{
StartX = NewX + VIEWTHRESHOLD;
EndX = PrevX - VIEWTHRESHOLD;
}
if (StepY > 0)
{
StartY = NewY - VIEWTHRESHOLD;
EndY = PrevY + VIEWTHRESHOLD;
}
else
{
StartY = NewY + VIEWTHRESHOLD;
EndY = PrevY - VIEWTHRESHOLD;
}
for (int x = StartX - StepX; x != EndX; x += StepX)
{
for (int y = StartY - StepY; y != EndY; y += StepY)
{
for (int z = 0; z < Target[x,y].Count; z++)
{
if (Target[x,y][z].GetType().Name == "COClient")
{
Cli = (COClient)Target[x,y][z];
Cli.SendData(Packet);
}
}
}
}
//Console.WriteLine("Step 5 complete");
}
public static void Walk(COClient Client, byte[] Packet)
{
int Direction = Packet[0x08] % 8;
int DX = 0;
int DY = 0;
COClient Cli;
Character Char = Client.Char;
Location Loc = Char.CurrentLoc;
ArrayList[,] Target = GetTarget(Client.Char.Map);
int PrevX = Loc.X;
int PrevY = Loc.Y;
switch (Direction)
{
case 0:
{
DY = 1;
break;
}
case 1:
{
DX = -1;
DY = 1;
break;
}
case 2:
{
DX = -1;
break;
}
case 3:
{
DX = -1;
DY = -1;
break;
}
case 4:
{
DY = -1;
break;
}
case 5:
{
DX = 1;
DY = -1;
break;
}
case 6:
{
DX = 1;
break;
}
case 7:
{
DY = 1;
DX = 1;
break;
}
default:
{
DX = 0;
DY = 0;
break;
}
}
int NewX = PrevX + DX;
int NewY = PrevY + DY;
Target[PrevX, PrevY].Remove(Client);
Target[NewX, NewY].Add(Client);
Client.Char.CurrentLoc = new Location(NewX, NewY);
//Update the clients
//1 - Clients here cannot see the jumper. A spawn must occur on both sides
int StepX = NewX > PrevX ? 1 : -1;
int StepY = NewY > PrevY ? 1 : -1;
int StartX;
int EndX;
int StartY;
int EndY;
if (StepX > 0)
{
StartX = PrevX + VIEWTHRESHOLD;
EndX = NewX + VIEWTHRESHOLD;
}
else
{
StartX = PrevX - VIEWTHRESHOLD;
EndX = NewX - VIEWTHRESHOLD;
}
if (StepY > 0)
{
StartY = NewY - VIEWTHRESHOLD;
EndY = NewY + VIEWTHRESHOLD;
}
else
{
StartY = NewY + VIEWTHRESHOLD;
EndY = NewY - VIEWTHRESHOLD;
}
for (int x = StartX - StepX; x != EndX; x += StepX)
{
for (int y = StartY - StepY; y != EndY; y += StepY)
{
for (int z = 0; z < Target[x,y].Count; z++)
{
if (Target[x,y][z].GetType().Name == "COClient")
{
Cli = (COClient)Target[x,y][z];
Cli.SendData(PacketBuilder.SpawnEntity(Client.Char));
Client.SendData(PacketBuilder.SpawnEntity(Cli.Char));
}
}
}
}
//Console.WriteLine("Step 1 complete");
//2 - Clients here cannot see the jumper. A spawn must occur on both sides
if (StepX > 0)
{
StartX = NewX - VIEWTHRESHOLD;
EndX = PrevX + VIEWTHRESHOLD;
}
else
{
StartX = NewX + VIEWTHRESHOLD;
EndX = PrevX - VIEWTHRESHOLD;
}
if (StepY > 0)
{
StartY = PrevY + VIEWTHRESHOLD;
EndY = NewY + VIEWTHRESHOLD;
}
else
{
StartY = PrevY - VIEWTHRESHOLD;
EndY = NewY - VIEWTHRESHOLD;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -