public void NotifyCastSpell(INavGrid navGrid, ISpell s, float x, float y, float xDragEnd, float yDragEnd, uint futureProjNetId, uint spellNetId) { var response = new CastSpellResponse(navGrid, s, x, y, xDragEnd, yDragEnd, futureProjNetId, spellNetId); _packetHandlerManager.BroadcastPacket(response, Channel.CHL_S2C); }
public CastSpellResponse(INavGrid navGrid, ISpell s, float x, float y, float xDragEnd, float yDragEnd, uint futureProjNetId, uint spellNetId) : base(PacketCmd.PKT_S2C_CAST_SPELL_ANS, s.Owner.NetId) { Write(Environment.TickCount); // syncID Write((byte)0); // Unk Write((short)0x66); // Buffer size from here Write((int)s.GetId()); // Spell hash, for example hash("EzrealMysticShot") Write((uint)spellNetId); // Spell net ID Write((byte)(s.Level - 1)); Write(1.0f); // attackSpeedMod WriteNetId(s.Owner); WriteNetId(s.Owner); Write((int)s.Owner.GetChampionHash()); Write((uint)futureProjNetId); // The projectile ID that will be spawned Write((float)x); Write((float)navGrid.GetHeightAtLocation(x, y)); Write((float)y); Write((float)xDragEnd); Write((float)navGrid.GetHeightAtLocation(xDragEnd, yDragEnd)); Write((float)yDragEnd); Write((byte)0); // numTargets (if >0, what follows is a list of {uint32 targetNetId, uint8 hitResult}) Write((float)s.SpellData.GetCastTime()); // designerCastTime Write(0.0f); // extraTimeForCast Write((float)s.SpellData.GetCastTime() /*+ s.ChannelTime*/); // designerTotalTime Write((float)s.GetCooldown()); Write(0.0f); // startCastTime Write((byte)0); // flags (isAutoAttack, secondAttack, forceCastingOrChannelling, mShouldOverrideCastPosition) Write((byte)s.Slot); Write((float)s.SpellData.ManaCost[s.Level]); Write((float)s.Owner.X); Write((float)s.Owner.GetZ()); Write((float)s.Owner.Y); Write((long)1); // Unk }
public BeginAutoAttack(INavGrid navGrid, IAttackableUnit attacker, IAttackableUnit attacked, uint futureProjNetId, bool isCritical) : base(PacketCmd.PKT_S2C_BEGIN_AUTO_ATTACK, attacker.NetId) { WriteNetId(attacked); Write((byte)0x80); // extraTime Write((uint)futureProjNetId); // Basic attack projectile ID, to be spawned later if (isCritical) { Write((byte)0x49); // attackSlot } else { Write((byte)0x40); // attackSlot } Write((byte)0x80); // not sure what this is, but it should be correct (or maybe attacked x z y?) - 4.18 Write((byte)0x01); Write(MovementVector.TargetXToNormalFormat(navGrid, attacked.X)); Write((byte)0x80); Write((byte)0x01); Write(MovementVector.TargetYToNormalFormat(navGrid, attacked.Y)); Write((byte)0xCC); Write((byte)0x35); Write((byte)0xC4); Write((byte)0xD1); Write((float)attacker.X); Write((float)attacker.Y); }
public void NotifyCastSpell(INavGrid navGrid, ISpell s, Vector2 start, Vector2 end, uint futureProjNetId, uint spellNetId) { var response = new CastSpellResponse(navGrid, s, start.X, start.Y, end.X, end.Y, futureProjNetId, spellNetId); _packetHandlerManager.BroadcastPacket(response, Channel.CHL_S2C); }
public CastSpellResponse(INavGrid navGrid, ISpell s, Vector2 start, Vector2 end, uint futureProjNetId, uint spellNetId) { NavGrid = navGrid; Spell = s; Start = start; End = end; FutureProjNetId = futureProjNetId; SpellNetId = spellNetId; }
public SpawnCampMonster(INavGrid navGrid, IMonster m) : base(PacketCmd.PKT_S2C_OBJECT_SPAWN, m.NetId) { Write((byte)0x79); Write((byte)0x01); Write((byte)0x77); Write((byte)0x01); Write((byte)0x63); // 0x63 (99) for jungle monster, 3 for minion WriteNetId(m); WriteNetId(m); Write((byte)0x40); Write(m.X); //x Write(m.GetZ()); //z Write(m.Y); //y Write(m.X); //x Write(m.GetZ()); //z Write(m.Y); //y Write(m.Facing.X); //facing x Write(navGrid.GetHeightAtLocation(m.Facing.X, m.Facing.Y)); //facing z Write(m.Facing.Y); //facing y WriteConstLengthString(m.Name, 64); WriteConstLengthString(m.Model, 64); WriteConstLengthString(m.Name, 64); WriteConstLengthString(m.SpawnAnimation, 64); Write((int)m.Team); // Probably a short Fill(0, 12); // Unk Write((int)m.CampId); // Camp id. Camp needs to exist Write(0); // Unk Write((int)m.CampUnk); Write(1); // Unk Write(m.SpawnAnimationTime); // After this many seconds, the camp icon appears in the minimap Write(1191.533936f); // Unk Write(1); // Unk Fill(0, 40); // Unk Write(1.0f); // Unk Fill(0, 13); // Unk Write((byte)3); //type 3=champ/jungle; 2=minion Write((byte)0xF1); //<-| Write((byte)0xFB); // |-> Unk Write((byte)0x27); // | Write((byte)0x00); //<-| Write(m.X); //x Write(m.Y); //y Write(-0.8589599f); // rotation1 from -1 to 1 Write(0.5120428f); // rotation2 from -1 to 1 }
public MovementResponse(INavGrid navGrid, List <IGameObject> actors) : base(PacketCmd.PKT_S2C_MOVE_ANS) { Write(Environment.TickCount); // syncID Write((short)actors.Count); foreach (var actor in actors) { var waypoints = actor.Waypoints; var numCoords = waypoints.Count * 2; Write((byte)numCoords); WriteNetId(actor); Write(Movement.EncodeWaypoints(navGrid, waypoints)); } }
public SpawnMonster(INavGrid navGrid, IMonster m) : base(PacketCmd.PKT_S2C_OBJECT_SPAWN) { WriteNetId(m); Write((short)345); Write((short)343); Write((byte)0x63); // 0x63 (99) for jungle monster, 3 for minion WriteNetId(m); WriteNetId(m); Write((byte)0x40); Write(m.X); //x Write(m.GetZ()); //z Write(m.Y); //y Write(m.X); //x Write(m.GetZ()); //z Write(m.Y); //y Write(m.Facing.X); //facing x Write(navGrid.GetHeightAtLocation(m.Facing.X, m.Facing.Y)); //facing z Write(m.Facing.Y); //facing y WriteConstLengthString(m.Name, 64); WriteConstLengthString(m.Model, 64); WriteConstLengthString(m.Name, 64); Fill(0, 64); // empty Write((int)m.Team); // Probably a short Fill(0, 12); Write(1); //campId 1 Write(100); Write(74); Write((long)1); Write(115.0066f); Write((byte)0); Fill(0, 11); Write(1.0f); // Unk Fill(0, 13); Write((byte)3); //type 3=champ/jungle; 2=minion Write(13337); Write(m.X); //x Write(m.Y); //y Write(-0.8589599f); // rotation1 from -1 to 1 Write(0.5120428f); //rotation2 from -1 to 1 }
public SpawnParticle(INavGrid navGrid, IParticle particle) : base(PacketCmd.PKT_S2C_SPAWN_PARTICLE, particle.Owner.NetId) { Write((byte)1); // number of particles Write((uint)particle.Owner.GetChampionHash()); WriteStringHash(particle.Name); Write(0x00000020); // flags ? Write((short)0); // Unk WriteStringHash(particle.BoneName); Write((byte)1); // number of targets ? WriteNetId(particle.Owner); WriteNetId(particle); // Particle net id ? WriteNetId(particle.Owner); if (particle.Target.IsSimpleTarget) { Write(0); } else { WriteNetId(particle.Target as IGameObject); } Write(0); // unk for (var i = 0; i < 3; ++i) { var ownerHeight = navGrid.GetHeightAtLocation(particle.Owner.X, particle.Owner.Y); var particleHeight = navGrid.GetHeightAtLocation(particle.X, particle.Y); var higherValue = Math.Max(ownerHeight, particleHeight); Write((short)((particle.Target.X - navGrid.MapWidth / 2) / 2)); Write(higherValue); Write((short)((particle.Target.Y - navGrid.MapHeight / 2) / 2)); } Write((uint)0); // unk Write((uint)0); // unk Write((uint)0); // unk Write((uint)0); // unk Write(particle.Size); // Particle size }
public EnterVisionAgain(INavGrid navGrid, IChampion c) : base(PacketCmd.PKT_S2C_OBJECT_SPAWN, c.NetId) { Write((short)0); // extraInfo Write((byte)0); //c.getInventory().getItems().size(); // itemCount? //buffer.Write((short)7; // unknown /* * for (int i = 0; i < c.getInventory().getItems().size(); i++) { * ItemInstance* item = c.getInventory().getItems()[i]; * * if (item != 0 && item.getTemplate() != 0) { * buffer.Write((short)item.getStacks(); * buffer.Write((short)0; // unk * buffer.Write((int)item.getTemplate().getId(); * buffer.Write((short)item.getSlot(); * } * else { * buffer.fill(0, 7); * } * } */ Fill(0, 10); Write(1.0f); Fill(0, 13); Write((byte)2); // Type of data: Waypoints=2 Write(Environment.TickCount); // unk var waypoints = c.Waypoints; Write((byte)((waypoints.Count - c.CurWaypoint + 1) * 2)); // coordCount WriteNetId(c); Write((byte)0); // movement mask; 1=KeepMoving? Write(MovementVector.TargetXToNormalFormat(navGrid, c.X)); Write(MovementVector.TargetYToNormalFormat(navGrid, c.Y)); for (var i = c.CurWaypoint; i < waypoints.Count; ++i) { Write(MovementVector.TargetXToNormalFormat(navGrid, waypoints[i].X)); Write(MovementVector.TargetXToNormalFormat(navGrid, waypoints[i].Y)); } }
public Dash(INavGrid navGrid, IAttackableUnit u, ITarget t, float dashSpeed, bool keepFacingLastDirection, float leapHeight = 0.0f, float followTargetMaxDistance = 0.0f, float backDistance = 0.0f, float travelTime = 0.0f ) : base(PacketCmd.PKT_S2C_DASH) { Write(Environment.TickCount); // syncID Write((short)1); // Number of dashes Write((byte)4); // Waypoints size * 2 WriteNetId(u); Write(dashSpeed); Write(leapHeight); Write(u.X); Write(u.Y); Write((byte)(keepFacingLastDirection ? 0x01 : 0x00)); if (t.IsSimpleTarget) { Write((uint)0); } else { WriteNetId(t as IGameObject); } Write(followTargetMaxDistance); Write(backDistance); Write(travelTime); var waypoints = new List <Vector2> { new Vector2(u.X, u.Y), new Vector2(t.X, t.Y) }; Write(Movement.EncodeWaypoints(navGrid, waypoints)); }
public EnterVisionAgain(INavGrid navGrid, IMinion m) : base(PacketCmd.PKT_S2C_OBJECT_SPAWN, m.NetId) { Fill(0, 13); Write(1.0f); Fill(0, 13); Write((byte)0x02); Write(Environment.TickCount); // unk var waypoints = m.Waypoints; Write((byte)((waypoints.Count - m.CurWaypoint + 1) * 2)); // coordCount WriteNetId(m); // TODO: Check if Movement.EncodeWaypoints is what we need to use here Write((byte)0); // movement mask Write(MovementVector.TargetXToNormalFormat(navGrid, m.X)); Write(MovementVector.TargetYToNormalFormat(navGrid, m.Y)); for (var i = m.CurWaypoint; i < waypoints.Count; i++) { Write(MovementVector.TargetXToNormalFormat(navGrid, waypoints[i].X)); Write(MovementVector.TargetXToNormalFormat(navGrid, waypoints[i].Y)); } }
public PacketNotifier(IPacketHandlerManager packetHandlerManager, INavGrid navGrid) { _packetHandlerManager = packetHandlerManager; _navGrid = navGrid; }
public static byte[] EncodeWaypoints(INavGrid navGrid, List <Vector2> waypoints) { var mapSize = navGrid.GetSize(); var numCoords = waypoints.Count * 2; var maskBytes = new byte[(numCoords - 3) / 8 + 1]; var tempStream = new MemoryStream(); var resultStream = new MemoryStream(); var tempBuffer = new BinaryWriter(tempStream); var resultBuffer = new BinaryWriter(resultStream); var lastCoord = new Vector2(); var coordinate = 0; foreach (var waypoint in waypoints) { var curVector = new Vector2((waypoint.X - mapSize.X) / 2, (waypoint.Y - mapSize.Y) / 2); if (coordinate == 0) { tempBuffer.Write((short)curVector.X); tempBuffer.Write((short)curVector.Y); } else { var relative = new Vector2(curVector.X - lastCoord.X, curVector.Y - lastCoord.Y); var isAbsolute = IsAbsolute(relative); if (isAbsolute.Item1) { tempBuffer.Write((short)curVector.X); } else { tempBuffer.Write((byte)relative.X); } if (isAbsolute.Item2) { tempBuffer.Write((short)curVector.Y); } else { tempBuffer.Write((byte)relative.Y); } SetBitmaskValue(ref maskBytes, coordinate - 2, !isAbsolute.Item1); SetBitmaskValue(ref maskBytes, coordinate - 1, !isAbsolute.Item2); } lastCoord = curVector; coordinate += 2; } if (numCoords > 2) { resultBuffer.Write(maskBytes); } resultBuffer.Write(tempStream.ToArray()); return(resultStream.ToArray()); }
public static void FindPath(INavGrid grid, IGridPoint start, IGridPoint destination) { AStar.FindPath(start, destination, (p1, p2) => (p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y), p => grid.getPassableNeighbours(p)); }
public MinionSpawn(INavGrid navGrid, IMinion m) : base(PacketCmd.PKT_S2C_OBJECT_SPAWN, m.NetId) { Write((uint)0x00150017); // unk Write((byte)0x03); // SpawnType - 3 = minion WriteNetId(m); WriteNetId(m); Write((uint)m.SpawnPosition); Write((byte)0xFF); // unk Write((byte)1); // wave number ? Write((byte)m.MinionSpawnType); if (m.MinionSpawnType == MinionSpawnType.MINION_TYPE_MELEE) { Write((byte)0); // unk } else { Write((byte)1); // unk } Write((byte)0); // unk if (m.MinionSpawnType == MinionSpawnType.MINION_TYPE_CASTER) { Write(0x00010007); // unk } else if (m.MinionSpawnType == MinionSpawnType.MINION_TYPE_MELEE) { Write(0x0001000A); // unk } else if (m.MinionSpawnType == MinionSpawnType.MINION_TYPE_CANNON) { Write(0x0001000D); } else { Write(0x00010007); // unk } Write(0x00000000); // unk Write(0x00000000); // unk Write((short)0x0000); // unk Write(1.0f); // unk Write(0x00000000); // unk Write(0x00000000); // unk Write(0x00000000); // unk Write((short)0x0200); // unk Write(Environment.TickCount); // unk var waypoints = m.Waypoints; Write((byte)((waypoints.Count - m.CurWaypoint + 1) * 2)); // coordCount WriteNetId(m); Write((byte)0); // movement mask Write(MovementVector.TargetXToNormalFormat(navGrid, m.X)); Write(MovementVector.TargetYToNormalFormat(navGrid, m.Y)); for (var i = m.CurWaypoint; i < waypoints.Count; ++i) { Write(MovementVector.TargetXToNormalFormat(navGrid, waypoints[i].X)); Write(MovementVector.TargetXToNormalFormat(navGrid, waypoints[i].Y)); } }
public static short TargetYToNormalFormat(INavGrid navGrid, float value) { return(FormatCoordinate(value, navGrid.MiddleOfMap.Y)); }
public static Path <T> FindPath <T>(INavGrid <T> navGrid, T start, T destination, AccessibilityPredicate IsAccessible) where T : IEquatable <T> { Vector2Int startIndices = navGrid.GetGridPosition(start); Vector2Int destinationIndices = navGrid.GetGridPosition(destination); if (!IsAccessible(startIndices.x, startIndices.y) || !IsAccessible(destinationIndices.x, destinationIndices.y)) { return(null); } if (start.Equals(destination)) { return(new Path <T>(start)); } int length = navGrid.Length; int width = navGrid.Width; bool[,] closedList = new bool[length, width]; AStarTile <T>[,] tiles = new AStarTile <T> [length, width]; for (int x = 0; x < length; x++) { for (int y = 0; y < width; y++) { tiles[x, y].indices = new Vector2Int(x, y); tiles[x, y].previous = new Vector2Int(-1, -1); tiles[x, y].f = float.MaxValue; tiles[x, y].g = float.MaxValue; tiles[x, y].h = float.MaxValue; } } FibonacciHeap <AStarTile <T> > openList = new FibonacciHeap <AStarTile <T> >(); Dictionary <Vector2Int, FibonacciHeapNode <AStarTile <T> > > openListMap = new Dictionary <Vector2Int, FibonacciHeapNode <AStarTile <T> > >(); tiles[startIndices.x, startIndices.y].indices = startIndices; tiles[startIndices.x, startIndices.y].previous = startIndices; tiles[startIndices.x, startIndices.y].f = 0; tiles[startIndices.x, startIndices.y].g = 0; tiles[startIndices.x, startIndices.y].h = 0; openListMap.Add(startIndices, openList.Push(tiles[startIndices.x, startIndices.y])); while (!openList.IsEmpty()) { AStarTile <T> current = openList.Pop().Value; Vector2Int currentIndices = current.indices; int x = currentIndices.x; int y = currentIndices.y; closedList[x, y] = true; List <Vector2Int> adjacentGridPositions = navGrid.GetAdjacentGridPositions(x, y); for (int i = 0; i < adjacentGridPositions.Count; i++) { Vector2Int neighborIndices = adjacentGridPositions[i]; int xi = neighborIndices.x; int yi = neighborIndices.y; if (neighborIndices == destinationIndices) { tiles[xi, yi].previous = currentIndices; LinkedList <T> wayPoints = new LinkedList <T>(); while (neighborIndices != startIndices) { wayPoints.AddFirst(navGrid.GetTile(neighborIndices)); neighborIndices = tiles[neighborIndices.x, neighborIndices.y].previous; } return(new Path <T>(start, wayPoints)); } if (closedList[xi, yi] || !IsAccessible(xi, yi)) { continue; } float gNew = current.g + MathUtility.ManhattanDistance(xi, yi, x, y); float hNew = MathUtility.ManhattanDistance(xi, yi, destinationIndices.x, destinationIndices.y); float fNew = gNew + hNew; if (tiles[xi, yi].f < fNew) { continue; } tiles[xi, yi].previous = currentIndices; tiles[xi, yi].g = gNew; tiles[xi, yi].h = hNew; tiles[xi, yi].f = fNew; if (!openListMap.ContainsKey(neighborIndices)) { openListMap.Add(neighborIndices, openList.Push(tiles[xi, yi])); } else { openList.Decrement(openListMap[neighborIndices], tiles[xi, yi]); } } } return(null); }
public MovementResponse(INavGrid navGrid, IGameObject obj) : this(navGrid, new List <IGameObject> { obj }) { }
public SpawnProjectile(INavGrid navGrid, IProjectile p) : base(PacketCmd.PKT_S2C_SPAWN_PROJECTILE, p.NetId) { var targetZ = navGrid.GetHeightAtLocation(p.Target.X, p.Target.Y); Write(p.X); Write(p.GetZ() + 100.0f); Write(p.Y); Write(p.X); Write(p.GetZ()); Write(p.Y); Write(-0.992436f); // Rotation X Write(0); // Rotation Z Write(-0.122766f); // Rotation Y Write(-1984.871338f); // Unk Write(-166.666656f); // Unk Write(-245.531418f); // Unk Write(p.X); Write(p.GetZ() + 100.0f); Write(p.Y); Write(p.Target.X); Write(navGrid.GetHeightAtLocation(p.Target.X, p.Target.Y)); Write(p.Target.Y); Write(p.X); Write(p.GetZ()); Write(p.Y); Write(0); // Unk ((float)castDelay ?) Write(p.GetMoveSpeed()); // Projectile speed Write(0); // Unk Write(0); // Unk Write(0x7f7fffff); // Unk Write((byte)0); // Unk if (!p.Target.IsSimpleTarget) { Write((short)0x6B); // Buffer size from here } else { Write((short)0x66); // Buffer size from here } Write(p.ProjectileId); // projectile ID (hashed name) Write(0); // Second net ID Write((byte)0); // spellLevel Write(1.0f); // attackSpeedMod WriteNetId(p.Owner); WriteNetId(p.Owner); if (p.Owner is IChampion c) { Write(c.GetChampionHash()); } else { Write(0); } WriteNetId(p); Write(p.Target.X); Write(navGrid.GetHeightAtLocation(p.Target.X, p.Target.Y)); Write(p.Target.Y); Write(p.Target.X); Write(navGrid.GetHeightAtLocation(p.Target.X, p.Target.Y) + 100.0f); Write(p.Target.Y); if (!p.Target.IsSimpleTarget) { Write((byte)0x01); // numTargets WriteNetId(p.Target as IAttackableUnit); Write((byte)0); // hitResult } else { Write((byte)0); // numTargets } Write(1.0f); // designerCastTime -- Doesn't seem to matter Write(0); // extraTimeForCast -- Doesn't seem to matter Write(1.0f); // designerTotalTime -- Doesn't seem to matter Write(0.0f); // cooldown -- Doesn't seem to matter Write(0.0f); // startCastTime -- Doesn't seem to matter Write((byte)0x00); // flags? Write((byte)0x30); // slot? Write(0.0f); // manaCost? Write(p.X); Write(p.GetZ()); Write(p.Y); Write(0); // Unk Write(0); // Unk }