public System.Collections.IEnumerator LoadSpriteAssets() { m_SpritesBundleLoadingRequest = AssetBundle.LoadFromFileAsync(Path.Combine(Application.streamingAssetsPath, "sprites")); yield return(m_SpritesBundleLoadingRequest); var assetBundle = m_SpritesBundleLoadingRequest.assetBundle; if (assetBundle == null) { Debug.LogWarning("Failed to load AssetBundle!"); yield break; } TextAsset catalogContent = Resources.Load("catalog-content") as TextAsset; if (!catalogContent) { Debug.LogWarning("Failed to load AssetBundle!"); assetBundle.Unload(true); yield break; } Appearances.SpritesProvider spriteProvider = new Appearances.SpritesProvider(assetBundle, catalogContent); AppearanceStorage.SetSpriteProvider(spriteProvider); BackgroundCenterPanel.gameObject.SetActive(true); LobbyPanel.gameObject.SetActive(true); LoadingAppearancesWindow.gameObject.SetActive(false); }
public void OnDestroy() { // since we are using threads to do our work (networking, ..) // away of unity's default classes, we need to shutdown things // to avoid errors in the console while debugging if (ProtocolGame != null && ProtocolGame.IsGameRunning) { ProtocolGame.Disconnect(); // force disconnection (by trying to logout) } AppearanceStorage.UnloadSpriteProvider(); OnSecondaryTimeCheck.RemoveAllListeners(); CancelInvoke("SecondaryTimerCheck"); CancelInvoke("SaveMiniMap"); OptionStorage = null; InputHandler = null; AppearanceStorage = null; CreatureStorage = null; MiniMapStorage = null; MiniMapRenderer = null; WorldMapStorage = null; WorldMapRenderer = null; ChatStorage = null; MessageStorage = null; WorldMapRenderingTexture.Release(); MiniMapRenderingTexture.Release(); }
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 void ParseGraphicalEffects(Internal.CommunicationStream message) { var initialPosition = message.ReadPosition(); int modifier = message.ReadUnsignedByte(); Appearances.AppearanceInstance effect = null; byte effectId = 0; var fromPosition = initialPosition; ushort unclampedOffset = 0; while (modifier != 0) { if (modifier == 1) { unclampedOffset = message.ReadUnsignedShort(); int offset = unclampedOffset % 256; fromPosition.x += offset % Constants.MapSizeX; fromPosition.y += offset / Constants.MapSizeX; } // the effect is far away from the initial position while (fromPosition.x - initialPosition.x >= Constants.MapSizeX) { fromPosition.x -= Constants.MapSizeX; fromPosition.y++; } if ((unclampedOffset >= 1024 && modifier == 1) || (modifier & 3) == 0) { effectId = message.ReadUnsignedByte(); int deltaX = message.ReadSignedByte(); int deltaY = message.ReadSignedByte(); var toPosition = new Vector3Int(fromPosition.x + deltaX, fromPosition.y + deltaY, fromPosition.z); effect = AppearanceStorage.CreateMissileInstance(effectId, fromPosition, toPosition); } else if (unclampedOffset >= 768 || modifier == 3) { effectId = message.ReadUnsignedByte(); effect = AppearanceStorage.CreateEffectInstance(effectId); } else { throw new System.NotImplementedException(); } if (!effect) { throw new System.Exception("ProtocolGame.ParseGraphicalEffects: Unknown effect: " + effectId); } WorldMapStorage.AppendEffect(fromPosition, effect); modifier = message.ReadUnsignedByte(); } }
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); }
public void LoadProtoAppearanaces() { TextAsset appearancesBinary = Resources.Load("appearances001") as TextAsset; if (!appearancesBinary) { throw new System.Exception("GameManager.LoadSpriteAssets: Unable to appearances asset."); } AppearanceStorage.SetProtoAppearances(Proto.Appearances001.Appearances.Parser.ParseFrom(appearancesBinary.bytes)); }
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 void ParseGraphicalEffect(Internal.CommunicationStream message) { var position = message.ReadPosition(); byte effectId = message.ReadUnsignedByte(); var effect = AppearanceStorage.CreateEffectInstance(effectId); if (!effect) { throw new System.Exception("ProtocolGame.ParseGraphicalEffect: Unknown effect id: " + effectId); } WorldMapStorage.AppendEffect(position, effect); }
private void ParseMissleEffect(Internal.CommunicationStream message) { var fromPosition = message.ReadPosition(); var toPosition = message.ReadPosition(); byte missleId = message.ReadUnsignedByte(); var missle = AppearanceStorage.CreateMissileInstance(missleId, fromPosition, toPosition); if (!missle) { throw new System.Exception("ProtocolGame.ParseMissleEffect: Unknown missle id: " + missleId); } WorldMapStorage.AppendEffect(fromPosition, missle); }
private AppearanceInstance ReadMountOutfit(Internal.ByteArray message, AppearanceInstance instance = null) { uint outfitID = message.ReadUnsignedShort(); OutfitInstance outfitInstance = instance as OutfitInstance; if (!!outfitInstance && outfitInstance.ID == outfitID) { return(outfitInstance); } if (outfitID != 0) { return(AppearanceStorage.CreateOutfitInstance(outfitID, 0, 0, 0, 0, 0)); } return(null); }
private AppearanceInstance ReadMountOutfit(Internal.CommunicationStream message, AppearanceInstance instance = null) { uint outfitId = message.ReadUnsignedShort(); OutfitInstance outfitInstance = instance as OutfitInstance; if (!!outfitInstance && outfitInstance.Id == outfitId) { return(outfitInstance); } if (outfitId != 0) { return(AppearanceStorage.CreateOutfitInstance(outfitId, 0, 0, 0, 0, 0)); } return(null); }
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); } }