2 using Microsoft.Xna.Framework;
3 using Microsoft.Xna.Framework.Graphics;
9 partial class Rope : ItemComponent, IDrawableComponent
11 private Sprite sprite, startSprite, endSprite;
13 private RoundSound snapSound, reelSound;
38 public Vector2
Origin {
get;
set; } =
new Vector2(0.5f, 0.5f);
51 if (target ==
null || source ==
null) {
return Vector2.Zero; }
53 Vector2 sourcePos = GetSourcePos();
61 [
Serialize(
"1.0, 1.0",
IsPropertySaveable.No, description:
"When reeling in, the pitch slides from X to Y, depending on the length of the rope.")]
64 get => _reelSoundPitchSlide;
67 _reelSoundPitchSlide =
new Vector2(
72 private Vector2 _reelSoundPitchSlide;
76 foreach (var subElement
in element.
Elements())
78 switch (subElement.Name.ToString().ToLowerInvariant())
81 sprite =
new Sprite(subElement);
84 startSprite =
new Sprite(subElement);
87 endSprite =
new Sprite(subElement);
99 partial
void UpdateProjSpecific()
108 reelSoundChannel =
null;
112 public void Draw(SpriteBatch spriteBatch,
bool editing,
float itemDepth = -1, Color? overrideColor =
null)
114 if (target ==
null || target.
Removed) {
return; }
116 if (source is
Limb limb && limb.
Removed) {
return; }
119 Vector2 startPos = GetSourcePos(useDrawPosition:
true);
120 startPos.Y = -startPos.Y;
121 if ((source as
Item)?.GetComponent<Turret>() is { } turret)
123 if (turret.BarrelSprite !=
null)
125 startPos +=
new Vector2((
float)Math.Cos(turret.Rotation), (
float)Math.Sin(turret.Rotation)) * turret.BarrelSprite.size.Y * turret.BarrelSprite.RelativeOrigin.Y *
item.
Scale * 0.9f;
127 startPos -= turret.GetRecoilOffset();
133 flippedPos.X = -flippedPos.X;
135 endPos += Vector2.Transform(flippedPos, Matrix.CreateRotationZ(target.
body.
Rotation));
136 endPos.Y = -endPos.Y;
141 Vector2 diff = target.
DrawPosition -
new Vector2(startPos.X, -startPos.Y);
147 float positionMultiplier = snapState;
150 positionMultiplier /= 2;
151 DrawRope(spriteBatch, endPos - diff * positionMultiplier, endPos, width);
153 DrawRope(spriteBatch, startPos, startPos + diff * positionMultiplier, width);
158 DrawRope(spriteBatch, startPos, endPos,
SpriteWidth);
161 if (startSprite !=
null || endSprite !=
null)
163 Vector2 dir = endPos - startPos;
164 float angle = (float)Math.Atan2(dir.Y, dir.X);
165 if (startSprite !=
null)
168 startSprite?.Draw(spriteBatch, startPos, overrideColor ??
SpriteColor, angle, depth: depth);
173 endSprite?.Draw(spriteBatch, endPos, overrideColor ??
SpriteColor, angle, depth: depth);
178 private void DrawRope(SpriteBatch spriteBatch, Vector2 startPos, Vector2 endPos,
int width, Color? overrideColor =
null)
180 float depth = sprite ==
null ?
184 if (sprite?.Texture ==
null)
186 GUI.DrawLine(spriteBatch,
189 overrideColor ??
SpriteColor, depth: depth, width: width);
195 float length = Vector2.Distance(startPos, endPos);
196 Vector2 dir = (endPos - startPos) / length;
198 for (x = 0.0f; x <= length - sprite.size.X; x += sprite.size.X)
200 GUI.DrawLine(spriteBatch, sprite,
201 startPos + dir * (x - 5.0f),
202 startPos + dir * (x + sprite.size.X),
203 overrideColor ??
SpriteColor, depth: depth, width: width);
205 float leftOver = length - x;
208 GUI.DrawLine(spriteBatch, sprite,
209 startPos + dir * (x - 5.0f),
211 overrideColor ??
SpriteColor, depth: depth, width: width);
216 GUI.DrawLine(spriteBatch, sprite,
219 overrideColor ??
SpriteColor, depth: depth, width: width);
223 private void PlaySound(RoundSound sound, Vector2 position)
225 if (sound ==
null) {
return; }
226 if (sound == reelSound)
228 if (reelSoundChannel is not { IsPlaying:
true })
230 reelSoundChannel = SoundPlayer.PlaySound(sound.Sound, position, sound.Volume, sound.Range, ignoreMuffling: sound.IgnoreMuffling, freqMult: sound.GetRandomFrequencyMultiplier());
231 if (reelSoundChannel !=
null)
233 reelSoundChannel.
Looping =
true;
238 reelSoundChannel.
Position =
new Vector3(position, 0);
239 reelSoundChannel.
Gain = MathHelper.Lerp(0, 1.0f, MathUtils.InverseLerp(
MinPullDistance,
MaxLength, MathUtils.Pow(currentRopeLength, 1.5f)));
245 SoundPlayer.PlaySound(sound.Sound, position, sound.Volume, sound.Range, ignoreMuffling: sound.IgnoreMuffling, freqMult: sound.GetRandomFrequencyMultiplier());
265 Limb sourceLimb = sourceCharacter.AnimController.Limbs[limbIndex];
266 Attach(sourceLimb, target);
267 sourceCharacter.AnimController.DragWithRope();
271 Attach(spatialEntity, target);
281 startSprite?.Remove();
286 reelSoundChannel =
null;
readonly AnimController AnimController
IEnumerable< ContentXElement > Elements()
virtual Vector2 DrawPosition
static Entity FindEntityByID(ushort ID)
Find an entity based on the ID
Inventory ParentInventory
override void RemoveComponentSpecific()
void Attach(ISpatialEntity source, Item target)
void ClientEventRead(IReadMessage msg, float sendingTime)
void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth=-1, Color? overrideColor=null)
Vector2 ReelSoundPitchSlide
static ? RoundSound Load(ContentXElement element, bool stream=false)
const float MaxFrequencyMultiplier
float FrequencyMultiplier
const float MinFrequencyMultiplier