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); } }
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 override void Update(float deltaTime, Camera cam) { if (nodes.Count == 0) { return; } Character user = item.ParentInventory?.Owner as Character; editNodeDelay = (user?.SelectedConstruction == null) ? editNodeDelay - deltaTime : 0.5f; Submarine sub = item.Submarine; if (connections[0] != null && connections[0].Item.Submarine != null) { sub = connections[0].Item.Submarine; } if (connections[1] != null && connections[1].Item.Submarine != null) { sub = connections[1].Item.Submarine; } if (Screen.Selected != GameMain.SubEditorScreen) { //cannot run wires from sub to another if (item.Submarine != sub && sub != null && item.Submarine != null) { ClearConnections(); return; } if (item.CurrentHull == null) { Structure attachTarget = Structure.GetAttachTarget(item.WorldPosition); canPlaceNode = attachTarget != null; sub ??= attachTarget?.Submarine; Vector2 attachPos = GetAttachPosition(user); newNodePos = sub == null ? attachPos : attachPos - sub.Position - sub.HiddenSubPosition; } else { newNodePos = GetAttachPosition(user); if (sub != null) { newNodePos -= sub.HiddenSubPosition; } canPlaceNode = true; } //prevent the wire from extending too far when rewiring if (nodes.Count > 0) { if (user == null) { return; } Vector2 prevNodePos = nodes[nodes.Count - 1]; if (sub != null) { prevNodePos += sub.HiddenSubPosition; } currLength = 0.0f; for (int i = 0; i < nodes.Count - 1; i++) { currLength += Vector2.Distance(nodes[i], nodes[i + 1]); } Vector2 itemPos = item.Position; if (sub != null && user.Submarine == null) { prevNodePos += sub.Position; } currLength += Vector2.Distance(prevNodePos, itemPos); if (currLength > MaxLength) { Vector2 diff = prevNodePos - user.Position; Vector2 pullBackDir = diff == Vector2.Zero ? Vector2.Zero : Vector2.Normalize(diff); Vector2 forceDir = pullBackDir; if (!user.AnimController.InWater) { forceDir.Y = 0.0f; } user.AnimController.Collider.ApplyForce(forceDir * user.Mass * 50.0f, maxVelocity: NetConfig.MaxPhysicsBodyVelocity * 0.5f); if (diff.LengthSquared() > 50.0f * 50.0f) { user.AnimController.UpdateUseItem(true, user.WorldPosition + pullBackDir * Math.Min(150.0f, diff.Length())); } if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer) { if (currLength > MaxLength * 1.5f) { ClearConnections(); #if SERVER CreateNetworkEvent(); #endif return; } } } } } else { #if CLIENT bool disableGrid = SubEditorScreen.IsSubEditor() && PlayerInput.IsShiftDown(); newNodePos = disableGrid ? item.Position : RoundNode(item.Position); #else newNodePos = RoundNode(item.Position); #endif if (sub != null) { newNodePos -= sub.HiddenSubPosition; } canPlaceNode = true; } if (item != null) { Vector2 relativeNodePos = newNodePos - item.Position; if (sub != null) { relativeNodePos += sub.HiddenSubPosition; } sectionExtents = new Vector2( Math.Max(Math.Abs(relativeNodePos.X), sectionExtents.X), Math.Max(Math.Abs(relativeNodePos.Y), sectionExtents.Y)); } }
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 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); void UpdateBarrel() { rotation = (minRotation + maxRotation) / 2; } }