Esempio n. 1
0
        // Get water state on map
        public ZLiquidStatus GetLiquidStatus(float x, float y, float z, uint ReqLiquidType, LiquidData data)
        {
            // Check water type (if no water return)
            if (_liquidGlobalFlags == 0 && _liquidFlags == null)
            {
                return(ZLiquidStatus.NoWater);
            }

            // Get cell
            float cx = MapConst.MapResolution * (32 - x / MapConst.SizeofGrids);
            float cy = MapConst.MapResolution * (32 - y / MapConst.SizeofGrids);

            int x_int = (int)cx & (MapConst.MapResolution - 1);
            int y_int = (int)cy & (MapConst.MapResolution - 1);

            // Check water type in cell
            int              idx         = (x_int >> 3) * 16 + (y_int >> 3);
            byte             type        = _liquidFlags != null ? _liquidFlags[idx] : _liquidGlobalFlags;
            uint             entry       = _liquidEntry != null ? _liquidEntry[idx] : _liquidGlobalEntry;
            LiquidTypeRecord liquidEntry = CliDB.LiquidTypeStorage.LookupByKey(entry);

            if (liquidEntry != null)
            {
                type &= (byte)MapConst.MapLiquidTypeDarkWater;
                uint liqTypeIdx = liquidEntry.SoundBank;
                if (entry < 21)
                {
                    var area = CliDB.AreaTableStorage.LookupByKey(GetArea(x, y));
                    if (area != null)
                    {
                        uint overrideLiquid = area.LiquidTypeID[liquidEntry.SoundBank];
                        if (overrideLiquid == 0 && area.ParentAreaID == 0)
                        {
                            area = CliDB.AreaTableStorage.LookupByKey(area.ParentAreaID);
                            if (area != null)
                            {
                                overrideLiquid = area.LiquidTypeID[liquidEntry.SoundBank];
                            }
                        }
                        var liq = CliDB.LiquidTypeStorage.LookupByKey(overrideLiquid);
                        if (liq != null)
                        {
                            entry      = overrideLiquid;
                            liqTypeIdx = liq.SoundBank;
                        }
                    }
                }
                type |= (byte)(1 << (int)liqTypeIdx);
            }

            if (type == 0)
            {
                return(ZLiquidStatus.NoWater);
            }

            // Check req liquid type mask
            if (ReqLiquidType != 0 && !Convert.ToBoolean(ReqLiquidType & type))
            {
                return(ZLiquidStatus.NoWater);
            }

            // Check water level:
            // Check water height map
            int lx_int = x_int - _liquidOffY;
            int ly_int = y_int - _liquidOffX;

            if (lx_int < 0 || lx_int >= _liquidHeight)
            {
                return(ZLiquidStatus.NoWater);
            }
            if (ly_int < 0 || ly_int >= _liquidWidth)
            {
                return(ZLiquidStatus.NoWater);
            }

            // Get water level
            float liquid_level = _liquidMap != null ? _liquidMap[lx_int * _liquidWidth + ly_int] : _liquidLevel;
            // Get ground level (sub 0.2 for fix some errors)
            float ground_level = GetHeight(x, y);

            // Check water level and ground level
            if (liquid_level < ground_level || z < ground_level - 2)
            {
                return(ZLiquidStatus.NoWater);
            }

            // All ok in water . store data
            if (data != null)
            {
                data.entry       = entry;
                data.type_flags  = type;
                data.level       = liquid_level;
                data.depth_level = ground_level;
            }

            // For speed check as int values
            float delta = liquid_level - z;

            if (delta > 2.0f)                   // Under water
            {
                return(ZLiquidStatus.UnderWater);
            }
            if (delta > 0.0f)                   // In water
            {
                return(ZLiquidStatus.InWater);
            }
            if (delta > -0.1f)                   // Walk on water
            {
                return(ZLiquidStatus.WaterWalk);
            }
            // Above water
            return(ZLiquidStatus.AboveWater);
        }
Esempio n. 2
0
        public override void UpdateUnderwaterState(Map m, float x, float y, float z)
        {
            LiquidData    liquid_status;
            ZLiquidStatus res = m.getLiquidStatus(GetPhaseShift(), x, y, z, MapConst.MapAllLiquidTypes, out liquid_status);

            if (res == 0)
            {
                m_MirrorTimerFlags &= ~(PlayerUnderwaterState.InWater | PlayerUnderwaterState.InLava | PlayerUnderwaterState.InSlime | PlayerUnderwaterState.InDarkWater);
                if (_lastLiquid != null && _lastLiquid.SpellID != 0)
                {
                    RemoveAurasDueToSpell(_lastLiquid.SpellID);
                }

                _lastLiquid = null;
                return;
            }
            uint liqEntry = liquid_status.entry;

            if (liqEntry != 0)
            {
                LiquidTypeRecord liquid = CliDB.LiquidTypeStorage.LookupByKey(liqEntry);
                if (_lastLiquid != null && _lastLiquid.SpellID != 0 && _lastLiquid != liquid)
                {
                    RemoveAurasDueToSpell(_lastLiquid.SpellID);
                }

                if (liquid != null && liquid.SpellID != 0)
                {
                    if (res.HasAnyFlag(ZLiquidStatus.UnderWater | ZLiquidStatus.InWater))
                    {
                        if (!HasAura(liquid.SpellID))
                        {
                            CastSpell(this, liquid.SpellID, true);
                        }
                    }
                    else
                    {
                        RemoveAurasDueToSpell(liquid.SpellID);
                    }
                }

                _lastLiquid = liquid;
            }
            else if (_lastLiquid != null && _lastLiquid.SpellID != 0)
            {
                RemoveAurasDueToSpell(_lastLiquid.SpellID);
                _lastLiquid = null;
            }


            // All liquids type - check under water position
            if (liquid_status.type_flags.HasAnyFlag <uint>(MapConst.MapLiquidTypeWater | MapConst.MapLiquidTypeOcean | MapConst.MapLiquidTypeMagma | MapConst.MapLiquidTypeSlime))
            {
                if (res.HasAnyFlag(ZLiquidStatus.UnderWater))
                {
                    m_MirrorTimerFlags |= PlayerUnderwaterState.InWater;
                }
                else
                {
                    m_MirrorTimerFlags &= ~PlayerUnderwaterState.InWater;
                }
            }

            // Allow travel in dark water on taxi or transport
            if (liquid_status.type_flags.HasAnyFlag <uint>(MapConst.MapLiquidTypeDarkWater) && !IsInFlight() && GetTransport() == null)
            {
                m_MirrorTimerFlags |= PlayerUnderwaterState.InDarkWater;
            }
            else
            {
                m_MirrorTimerFlags &= ~PlayerUnderwaterState.InDarkWater;
            }

            // in lava check, anywhere in lava level
            if (liquid_status.type_flags.HasAnyFlag <uint>(MapConst.MapLiquidTypeMagma))
            {
                if (res.HasAnyFlag(ZLiquidStatus.UnderWater | ZLiquidStatus.InWater | ZLiquidStatus.WaterWalk))
                {
                    m_MirrorTimerFlags |= PlayerUnderwaterState.InLava;
                }
                else
                {
                    m_MirrorTimerFlags &= ~PlayerUnderwaterState.InLava;
                }
            }
            // in slime check, anywhere in slime level
            if (liquid_status.type_flags.HasAnyFlag <uint>(MapConst.MapLiquidTypeSlime))
            {
                if (res.HasAnyFlag(ZLiquidStatus.UnderWater | ZLiquidStatus.InWater | ZLiquidStatus.WaterWalk))
                {
                    m_MirrorTimerFlags |= PlayerUnderwaterState.InSlime;
                }
                else
                {
                    m_MirrorTimerFlags &= ~PlayerUnderwaterState.InSlime;
                }
            }
        }