Fixing items if sufficient skills+tools, choosing server port
This commit is contained in:
@@ -57,7 +57,7 @@ namespace Subsurface.Items.Components
|
||||
isActive = true;
|
||||
reload = 1.0f;
|
||||
|
||||
bool failed = UseFailed(character);
|
||||
bool failed = DoesUseFail(character);
|
||||
|
||||
List<Body> limbBodies = new List<Body>();
|
||||
foreach (Limb l in character.AnimController.limbs)
|
||||
|
||||
@@ -93,6 +93,9 @@ namespace Subsurface.Items.Components
|
||||
public override bool Use(float deltaTime, Character character = null)
|
||||
{
|
||||
if (character == null) return false;
|
||||
if (!character.SecondaryKeyDown.State) return false;
|
||||
|
||||
if (DoesUseFail(character)) return false;
|
||||
|
||||
isActive = true;
|
||||
|
||||
|
||||
@@ -356,24 +356,39 @@ namespace Subsurface
|
||||
}
|
||||
|
||||
public bool HasRequiredSkills(Character character)
|
||||
{
|
||||
Skill temp;
|
||||
return HasRequiredSkills(character, out temp);
|
||||
}
|
||||
|
||||
public bool HasRequiredSkills(Character character, out Skill insufficientSkill)
|
||||
{
|
||||
foreach (Skill skill in requiredSkills)
|
||||
{
|
||||
int characterLevel = character.GetSkillLevel(skill.Name);
|
||||
if (characterLevel < skill.Level) return false;
|
||||
if (characterLevel < skill.Level)
|
||||
{
|
||||
insufficientSkill = skill;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
insufficientSkill = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool UseFailed(Character character)
|
||||
protected bool DoesUseFail(Character character)
|
||||
{
|
||||
foreach (Skill skill in requiredSkills)
|
||||
{
|
||||
int characterLevel = character.GetSkillLevel(skill.Name);
|
||||
if (characterLevel > skill.Level) continue;
|
||||
|
||||
if (Rand.Int(characterLevel) - skill.Level < 0) return true;
|
||||
if (Rand.Int(characterLevel) - skill.Level < 0)
|
||||
{
|
||||
item.ApplyStatusEffects(ActionType.OnFailure, 1.0f, character);
|
||||
//Item.ApplyStatusEffects();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -308,7 +308,7 @@ namespace Subsurface.Items.Components
|
||||
|
||||
float xOffset = (graphTimer / (float)updateGraphInterval);
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true);
|
||||
//GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true);
|
||||
|
||||
spriteBatch.DrawString(GUI.Font, "Temperature: " + (int)temperature + " C", new Vector2(x + 30, y + 30), Color.White);
|
||||
DrawGraph(tempGraph, spriteBatch, x + 30, y + 50, 10000.0f, xOffset);
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
class FixRequirement
|
||||
{
|
||||
string name;
|
||||
|
||||
private static GUIFrame frame;
|
||||
|
||||
List<Skill> requiredSkills;
|
||||
List<string> requiredItems;
|
||||
|
||||
public bool Fixed;
|
||||
|
||||
public FixRequirement(XElement element)
|
||||
{
|
||||
name = ToolBox.GetAttributeString(element, "name", "");
|
||||
|
||||
requiredSkills = new List<Skill>();
|
||||
requiredItems = new List<string>();
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLower())
|
||||
{
|
||||
case "skill":
|
||||
string skillName = ToolBox.GetAttributeString(subElement, "name", "");
|
||||
int level = ToolBox.GetAttributeInt(subElement, "level", 1);
|
||||
|
||||
requiredSkills.Add(new Skill(skillName, level));
|
||||
break;
|
||||
case "item":
|
||||
string itemName = ToolBox.GetAttributeString(subElement, "name", "");
|
||||
|
||||
requiredItems.Add(itemName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Fix(Character character, GUIComponent reqFrame)
|
||||
{
|
||||
bool success = true;
|
||||
foreach (string itemName in requiredItems)
|
||||
{
|
||||
GUIComponent component = reqFrame.children.Find(c => c.UserData as string == itemName);
|
||||
|
||||
GUITextBlock text = component as GUITextBlock;
|
||||
bool itemFound = (character.Inventory.items.FirstOrDefault(i => i !=null && i.Name == itemName) != null);
|
||||
|
||||
if (!itemFound) success = false;
|
||||
|
||||
if (text != null) text.TextColor = itemFound ? Color.LightGreen : Color.Red;
|
||||
}
|
||||
|
||||
foreach (Skill skill in requiredSkills)
|
||||
{
|
||||
GUIComponent component = reqFrame.children.Find(c => c.UserData as Skill == skill);
|
||||
GUITextBlock text = component as GUITextBlock;
|
||||
|
||||
float characterSkill = character.GetSkillLevel(skill.Name);
|
||||
bool sufficientSkill = characterSkill >= skill.Level;
|
||||
|
||||
if (!sufficientSkill) success = false;
|
||||
|
||||
if (text != null) text.TextColor = sufficientSkill ? Color.LightGreen : Color.Red;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
private static void CreateGUIFrame(Item item)
|
||||
{
|
||||
int width = 400, height = 500;
|
||||
int x = 0, y = 0;
|
||||
|
||||
frame = new GUIFrame(new Rectangle(0, 0, width, height), Color.White * 0.8f, Alignment.Center, GUI.style);
|
||||
frame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
|
||||
frame.UserData = item;
|
||||
|
||||
new GUITextBlock(new Rectangle(0,0,200,20), "Attempting to fix " + item.Name, GUI.style, frame);
|
||||
|
||||
y = y + 40;
|
||||
foreach (FixRequirement requirement in item.FixRequirements)
|
||||
{
|
||||
GUIFrame reqFrame = new GUIFrame(
|
||||
new Rectangle(0, y, 0, 20 + Math.Max(requirement.requiredItems.Count, requirement.requiredSkills.Count) * 15),
|
||||
Color.Transparent, null, frame);
|
||||
reqFrame.UserData = requirement;
|
||||
|
||||
|
||||
var fixButton = new GUIButton(new Rectangle(0, 0, 50, 20), "Fix", GUI.style, reqFrame);
|
||||
fixButton.OnClicked = FixButtonPressed;
|
||||
fixButton.UserData = requirement;
|
||||
|
||||
new GUITickBox(new Rectangle(70, 0, 20,20), requirement.name, Alignment.Left, reqFrame);
|
||||
|
||||
int y2 = 20;
|
||||
foreach (string itemName in requirement.requiredItems)
|
||||
{
|
||||
var itemBlock = new GUITextBlock(new Rectangle(30, y2, 200, 15), itemName, GUI.style, reqFrame);
|
||||
itemBlock.Font = GUI.SmallFont;
|
||||
itemBlock.UserData = itemName;
|
||||
|
||||
y2 += 15;
|
||||
}
|
||||
|
||||
y2 = 20;
|
||||
foreach (Skill skill in requirement.requiredSkills)
|
||||
{
|
||||
var skillBlock = new GUITextBlock(new Rectangle(150, y2, 200, 15), skill.Name + " - " + skill.Level, GUI.style, Alignment.Right, Alignment.TopLeft, reqFrame);
|
||||
skillBlock.Font = GUI.SmallFont;
|
||||
skillBlock.UserData = skill;
|
||||
|
||||
|
||||
y2 += 15;
|
||||
}
|
||||
|
||||
y += reqFrame.Rect.Height;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool FixButtonPressed(GUIButton button, object obj)
|
||||
{
|
||||
FixRequirement requirement = obj as FixRequirement;
|
||||
if (requirement == null) return false;
|
||||
|
||||
requirement.Fixed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void UpdateGUIFrame(Item item, Character character)
|
||||
{
|
||||
bool unfixedFound = false;
|
||||
foreach (GUIComponent child in frame.children)
|
||||
{
|
||||
FixRequirement requirement = child.UserData as FixRequirement;
|
||||
if (requirement == null) continue;
|
||||
|
||||
if (requirement.Fixed)
|
||||
{
|
||||
child.Color = Color.LightGreen * 0.3f;
|
||||
child.GetChild<GUITickBox>().Selected = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool canBeFixed = requirement.Fix(character, child);
|
||||
unfixedFound = true;
|
||||
//child.GetChild<GUITickBox>().Selected = canBeFixed;
|
||||
GUITickBox tickBox = child.GetChild<GUITickBox>();
|
||||
if (tickBox.Selected)
|
||||
{
|
||||
tickBox.Selected = canBeFixed;
|
||||
requirement.Fixed = canBeFixed;
|
||||
|
||||
}
|
||||
child.Color = Color.Red * 0.2f;
|
||||
//tickBox.State = GUIComponent.ComponentState.None;
|
||||
}
|
||||
}
|
||||
if (!unfixedFound)
|
||||
{
|
||||
item.Condition = 100.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawHud(SpriteBatch spriteBatch, Item item, Character character)
|
||||
{
|
||||
if (frame == null || frame.UserData != item)
|
||||
{
|
||||
CreateGUIFrame(item);
|
||||
|
||||
}
|
||||
UpdateGUIFrame(item, character);
|
||||
frame.Update((float)Physics.step);
|
||||
frame.Draw(spriteBatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
+39
-32
@@ -17,7 +17,7 @@ namespace Subsurface
|
||||
|
||||
public enum ActionType
|
||||
{
|
||||
OnPicked, OnWearing, OnContaining, OnContained, OnActive, OnUse
|
||||
OnPicked, OnWearing, OnContaining, OnContained, OnActive, OnUse, OnFailure
|
||||
}
|
||||
|
||||
class Item : MapEntity, IDamageable, IPropertyObject
|
||||
@@ -27,6 +27,7 @@ namespace Subsurface
|
||||
|
||||
private List<string> tags;
|
||||
|
||||
|
||||
public Hull CurrentHull;
|
||||
|
||||
//components that determine the functionality of the item
|
||||
@@ -47,6 +48,8 @@ namespace Subsurface
|
||||
|
||||
public Item container;
|
||||
|
||||
public List<FixRequirement> FixRequirements;
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return prefab.Name; }
|
||||
@@ -57,7 +60,6 @@ namespace Subsurface
|
||||
get { return prefab.sprite; }
|
||||
}
|
||||
|
||||
|
||||
public float Condition
|
||||
{
|
||||
get { return condition; }
|
||||
@@ -69,6 +71,7 @@ namespace Subsurface
|
||||
get { return condition; }
|
||||
}
|
||||
|
||||
|
||||
[Editable, HasDefaultValue("", true)]
|
||||
public string Tags
|
||||
{
|
||||
@@ -181,17 +184,13 @@ namespace Subsurface
|
||||
{
|
||||
prefab = itemPrefab;
|
||||
|
||||
linkedTo = new ObservableCollection<MapEntity>();
|
||||
components = new List<ItemComponent>();
|
||||
|
||||
tags = new List<string>();
|
||||
linkedTo = new ObservableCollection<MapEntity>();
|
||||
components = new List<ItemComponent>();
|
||||
FixRequirements = new List<FixRequirement>();
|
||||
tags = new List<string>();
|
||||
|
||||
rect = newRect;
|
||||
//rect.X -= rect.Width / 2;
|
||||
//rect.Y += rect.Height / 2;
|
||||
|
||||
//dir = 1.0f;
|
||||
|
||||
|
||||
FindHull();
|
||||
|
||||
condition = 100.0f;
|
||||
@@ -210,21 +209,8 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
properties = ObjectProperty.InitProperties(this, element);
|
||||
|
||||
//foreach (XAttribute attribute in element.Attributes())
|
||||
//{
|
||||
// ObjectProperty property = null;
|
||||
// if (!properties.TryGetValue(attribute.Name.ToString().ToLower(), out property)) continue;
|
||||
// if (property.Attributes.OfType<Initable>().Count() == 0) continue;
|
||||
// property.TrySetValue(attribute.Value);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
//highlightText = new List<string>();
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLower())
|
||||
@@ -240,6 +226,9 @@ namespace Subsurface
|
||||
aiTarget.SightRange = ToolBox.GetAttributeFloat(subElement, "sightrange", 1000.0f);
|
||||
aiTarget.SoundRange = ToolBox.GetAttributeFloat(subElement, "soundrange", 0.0f);
|
||||
break;
|
||||
case "fixrequirement":
|
||||
FixRequirements.Add(new FixRequirement(subElement));
|
||||
break;
|
||||
default:
|
||||
ItemComponent ic = ItemComponent.Load(subElement, this, prefab.ConfigFile);
|
||||
if (ic == null) break;
|
||||
@@ -638,16 +627,23 @@ namespace Subsurface
|
||||
|
||||
public virtual void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
if (editingHUD==null || editingHUD.UserData as Item != this)
|
||||
if (condition>0.0f)
|
||||
{
|
||||
editingHUD = CreateEditingHUD(true);
|
||||
if (editingHUD==null || editingHUD.UserData as Item != this)
|
||||
{
|
||||
editingHUD = CreateEditingHUD(true);
|
||||
}
|
||||
|
||||
editingHUD.Draw(spriteBatch);
|
||||
|
||||
foreach (ItemComponent ic in components)
|
||||
{
|
||||
ic.DrawHUD(spriteBatch, character);
|
||||
}
|
||||
}
|
||||
|
||||
editingHUD.Draw(spriteBatch);
|
||||
|
||||
foreach (ItemComponent ic in components)
|
||||
else
|
||||
{
|
||||
ic.DrawHUD(spriteBatch, character);
|
||||
FixRequirement.DrawHud(spriteBatch, this, character);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -730,9 +726,16 @@ namespace Subsurface
|
||||
bool hasRequiredSkills = true;
|
||||
|
||||
bool picked = false, selected = false;
|
||||
|
||||
Skill requiredSkill = null;
|
||||
|
||||
foreach (ItemComponent ic in components)
|
||||
{
|
||||
if (!ic.HasRequiredSkills(picker)) hasRequiredSkills = false;
|
||||
Skill tempRequiredSkill;
|
||||
if (!ic.HasRequiredSkills(picker, out tempRequiredSkill)) hasRequiredSkills = false;
|
||||
|
||||
if (tempRequiredSkill != null) requiredSkill = tempRequiredSkill;
|
||||
|
||||
if (!ic.HasRequiredItems(picker, picker == Character.Controlled) && !forcePick) continue;
|
||||
if ((ic.CanBePicked && ic.Pick(picker)) || (ic.CanBeSelected && ic.Select(picker)))
|
||||
{
|
||||
@@ -751,6 +754,10 @@ namespace Subsurface
|
||||
if (!hasRequiredSkills && Character.Controlled==picker)
|
||||
{
|
||||
GUI.AddMessage("Your skills may be insufficient to use the item!", Color.Red, 5.0f);
|
||||
if (requiredSkill != null)
|
||||
{
|
||||
GUI.AddMessage("("+requiredSkill.Name+" level "+requiredSkill.Level+" required)", Color.Red, 5.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (container!=null) container.RemoveContained(this);
|
||||
|
||||
@@ -25,9 +25,6 @@ namespace Subsurface
|
||||
//how close the character has to be to the item to pick it up
|
||||
private float pickDistance;
|
||||
|
||||
|
||||
//public List<Sound> sounds;
|
||||
|
||||
//an area next to the construction
|
||||
//the construction can be Activated() by a character inside the area
|
||||
public List<Rectangle> Triggers;
|
||||
@@ -144,40 +141,19 @@ namespace Subsurface
|
||||
name = ToolBox.GetAttributeString(element, "name", "");
|
||||
if (name == "") DebugConsole.ThrowError("Unnamed item in "+filePath+"!");
|
||||
|
||||
//if (element.Attribute("sprite") != null)
|
||||
//{
|
||||
// sprite = new Sprite(Path.GetDirectoryName(filePath) + "/" + element.Attribute("sprite").Value, new Vector2(0.5f, 0.5f));
|
||||
// sprite.Depth = 0.5f;
|
||||
//}
|
||||
|
||||
//var initableProperties = GetProperties<Initable>();
|
||||
//foreach (ObjectProperty initableProperty in initableProperties)
|
||||
//{
|
||||
// object value = ToolBox.GetAttributeObject(element, initableProperty.Name.ToLower());
|
||||
// if (value == null)
|
||||
// {
|
||||
// foreach (var ini in initableProperty.Attributes.OfType<Initable>())
|
||||
// {
|
||||
// value = ini.defaultValue;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// initableProperty.TrySetValue(value);
|
||||
//}
|
||||
|
||||
pickDistance = ConvertUnits.ToSimUnits(ToolBox.GetAttributeFloat(element, "pickdistance", 0.0f));
|
||||
|
||||
isLinkable = ToolBox.GetAttributeBool(element, "linkable", false);
|
||||
isLinkable = ToolBox.GetAttributeBool(element, "linkable", false);
|
||||
|
||||
resizeHorizontal = ToolBox.GetAttributeBool(element, "resizehorizontal", false);
|
||||
resizeVertical = ToolBox.GetAttributeBool(element, "resizevertical", false);
|
||||
resizeHorizontal = ToolBox.GetAttributeBool(element, "resizehorizontal", false);
|
||||
resizeVertical = ToolBox.GetAttributeBool(element, "resizevertical", false);
|
||||
|
||||
focusOnSelected = ToolBox.GetAttributeBool(element, "focusonselected", false);
|
||||
focusOnSelected = ToolBox.GetAttributeBool(element, "focusonselected", false);
|
||||
|
||||
offsetOnSelected = ToolBox.GetAttributeFloat(element, "offsetonselected", 0.0f);
|
||||
offsetOnSelected = ToolBox.GetAttributeFloat(element, "offsetonselected", 0.0f);
|
||||
|
||||
Triggers = new List<Rectangle>();
|
||||
Triggers = new List<Rectangle>();
|
||||
|
||||
foreach (XElement subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLower())
|
||||
@@ -201,18 +177,6 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
//sounds = new List<Sound>();
|
||||
//var soundElements = element.Descendants();
|
||||
//foreach (XElement soundElement in soundElements)
|
||||
//{
|
||||
// if (soundElement.Name.ToString().ToLower() != "sound") continue;
|
||||
// string soundPath = ToolBox.GetAttributeString(soundElement, "path", "");
|
||||
// if (soundPath == "") continue;
|
||||
|
||||
// Sound sound = Sound.Load(soundPath);
|
||||
// if (sound != null) sounds.Add(sound);
|
||||
//}
|
||||
|
||||
list.Add(this);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user