private void UpdateDeformations(float deltaTime) { if (ActivePrefab.DeformableSprite == null) { return; } foreach (SpriteDeformation deformation in spriteDeformations) { if (deformation is PositionalDeformation positionalDeformation) { UpdatePositionalDeformation(positionalDeformation, deltaTime); } deformation.Update(deltaTime); } CurrentSpriteDeformation = SpriteDeformation.GetDeformation(spriteDeformations, ActivePrefab.DeformableSprite.Size); if (LightSources != null) { foreach (LightSource lightSource in LightSources) { if (lightSource?.DeformableLightSprite != null) { lightSource.DeformableLightSprite.Deform(CurrentSpriteDeformation); } } } }
public BackgroundCreature(BackgroundCreaturePrefab prefab, Vector2 position) { this.Prefab = prefab; this.position = position; drawPosition = position; steeringManager = new SteeringManager(this); velocity = new Vector3( Rand.Range(-prefab.Speed, prefab.Speed, Rand.RandSync.ClientOnly), Rand.Range(-prefab.Speed, prefab.Speed, Rand.RandSync.ClientOnly), Rand.Range(0.0f, prefab.WanderZAmount, Rand.RandSync.ClientOnly)); checkWallsTimer = Rand.Range(0.0f, CheckWallsInterval, Rand.RandSync.ClientOnly); foreach (XElement subElement in prefab.Config.Elements()) { List <SpriteDeformation> deformationList = null; switch (subElement.Name.ToString().ToLowerInvariant()) { case "deformablesprite": deformationList = spriteDeformations; break; case "deformablelightsprite": deformationList = lightSpriteDeformations; break; default: continue; } foreach (XElement animationElement in subElement.Elements()) { SpriteDeformation deformation = null; int sync = animationElement.GetAttributeInt("sync", -1); if (sync > -1) { string typeName = animationElement.GetAttributeString("type", "").ToLowerInvariant(); deformation = uniqueSpriteDeformations.Find(d => d.TypeName == typeName && d.Sync == sync); } if (deformation == null) { deformation = SpriteDeformation.Load(animationElement, prefab.Name); if (deformation != null) { uniqueSpriteDeformations.Add(deformation); } } if (deformation != null) { deformationList.Add(deformation); } } } }
private void UpdateDeformations(float deltaTime) { foreach (SpriteDeformation deformation in uniqueSpriteDeformations) { deformation.Update(deltaTime); } if (spriteDeformations.Count > 0) { CurrentSpriteDeformation = SpriteDeformation.GetDeformation(spriteDeformations, Prefab.DeformableSprite.Size); } if (lightSpriteDeformations.Count > 0) { CurrentLightSpriteDeformation = SpriteDeformation.GetDeformation(lightSpriteDeformations, Prefab.DeformableLightSprite.Size); } }
private void LoadElementsProjSpecific(XElement element, int parentTriggerIndex) { foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "leveltrigger": case "trigger": LoadElementsProjSpecific(subElement, LevelTriggerElements.IndexOf(subElement)); break; case "lightsource": LightSourceTriggerIndex.Add(parentTriggerIndex); LightSourceParams.Add(new LightSourceParams(subElement)); break; case "particleemitter": if (ParticleEmitterPrefabs == null) { ParticleEmitterPrefabs = new List <ParticleEmitterPrefab>(); EmitterPositions = new List <Vector2>(); ParticleEmitterTriggerIndex = new List <int>(); } ParticleEmitterPrefabs.Add(new ParticleEmitterPrefab(subElement)); ParticleEmitterTriggerIndex.Add(parentTriggerIndex); EmitterPositions.Add(subElement.GetAttributeVector2("position", Vector2.Zero)); break; case "sound": Sounds.Add(new SoundConfig(subElement, parentTriggerIndex)); break; case "deformablesprite": foreach (XElement deformElement in subElement.Elements()) { var deformation = SpriteDeformation.Load(deformElement, Name); if (deformation != null) { SpriteDeformations.Add(deformation); } } break; } } }
public GUIComponent CreateEditor(GUIComponent parent, List <SpriteDeformation> deformations, string parentDebugName) { var container = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.0f), parent.RectTransform)) { AbsoluteSpacing = 5, CanBeFocused = true }; new GUITextBlock(new RectTransform(new Point(container.Rect.Width, (int)(60 * GUI.Scale)), container.RectTransform) { IsFixedSize = true }, "Sprite Deformations", textAlignment: Alignment.BottomCenter, font: GUI.LargeFont); var resolutionField = GUI.CreatePointField(new Point(subDivX + 1, subDivY + 1), (int)(30 * GUI.Scale), "Resolution", container.RectTransform, "How many vertices the deformable sprite has on the x and y axes. Larger values make the deformations look smoother, but are more performance intensive."); resolutionField.RectTransform.IsFixedSize = true; GUINumberInput xField = null, yField = null; foreach (GUIComponent child in resolutionField.GetAllChildren()) { if (yField == null) { yField = child as GUINumberInput; } else { xField = child as GUINumberInput; if (xField != null) { break; } } } xField.MinValueInt = 2; xField.MaxValueInt = SpriteDeformationParams.ShaderMaxResolution.X - 1; xField.OnValueChanged = (numberInput) => { ChangeResolution(); }; yField.MinValueInt = 2; yField.MaxValueInt = SpriteDeformationParams.ShaderMaxResolution.Y - 1; yField.OnValueChanged = (numberInput) => { ChangeResolution(); }; void ChangeResolution() { subDivX = xField.IntValue - 1; subDivY = yField.IntValue - 1; foreach (SpriteDeformation deformation in deformations) { deformation.SetResolution(new Point(xField.IntValue, yField.IntValue)); } SetupVertexBuffers(); SetupIndexBuffer(); } foreach (SpriteDeformation deformation in deformations) { var deformEditor = new SerializableEntityEditor(container.RectTransform, deformation.Params, inGame: false, showName: true, titleFont: GUI.SubHeadingFont); deformEditor.RectTransform.MinSize = new Point(deformEditor.Rect.Width, deformEditor.Rect.Height); } var deformationDD = new GUIDropDown(new RectTransform(new Point(container.Rect.Width, 30), container.RectTransform), "Add new sprite deformation"); deformationDD.OnSelected = (selected, userdata) => { deformations.Add(SpriteDeformation.Load((string)userdata, parentDebugName)); deformationDD.Text = "Add new sprite deformation"; return(false); }; foreach (string deformationType in SpriteDeformation.DeformationTypes) { deformationDD.AddItem(deformationType, deformationType); } container.RectTransform.Resize(new Point( container.Rect.Width, container.Children.Sum(c => c.Rect.Height + container.AbsoluteSpacing)), false); container.RectTransform.MinSize = new Point(0, container.Rect.Height); container.RectTransform.MaxSize = new Point(int.MaxValue, container.Rect.Height); container.RectTransform.IsFixedSize = true; container.Recalculate(); return(container); }
partial void InitProjSpecific() { CurrentSwingAmount = Prefab.SwingAmountRad; CurrentScaleOscillation = Prefab.ScaleOscillation; SwingTimer = Rand.Range(0.0f, MathHelper.TwoPi); ScaleOscillateTimer = Rand.Range(0.0f, MathHelper.TwoPi); if (Prefab.ParticleEmitterPrefabs != null) { ParticleEmitters = new ParticleEmitter[Prefab.ParticleEmitterPrefabs.Count]; ParticleEmitterTriggers = new LevelTrigger[Prefab.ParticleEmitterPrefabs.Count]; for (int i = 0; i < Prefab.ParticleEmitterPrefabs.Count; i++) { ParticleEmitters[i] = new ParticleEmitter(Prefab.ParticleEmitterPrefabs[i]); ParticleEmitterTriggers[i] = Prefab.ParticleEmitterTriggerIndex[i] > -1 ? Triggers[Prefab.ParticleEmitterTriggerIndex[i]] : null; } } if (Prefab.LightSourceParams != null) { LightSources = new LightSource[Prefab.LightSourceParams.Count]; LightSourceTriggers = new LevelTrigger[Prefab.LightSourceParams.Count]; for (int i = 0; i < Prefab.LightSourceParams.Count; i++) { LightSources[i] = new LightSource(Prefab.LightSourceParams[i]) { Position = new Vector2(Position.X, Position.Y), IsBackground = true }; LightSourceTriggers[i] = Prefab.LightSourceTriggerIndex[i] > -1 ? Triggers[Prefab.LightSourceTriggerIndex[i]] : null; } } Sounds = new RoundSound[Prefab.Sounds.Count]; SoundChannels = new SoundChannel[Prefab.Sounds.Count]; SoundTriggers = new LevelTrigger[Prefab.Sounds.Count]; for (int i = 0; i < Prefab.Sounds.Count; i++) { Sounds[i] = Submarine.LoadRoundSound(Prefab.Sounds[i].SoundElement, false); SoundTriggers[i] = Prefab.Sounds[i].TriggerIndex > -1 ? Triggers[Prefab.Sounds[i].TriggerIndex] : null; } int j = 0; foreach (XElement subElement in Prefab.Config.Elements()) { if (subElement.Name.ToString().ToLowerInvariant() != "deformablesprite") { continue; } foreach (XElement animationElement in subElement.Elements()) { var newDeformation = SpriteDeformation.Load(animationElement, Prefab.Name); if (newDeformation != null) { newDeformation.DeformationParams = Prefab.SpriteDeformations[j].DeformationParams; spriteDeformations.Add(newDeformation); j++; } } } }
partial void InitProjSpecific() { Sprite?.EnsureLazyLoaded(); Prefab.DeformableSprite?.EnsureLazyLoaded(); CurrentSwingAmount = Prefab.SwingAmountRad; CurrentScaleOscillation = Prefab.ScaleOscillation; SwingTimer = Rand.Range(0.0f, MathHelper.TwoPi); ScaleOscillateTimer = Rand.Range(0.0f, MathHelper.TwoPi); if (Prefab.ParticleEmitterPrefabs != null) { ParticleEmitters = new ParticleEmitter[Prefab.ParticleEmitterPrefabs.Count]; ParticleEmitterTriggers = new LevelTrigger[Prefab.ParticleEmitterPrefabs.Count]; for (int i = 0; i < Prefab.ParticleEmitterPrefabs.Count; i++) { ParticleEmitters[i] = new ParticleEmitter(Prefab.ParticleEmitterPrefabs[i]); ParticleEmitterTriggers[i] = Prefab.ParticleEmitterTriggerIndex[i] > -1 ? Triggers[Prefab.ParticleEmitterTriggerIndex[i]] : null; } } if (Prefab.LightSourceParams != null && Prefab.LightSourceParams.Count > 0) { LightSources = new LightSource[Prefab.LightSourceParams.Count]; LightSourceTriggers = new LevelTrigger[Prefab.LightSourceParams.Count]; for (int i = 0; i < Prefab.LightSourceParams.Count; i++) { LightSources[i] = new LightSource(Prefab.LightSourceParams[i]) { Position = new Vector2(Position.X, Position.Y), IsBackground = true }; LightSourceTriggers[i] = Prefab.LightSourceTriggerIndex[i] > -1 ? Triggers[Prefab.LightSourceTriggerIndex[i]] : null; } } Sounds = new RoundSound[Prefab.Sounds.Count]; SoundChannels = new SoundChannel[Prefab.Sounds.Count]; SoundTriggers = new LevelTrigger[Prefab.Sounds.Count]; for (int i = 0; i < Prefab.Sounds.Count; i++) { Sounds[i] = Submarine.LoadRoundSound(Prefab.Sounds[i].SoundElement, false); SoundTriggers[i] = Prefab.Sounds[i].TriggerIndex > -1 ? Triggers[Prefab.Sounds[i].TriggerIndex] : null; } int j = 0; foreach (XElement subElement in Prefab.Config.Elements()) { if (!subElement.Name.ToString().Equals("deformablesprite", StringComparison.OrdinalIgnoreCase)) { continue; } foreach (XElement animationElement in subElement.Elements()) { var newDeformation = SpriteDeformation.Load(animationElement, Prefab.Name); if (newDeformation != null) { newDeformation.Params = Prefab.SpriteDeformations[j].Params; spriteDeformations.Add(newDeformation); j++; } } } VisibleOnSonar = Prefab.SonarDisruption > 0.0f || Prefab.OverrideProperties.Any(p => p != null && p.SonarDisruption > 0.0f) || (Triggers != null && Triggers.Any(t => !MathUtils.NearlyEqual(t.Force, Vector2.Zero) && t.ForceMode != LevelTrigger.TriggerForceMode.LimitVelocity || !string.IsNullOrWhiteSpace(t.InfectIdentifier))); if (VisibleOnSonar && Triggers.Any()) { SonarRadius = Triggers.Select(t => t.ColliderRadius * 1.5f).Max(); } }
public void Draw(SpriteBatch spriteBatch, Camera cam, Color?overrideColor = null) { float brightness = 1.0f - (burnOverLayStrength / 100.0f) * 0.5f; Color color = new Color(brightness, brightness, brightness); color = overrideColor ?? color; if (isSevered) { if (severedFadeOutTimer > SeveredFadeOutTime) { return; } else if (severedFadeOutTimer > SeveredFadeOutTime - 1.0f) { color *= SeveredFadeOutTime - severedFadeOutTimer; } } body.Dir = Dir; bool hideLimb = wearingItems.Any(w => w != null && w.HideLimb); body.UpdateDrawPosition(); if (!hideLimb) { var activeSprite = ActiveSprite; if (DeformSprite != null && activeSprite == DeformSprite.Sprite) { if (Deformations != null && Deformations.Any()) { var deformation = SpriteDeformation.GetDeformation(Deformations, DeformSprite.Size); DeformSprite.Deform(deformation); } else { DeformSprite.Reset(); } body.Draw(DeformSprite, cam, Vector2.One * Scale * TextureScale, color); } else { body.Draw(spriteBatch, activeSprite, color, null, Scale * TextureScale); } } if (LightSource != null) { LightSource.Position = body.DrawPosition; LightSource.LightSpriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipVertically; } float depthStep = 0.000001f; WearableSprite onlyDrawable = wearingItems.Find(w => w.HideOtherWearables); SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally; if (onlyDrawable == null) { if (HuskSprite != null && (character.SpeciesName == "Humanhusk" || (character.SpeciesName == "Human" && character.CharacterHealth.GetAffliction <AfflictionHusk>("huskinfection")?.State == AfflictionHusk.InfectionState.Active))) { DrawWearable(HuskSprite, depthStep, spriteBatch, color, spriteEffect); } foreach (WearableSprite wearable in OtherWearables) { DrawWearable(wearable, depthStep, spriteBatch, color, spriteEffect); //if there are multiple sprites on this limb, make the successive ones be drawn in front depthStep += 0.000001f; } } foreach (WearableSprite wearable in WearingItems) { if (onlyDrawable != null && onlyDrawable != wearable) { continue; } DrawWearable(wearable, depthStep, spriteBatch, color, spriteEffect); //if there are multiple sprites on this limb, make the successive ones be drawn in front depthStep += 0.000001f; } if (damageOverlayStrength > 0.0f && DamagedSprite != null && !hideLimb) { float depth = ActiveSprite.Depth - 0.0000015f; // TODO: enable when the damage overlay textures have been remade. //DamagedSprite.Draw(spriteBatch, // new Vector2(body.DrawPosition.X, -body.DrawPosition.Y), // color * Math.Min(damageOverlayStrength, 1.0f), ActiveSprite.Origin, // -body.DrawRotation, // 1.0f, spriteEffect, depth); } if (GameMain.DebugDraw) { if (pullJoint != null) { Vector2 pos = ConvertUnits.ToDisplayUnits(pullJoint.WorldAnchorB); GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), Color.Red, true); } var bodyDrawPos = body.DrawPosition; bodyDrawPos.Y = -bodyDrawPos.Y; if (IsStuck) { Vector2 from = ConvertUnits.ToDisplayUnits(attachJoint.WorldAnchorA); from.Y = -from.Y; Vector2 to = ConvertUnits.ToDisplayUnits(attachJoint.WorldAnchorB); to.Y = -to.Y; var localFront = body.GetLocalFront(MathHelper.ToRadians(limbParams.Ragdoll.SpritesheetOrientation)); var front = ConvertUnits.ToDisplayUnits(body.FarseerBody.GetWorldPoint(localFront)); front.Y = -front.Y; GUI.DrawLine(spriteBatch, bodyDrawPos, front, Color.Yellow, width: 2); GUI.DrawLine(spriteBatch, from, to, Color.Red, width: 1); GUI.DrawRectangle(spriteBatch, new Rectangle((int)from.X, (int)from.Y, 12, 12), Color.White, true); GUI.DrawRectangle(spriteBatch, new Rectangle((int)to.X, (int)to.Y, 12, 12), Color.White, true); GUI.DrawRectangle(spriteBatch, new Rectangle((int)from.X, (int)from.Y, 10, 10), Color.Blue, true); GUI.DrawRectangle(spriteBatch, new Rectangle((int)to.X, (int)to.Y, 10, 10), Color.Red, true); GUI.DrawRectangle(spriteBatch, new Rectangle((int)front.X, (int)front.Y, 10, 10), Color.Yellow, true); //Vector2 mainLimbFront = ConvertUnits.ToDisplayUnits(ragdoll.MainLimb.body.FarseerBody.GetWorldPoint(ragdoll.MainLimb.body.GetFrontLocal(MathHelper.ToRadians(ragdoll.RagdollParams.SpritesheetOrientation)))); //mainLimbFront.Y = -mainLimbFront.Y; //var mainLimbDrawPos = ragdoll.MainLimb.body.DrawPosition; //mainLimbDrawPos.Y = -mainLimbDrawPos.Y; //GUI.DrawLine(spriteBatch, mainLimbDrawPos, mainLimbFront, Color.White, width: 5); //GUI.DrawRectangle(spriteBatch, new Rectangle((int)mainLimbFront.X, (int)mainLimbFront.Y, 10, 10), Color.Yellow, true); } foreach (var modifier in damageModifiers) { float rotation = -body.TransformedRotation + GetArmorSectorRotationOffset(modifier.ArmorSector) * Dir; Vector2 forward = VectorExtensions.Forward(rotation); float size = ConvertUnits.ToDisplayUnits(body.GetSize().Length() / 2); color = modifier.DamageMultiplier > 1 ? Color.Red : Color.GreenYellow; GUI.DrawLine(spriteBatch, bodyDrawPos, bodyDrawPos + Vector2.Normalize(forward) * size, color, width: (int)Math.Round(4 / cam.Zoom)); ShapeExtensions.DrawSector(spriteBatch, bodyDrawPos, size, GetArmorSectorSize(modifier.ArmorSector) * Dir, 40, color, rotation + MathHelper.Pi, thickness: 2 / cam.Zoom); } } }
partial void InitProjSpecific(XElement element) { foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "sprite": Sprite = new Sprite(subElement, "", GetSpritePath(subElement)); break; case "damagedsprite": DamagedSprite = new Sprite(subElement, "", GetSpritePath(subElement)); break; case "conditionalsprite": ConditionalSprites.Add(new ConditionalSprite(subElement, character, file: GetSpritePath(subElement))); break; case "deformablesprite": DeformSprite = new DeformableSprite(subElement, filePath: GetSpritePath(subElement)); foreach (XElement animationElement in subElement.Elements()) { int sync = animationElement.GetAttributeInt("sync", -1); SpriteDeformation deformation = null; if (sync > -1) { // if the element is marked with the sync attribute, use a deformation of the same type with the same sync value, if there is one already. string typeName = animationElement.GetAttributeString("type", "").ToLowerInvariant(); deformation = ragdoll.Limbs .Where(l => l != null) .SelectMany(l => l.Deformations) .Where(d => d.TypeName == typeName && d.Sync == sync) .FirstOrDefault(); } if (deformation == null) { deformation = SpriteDeformation.Load(animationElement, character.SpeciesName); if (deformation != null) { ragdoll.SpriteDeformations.Add(deformation); } } if (deformation != null) { Deformations.Add(deformation); } } break; case "lightsource": LightSource = new LightSource(subElement); InitialLightSourceColor = LightSource.Color; break; case "sound": HitSoundTag = subElement.GetAttributeString("tag", ""); if (string.IsNullOrWhiteSpace(HitSoundTag)) { //legacy support HitSoundTag = subElement.GetAttributeString("file", ""); } break; } } }
public void Draw(SpriteBatch spriteBatch, Camera cam, Color?overrideColor = null) { float brightness = 1.0f - (burnOverLayStrength / 100.0f) * 0.5f; Color color = new Color(brightness, brightness, brightness); color = overrideColor ?? color; if (isSevered) { if (severedFadeOutTimer > SeveredFadeOutTime) { return; } else if (severedFadeOutTimer > SeveredFadeOutTime - 1.0f) { color *= SeveredFadeOutTime - severedFadeOutTimer; } } body.Dir = Dir; bool enableHuskSprite = character.IsHusk || character.CharacterHealth.GetAffliction <AfflictionHusk>("huskinfection")?.State == AfflictionHusk.InfectionState.Active; float herpesStrength = character.CharacterHealth.GetAfflictionStrength("spaceherpes"); bool hideLimb = Params.Hide || enableHuskSprite && HuskSprite != null && HuskSprite.HideLimb || OtherWearables.Any(w => w.HideLimb) || wearingItems.Any(w => w != null && w.HideLimb); var activeSprite = ActiveSprite; if (type == LimbType.Head) { CalculateHeadPosition(activeSprite); } // TODO: there's now two calls to this, because body.Draw() method calls this too -> is this an issue? body.UpdateDrawPosition(); if (!hideLimb) { var deformSprite = DeformSprite; if (deformSprite != null) { if (Deformations != null && Deformations.Any()) { var deformation = SpriteDeformation.GetDeformation(Deformations, deformSprite.Size); deformSprite.Deform(deformation); } else { deformSprite.Reset(); } body.Draw(deformSprite, cam, Vector2.One * Scale * TextureScale, color, Params.MirrorHorizontally); } else { body.Draw(spriteBatch, activeSprite, color, null, Scale * TextureScale, Params.MirrorHorizontally, Params.MirrorVertically); } } SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally; if (LightSource != null) { LightSource.Position = body.DrawPosition; if (LightSource.ParentSub != null) { LightSource.Position -= LightSource.ParentSub.DrawPosition; } LightSource.LightSpriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipVertically; } if (damageOverlayStrength > 0.0f && DamagedSprite != null && !hideLimb) { DamagedSprite.Draw(spriteBatch, new Vector2(body.DrawPosition.X, -body.DrawPosition.Y), color * Math.Min(damageOverlayStrength, 1.0f), activeSprite.Origin, -body.DrawRotation, Scale, spriteEffect, activeSprite.Depth - 0.0000015f); } foreach (var decorativeSprite in DecorativeSprites) { if (!spriteAnimState[decorativeSprite].IsActive) { continue; } float rotation = decorativeSprite.GetRotation(ref spriteAnimState[decorativeSprite].RotationState); Vector2 offset = decorativeSprite.GetOffset(ref spriteAnimState[decorativeSprite].OffsetState) * Scale; var ca = (float)Math.Cos(-body.Rotation); var sa = (float)Math.Sin(-body.Rotation); Vector2 transformedOffset = new Vector2(ca * offset.X + sa * offset.Y, -sa * offset.X + ca * offset.Y); decorativeSprite.Sprite.Draw(spriteBatch, new Vector2(body.DrawPosition.X + transformedOffset.X, -(body.DrawPosition.Y + transformedOffset.Y)), color, -body.Rotation + rotation, Scale, spriteEffect, depth: decorativeSprite.Sprite.Depth); } float depthStep = 0.000001f; float step = depthStep; WearableSprite onlyDrawable = wearingItems.Find(w => w.HideOtherWearables); if (Params.MirrorHorizontally) { spriteEffect = spriteEffect == SpriteEffects.None ? SpriteEffects.FlipHorizontally : SpriteEffects.None; } if (Params.MirrorVertically) { spriteEffect |= SpriteEffects.FlipVertically; } if (onlyDrawable == null) { if (HerpesSprite != null) { DrawWearable(HerpesSprite, depthStep, spriteBatch, color * Math.Min(herpesStrength / 10.0f, 1.0f), spriteEffect); depthStep += step; } if (HuskSprite != null && enableHuskSprite) { DrawWearable(HuskSprite, depthStep, spriteBatch, color, spriteEffect); depthStep += step; } foreach (WearableSprite wearable in OtherWearables) { if (wearable.Type == WearableType.Beard && enableHuskSprite && HuskSprite != null) { continue; } DrawWearable(wearable, depthStep, spriteBatch, color, spriteEffect); //if there are multiple sprites on this limb, make the successive ones be drawn in front depthStep += step; } } foreach (WearableSprite wearable in WearingItems) { if (onlyDrawable != null && onlyDrawable != wearable) { continue; } DrawWearable(wearable, depthStep, spriteBatch, color, spriteEffect); //if there are multiple sprites on this limb, make the successive ones be drawn in front depthStep += step; } if (GameMain.DebugDraw) { if (pullJoint != null) { Vector2 pos = ConvertUnits.ToDisplayUnits(pullJoint.WorldAnchorB); GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), Color.Red, true); } var bodyDrawPos = body.DrawPosition; bodyDrawPos.Y = -bodyDrawPos.Y; if (IsStuck) { Vector2 from = ConvertUnits.ToDisplayUnits(attachJoint.WorldAnchorA); from.Y = -from.Y; Vector2 to = ConvertUnits.ToDisplayUnits(attachJoint.WorldAnchorB); to.Y = -to.Y; var localFront = body.GetLocalFront(Params.GetSpriteOrientation()); var front = ConvertUnits.ToDisplayUnits(body.FarseerBody.GetWorldPoint(localFront)); front.Y = -front.Y; GUI.DrawLine(spriteBatch, bodyDrawPos, front, Color.Yellow, width: 2); GUI.DrawLine(spriteBatch, from, to, Color.Red, width: 1); GUI.DrawRectangle(spriteBatch, new Rectangle((int)from.X, (int)from.Y, 12, 12), Color.White, true); GUI.DrawRectangle(spriteBatch, new Rectangle((int)to.X, (int)to.Y, 12, 12), Color.White, true); GUI.DrawRectangle(spriteBatch, new Rectangle((int)from.X, (int)from.Y, 10, 10), Color.Blue, true); GUI.DrawRectangle(spriteBatch, new Rectangle((int)to.X, (int)to.Y, 10, 10), Color.Red, true); GUI.DrawRectangle(spriteBatch, new Rectangle((int)front.X, (int)front.Y, 10, 10), Color.Yellow, true); //Vector2 mainLimbFront = ConvertUnits.ToDisplayUnits(ragdoll.MainLimb.body.FarseerBody.GetWorldPoint(ragdoll.MainLimb.body.GetFrontLocal(MathHelper.ToRadians(limbParams.Orientation)))); //mainLimbFront.Y = -mainLimbFront.Y; //var mainLimbDrawPos = ragdoll.MainLimb.body.DrawPosition; //mainLimbDrawPos.Y = -mainLimbDrawPos.Y; //GUI.DrawLine(spriteBatch, mainLimbDrawPos, mainLimbFront, Color.White, width: 5); //GUI.DrawRectangle(spriteBatch, new Rectangle((int)mainLimbFront.X, (int)mainLimbFront.Y, 10, 10), Color.Yellow, true); } DrawDamageModifiers(spriteBatch, cam, bodyDrawPos, isScreenSpace: false); } }
partial void InitProjSpecific(XElement element) { for (int i = 0; i < Params.decorativeSpriteParams.Count; i++) { var param = Params.decorativeSpriteParams[i]; var decorativeSprite = new DecorativeSprite(param.Element, file: GetSpritePath(param.Element, param)); DecorativeSprites.Add(decorativeSprite); int groupID = decorativeSprite.RandomGroupID; if (!DecorativeSpriteGroups.ContainsKey(groupID)) { DecorativeSpriteGroups.Add(groupID, new List <DecorativeSprite>()); } DecorativeSpriteGroups[groupID].Add(decorativeSprite); spriteAnimState.Add(decorativeSprite, new SpriteState()); } foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) { case "sprite": Sprite = new Sprite(subElement, file: GetSpritePath(subElement, Params.normalSpriteParams)); break; case "damagedsprite": DamagedSprite = new Sprite(subElement, file: GetSpritePath(subElement, Params.damagedSpriteParams)); break; case "conditionalsprite": var conditionalSprite = new ConditionalSprite(subElement, character, file: GetSpritePath(subElement, null)); ConditionalSprites.Add(conditionalSprite); if (conditionalSprite.DeformableSprite != null) { CreateDeformations(subElement.GetChildElement("deformablesprite")); } break; case "deformablesprite": _deformSprite = new DeformableSprite(subElement, filePath: GetSpritePath(subElement, Params.deformSpriteParams)); CreateDeformations(subElement); break; case "lightsource": LightSource = new LightSource(subElement); InitialLightSourceColor = LightSource.Color; break; } void CreateDeformations(XElement e) { foreach (XElement animationElement in e.GetChildElements("spritedeformation")) { int sync = animationElement.GetAttributeInt("sync", -1); SpriteDeformation deformation = null; if (sync > -1) { // if the element is marked with the sync attribute, use a deformation of the same type with the same sync value, if there is one already. string typeName = animationElement.GetAttributeString("type", "").ToLowerInvariant(); deformation = ragdoll.Limbs .Where(l => l != null) .SelectMany(l => l.Deformations) .Where(d => d.TypeName == typeName && d.Sync == sync) .FirstOrDefault(); } if (deformation == null) { deformation = SpriteDeformation.Load(animationElement, character.SpeciesName); if (deformation != null) { ragdoll.SpriteDeformations.Add(deformation); } } if (deformation != null) { Deformations.Add(deformation); } } } } }
public void Draw(SpriteBatch spriteBatch, Camera cam, Color?overrideColor = null) { float brightness = 1.0f - (burnOverLayStrength / 100.0f) * 0.5f; Color color = new Color(brightness, brightness, brightness); color = overrideColor ?? color; if (isSevered) { if (severedFadeOutTimer > SeveredFadeOutTime) { return; } else if (severedFadeOutTimer > SeveredFadeOutTime - 1.0f) { color *= SeveredFadeOutTime - severedFadeOutTimer; } } body.Dir = Dir; bool hideLimb = wearingItems.Any(w => w != null && w.HideLimb); body.UpdateDrawPosition(); if (!hideLimb) { if (DeformSprite != null) { if (Deformations != null && Deformations.Any()) { var deformation = SpriteDeformation.GetDeformation(Deformations, DeformSprite.Size); DeformSprite.Deform(deformation); } else { DeformSprite.Reset(); } body.Draw(DeformSprite, cam, Vector2.One * Scale * TextureScale, color); } else { body.Draw(spriteBatch, Sprite, color, null, Scale * TextureScale); } } if (LightSource != null) { LightSource.Position = body.DrawPosition; LightSource.LightSpriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipVertically; } float depthStep = 0.000001f; WearableSprite onlyDrawable = wearingItems.Find(w => w.HideOtherWearables); SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally; if (onlyDrawable == null) { foreach (WearableSprite wearable in OtherWearables) { DrawWearable(wearable, depthStep, spriteBatch, color, spriteEffect); //if there are multiple sprites on this limb, make the successive ones be drawn in front depthStep += 0.000001f; } } foreach (WearableSprite wearable in WearingItems) { if (onlyDrawable != null && onlyDrawable != wearable) { continue; } DrawWearable(wearable, depthStep, spriteBatch, color, spriteEffect); //if there are multiple sprites on this limb, make the successive ones be drawn in front depthStep += 0.000001f; } if (damageOverlayStrength > 0.0f && DamagedSprite != null && !hideLimb) { float depth = ActiveSprite.Depth - 0.0000015f; DamagedSprite.Draw(spriteBatch, new Vector2(body.DrawPosition.X, -body.DrawPosition.Y), color * Math.Min(damageOverlayStrength / 50.0f, 1.0f), ActiveSprite.Origin, -body.DrawRotation, 1.0f, spriteEffect, depth); } if (GameMain.DebugDraw) { if (pullJoint != null) { Vector2 pos = ConvertUnits.ToDisplayUnits(pullJoint.WorldAnchorB); GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), Color.Red, true); } if (IsStuck) { Vector2 from = ConvertUnits.ToDisplayUnits(attachJoint.WorldAnchorA); from.Y = -from.Y; Vector2 to = ConvertUnits.ToDisplayUnits(attachJoint.WorldAnchorB); to.Y = -to.Y; var localFront = body.GetLocalFront(MathHelper.ToRadians(limbParams.Ragdoll.SpritesheetOrientation)); var front = ConvertUnits.ToDisplayUnits(body.FarseerBody.GetWorldPoint(localFront)); front.Y = -front.Y; var drawPos = body.DrawPosition; drawPos.Y = -drawPos.Y; GUI.DrawLine(spriteBatch, drawPos, front, Color.Yellow, width: 2); GUI.DrawLine(spriteBatch, from, to, Color.Red, width: 1); GUI.DrawRectangle(spriteBatch, new Rectangle((int)from.X, (int)from.Y, 12, 12), Color.White, true); GUI.DrawRectangle(spriteBatch, new Rectangle((int)to.X, (int)to.Y, 12, 12), Color.White, true); GUI.DrawRectangle(spriteBatch, new Rectangle((int)from.X, (int)from.Y, 10, 10), Color.Blue, true); GUI.DrawRectangle(spriteBatch, new Rectangle((int)to.X, (int)to.Y, 10, 10), Color.Red, true); GUI.DrawRectangle(spriteBatch, new Rectangle((int)front.X, (int)front.Y, 10, 10), Color.Yellow, true); //Vector2 mainLimbFront = ConvertUnits.ToDisplayUnits(ragdoll.MainLimb.body.FarseerBody.GetWorldPoint(ragdoll.MainLimb.body.GetFrontLocal(MathHelper.ToRadians(ragdoll.RagdollParams.SpritesheetOrientation)))); //mainLimbFront.Y = -mainLimbFront.Y; //var mainLimbDrawPos = ragdoll.MainLimb.body.DrawPosition; //mainLimbDrawPos.Y = -mainLimbDrawPos.Y; //GUI.DrawLine(spriteBatch, mainLimbDrawPos, mainLimbFront, Color.White, width: 5); //GUI.DrawRectangle(spriteBatch, new Rectangle((int)mainLimbFront.X, (int)mainLimbFront.Y, 10, 10), Color.Yellow, true); } } }
public void Draw(SpriteBatch spriteBatch, Camera cam, Color?overrideColor = null) { float brightness = 1.0f - (burnOverLayStrength / 100.0f) * 0.5f; Color color = new Color(brightness, brightness, brightness); color = overrideColor ?? color; if (isSevered) { if (severedFadeOutTimer > SeveredFadeOutTime) { return; } else if (severedFadeOutTimer > SeveredFadeOutTime - 1.0f) { color *= SeveredFadeOutTime - severedFadeOutTimer; } } body.Dir = Dir; bool hideLimb = wearingItems.Any(w => w != null && w.HideLimb); body.UpdateDrawPosition(); if (!hideLimb) { if (DeformSprite != null) { if (Deformations != null && Deformations.Any()) { var deformation = SpriteDeformation.GetDeformation(Deformations, DeformSprite.Size); DeformSprite.Deform(deformation); } else { DeformSprite.Reset(); } body.Draw(DeformSprite, cam, Vector2.One * Scale * TextureScale, color); } else { body.Draw(spriteBatch, Sprite, color, null, Scale * TextureScale); } } if (LightSource != null) { LightSource.Position = body.DrawPosition; LightSource.LightSpriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipVertically; } float depthStep = 0.000001f; WearableSprite onlyDrawable = wearingItems.Find(w => w.HideOtherWearables); foreach (WearableSprite wearable in WearingItems) { if (onlyDrawable != null && onlyDrawable != wearable) { continue; } SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally; Vector2 origin = wearable.InheritOrigin ? ActiveSprite.Origin : wearable.Sprite.Origin; // If the wearable inherits the origin, flipping is already handled. if (!wearable.InheritOrigin && body.Dir == -1.0f) { origin.X = wearable.Sprite.SourceRect.Width - origin.X; } if (wearable.InheritSourceRect) { wearable.Sprite.SourceRect = ActiveSprite.SourceRect; } float depth = wearable.Sprite.Depth; if (wearable.InheritLimbDepth) { depth = ActiveSprite.Depth - depthStep; if (wearable.DepthLimb != LimbType.None) { Limb depthLimb = character.AnimController.GetLimb(wearable.DepthLimb); if (depthLimb != null) { depth = depthLimb.ActiveSprite.Depth - depthStep; } } } // Draw outer cloths on top of inner cloths. if (wearable.WearableComponent.AllowedSlots.Contains(InvSlotType.OuterClothes)) { depth -= depthStep; } //if there are multiple sprites on this limb, make the successive ones be drawn in front depthStep += 0.000001f; float textureScale = wearable.InheritTextureScale ? TextureScale : 1; Color wearableColor = wearable.WearableComponent.Item.GetSpriteColor(); wearable.Sprite.Draw(spriteBatch, new Vector2(body.DrawPosition.X, -body.DrawPosition.Y), new Color((color.R * wearableColor.R) / (255.0f * 255.0f), (color.G * wearableColor.G) / (255.0f * 255.0f), (color.B * wearableColor.B) / (255.0f * 255.0f)) * ((color.A * wearableColor.A) / (255.0f * 255.0f)), origin, -body.DrawRotation, Scale * textureScale, spriteEffect, depth); } if (damageOverlayStrength > 0.0f && DamagedSprite != null && !hideLimb) { SpriteEffects spriteEffect = (dir == Direction.Right) ? SpriteEffects.None : SpriteEffects.FlipHorizontally; float depth = ActiveSprite.Depth - 0.0000015f; DamagedSprite.Draw(spriteBatch, new Vector2(body.DrawPosition.X, -body.DrawPosition.Y), color * Math.Min(damageOverlayStrength / 50.0f, 1.0f), ActiveSprite.Origin, -body.DrawRotation, 1.0f, spriteEffect, depth); } if (GameMain.DebugDraw) { if (pullJoint != null) { Vector2 pos = ConvertUnits.ToDisplayUnits(pullJoint.WorldAnchorB); GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), Color.Red, true); } } }