public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1) { if (!MathUtils.NearlyEqual(item.Rotation, prevBaseRotation) || !MathUtils.NearlyEqual(item.Scale, prevScale)) { UpdateTransformedBarrelPos(); } Vector2 drawPos = GetDrawPos(); float recoilOffset = 0.0f; if (Math.Abs(RecoilDistance) > 0.0f && recoilTimer > 0.0f) { float diff = RetractionTime - RecoilTime; if (recoilTimer >= diff) { //move the barrel backwards 0.1 seconds (defined by RecoilTime) after launching recoilOffset = RecoilDistance * (1.0f - (recoilTimer - diff) / RecoilTime); } else if (recoilTimer <= diff - RetractionDelay) { //move back to normal position while reloading float t = diff - RetractionDelay; recoilOffset = RecoilDistance * recoilTimer / t; } else { recoilOffset = RecoilDistance; } } railSprite?.Draw(spriteBatch, drawPos, item.SpriteColor, rotation + MathHelper.PiOver2, item.Scale, SpriteEffects.None, item.SpriteDepth + (railSprite.Depth - item.Sprite.Depth)); barrelSprite?.Draw(spriteBatch, drawPos - new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * recoilOffset * item.Scale, item.SpriteColor, rotation + MathHelper.PiOver2, item.Scale, SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth)); if (!editing || GUI.DisableHUD || !item.IsSelected) { return; } const float widgetRadius = 60.0f; Vector2 center = new Vector2((float)Math.Cos((maxRotation + minRotation) / 2), (float)Math.Sin((maxRotation + minRotation) / 2)); GUI.DrawLine(spriteBatch, drawPos, drawPos + center * widgetRadius, Color.LightGreen); const float coneRadius = 300.0f; float radians = maxRotation - minRotation; float circleRadius = coneRadius / Screen.Selected.Cam.Zoom * GUI.Scale; float lineThickness = 1f / Screen.Selected.Cam.Zoom; if (Math.Abs(minRotation - maxRotation) < 0.02f) { spriteBatch.DrawLine(drawPos, drawPos + center * circleRadius, GUI.Style.Green, thickness: lineThickness); } else if (radians > Math.PI * 2) { spriteBatch.DrawCircle(drawPos, circleRadius, 180, GUI.Style.Red, thickness: lineThickness); } else { spriteBatch.DrawSector(drawPos, circleRadius, radians, (int)Math.Abs(90 * radians), GUI.Style.Green, offset: minRotation, thickness: lineThickness); } int baseWidgetScale = GUI.IntScale(16); int widgetSize = (int)(Math.Max(baseWidgetScale, baseWidgetScale / Screen.Selected.Cam.Zoom)); float widgetThickness = Math.Max(1f, lineThickness); Widget minRotationWidget = GetWidget("minrotation", spriteBatch, size: widgetSize, thickness: widgetThickness, initMethod: (widget) => { widget.Selected += () => { oldRotation = RotationLimits; }; widget.MouseDown += () => { widget.color = GUI.Style.Green; prevAngle = minRotation; }; widget.Deselected += () => { widget.color = Color.Yellow; item.CreateEditingHUD(); RotationLimits = RotationLimits; if (SubEditorScreen.IsSubEditor()) { SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation)); } }; widget.MouseHeld += (deltaTime) => { minRotation = GetRotationAngle(GetDrawPos()); UpdateBarrel(); MapEntity.DisableSelect = true; }; widget.PreUpdate += (deltaTime) => { widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y); widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos); }; widget.PostUpdate += (deltaTime) => { widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos); widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y); }; widget.PreDraw += (sprtBtch, deltaTime) => { widget.tooltip = "Min: " + (int)MathHelper.ToDegrees(minRotation); widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(minRotation), (float)Math.Sin(minRotation)) * coneRadius / Screen.Selected.Cam.Zoom * GUI.Scale; widget.Update(deltaTime); }; }); Widget maxRotationWidget = GetWidget("maxrotation", spriteBatch, size: widgetSize, thickness: widgetThickness, initMethod: (widget) => { widget.Selected += () => { oldRotation = RotationLimits; }; widget.MouseDown += () => { widget.color = GUI.Style.Green; prevAngle = maxRotation; }; widget.Deselected += () => { widget.color = Color.Yellow; item.CreateEditingHUD(); RotationLimits = RotationLimits; if (SubEditorScreen.IsSubEditor()) { SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation)); } }; widget.MouseHeld += (deltaTime) => { maxRotation = GetRotationAngle(GetDrawPos()); UpdateBarrel(); MapEntity.DisableSelect = true; }; widget.PreUpdate += (deltaTime) => { widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y); widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos); }; widget.PostUpdate += (deltaTime) => { widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos); widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y); }; widget.PreDraw += (sprtBtch, deltaTime) => { widget.tooltip = "Max: " + (int)MathHelper.ToDegrees(maxRotation); widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(maxRotation), (float)Math.Sin(maxRotation)) * coneRadius / Screen.Selected.Cam.Zoom * GUI.Scale; widget.Update(deltaTime); }; }); minRotationWidget.Draw(spriteBatch, (float)Timing.Step); maxRotationWidget.Draw(spriteBatch, (float)Timing.Step); Vector2 GetDrawPos() { Vector2 drawPos = new Vector2(item.Rect.X + transformedBarrelPos.X, item.Rect.Y - transformedBarrelPos.Y); if (item.Submarine != null) { drawPos += item.Submarine.DrawPosition; } drawPos.Y = -drawPos.Y; return(drawPos); } void UpdateBarrel() { rotation = (minRotation + maxRotation) / 2; } }
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1) { if (!MathUtils.NearlyEqual(item.Rotation, prevBaseRotation) || !MathUtils.NearlyEqual(item.Scale, prevScale)) { UpdateTransformedBarrelPos(); } Vector2 drawPos = GetDrawPos(); float recoilOffset = 0.0f; if (Math.Abs(RecoilDistance) > 0.0f && recoilTimer > 0.0f) { float diff = RetractionTime - RecoilTime; if (recoilTimer >= diff) { //move the barrel backwards 0.1 seconds (defined by RecoilTime) after launching recoilOffset = RecoilDistance * (1.0f - (recoilTimer - diff) / RecoilTime); } else if (recoilTimer <= diff - RetractionDelay) { //move back to normal position while reloading float t = diff - RetractionDelay; recoilOffset = RecoilDistance * recoilTimer / t; } else { recoilOffset = RecoilDistance; } } railSprite?.Draw(spriteBatch, drawPos, item.SpriteColor, rotation + MathHelper.PiOver2, item.Scale, SpriteEffects.None, item.SpriteDepth + (railSprite.Depth - item.Sprite.Depth)); barrelSprite?.Draw(spriteBatch, drawPos - new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * recoilOffset * item.Scale, item.SpriteColor, rotation + MathHelper.PiOver2, item.Scale, SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth)); float chargeRatio = currentChargeTime / MaxChargeTime; foreach ((Sprite chargeSprite, Vector2 position) in chargeSprites) { chargeSprite?.Draw(spriteBatch, drawPos - MathUtils.RotatePoint(new Vector2(position.X * chargeRatio, position.Y * chargeRatio) * item.Scale, rotation + MathHelper.PiOver2), item.SpriteColor, rotation + MathHelper.PiOver2, item.Scale, SpriteEffects.None, item.SpriteDepth + (chargeSprite.Depth - item.Sprite.Depth)); } int spinningBarrelCount = spinningBarrelSprites.Count; for (int i = 0; i < spinningBarrelCount; i++) { // this block is messy since I was debugging it with a bunch of values, should be cleaned up / optimized if prototype is accepted Sprite spinningBarrel = spinningBarrelSprites[i]; float barrelCirclePosition = (MaxCircle * i / spinningBarrelCount + currentBarrelSpin) % MaxCircle; float newDepth = item.SpriteDepth + (spinningBarrel.Depth - item.Sprite.Depth) + (barrelCirclePosition > HalfCircle ? 0.0f : 0.001f); float barrelColorPosition = (barrelCirclePosition + QuarterCircle) % MaxCircle; float colorOffset = Math.Abs(barrelColorPosition - HalfCircle) / HalfCircle; Color newColorModifier = Color.Lerp(Color.Black, Color.Gray, colorOffset); float barrelHalfCirclePosition = Math.Abs(barrelCirclePosition - HalfCircle); float barrelPositionModifier = MathUtils.SmoothStep(barrelHalfCirclePosition / HalfCircle); float newPositionOffset = barrelPositionModifier * SpinningBarrelDistance; spinningBarrel.Draw(spriteBatch, drawPos - MathUtils.RotatePoint(new Vector2(newPositionOffset, 0f) * item.Scale, rotation + MathHelper.PiOver2), Color.Lerp(item.SpriteColor, newColorModifier, 0.8f), rotation + MathHelper.PiOver2, item.Scale, SpriteEffects.None, newDepth); } if (!editing || GUI.DisableHUD || !item.IsSelected) { return; } const float widgetRadius = 60.0f; Vector2 center = new Vector2((float)Math.Cos((maxRotation + minRotation) / 2), (float)Math.Sin((maxRotation + minRotation) / 2)); GUI.DrawLine(spriteBatch, drawPos, drawPos + center * widgetRadius, Color.LightGreen); const float coneRadius = 300.0f; float radians = maxRotation - minRotation; float circleRadius = coneRadius / Screen.Selected.Cam.Zoom * GUI.Scale; float lineThickness = 1f / Screen.Selected.Cam.Zoom; if (Math.Abs(minRotation - maxRotation) < 0.02f) { spriteBatch.DrawLine(drawPos, drawPos + center * circleRadius, GUI.Style.Green, thickness: lineThickness); } else if (radians > Math.PI * 2) { spriteBatch.DrawCircle(drawPos, circleRadius, 180, GUI.Style.Red, thickness: lineThickness); } else { spriteBatch.DrawSector(drawPos, circleRadius, radians, (int)Math.Abs(90 * radians), GUI.Style.Green, offset: minRotation, thickness: lineThickness); } int baseWidgetScale = GUI.IntScale(16); int widgetSize = (int)(Math.Max(baseWidgetScale, baseWidgetScale / Screen.Selected.Cam.Zoom)); float widgetThickness = Math.Max(1f, lineThickness); Widget minRotationWidget = GetWidget("minrotation", spriteBatch, size: widgetSize, thickness: widgetThickness, initMethod: (widget) => { widget.Selected += () => { oldRotation = RotationLimits; }; widget.MouseDown += () => { widget.color = GUI.Style.Green; prevAngle = minRotation; }; widget.Deselected += () => { widget.color = Color.Yellow; item.CreateEditingHUD(); RotationLimits = RotationLimits; if (SubEditorScreen.IsSubEditor()) { SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation)); } }; widget.MouseHeld += (deltaTime) => { minRotation = GetRotationAngle(GetDrawPos()); UpdateBarrel(); MapEntity.DisableSelect = true; }; widget.PreUpdate += (deltaTime) => { widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y); widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos); }; widget.PostUpdate += (deltaTime) => { widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos); widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y); }; widget.PreDraw += (sprtBtch, deltaTime) => { widget.tooltip = "Min: " + (int)MathHelper.ToDegrees(minRotation); widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(minRotation), (float)Math.Sin(minRotation)) * coneRadius / Screen.Selected.Cam.Zoom * GUI.Scale; widget.Update(deltaTime); }; }); Widget maxRotationWidget = GetWidget("maxrotation", spriteBatch, size: widgetSize, thickness: widgetThickness, initMethod: (widget) => { widget.Selected += () => { oldRotation = RotationLimits; }; widget.MouseDown += () => { widget.color = GUI.Style.Green; prevAngle = maxRotation; }; widget.Deselected += () => { widget.color = Color.Yellow; item.CreateEditingHUD(); RotationLimits = RotationLimits; if (SubEditorScreen.IsSubEditor()) { SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation)); } }; widget.MouseHeld += (deltaTime) => { maxRotation = GetRotationAngle(GetDrawPos()); UpdateBarrel(); MapEntity.DisableSelect = true; }; widget.PreUpdate += (deltaTime) => { widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y); widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos); }; widget.PostUpdate += (deltaTime) => { widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos); widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y); }; widget.PreDraw += (sprtBtch, deltaTime) => { widget.tooltip = "Max: " + (int)MathHelper.ToDegrees(maxRotation); widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(maxRotation), (float)Math.Sin(maxRotation)) * coneRadius / Screen.Selected.Cam.Zoom * GUI.Scale; widget.Update(deltaTime); }; }); minRotationWidget.Draw(spriteBatch, (float)Timing.Step); maxRotationWidget.Draw(spriteBatch, (float)Timing.Step); Vector2 GetDrawPos() { Vector2 drawPos = new Vector2(item.Rect.X + transformedBarrelPos.X, item.Rect.Y - transformedBarrelPos.Y); if (item.Submarine != null) { drawPos += item.Submarine.DrawPosition; } drawPos.Y = -drawPos.Y; return(drawPos); } void UpdateBarrel() { rotation = (minRotation + maxRotation) / 2; } }
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1) { if (!MathUtils.NearlyEqual(item.Rotation, prevBaseRotation)) { UpdateTransformedBarrelPos(); } Vector2 drawPos = GetDrawPos(); float recoilOffset = 0.0f; if (Math.Abs(RecoilDistance) > 0.0f && recoilTimer > 0.0f) { float diff = RetractionTime - RecoilTime; if (recoilTimer >= diff) { //move the barrel backwards 0.1 seconds (defined by RecoilTime) after launching recoilOffset = RecoilDistance * (1.0f - (recoilTimer - diff) / RecoilTime); } else if (recoilTimer <= diff - RetractionDelay) { //move back to normal position while reloading float t = diff - RetractionDelay; recoilOffset = RecoilDistance * recoilTimer / t; } else { recoilOffset = RecoilDistance; } } railSprite?.Draw(spriteBatch, drawPos, item.SpriteColor, rotation + MathHelper.PiOver2, item.Scale, SpriteEffects.None, item.SpriteDepth + (railSprite.Depth - item.Sprite.Depth)); barrelSprite?.Draw(spriteBatch, drawPos - new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) * recoilOffset * item.Scale, item.SpriteColor, rotation + MathHelper.PiOver2, item.Scale, SpriteEffects.None, item.SpriteDepth + (barrelSprite.Depth - item.Sprite.Depth)); if (!editing || GUI.DisableHUD || !item.IsSelected) { return; } float widgetRadius = 60.0f; GUI.DrawLine(spriteBatch, drawPos, drawPos + new Vector2((float)Math.Cos(minRotation), (float)Math.Sin(minRotation)) * widgetRadius, GUI.Style.Green); GUI.DrawLine(spriteBatch, drawPos, drawPos + new Vector2((float)Math.Cos(maxRotation), (float)Math.Sin(maxRotation)) * widgetRadius, GUI.Style.Green); GUI.DrawLine(spriteBatch, drawPos, drawPos + new Vector2((float)Math.Cos((maxRotation + minRotation) / 2), (float)Math.Sin((maxRotation + minRotation) / 2)) * widgetRadius, Color.LightGreen); Widget minRotationWidget = GetWidget("minrotation", spriteBatch, size: 10, initMethod: (widget) => { widget.Selected += () => { oldRotation = RotationLimits; }; widget.MouseDown += () => { widget.color = GUI.Style.Green; prevAngle = minRotation; }; widget.Deselected += () => { widget.color = Color.Yellow; item.CreateEditingHUD(); if (SubEditorScreen.IsSubEditor()) { SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation)); } }; widget.MouseHeld += (deltaTime) => { minRotation = GetRotationAngle(GetDrawPos()); if (minRotation > maxRotation) { float temp = minRotation; minRotation = maxRotation; maxRotation = temp; } MapEntity.DisableSelect = true; }; widget.PreUpdate += (deltaTime) => { widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y); widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos); }; widget.PostUpdate += (deltaTime) => { widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos); widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y); }; widget.PreDraw += (sprtBtch, deltaTime) => { widget.tooltip = "Min: " + (int)MathHelper.ToDegrees(minRotation); widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(minRotation), (float)Math.Sin(minRotation)) * widgetRadius; widget.Update(deltaTime); }; }); Widget maxRotationWidget = GetWidget("maxrotation", spriteBatch, size: 10, initMethod: (widget) => { widget.Selected += () => { oldRotation = RotationLimits; }; widget.MouseDown += () => { widget.color = GUI.Style.Green; prevAngle = minRotation; }; widget.Deselected += () => { widget.color = Color.Yellow; item.CreateEditingHUD(); if (SubEditorScreen.IsSubEditor()) { SubEditorScreen.StoreCommand(new PropertyCommand(this, "RotationLimits", RotationLimits, oldRotation)); } }; widget.MouseHeld += (deltaTime) => { maxRotation = GetRotationAngle(GetDrawPos()); if (minRotation > maxRotation) { float temp = minRotation; minRotation = maxRotation; maxRotation = temp; } MapEntity.DisableSelect = true; }; widget.PreUpdate += (deltaTime) => { widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y); widget.DrawPos = Screen.Selected.Cam.WorldToScreen(widget.DrawPos); }; widget.PostUpdate += (deltaTime) => { widget.DrawPos = Screen.Selected.Cam.ScreenToWorld(widget.DrawPos); widget.DrawPos = new Vector2(widget.DrawPos.X, -widget.DrawPos.Y); }; widget.PreDraw += (sprtBtch, deltaTime) => { widget.tooltip = "Max: " + (int)MathHelper.ToDegrees(maxRotation); widget.DrawPos = GetDrawPos() + new Vector2((float)Math.Cos(maxRotation), (float)Math.Sin(maxRotation)) * widgetRadius; widget.Update(deltaTime); }; }); minRotationWidget.Draw(spriteBatch, (float)Timing.Step); maxRotationWidget.Draw(spriteBatch, (float)Timing.Step); Vector2 GetDrawPos() { Vector2 drawPos = new Vector2(item.Rect.X + transformedBarrelPos.X, item.Rect.Y - transformedBarrelPos.Y); if (item.Submarine != null) { drawPos += item.Submarine.DrawPosition; } drawPos.Y = -drawPos.Y; return(drawPos); } }