4 using Microsoft.Xna.Framework;
5 using Microsoft.Xna.Framework.Graphics;
7 using System.Collections.Generic;
11 partial class Repairable : ItemComponent, IDrawableComponent
27 private readonly List<ParticleEmitter> particleEmitters =
new List<ParticleEmitter>();
29 private readonly List<Vector2> particleEmitterConditionRanges =
new List<Vector2>();
39 private bool qteSuccess;
41 private float qteTimer;
42 private const float QteDuration = 0.5f;
43 private float qteCooldown;
44 private const float QteCooldownDuration = 0.5f;
48 [
Serialize(
"",
IsPropertySaveable.No, description:
"An optional description of the needed repairs displayed in the repair interface.")]
58 get {
return Vector2.Zero; }
75 if (IsTinkerable(character)) {
return true; }
83 foreach (var subElement
in element.
Elements())
85 switch (subElement.Name.ToString().ToLowerInvariant())
88 case "particleemitter":
90 float minCondition = subElement.GetAttributeFloat(
"mincondition", 0.0f);
91 float maxCondition = subElement.GetAttributeFloat(
"maxcondition", 100.0f);
93 if (maxCondition < minCondition)
95 DebugConsole.ThrowError(
"Invalid damage particle configuration in the Repairable component of " +
item.
Name +
". MaxCondition needs to be larger than MinCondition.");
96 float temp = maxCondition;
97 maxCondition = minCondition;
100 particleEmitterConditionRanges.Add(
new Vector2(minCondition, maxCondition));
107 private void RecreateGUI()
122 RelativeSpacing = 0.05f,
127 header, textAlignment: Alignment.TopCenter, font: GUIStyle.LargeFont);
130 Description, font: GUIStyle.SmallFont, wrap:
true);
133 TextManager.Get(
"RequiredRepairSkills"), font: GUIStyle.SubHeadingFont);
134 skillTextContainer = paddedFrame;
139 font: GUIStyle.SmallFont)
145 var progressBarHolder =
new GUILayoutGroup(
new RectTransform(
new Vector2(1.0f, 0.2f), paddedFrame.RectTransform), isHorizontal:
true)
148 RelativeSpacing = 0.02f
152 color: GUIStyle.Green, barSize: 0.0f, style:
"DeviceProgressBar");
156 IgnoreLayoutGroups =
true
159 qteTimer = QteDuration;
161 repairButtonText = TextManager.Get(
"RepairButton");
162 repairingText = TextManager.Get(
"Repairing");
166 OnClicked = (btn, obj) =>
169 item.CreateClientEvent(
this);
182 extraButtonContainer =
new GUILayoutGroup(
new RectTransform(
new Vector2(1.0f, 0.15f), paddedFrame.RectTransform), isHorizontal:
true)
184 IgnoreLayoutGroups =
true,
186 AbsoluteSpacing = GUI.IntScale(5)
189 sabotageButtonText = TextManager.Get(
"SabotageButton");
190 sabotagingText = TextManager.Get(
"Sabotaging");
193 IgnoreLayoutGroups =
true,
195 OnClicked = (btn, obj) =>
198 item.CreateClientEvent(
this);
208 tinkerButtonText = TextManager.Get(
"TinkerButton").
Fallback(
"Tinker");
209 tinkeringText = TextManager.Get(
"Tinkering").
Fallback(
"Tinkering");
212 IgnoreLayoutGroups =
true,
214 OnClicked = (btn, obj) =>
217 item.CreateClientEvent(
this);
225 partial
void UpdateProjSpecific(
float deltaTime)
246 if (!GameMain.IsMultiplayer)
248 switch (requestStartFixAction)
264 for (
int i = 0; i < particleEmitters.Count; i++)
266 if ((conditionPercentage >= particleEmitterConditionRanges[i].X && conditionPercentage <= particleEmitterConditionRanges[i].Y) ||
FakeBrokenTimer > 0.0f)
274 if (repairSoundChannel ==
null || !repairSoundChannel.
IsPlaying)
279 if (qteCooldown > 0.0f)
281 qteCooldown -= deltaTime;
282 if (qteCooldown <= 0.0f)
284 qteTimer = QteDuration;
289 qteTimer -= deltaTime * (qteTimer / QteDuration);
290 if (qteTimer < 0.0f) { qteTimer = QteDuration; }
296 repairSoundChannel =
null;
307 progressBar.
Color = ToolBox.GradientLerp(progressBar.
BarSize, GUIStyle.Red, GUIStyle.Orange, GUIStyle.Green);
310 Color qteSliderColor = Color.White;
311 if (qteCooldown > 0.0f)
313 qteSliderColor = qteSuccess ? GUIStyle.Green : GUIStyle.Red * 0.5f;
314 progressBar.
Color = ToolBox.GradientLerp(qteCooldown / QteCooldownDuration, progressBar.
Color, qteSliderColor, Color.White);
320 qteSliderColor = Color.Lerp(qteSliderColor, GUIStyle.Green, 0.5f);
325 GUI.DrawRectangle(spriteBatch,
326 new Rectangle(sliderRect.X + (
int)((qteTimer / QteDuration) * sliderRect.Width), sliderRect.Y - 5, 2, sliderRect.Height + 10),
327 qteSliderColor,
true);
332 progressBar.
Color = ToolBox.GradientLerp((
item.
Condition - defaultMaxCondition) / extraCondition, GUIStyle.ColorReputationHigh, GUIStyle.ColorReputationVeryHigh);
333 progressBarOverlayText.
Visible =
true;
334 progressBarOverlayText.
Text = $
"{(int)Math.Round((item.Condition / defaultMaxCondition) * 100)}%";
338 progressBarOverlayText.
Visible =
false;
344 repairingText +
new string(
'.', ((
int)(Timing.TotalTime * 2.0f) % 3) + 1);
351 sabotagingText +
new string(
'.', ((
int)(Timing.TotalTime * 2.0f) % 3) + 1);
358 tinkeringText +
new string(
'.', ((
int)(Timing.TotalTime * 2.0f) % 3) + 1);
373 public void Draw(SpriteBatch spriteBatch,
bool editing,
float itemDepth = -1, Color? overrideColor =
null)
380 GUI.DrawString(spriteBatch,
382 Color.Red, Color.Black * 0.5f);
385 else if (deteriorationTimer > 0.0f)
387 GUI.DrawString(spriteBatch,
389 paused ? Color.Cyan : Color.Lime, Color.Black * 0.5f);
393 GUI.DrawString(spriteBatch,
395 paused ? Color.Cyan : GUIStyle.Red, Color.Black * 0.5f);
397 GUI.DrawString(spriteBatch,
402 GUI.DrawString(spriteBatch,
411 base.RemoveComponentSpecific();
413 repairSoundChannel =
null;
416 private void QTEAction()
421 qteSuccess = qteCooldown <= 0.0f && qteTimer / QteDuration <=
item.
Condition / defaultMaxCondition;
433 if (!qteSuccess && qteCooldown > 0.0f) { qteTimer = QteDuration; }
434 qteCooldown = QteCooldownDuration;
437 item.CreateClientEvent(
this);
453 qteTimer = QteDuration;
Affliction GetAffliction(string identifier, bool allowLimbAfflictions=true)
CharacterHealth CharacterHealth
Item????????? SelectedItem
The primary selected item. It can be any device that character interacts with. This excludes items li...
static Character? Controlled
IEnumerable< ContentXElement > Elements()
virtual Vector2 DrawPosition
static Entity FindEntityByID(ushort ID)
Find an entity based on the ID
virtual void ClearChildren()
virtual void DrawManually(SpriteBatch spriteBatch, bool alsoChildren=false, bool recursive=true)
By default, all the gui elements are drawn automatically in the same order they appear on the update ...
RectTransform RectTransform
IEnumerable< GUIComponent > Children
Rectangle GetSliderRect(float fillAmount)
Get the area the slider should be drawn inside
bool AutoScaleHorizontal
When enabled, the text is automatically scaled down to fit the textblock horizontally.
static bool IsMultiplayer
float MaxRepairConditionMultiplier
float ConditionPercentageRelativeToDefaultMaxCondition
Condition percentage disregarding MaxRepairConditionMultiplier (i.e. this can go above 100% if the it...
override string Name
Note that this is not a LocalizedString instance, just the current name of the item as a string....
float ConditionPercentage
virtual bool HasRequiredItems(Character character, bool addMessage, LocalizedString msg=null)
void TryCreateDragHandle()
readonly List< Skill > RequiredSkills
void ClientEventRead(IReadMessage msg, float sendingTime)
override void RemoveComponentSpecific()
override bool ShouldDrawHUD(Character character)
float MaxStressDeteriorationMultiplier
void RepairBoost(bool qteSuccess)
float SkillRequirementMultiplier
override void DrawHUD(SpriteBatch spriteBatch, Character character)
bool StartRepairing(Character character, FixActions action)
void Draw(SpriteBatch spriteBatch, bool editing, float itemDepth=-1, Color? overrideColor=null)
float StressDeteriorationMultiplier
void ClientEventWrite(IWriteMessage msg, NetEntityEvent.IData extraData=null)
float ForceDeteriorationTimer
override void CreateGUI()
Overload this method and implement. The method is automatically called when the resolution changes.
float MinSabotageCondition
LocalizedString Fallback(LocalizedString fallback, bool useDefaultLanguageIfFound=true)
Use this text instead if the original text cannot be found.
bool IsHidden
Is the entity hidden due to HiddenInGame being enabled or the layer the entity is in being hidden?
Highlights an UI element of some kind. Generally used in tutorials.
int ReadRangedInteger(int min, int max)
void WriteRangedInteger(int val, int min, int max)
void WriteBoolean(bool val)