public static void Send(Packet p, WorldObject source, ESendTarget target) { if (target != ESendTarget.AllClients && target != ESendTarget.ChatMainchat) { if (source == null) { ServerConsole.ErrorLine("World.Send: WorldObject (source) cant be null on type " + target + "!"); return; } } Rectangle2D area; switch (target) { case ESendTarget.Self: if (source is Character && (source as Character).Account.Netstate != null) { (source as Character).Account.Netstate.Send(p); } break; case ESendTarget.AllClients: World.SendAllClients(p); break; case ESendTarget.AllSameMap: // Source must have a map/is moveable if (source is WorldObjectUnit) { foreach (MapBlock block in (source as WorldObjectUnit).Map.Blocks) { foreach (WorldObject obj in block.Values) { if (obj is Character) { (obj as Character).Account.Netstate.Send(p); } } } } break; case ESendTarget.Area: case ESendTarget.AreaWithoutOwnChatrooms: case ESendTarget.AreaWithoutChatrooms: case ESendTarget.AreaWithoutSelf: //if (sd && bl->prev == NULL) //Otherwise source misses the packet // TODO: what means that? how exactly do they using ->prev and ->next pointer? if ((source is Character) && (target == ESendTarget.Area || target == ESendTarget.AreaWithoutOwnChatrooms)) { (source as Character).Account.Netstate.Send(p); } if (source is Character) { area = new Rectangle2D((source as Character).Location.X - Global.AREA_SIZE, (source as Character).Location.Y - Global.AREA_SIZE, (source as Character).Location.X + Global.AREA_SIZE, (source as Character).Location.Y + Global.AREA_SIZE, true); (source as Character).Map.ForeachInRange(area, mForeachInRangeCallback, new object[] { source, p, target }); } break; case ESendTarget.HearableAreaWithoutChatrooms: if (source is Character) { area = new Rectangle2D((source as Character).Location.X - (Global.AREA_SIZE - 5), (source as Character).Location.Y - (Global.AREA_SIZE - 5), (source as Character).Location.X + (Global.AREA_SIZE - 5), (source as Character).Location.Y + (Global.AREA_SIZE - 5), true); (source as Character).Map.ForeachInRange(area, mForeachInRangeCallback, new object[] { source, p, ESendTarget.AreaWithoutChatrooms }); } break; } }
public void MakeHold(Rectangle2D r) { if (r.mStart.X < mStart.X) mStart.X = r.mStart.X; if (r.mStart.Y < mStart.Y) mStart.Y = r.mStart.Y; if (r.mEnd.X > mEnd.X) mEnd.X = r.mEnd.X; if (r.mEnd.Y > mEnd.Y) mEnd.Y = r.mEnd.Y; }
public void ForeachInRange(Rectangle2D area, EDatabaseType type, ForeachInRangeVoidDelegate callback, object[] args) { List<WorldObject> objects = ObjectsInRange(area, type); for (int i = 0; i < objects.Count; i++) { WorldObject obj = objects[i]; callback(obj, args); } }
public void ForeachInRange(Rectangle2D area, ForeachInRangeDelegate callback, object[] args) { ForeachInRange(area, EDatabaseType.Char, callback, args); }
public List<WorldObject> ObjectsInRange(Rectangle2D area, EDatabaseType type) { List<WorldObject> list = new List<WorldObject>(); MapBlock block; for (int x = area.X / Global.BLOCK_SIZE; x < area.EndX / Global.BLOCK_SIZE; ++x) { for (int y = area.Y / Global.BLOCK_SIZE; y < area.EndY / Global.BLOCK_SIZE; ++y) { if ((block = GetBlockReal(x, y)) == null) { continue; } if (type != EDatabaseType.All) { foreach (WorldObject obj in block.Values) { if ((obj.WorldID.Type & type) > 0) { list.Add(obj); } } } else { list.AddRange(block.Values); } } } return list; }