private void ParseCreateOnMap(Internal.CommunicationStream message) { var absolutePosition = message.ReadPosition(); if (!WorldMapStorage.IsVisible(absolutePosition, true)) { throw new System.Exception("ProtocolGame.ParseCreateOnMap: Co-ordinate " + absolutePosition + " is out of range."); } var mapPosition = WorldMapStorage.ToMap(absolutePosition); int stackPos = 255; if (OpenTibiaUnity.GameManager.ClientVersion >= 841) { stackPos = message.ReadUnsignedByte(); } int typeOrId = message.ReadUnsignedShort(); Appearances.ObjectInstance @object; if (typeOrId == Appearances.AppearanceInstance.Creature || typeOrId == Appearances.AppearanceInstance.OutdatedCreature || typeOrId == Appearances.AppearanceInstance.UnknownCreature) { var creature = ProtocolGameExtentions.ReadCreatureInstance(message, typeOrId, absolutePosition); if (creature.Id == Player.Id) { Player.StopAutowalk(true); } @object = AppearanceStorage.CreateObjectInstance(Appearances.AppearanceInstance.Creature, creature.Id); } else { @object = ProtocolGameExtentions.ReadObjectInstance(message, typeOrId); } if (stackPos == 255) { WorldMapStorage.PutObject(mapPosition, @object); } else { if (stackPos > Constants.MapSizeW) { throw new System.Exception("ProtocolGame.ParseCreateOnMap: Invalid stack position (" + stackPos + ")."); } WorldMapStorage.InsertObject(mapPosition, stackPos, @object); } if (absolutePosition.z == MiniMapStorage.PositionZ) { WorldMapStorage.UpdateMiniMap(mapPosition); uint color = WorldMapStorage.GetMiniMapColour(mapPosition); int cost = WorldMapStorage.GetMiniMapCost(mapPosition); MiniMapStorage.UpdateField(absolutePosition, color, cost, false); } WorldMapStorage.CacheRefresh = true; }
private int ReadField(Internal.ByteArray message, int x, int y, int z) { var mapPosition = new UnityEngine.Vector3Int(x, y, z); var absolutePosition = WorldMapStorage.ToAbsolute(mapPosition); int typeOrId; int stackPos = 0; bool gotEffect = false; while (true) { typeOrId = message.ReadUnsignedShort(); if (typeOrId >= 65280) { break; } if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameEnvironmentEffect) && !gotEffect) { var effectObject = AppearanceStorage.CreateEnvironmentalEffect((uint)typeOrId); WorldMapStorage.SetEnvironmentalEffect(mapPosition, effectObject); gotEffect = true; continue; } if (typeOrId == AppearanceInstance.UnknownCreature || typeOrId == AppearanceInstance.OutdatedCreature || typeOrId == AppearanceInstance.Creature) { var creature = ReadCreatureInstance(message, typeOrId, absolutePosition); var @object = AppearanceStorage.CreateObjectInstance(AppearanceInstance.Creature, creature.ID); if (stackPos < Constants.MapSizeW) { WorldMapStorage.AppendObject(mapPosition, @object); } } else { var @object = ReadObjectInstance(message, typeOrId); if (stackPos < Constants.MapSizeW) { WorldMapStorage.AppendObject(mapPosition, @object); } else { throw new System.Exception("ProtocolGameUtility.ReadField: Expected creatures but received regular object."); } } stackPos++; } return(typeOrId - 65280); }
private ObjectInstance ReadObjectInstance(Internal.CommunicationStream message, int id = -1) { if (id == -1) { id = message.ReadUnsignedShort(); } if (id == 0) { return(null); } else if (id <= AppearanceInstance.Creature) { throw new System.Exception("ProtocolGameUtility.ReadObjectInstance: Invalid type (id = " + id + ")"); } var @object = AppearanceStorage.CreateObjectInstance((uint)id, 0); if (!@object) { throw new System.Exception("ProtocolGameUtility.ReadObjectInstance: Invalid instance with id " + id); } if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameObjectMarks)) { @object.Marks.SetMark(MarkType.Permenant, message.ReadUnsignedByte()); } if (@object.Type.IsStackable || @object.Type.IsFluidContainer || @object.Type.IsSplash) { @object.Data = message.ReadUnsignedByte(); } if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameItemAnimationPhase)) { if (@object.Type.FrameGroups[(int)Protobuf.Shared.FrameGroupType.Idle].SpriteInfo.IsAnimation) { int phase = message.ReadUnsignedByte(); @object.Phase = phase == 0 ? Constants.PhaseAutomatic : phase; } } if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameQuickLoot) && @object.Type.IsContainer) { bool assignedToQuickLoot = message.ReadBoolean(); if (assignedToQuickLoot) { uint lootContainers = message.ReadUnsignedInt(); // 1 << ObjectCategory | .... } } return(@object); }
private AppearanceInstance ReadCreatureOutfit(Internal.ByteArray message, AppearanceInstance instance = null) { int outfitID; if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GameOutfitIDU16)) { outfitID = message.ReadUnsignedShort(); } else { outfitID = message.ReadUnsignedByte(); } if (outfitID != 0) { int headColor = message.ReadUnsignedByte(); int torsoColor = message.ReadUnsignedByte(); int legsColor = message.ReadUnsignedByte(); int detailColor = message.ReadUnsignedByte(); int addonsFlags = 0; if (OpenTibiaUnity.GameManager.GetFeature(GameFeature.GamePlayerAddons)) { addonsFlags = message.ReadUnsignedByte(); } OutfitInstance outfitInstance = instance as OutfitInstance; if (!!outfitInstance) { outfitInstance.UpdateProperties(headColor, torsoColor, legsColor, detailColor, addonsFlags); return(instance); } return(AppearanceStorage.CreateOutfitInstance((uint)outfitID, headColor, torsoColor, legsColor, detailColor, addonsFlags)); } uint objectID = message.ReadUnsignedShort(); ObjectInstance objectInstance = instance as ObjectInstance; if (!!objectInstance && objectInstance.ID == objectID) { return(objectInstance); } if (objectID == 0) { return(AppearanceStorage.CreateOutfitInstance(OutfitInstance.InvisibleOutfitID, 0, 0, 0, 0, 0)); } return(AppearanceStorage.CreateObjectInstance(objectID, 0)); }
private void ParseCreatureMove(Internal.ByteArray message) { int x = message.ReadUnsignedShort(); UnityEngine.Vector3Int oldAbsolutePosition; UnityEngine.Vector3Int oldMapPosition; int stackPos = -1; Appearances.ObjectInstance @object; Creatures.Creature creature; if (x != 65535) { oldAbsolutePosition = message.ReadPosition(x); if (!WorldMapStorage.IsVisible(oldAbsolutePosition, true)) { throw new System.Exception("ProtocolGame.ParseCreatureMove: Start Co-ordinate " + oldAbsolutePosition + " is out of range."); } oldMapPosition = WorldMapStorage.ToMap(oldAbsolutePosition); stackPos = message.ReadUnsignedByte(); @object = WorldMapStorage.GetObject(oldMapPosition, stackPos); if (!@object || [email protected] || !(creature = CreatureStorage.GetCreature(@object.Data))) { throw new System.Exception("ProtocolGame.ParseCreatureMove: No creature at position " + oldAbsolutePosition); } } else { uint creatureId = message.ReadUnsignedInt(); @object = AppearanceStorage.CreateObjectInstance(Appearances.AppearanceInstance.Creature, creatureId); if (!(creature = CreatureStorage.GetCreature(creatureId))) { throw new System.Exception("ProtocolGame.ParseCreatureMove: Creature " + creatureId + " not found"); } oldAbsolutePosition = creature.Position; if (!WorldMapStorage.IsVisible(oldAbsolutePosition, true)) { throw new System.Exception("ProtocolGame.ParseCreatureMove: Start Co-ordinate " + oldAbsolutePosition + " is out of range."); } oldMapPosition = WorldMapStorage.ToMap(oldAbsolutePosition); } var newAbsolutePosition = message.ReadPosition(); if (!WorldMapStorage.IsVisible(newAbsolutePosition, true)) { throw new System.Exception("ProtocolGame.ParseCreatureMove: Target Co-ordinate " + oldAbsolutePosition + " is out of range."); } var newMapPosition = WorldMapStorage.ToMap(newAbsolutePosition); var delta = newMapPosition - oldMapPosition; // if the movement is not actually a move (usually he is teleported) bool pushMovement = delta.z != 0 || System.Math.Abs(delta.x) > 1 || System.Math.Abs(delta.y) > 1; Appearances.ObjectInstance otherObj = null; if (!pushMovement && (!(otherObj = WorldMapStorage.GetObject(newMapPosition, 0)) || !otherObj.Type || !otherObj.Type.IsGround)) { throw new System.Exception("ProtocolGame.ParseCreatureMove: Target field " + newAbsolutePosition + " has no BANK."); } if (x != 65535) { WorldMapStorage.DeleteObject(oldMapPosition, stackPos); } WorldMapStorage.PutObject(newMapPosition, @object); creature.Position = newAbsolutePosition; if (pushMovement) { if (creature.Id == Player.Id) { Player.StopAutowalk(true); } if (delta.x > 0) { creature.Direction = Direction.East; } else if (delta.x < 0) { creature.Direction = Direction.West; } else if (delta.y < 0) { creature.Direction = Direction.North; } else if (delta.y > 0) { creature.Direction = Direction.South; } if (creature.Id != Player.Id) { creature.StopMovementAnimation(); } } else { creature.StartMovementAnimation(delta.x, delta.y, (int)otherObj.Type.GroundSpeed); } CreatureStorage.MarkOpponentVisible(creature, true); CreatureStorage.InvalidateOpponents(); if (oldAbsolutePosition.z == MiniMapStorage.PositionZ) { WorldMapStorage.UpdateMiniMap(oldMapPosition); uint color = WorldMapStorage.GetMiniMapColour(oldMapPosition); int cost = WorldMapStorage.GetMiniMapCost(oldMapPosition); MiniMapStorage.UpdateField(oldAbsolutePosition, color, cost, false); } if (newAbsolutePosition.z == MiniMapStorage.PositionZ) { WorldMapStorage.UpdateMiniMap(newMapPosition); uint color = WorldMapStorage.GetMiniMapColour(newMapPosition); int cost = WorldMapStorage.GetMiniMapCost(newMapPosition); MiniMapStorage.UpdateField(newAbsolutePosition, color, cost, false); } }
private void ParseChangeOnMap(Internal.ByteArray message) { int x = message.ReadUnsignedShort(); Appearances.ObjectInstance objectInstance; Creatures.Creature creature = null; UnityEngine.Vector3Int absolutePosition; UnityEngine.Vector3Int mapPosition; if (x != 65535) { absolutePosition = message.ReadPosition(x); if (!WorldMapStorage.IsVisible(absolutePosition, true)) { throw new System.Exception("ProtocolGame.ParseChangeOnMap: Co-ordinate " + absolutePosition + " is out of range."); } mapPosition = WorldMapStorage.ToMap(absolutePosition); int stackPos = message.ReadUnsignedByte(); if (!(objectInstance = WorldMapStorage.GetObject(mapPosition, stackPos))) { throw new System.Exception("ProtocolGame.ParseChangeOnMap: Object not found."); } if (objectInstance.IsCreature && !(creature = CreatureStorage.GetCreature(objectInstance.Data))) { throw new System.Exception("ProtocolGame.ParseChangeOnMap: Creature not found: " + objectInstance.Data); } if (!!creature) { CreatureStorage.MarkOpponentVisible(creature, false); } int typeOrId = message.ReadUnsignedShort(); if (typeOrId == Appearances.AppearanceInstance.UnknownCreature || typeOrId == Appearances.AppearanceInstance.OutdatedCreature || typeOrId == Appearances.AppearanceInstance.Creature) { creature = ReadCreatureInstance(message, typeOrId, absolutePosition); objectInstance = AppearanceStorage.CreateObjectInstance(Appearances.AppearanceInstance.Creature, creature.Id); } else { objectInstance = ReadObjectInstance(message, typeOrId); } WorldMapStorage.ChangeObject(mapPosition, stackPos, objectInstance); } else { uint creatureId = message.ReadUnsignedInt(); if (!(creature = CreatureStorage.GetCreature(creatureId))) { throw new System.Exception("ProtocolGame.ParseChangeOnMap: Creature " + creatureId + " not found"); } absolutePosition = creature.Position; if (!WorldMapStorage.IsVisible(absolutePosition, true)) { throw new System.Exception("ProtocolGame.ParseChangeOnMap: Co-ordinate " + absolutePosition + " is out of range."); } mapPosition = WorldMapStorage.ToMap(absolutePosition); CreatureStorage.MarkOpponentVisible(creature, false); int otherType = message.ReadUnsignedShort(); if (otherType == Appearances.AppearanceInstance.Creature || otherType == Appearances.AppearanceInstance.OutdatedCreature || otherType == Appearances.AppearanceInstance.UnknownCreature) { creature = ReadCreatureInstance(message, otherType); } else { throw new System.Exception("ProtocolGame.ParseChangeOnMap: Received object of type " + otherType + " when a creature was expected."); } } if (absolutePosition.z == MiniMapStorage.PositionZ) { WorldMapStorage.UpdateMiniMap(mapPosition); uint color = WorldMapStorage.GetMiniMapColour(mapPosition); int cost = WorldMapStorage.GetMiniMapCost(mapPosition); MiniMapStorage.UpdateField(absolutePosition, color, cost, false); } }