public WorldMapRenderer() { int mapCapacity = Constants.MapSizeX * Constants.MapSizeY; m_MinZPlane = new int[mapCapacity]; m_CreatureField = new RenderAtom[mapCapacity][]; m_CreatureCount = new int[mapCapacity]; m_DrawnCreatures = new RenderAtom[mapCapacity * Constants.MapSizeW]; m_CreatureStatus = new Dictionary <uint, Core.Components.CreatureStatusPanel>(); for (int i = 0; i < mapCapacity; i++) { m_CreatureField[i] = new RenderAtom[Constants.MapSizeW]; for (int j = 0; j < Constants.MapSizeW; j++) { m_CreatureField[i][j] = new RenderAtom(); } m_CreatureCount[i] = 0; } for (int i = 0; i < m_DrawnCreatures.Length; i++) { m_DrawnCreatures[i] = new RenderAtom(); } m_DrawnTextualEffects = new RenderAtom[Constants.NumEffects]; for (int i = 0; i < m_DrawnTextualEffects.Length; i++) { m_DrawnTextualEffects[i] = new RenderAtom(); } // enable this if you intend to change the name during the game.. // Creatures.Creature.onNameChange.AddListener(OnCreatureNameChange); Creatures.Creature.onSkillChange.AddListener(OnCreatureSkillChange); }
public virtual void Assign(RenderAtom other) { if (!other || other == this) { return; } x = other.x; y = other.y; z = other.z; fieldX = other.fieldX; fieldY = other.fieldY; Object = other.Object; }
private void InternalDrawCreatureStatusClassic(RenderAtom renderAtom, float rectX, float rectY, bool isVisible, bool drawNames, bool drawHealth, bool drawMana, bool drawFlags) { var creature = renderAtom.Object as Creatures.Creature; Components.CreatureStatusPanel statusPanel = null; m_CreatureStatus.TryGetValue(creature.ID, out statusPanel); if (creature.Position.z != m_Player.Position.z) { if (statusPanel != null) { m_CreatureStatus.Remove(creature.ID); UnityEngine.Object.Destroy(statusPanel.gameObject); } return; } bool mustInit = statusPanel == null; if (mustInit) { statusPanel = UnityEngine.Object.Instantiate(OpenTibiaUnity.GameManager.CreatureStatusPanelPrefab, OpenTibiaUnity.GameManager.CreatureStatusContainer); statusPanel.name = "CreatureStatus_" + creature.Name; statusPanel.UpdateProperties(creature.Name, creature.HealthPercent, creature.ManaPercent); m_CreatureStatus.Add(creature.ID, statusPanel); } statusPanel.CachedRenderCount = m_RenderCounter; statusPanel.UpdateCreatureMisc(isVisible, m_LightmapRenderer.CalculateCreatureBrightnessFactor(creature, creature.ID == m_Player.ID)); statusPanel.SetDrawingProperties(drawNames, drawHealth, drawMana); statusPanel.SetFlags(drawFlags, creature.PartyFlag, creature.PKFlag, creature.SummonTypeFlag, creature.SpeechCategory, creature.GuildFlag); // the animation delta is already applied earlier on creatures check // but we need to add the animation delta of the screen float x = renderAtom.x - 2 * Constants.FieldSize - m_Player.AnimationDelta.x + 27 / 2f; float y = renderAtom.y - 2 * Constants.FieldSize - m_Player.AnimationDelta.y - 8; var rectTransform = statusPanel.transform as RectTransform; rectTransform.anchoredPosition = new Vector2(x * m_LayerZoom.x, -y * m_LayerZoom.y); }
private void InternalDrawCreatureStatusHUD(RenderAtom renderAtom, int rectX, int rectY, bool isVisible, bool drawNames, bool drawHealth, bool drawMana, bool drawFlags) { // TODO }
private void InternalDrawField(float rectX, float rectY, int absoluteX, int absoluteY, int absoluteZ, int positionX, int positionY, int positionZ, bool drawLyingObjects) { Field field = m_WorldMapStorage.GetField(positionX, positionY, positionZ); int objCount = field.ObjectsCount; int mz = positionY * Constants.MapSizeX + positionX; bool isExplicitlyVisible = positionZ > m_MinZPlane[mz] || (positionX == 0 || positionZ >= m_MinZPlane[mz - 1]) || (positionY == 0 || positionZ >= m_MinZPlane[mz - Constants.MapSizeX]) || (positionX == 0 && positionY == 0 || positionZ >= m_MinZPlane[mz - Constants.MapSizeX - 1]); int objectsHeight = 0; Appearances.ObjectInstance previousHang = null; if (drawLyingObjects && objCount > 0 && isExplicitlyVisible) { Appearances.ObjectInstance obj; bool isLying = false; // cached objects don't have lights, animations or anything! for (int i = 0; i < field.CacheObjectsCount; i++) { if (!(obj = field.ObjectsRenderer[i])) { break; } var screenPosition = new Vector2(rectX - objectsHeight, rectY - objectsHeight); obj.DrawTo(screenPosition, m_ScreenZoom, absoluteX, absoluteY, absoluteZ); objectsHeight += (int)obj.Type.Elevation; if (objectsHeight > Constants.FieldHeight) { objectsHeight = Constants.FieldHeight; } } for (int i = field.CacheObjectsCount; i < objCount; i++) { if (!(obj = field.ObjectsRenderer[i]) || obj.ID == Appearances.AppearanceInstance.Creature || obj.Type.IsTop) { break; } if (m_OptionStorage.ShowLightEffects && obj.Type.IsLight) { // check how correct those are int lightX = ((int)rectX - objectsHeight - obj.Type.DisplacementX) / Constants.FieldSize; int lightY = ((int)rectY - objectsHeight - obj.Type.DisplacementY) / Constants.FieldSize; Color32 color32 = Colors.ColorFrom8Bit((byte)obj.Type.LightColor); m_LightmapRenderer.SetLightSource(lightX, lightY, positionZ, obj.Type.Brightness, color32); } var screenPosition = new Vector2(rectX - objectsHeight, rectY - objectsHeight); obj.DrawTo(screenPosition, m_ScreenZoom, absoluteX, absoluteY, absoluteZ); if (obj == m_HighlightObject) { m_ObjectCursor.DrawTo(rectX - objectsHeight, rectY - objectsHeight); } isLying = isLying || obj.Type.IsLyingObject; if (obj.Type.IsHangable && obj.Hang == Appearances.AppearanceInstance.HookSouth) { previousHang = obj; } objectsHeight += (int)obj.Type.Elevation; if (objectsHeight > Constants.FieldHeight) { objectsHeight = Constants.FieldHeight; } } // isLying corpse? draw cached lying objects if (isLying || field.CacheLyingObject) { int fieldSize = Constants.FieldSize; if (positionX > 0 && positionY > 0) { InternalDrawField(rectX - fieldSize, rectY - fieldSize, absoluteX - 1, absoluteY - 1, absoluteZ, positionX - 1, positionY - 1, positionZ, false); } else if (positionX > 0) { InternalDrawField(rectX - fieldSize, rectY, absoluteX - 1, absoluteY, absoluteZ, positionX - 1, positionY, positionZ, false); } else if (positionY > 0) { InternalDrawField(rectX, rectY - fieldSize, absoluteX, absoluteY - 1, absoluteZ, positionX, positionY - 1, positionZ, false); } } // draw hang object if (!!m_PreviousHang) { var screenPosition = new Vector2(m_HangPixelX, m_HangPixelY); m_PreviousHang.DrawTo(screenPosition, m_ScreenZoom, m_HangPatternX, m_HangPatternY, m_HangPatternZ); if (m_PreviousHang == m_HighlightObject) { m_ObjectCursor.DrawTo(m_HangPixelX, m_HangPixelY); } } if (!!previousHang) { m_PreviousHang = previousHang; m_HangPixelX = rectX; m_HangPixelY = rectY; m_HangPatternX = absoluteX; m_HangPatternY = absoluteY; m_HangPatternZ = absoluteZ; } else { m_PreviousHang = null; } } RenderAtom[] renderAtomArray = m_CreatureField[positionY * Constants.MapSizeX + positionX]; int creatureCount = m_CreatureCount[positionY * Constants.MapSizeX + positionX]; for (int i = 0; i < creatureCount; i++) { RenderAtom renderAtom = null; Creatures.Creature creature = null; if (!(renderAtom = renderAtomArray[i]) || !(creature = renderAtom.Object as Creatures.Creature) || !creature.Outfit) { continue; } if (drawLyingObjects) { renderAtom.x -= objectsHeight; renderAtom.y -= objectsHeight; } // Draw Marks m_HelperPoint.Set(renderAtom.x - Constants.FieldSize, renderAtom.y - Constants.FieldSize); creature.Marks.Draw(OpenTibiaUnity.GameManager.MarksViewTexture, m_HelperPoint.x, m_HelperPoint.y, m_ScreenZoom, Appearances.Marks.MarkType_ClientMapWindow); Vector2Int displacement = new Vector2Int(0, 0); if (isExplicitlyVisible && !!creature.MountOutfit) { displacement += creature.MountOutfit.Type.Displacement; var screenPosition = new Vector2(renderAtom.x + displacement.x, renderAtom.y + displacement.y); creature.MountOutfit.DrawTo(screenPosition, m_ScreenZoom, (int)creature.Direction, 0, 0); } if (isExplicitlyVisible) { displacement += creature.Outfit.Type.Displacement; var screenPosition = new Vector2(renderAtom.x + displacement.x, renderAtom.y + displacement.y); creature.Outfit.DrawTo(screenPosition, m_ScreenZoom, (int)creature.Direction, 0, !!creature.MountOutfit ? 1 : 0); } Appearances.ObjectInstance obj; if (isExplicitlyVisible && m_HighlightObject != null && (!!(obj = m_HighlightObject as Appearances.ObjectInstance) && creature.ID == obj.Data) || (m_HighlightObject is Creatures.Creature && m_HighlightObject == creature)) { m_ObjectCursor.DrawTo(renderAtom.x + displacement.x, renderAtom.y + displacement.y); } if (positionZ == m_PlayerZPlane && (m_CreatureStorage.IsOpponent(creature) || creature.ID == m_Player.ID)) { m_DrawnCreatures[m_DrawnCreaturesCount].Assign(renderAtom); m_DrawnCreaturesCount++; } if (isExplicitlyVisible && drawLyingObjects && m_OptionStorage.ShowLightEffects) { int lightX = renderAtom.x / Constants.FieldSize; int lightY = renderAtom.y / Constants.FieldSize; m_LightmapRenderer.SetLightSource(lightX, lightY, positionZ, (uint)creature.Brightness, creature.LightColor); if (!!creature.MountOutfit && creature.MountOutfit.Type.IsLight) { var color = Colors.ColorFrom8Bit((byte)creature.MountOutfit.Type.LightColor); m_LightmapRenderer.SetLightSource(lightX, lightY, positionZ, creature.MountOutfit.Type.Brightness, color); } if (!!creature.Outfit && creature.Outfit.Type.IsLight) { var color = Colors.ColorFrom8Bit((byte)creature.Outfit.Type.LightColor); m_LightmapRenderer.SetLightSource(lightX, lightY, positionZ, creature.Outfit.Type.Brightness, color); } if (creature.ID == m_Player.ID && creature.Brightness < 2) { var color = new Color32(255, 255, 255, 255); m_LightmapRenderer.SetLightSource(lightX, lightY, positionZ, 2, color); } } } int effectRectX = (int)rectX - objectsHeight; int effectRectY = (int)rectY - objectsHeight; int effectLightX = effectRectX / Constants.FieldSize; int effectLightY = effectRectY / Constants.FieldSize; int loc29 = 0; int loc30 = 0; for (int i = field.EffectsCount - 1; i >= 0; i--) { var effect = field.Effects[i]; if (!effect) { continue; } if (effect is Appearances.TextualEffectInstance) { if (drawLyingObjects) { var renderAtom = m_DrawnTextualEffects[m_DrawnTextualEffectsCount]; renderAtom.Update(effect, effectRectX - Constants.FieldSize / 2 + loc29, effectRectY - Constants.FieldSize - 2 * effect.Phase, 0); if (renderAtom.y + (effect as Appearances.TextualEffectInstance).Height > loc30) { loc29 += (effect as Appearances.TextualEffectInstance).Width; } if (loc29 < 2 * Constants.FieldSize) { m_DrawnTextualEffectsCount++; loc30 = renderAtom.x; } } } else if (effect is Appearances.MissileInstance) { var missile = effect as Appearances.MissileInstance; var screenPosition = new Vector2(effectRectX + missile.AnimationDelta.x, effectRectY + missile.AnimationDelta.y); effect.DrawTo(screenPosition, m_ScreenZoom, absoluteX, absoluteY, absoluteZ); if (drawLyingObjects && m_OptionStorage.ShowLightEffects && effect.Type.IsLight) { var color = Colors.ColorFrom8Bit((byte)effect.Type.LightColor); m_LightmapRenderer.SetLightSource(effectLightX, effectLightY, positionZ, effect.Type.Brightness, color); } } else // EffectInstance { var screenPosition = new Vector2(effectRectX, effectRectY); effect.DrawTo(screenPosition, m_ScreenZoom, absoluteX, absoluteY, absoluteZ); if (drawLyingObjects && m_OptionStorage.ShowLightEffects && effect.Type.IsLight) { uint activeBrightness = (uint)((Math.Min(effect.Phase, effect.Type.FrameGroups[0].Phases + 1 - effect.Phase) * effect.Type.Brightness + 2) / 3); var color = Colors.ColorFrom8Bit((byte)effect.Type.LightColor); m_LightmapRenderer.SetLightSource(effectLightX, effectLightY, positionZ, Math.Min(activeBrightness, effect.Type.Brightness), color); } } } // TODO: this should be drawn on a separate render texture // (atmosphoric) if (!!field.EnvironmentalEffect) { var screenPosition = new Vector2(rectX, rectY); field.EnvironmentalEffect.DrawTo(screenPosition, m_ScreenZoom, absoluteX, absoluteY, absoluteZ); } if (drawLyingObjects && objCount > 0) { var obj = field.ObjectsRenderer[objCount - 1]; if (!!obj && !!obj.Type && obj.Type.IsTop) { var screenPosition = new Vector2(rectX, rectY); obj.DrawTo(screenPosition, m_ScreenZoom, absoluteX, absoluteY, absoluteZ); } } }
private void UpdateFloorCreatures(int z) { RenderAtom renderAtom = null; bool aboveGround = m_Player.Position.z <= 7; float optionsLevelSeparator = m_OptionStorage.LevelSeparator / 100f; int defaultBrightness = m_WorldMapStorage.AmbientCurrentBrightness; int brightness = aboveGround ? m_WorldMapStorage.AmbientCurrentBrightness : 0; for (int i = 0; i < m_CreatureCount.Length; i++) { m_CreatureCount[i] = 0; } for (int x = 0; x < Constants.MapSizeX; x++) { for (int y = 0; y < Constants.MapSizeY; y++) { Field field = m_WorldMapStorage.GetField(x, y, z); if (m_OptionStorage.ShowLightEffects) { var colorIndex = m_LightmapRenderer.ToColorIndex(x, y); if (z == m_PlayerZPlane && z > 0) { m_LightmapRenderer[colorIndex] = ILightmapRenderer.MulColor32(m_LightmapRenderer[colorIndex], optionsLevelSeparator); } Appearances.ObjectInstance obj; if (z == 0 || (obj = field.ObjectsRenderer[0]) != null && obj.Type.IsBank) { var color = m_LightmapRenderer[colorIndex]; m_LightmapRenderer.SetFieldBrightness(x, y, brightness, aboveGround); if (z > 0 && field.CacheTranslucent) { color = ILightmapRenderer.MulColor32(color, optionsLevelSeparator); var alterColor = m_LightmapRenderer[colorIndex]; color.r = Math.Max(color.r, alterColor.r); color.g = Math.Max(color.g, alterColor.g); color.b = Math.Max(color.b, alterColor.b); m_LightmapRenderer[colorIndex] = color; } } if (x > 0 && y > 0 && z < 7 && z == m_PlayerZPlane + m_WorldMapStorage.Position.z - 8 && m_WorldMapStorage.IsTranslucent(x - 1, y - 1, z + 1)) { m_LightmapRenderer.SetFieldBrightness(x, y, defaultBrightness, aboveGround); } } for (int i = field.ObjectsCount - 1; i >= field.CacheObjectsCount; i--) { var obj = field.ObjectsRenderer[i]; if (!obj || !obj.IsCreature) { continue; } var creature = m_CreatureStorage.GetCreature(obj.Data); if (!creature) { continue; } Vector2Int displacement = new Vector2Int();; if (!!creature.MountOutfit && !!creature.MountOutfit.Type) { displacement = creature.MountOutfit.Type.Displacement; } else if (!!creature.Outfit && !!creature.Outfit.Type) { displacement = creature.Outfit.Type.Displacement; } int positionX = (x + 1) * Constants.FieldSize + creature.AnimationDelta.x - displacement.x; int positionY = (y + 1) * Constants.FieldSize + creature.AnimationDelta.y - displacement.y; int fieldX = (positionX - 1) / Constants.FieldSize; int fieldY = (positionY - 1) / Constants.FieldSize; int fieldIndex = fieldY * Constants.MapSizeX + fieldX; if (!(fieldIndex < 0 || fieldIndex >= Constants.MapSizeX * Constants.MapSizeY)) { RenderAtom[] fieldAtoms = m_CreatureField[fieldIndex]; int j = 0; while (j < m_CreatureCount[fieldIndex] && !!(renderAtom = fieldAtoms[j]) && (renderAtom.y < positionY || renderAtom.y == positionY && renderAtom.x <= positionX)) { j++; } if (j < Constants.MapSizeZ) { if (m_CreatureCount[fieldIndex] < Constants.MapSizeW) { m_CreatureCount[fieldIndex]++; } renderAtom = fieldAtoms[m_CreatureCount[fieldIndex] - 1]; for (int k = m_CreatureCount[fieldIndex] - 1; k > j; k--) { fieldAtoms[k] = fieldAtoms[k - 1]; } fieldAtoms[j] = renderAtom; renderAtom.Update(creature, positionX, positionY, z, fieldX, fieldY); } } } } } }