コード例 #1
0
        public void ResetAnimationData()
        {
            var lastMobMode = MobMode;

            switch (LocationDetails.MovementType)
            {
            case eMovementType.Stopped:
                MobMode = eMobMode.PlayerTownNeutral;
                break;

            case eMovementType.Walking:
                MobMode = eMobMode.PlayerTownWalk;
                break;

            case eMovementType.Running:
                MobMode = eMobMode.PlayerRun;
                break;

            default:
                MobMode = eMobMode.PlayerNeutral;
                break;
            }
            if (lastMobMode != MobMode)
            {
                renderFrameIndex = 0;
            }

            currentDirectionCache = directionCache.FirstOrDefault(x => x.MobMode == MobMode && x.Direction == directionConversion[LocationDetails.MovementDirection]);
            if (currentDirectionCache != null)
            {
                return;
            }

            animationData = resourceManager.GetPlayerAnimation(Hero, MobMode, Equipment);
            if (animationData == null)
            {
                throw new OpenDiablo2Exception("Could not locate animation for the character!");
            }

            var palette = paletteProvider.PaletteTable["Units"];

            CacheFrames(animationData.Layers.Select(layer => resourceManager.GetPlayerDCC(layer, Equipment, palette)).ToArray());
        }
コード例 #2
0
        private unsafe void CacheFrames(MPQDCC[] layerData)
        {
            var directionCache = new DirectionCacheItem
            {
                MobMode   = MobMode,
                Direction = directionConversion[LocationDetails.MovementDirection]
            };

            var palette = paletteProvider.PaletteTable[Palettes.Units];

            var dirAnimation = animationData.Animations[0];

            directionCache.FramesToAnimate = dirAnimation.FramesPerDirection;
            directionCache.AnimationSpeed  = dirAnimation.AnimationSpeed;

            var minX = Int32.MaxValue;
            var minY = Int32.MaxValue;
            var maxX = Int32.MinValue;
            var maxY = Int32.MinValue;

            var layersIgnored = 0;

            foreach (var layer in layerData)
            {
                if (layer == null)
                {
                    layersIgnored++;
                    continue;
                }

                minX = Math.Min(minX, layer.Directions[directionConversion[LocationDetails.MovementDirection]].Box.Left);
                minY = Math.Min(minY, layer.Directions[directionConversion[LocationDetails.MovementDirection]].Box.Top);
                maxX = Math.Max(maxX, layer.Directions[directionConversion[LocationDetails.MovementDirection]].Box.Right);
                maxY = Math.Max(maxY, layer.Directions[directionConversion[LocationDetails.MovementDirection]].Box.Bottom);
            }

            if (layersIgnored > 0)
            {
                log.Warn($"{layersIgnored} animation layer(s) were not found!");
            }

            var frameW = (maxX - minX);
            var frameH = (maxY - minY);

            directionCache.SpriteTexture = new IntPtr[directionCache.FramesToAnimate];
            directionCache.SpriteRect    = new SDL.SDL_Rect[directionCache.FramesToAnimate];

            for (var frameIndex = 0; frameIndex < directionCache.FramesToAnimate; frameIndex++)
            {
                var texture = SDL.SDL_CreateTexture(renderer, SDL.SDL_PIXELFORMAT_ARGB8888, (int)SDL.SDL_TextureAccess.SDL_TEXTUREACCESS_STREAMING, frameW, frameH);

                SDL.SDL_LockTexture(texture, IntPtr.Zero, out IntPtr pixels, out int pitch);
                UInt32 *data = (UInt32 *)pixels;

                var priorityBase = (directionConversion[LocationDetails.MovementDirection] * animationData.FramesPerDirection * animationData.NumberOfLayers)
                                   + (frameIndex * animationData.NumberOfLayers);
                for (var i = 0; i < animationData.NumberOfLayers; i++)
                {
                    var comp = animationData.Priority[priorityBase + i];
                    if (!animationData.CompositLayers.ContainsKey(comp))
                    {
                        continue;
                    }

                    var layer = layerData[animationData.CompositLayers[comp]];

                    if (layer == null)
                    {
                        continue; // TODO: This is most likely not ok
                    }
                    var direction = layer.Directions[directionConversion[LocationDetails.MovementDirection]];
                    var frame     = direction.Frames[frameIndex];


                    for (var y = 0; y < direction.Box.Height; y++)
                    {
                        for (var x = 0; x < direction.Box.Width; x++)
                        {
                            var paletteIndex = frame.PixelData[x + (y * direction.Box.Width)];

                            if (paletteIndex == 0)
                            {
                                continue;
                            }

                            var color   = palette.Colors[paletteIndex];
                            var actualX = x + direction.Box.X - minX;
                            var actualY = y + direction.Box.Y - minY;

                            data[actualX + (actualY * (pitch / 4))] = color;
                        }
                    }
                }

                SDL.SDL_UnlockTexture(texture);
                SDL.SDL_SetTextureBlendMode(texture, SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND);

                directionCache.SpriteTexture[frameIndex] = texture;
                directionCache.SpriteRect[frameIndex]    = new SDL.SDL_Rect {
                    x = minX, y = minY, w = frameW, h = frameH
                };

                this.directionCache.Add(directionCache);
            }

            currentDirectionCache = directionCache;
        }