Status icons, skill/character refactoring

This commit is contained in:
Regalis
2015-09-25 12:42:42 +03:00
parent bf7619bcc4
commit 3587b4a4bb
20 changed files with 483 additions and 188 deletions

View File

@@ -124,6 +124,16 @@ namespace Subsurface
get { return cursorPosition; }
}
public Character ClosestCharacter
{
get { return closestCharacter; }
}
public Character SelectedCharacter
{
get { return selectedCharacter; }
}
//public AITarget AiTarget
//{
// get { return aiTarget; }
@@ -152,7 +162,7 @@ namespace Subsurface
{
get { return oxygen; }
set
{
{
oxygen = MathHelper.Clamp(value, 0.0f, 100.0f);
if (oxygen == 0.0f) Kill();
}
@@ -163,27 +173,25 @@ namespace Subsurface
get
{
return health;
//float totalHealth = 0.0f;
//foreach (Limb l in animController.limbs)
//{
// totalHealth += (l.MaxHealth - l.Damage);
//}
//return totalHealth/animController.limbs.Count();
}
set
{
health = MathHelper.Clamp(value, 0.0f, maxHealth);
if (health==0.0f) Kill();
if (health == 0.0f) Kill();
}
}
public float MaxHealth
{
get { return maxHealth; }
}
public float Bleeding
{
get { return bleeding; }
set
{
if (float.IsNaN(value) || float.IsInfinity(value)) return;
if (MathUtils.IsValid(value)) return;
bleeding = Math.Max(value, 0.0f);
}
}
@@ -287,6 +295,8 @@ namespace Subsurface
public Character(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false)
{
keys = new Key[Enum.GetNames(typeof(InputType)).Length];
keys[(int)InputType.Select] = new Key(false);
keys[(int)InputType.ActionHeld] = new Key(true);
@@ -513,22 +523,55 @@ namespace Subsurface
if (controlled == this)
{
Vector2 mouseSimPos = ConvertUnits.ToSimUnits(cam.ScreenToWorld(PlayerInput.MousePosition));
closestItem = FindClosestItem(mouseSimPos);
if (closestItem != null)
closestCharacter = FindClosestCharacter(mouseSimPos);
if (closestCharacter != null)
{
closestItem.IsHighlighted = true;
if (GetInputState(InputType.Select) && closestItem.Pick(this, forcePick))
if (closestCharacter != selectedCharacter) selectedCharacter = null;
if (!closestCharacter.isHumanoid) closestCharacter = null;
}
closestItem = FindClosestItem(mouseSimPos);
if (closestCharacter != null && closestItem != null)
{
if (Vector2.Distance(closestCharacter.SimPosition, mouseSimPos) < Vector2.Distance(closestItem.SimPosition, mouseSimPos))
{
new NetworkEvent(NetworkEventType.PickItem, ID, true, closestItem.ID);
if (selectedConstruction!=closestItem) closestItem = null;
}
else
{
closestCharacter = null;
}
}
closestCharacter = FindClosestCharacter(mouseSimPos);
if (closestCharacter != selectedCharacter) selectedCharacter = null;
if (closestCharacter!=null)
if (selectedCharacter==null)
{
if (closestItem != null)
{
closestItem.IsHighlighted = true;
if (GetInputState(InputType.Select) && closestItem.Pick(this, forcePick))
{
new NetworkEvent(NetworkEventType.PickItem, ID, true, closestItem.ID);
}
}
}
else
{
if (GetInputState(InputType.Select)) selectedCharacter = (selectedCharacter == null) ? closestCharacter : null;
if (Vector2.Distance(selectedCharacter.SimPosition, SimPosition) > 2.0f) selectedCharacter = null;
}
if (GetInputState(InputType.Select))
{
if (selectedCharacter!=null)
{
selectedCharacter = null;
}
else if (closestCharacter!=null && closestCharacter.isDead && closestCharacter.isHumanoid)
{
selectedCharacter = closestCharacter;
}
}
}
@@ -686,7 +729,11 @@ namespace Subsurface
return;
}
if (controlled == this) ControlLocalPlayer(cam);
if (controlled == this)
{
CharacterHUD.Update(deltaTime,this);
ControlLocalPlayer(cam);
}
Control(deltaTime, cam);
@@ -711,15 +758,11 @@ namespace Subsurface
PressureProtection -= deltaTime*100.0f;
}
//foreach (Limb limb in animController.limbs)
//{
Health = health - bleeding * deltaTime;
//}
Health = health - bleeding * deltaTime;
}
private void UpdateSightRange()
{
aiTarget.SightRange = 0.0f;
@@ -747,6 +790,11 @@ namespace Subsurface
// ConvertUnits.ToDisplayUnits(animController.targetMovement.X, animController.targetMovement.Y), Color.Green);
}
public void DrawHUD(SpriteBatch spriteBatch, Camera cam)
{
CharacterHUD.Draw(spriteBatch, this, cam);
}
public void DrawFront(SpriteBatch spriteBatch)
{
Vector2 pos = ConvertUnits.ToDisplayUnits(AnimController.Limbs[0].SimPosition);
@@ -772,67 +820,7 @@ namespace Subsurface
}
private static GUIProgressBar drowningBar, healthBar;
public void DrawHud(SpriteBatch spriteBatch, Camera cam)
{
if (drowningBar == null)
{
int width = 100, height = 20;
drowningBar = new GUIProgressBar(new Rectangle(20, GameMain.GraphicsHeight / 2, width, height), Color.Blue, 1.0f);
healthBar = new GUIProgressBar(new Rectangle(20, GameMain.GraphicsHeight / 2 + 30, width, height), Color.Red, 1.0f);
}
drowningBar.BarSize = Controlled.Oxygen / 100.0f;
if (drowningBar.BarSize < 0.95f) drowningBar.Draw(spriteBatch);
healthBar.BarSize = health / maxHealth;
if (healthBar.BarSize < 1.0f) healthBar.Draw(spriteBatch);
if (Controlled.Inventory != null) Controlled.Inventory.DrawOwn(spriteBatch);
Color color = Color.Orange;
if (closestCharacter != null && closestCharacter.isDead && closestCharacter.isHumanoid)
{
Vector2 startPos = Position + (closestCharacter.Position - Position) * 0.7f;
startPos = cam.WorldToScreen(startPos);
Vector2 textPos = startPos;
float stringWidth = GUI.Font.MeasureString(closestCharacter.Info.Name).X;
textPos -= new Vector2(stringWidth / 2, 20);
spriteBatch.DrawString(GUI.Font, closestCharacter.Info.Name, textPos, Color.Black);
spriteBatch.DrawString(GUI.Font, closestCharacter.Info.Name, textPos + new Vector2(1, -1), Color.Orange);
if (selectedCharacter==closestCharacter) closestCharacter.inventory.Draw(spriteBatch);
}
else if (closestItem != null && selectedConstruction==null)
{
Vector2 startPos = Position + (closestItem.Position - Position) * 0.7f;
startPos = cam.WorldToScreen(startPos);
Vector2 textPos = startPos;
float stringWidth = GUI.Font.MeasureString(closestItem.Prefab.Name).X;
textPos -= new Vector2(stringWidth / 2, 20);
spriteBatch.DrawString(GUI.Font, closestItem.Prefab.Name, textPos, Color.Black);
spriteBatch.DrawString(GUI.Font, closestItem.Prefab.Name, textPos + new Vector2(1, -1), Color.Orange);
textPos.Y += 50.0f;
foreach (ColoredText coloredText in closestItem.GetHUDTexts(Controlled))
{
textPos.X = startPos.X - GUI.Font.MeasureString(coloredText.Text).X / 2;
spriteBatch.DrawString(GUI.Font, coloredText.Text, textPos, Color.Black);
spriteBatch.DrawString(GUI.Font, coloredText.Text, textPos + new Vector2(1, -1), coloredText.Color);
textPos.Y += 25;
}
}
}
public void PlaySound(AIController.AiState state)
{
@@ -856,20 +844,23 @@ namespace Subsurface
}
}
public virtual AttackResult AddDamage(IDamageable attacker, Vector2 position, Attack attack, bool playSound = false)
public virtual AttackResult AddDamage(IDamageable attacker, Vector2 simPosition, Attack attack, bool playSound = false)
{
return AddDamage(position, attack.DamageType, attack.Damage, attack.BleedingDamage, attack.Stun, playSound);
return AddDamage(simPosition, attack.DamageType, attack.Damage, attack.BleedingDamage, attack.Stun, playSound);
}
public AttackResult AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound)
public AttackResult AddDamage(Vector2 simPosition, DamageType damageType, float amount, float bleedingAmount, float stun, bool playSound)
{
AnimController.StunTimer = Math.Max(AnimController.StunTimer, stun);
if (controlled == this) CharacterHUD.TakeDamage();
Limb closestLimb = null;
float closestDistance = 0.0f;
foreach (Limb limb in AnimController.Limbs)
{
float distance = Vector2.Distance(position, limb.SimPosition);
float distance = Vector2.Distance(simPosition, limb.SimPosition);
if (closestLimb == null || distance < closestDistance)
{
closestLimb = limb;
@@ -877,12 +868,12 @@ namespace Subsurface
}
}
Vector2 pull = position - closestLimb.SimPosition;
Vector2 pull = simPosition - closestLimb.SimPosition;
if (pull != Vector2.Zero) pull = Vector2.Normalize(pull);
closestLimb.body.ApplyForce(pull*Math.Min(amount*100.0f, 100.0f));
AttackResult attackResult = closestLimb.AddDamage(position, damageType, amount, bleedingAmount, playSound);
AttackResult attackResult = closestLimb.AddDamage(simPosition, damageType, amount, bleedingAmount, playSound);
health -= attackResult.Damage;
bleeding += attackResult.Bleeding;
@@ -938,6 +929,8 @@ namespace Subsurface
private IEnumerable<object> DeathAnim(Camera cam)
{
if (controlled != this) yield return CoroutineStatus.Success;
float dimDuration = 8.0f;
float timer = 0.0f;
@@ -967,9 +960,9 @@ namespace Subsurface
}
float lerpLightBack = 0.0f;
while (lerpLightBack<1.0f)
while (lerpLightBack < 1.0f)
{
lerpLightBack = Math.Min(lerpLightBack+0.05f,1.0f);
lerpLightBack = Math.Min(lerpLightBack + 0.05f, 1.0f);
GameMain.LightManager.AmbientLight = Color.Lerp(Color.DarkGray, prevAmbientLight, lerpLightBack);
yield return CoroutineStatus.Running;

View File

@@ -0,0 +1,142 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Subsurface
{
class CharacterHUD
{
private static Sprite statusIcons;
private static GUIProgressBar drowningBar, healthBar;
private static float pressureTimer;
public static void TakeDamage()
{
healthBar.Flash();
}
public static void Update(float deltaTime, Character character)
{
if (drowningBar != null)
{
drowningBar.Update(deltaTime);
if (character.Oxygen < 10.0f) drowningBar.Flash();
}
if (healthBar != null) healthBar.Update(deltaTime);
pressureTimer += ((character.AnimController.CurrentHull == null) ?
100.0f : character.AnimController.CurrentHull.LethalPressure)*deltaTime;
}
public static void Draw(SpriteBatch spriteBatch, Character character, Camera cam)
{
if (statusIcons==null)
{
statusIcons = new Sprite("Content/UI/statusIcons.png", Vector2.Zero);
}
DrawStatusIcons(spriteBatch, character);
if (character.Inventory != null) character.Inventory.DrawOwn(spriteBatch);
Color color = Color.Orange;
if (character.SelectedCharacter != null && character.SelectedCharacter.Inventory!=null)
{
character.SelectedCharacter.Inventory.Draw(spriteBatch);
//if (Vector2.Distance(selectedCharacter.SimPosition, SimPosition) > 2.0f) selectedCharacter = null;
}
if (character.ClosestCharacter != null && character.ClosestCharacter.IsDead)
{
Vector2 startPos = character.Position + (character.ClosestCharacter.Position - character.Position) * 0.7f;
startPos = cam.WorldToScreen(startPos);
Vector2 textPos = startPos;
float stringWidth = GUI.Font.MeasureString(character.ClosestCharacter.Info.Name).X;
textPos -= new Vector2(stringWidth / 2, 20);
spriteBatch.DrawString(GUI.Font, character.ClosestCharacter.Info.Name, textPos, Color.Black);
spriteBatch.DrawString(GUI.Font, character.ClosestCharacter.Info.Name, textPos + new Vector2(1, -1), Color.Orange);
}
else if (character.SelectedCharacter == null && character.ClosestItem != null && character.SelectedConstruction == null)
{
Vector2 startPos = character.Position + (character.ClosestItem.Position - character.Position) * 0.7f;
startPos = cam.WorldToScreen(startPos);
Vector2 textPos = startPos;
float stringWidth = GUI.Font.MeasureString(character.ClosestItem.Prefab.Name).X;
textPos -= new Vector2(stringWidth / 2, 20);
spriteBatch.DrawString(GUI.Font, character.ClosestItem.Prefab.Name, textPos, Color.Black);
spriteBatch.DrawString(GUI.Font, character.ClosestItem.Prefab.Name, textPos + new Vector2(1, -1), Color.Orange);
textPos.Y += 50.0f;
foreach (ColoredText coloredText in character.ClosestItem.GetHUDTexts(character))
{
textPos.X = startPos.X - GUI.Font.MeasureString(coloredText.Text).X / 2;
spriteBatch.DrawString(GUI.Font, coloredText.Text, textPos, Color.Black);
spriteBatch.DrawString(GUI.Font, coloredText.Text, textPos + new Vector2(1, -1), coloredText.Color);
textPos.Y += 25;
}
}
}
private static void DrawStatusIcons(SpriteBatch spriteBatch, Character character)
{
if (drowningBar == null)
{
int width = 100, height = 20;
drowningBar = new GUIProgressBar(new Rectangle(30, GameMain.GraphicsHeight - 200, width, height), Color.Blue, 1.0f);
new GUIImage(new Rectangle(-27, -7, 20, 20), new Rectangle(17, 0, 20, 24), statusIcons, Alignment.TopLeft, drowningBar);
healthBar = new GUIProgressBar(new Rectangle(30, GameMain.GraphicsHeight - 230, width, height), Color.Red, 1.0f);
new GUIImage(new Rectangle(-26, -7, 20, 20), new Rectangle(0, 0, 13, 24), statusIcons, Alignment.TopLeft, healthBar);
}
drowningBar.BarSize = character.Oxygen / 100.0f;
if (drowningBar.BarSize < 0.99f)
{
drowningBar.Draw(spriteBatch);
}
healthBar.BarSize = character.Health / character.MaxHealth;
if (healthBar.BarSize < 1.0f)
{
healthBar.Draw(spriteBatch);
}
int bloodDropCount = (int)Math.Floor(character.Bleeding);
bloodDropCount = MathHelper.Clamp(bloodDropCount, 0, 5);
for (int i = 1; i < bloodDropCount; i++)
{
spriteBatch.Draw(statusIcons.Texture, new Vector2(5.0f + 20 * i, healthBar.Rect.Y - 20.0f), new Rectangle(39, 3, 15, 19), Color.White * 0.8f);
}
float pressureFactor = (character.AnimController.CurrentHull == null) ?
100.0f : Math.Min(character.AnimController.CurrentHull.LethalPressure,100.0f);
if (character.PressureProtection > 0.0f) pressureFactor = 0.0f;
if (pressureFactor>0.0f)
{
float indicatorAlpha = ((float)Math.Sin(pressureTimer * 0.1f) + 1.0f) * 0.5f;
indicatorAlpha = MathHelper.Clamp(indicatorAlpha, 0.1f, pressureFactor/100.0f);
spriteBatch.Draw(statusIcons.Texture, new Vector2(10.0f, healthBar.Rect.Y - 60.0f), new Rectangle(0, 24, 24, 25), Color.White * indicatorAlpha);
}
}
}
}

View File

@@ -7,28 +7,6 @@ using System.Xml.Linq;
namespace Subsurface
{
class Skill
{
string name;
int level;
public string Name
{
get { return name; }
}
public int Level
{
get { return level; }
}
public Skill(string name, int level)
{
this.name = name;
this.level = level;
}
}
class Job
{
@@ -76,11 +54,9 @@ namespace Subsurface
prefab = jobPrefab;
skills = new Dictionary<string, Skill>();
foreach (KeyValuePair<string, Vector2> skill in prefab.Skills)
foreach (SkillPrefab skillPrefab in prefab.Skills)
{
skills.Add(
skill.Key,
new Skill( skill.Key, (int)Rand.Range(skill.Value.X, skill.Value.Y, false)));
skills.Add(skillPrefab.Name, new Skill(skillPrefab));
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Globalization;
using System.Xml.Linq;
using System.Linq;
namespace Subsurface
{
@@ -30,7 +31,7 @@ namespace Subsurface
public List<string> ItemNames;
public List<bool> EquipItem;
public Dictionary<string, Vector2> Skills;
public List<SkillPrefab> Skills;
public string Name
{
@@ -54,7 +55,7 @@ namespace Subsurface
public JobPrefab(XElement element)
{
name = element.Name.ToString();
name = ToolBox.GetAttributeString(element, "name", "name not found");
description = ToolBox.GetAttributeString(element, "description", "");
@@ -66,7 +67,7 @@ namespace Subsurface
ItemNames = new List<string>();
EquipItem = new List<bool>();
Skills = new Dictionary<string, Vector2>();
Skills = new List<SkillPrefab>();
foreach (XElement subElement in element.Elements())
{
@@ -82,10 +83,15 @@ namespace Subsurface
}
break;
case "skills":
LoadSkills(subElement);
foreach (XElement skillElement in subElement.Elements())
{
Skills.Add(new SkillPrefab(skillElement));
}
break;
}
}
Skills.Sort((x,y) => y.LevelRange.X.CompareTo(x.LevelRange.X));
}
public static JobPrefab Random()
@@ -93,28 +99,51 @@ namespace Subsurface
return List[Rand.Int(List.Count)];
}
private void LoadSkills(XElement element)
public GUIFrame CreateInfoFrame()
{
foreach (XElement subElement in element.Elements())
int width = 500, height = 400;
GUIFrame frame = new GUIFrame(new Rectangle(GameMain.GraphicsWidth / 2 - width / 2, GameMain.GraphicsHeight / 2 - height / 2, width, height), GUI.Style);
frame.Padding = new Vector4(30.0f, 30.0f, 30.0f, 30.0f);
new GUITextBlock(new Rectangle(0,0,100,20), name, GUI.Style, Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.LargeFont);
var descriptionBlock = new GUITextBlock(new Rectangle(0, 40, 0, 0), description, GUI.Style, Alignment.TopLeft, Alignment.TopLeft, frame, true, GUI.SmallFont);
new GUITextBlock(new Rectangle(0, 40 + descriptionBlock.Rect.Height + 20, 100, 20), "Skills: ", GUI.Style, Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.LargeFont);
int y = 40 + descriptionBlock.Rect.Height + 50;
foreach (SkillPrefab skill in Skills)
{
string skillName = ToolBox.GetAttributeString(subElement, "name", "");
string skillDescription = Skill.GetLevelName((int)skill.LevelRange.X);
string skillDescription2 = Skill.GetLevelName((int)skill.LevelRange.Y);
if (string.IsNullOrEmpty(skillName) || Skills.ContainsKey(skillName)) continue;
var levelString = ToolBox.GetAttributeString(subElement, "level", "");
if (levelString.Contains(","))
if (skillDescription2!= skillDescription)
{
Skills.Add(skillName, ToolBox.ParseToVector2(levelString, false));
}
else
{
float skillLevel = float.Parse(levelString, CultureInfo.InvariantCulture);
Skills.Add(skillName, new Vector2(skillLevel, skillLevel));
skillDescription += "/"+skillDescription2;
}
new GUITextBlock(new Rectangle(0, y, 100, 20),
" - " + skill.Name + ": " + skillDescription, GUI.Style, Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.SmallFont);
y += 20;
}
}
new GUITextBlock(new Rectangle(250, 40 + descriptionBlock.Rect.Height + 20, 0, 20), "Items: ", GUI.Style, Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.LargeFont);
y = 40 + descriptionBlock.Rect.Height + 50;
foreach (string itemName in ItemNames)
{
new GUITextBlock(new Rectangle(250, y, 100, 20),
" - " + itemName, GUI.Style, Alignment.TopLeft, Alignment.TopLeft, frame, false, GUI.SmallFont);
y += 20;
}
return frame;
}
public static void LoadAll(List<string> filePaths)
{

View File

@@ -0,0 +1,57 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Subsurface
{
class Skill
{
SkillPrefab prefab;
string name;
int level;
static string[] levelNames = new string[] {
"Untrained", "Incompetent", "Novice",
"Adequate", "Competent", "Proficient",
"Professional", "Master", "Legendary" };
public string Name
{
get { return name; }
}
public int Level
{
get { return level; }
}
public Skill(SkillPrefab prefab)
{
this.prefab = prefab;
this.name = prefab.Name;
this.level = (int)Rand.Range(prefab.LevelRange.X, prefab.LevelRange.Y);
}
public Skill(string name, int level)
{
this.name = name;
this.level = level;
}
/// <summary>
/// returns the "name" of some skill level (0-10 -> untrained, etc)
/// </summary>
public static string GetLevelName(int level)
{
level = MathHelper.Clamp(level, 0, 100);
int scaledLevel = (int)Math.Floor((level / 100.0f) * levelNames.Length);
return levelNames[Math.Min(scaledLevel, levelNames.Length - 1)];
}
}
}

View File

@@ -0,0 +1,51 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace Subsurface
{
class SkillPrefab
{
string name;
string description;
private Vector2 levelRange;
public string Name
{
get { return name; }
}
public string Description
{
get { return description; }
}
public Vector2 LevelRange
{
get { return levelRange; }
}
public SkillPrefab(XElement element)
{
name = ToolBox.GetAttributeString(element, "name", "");
var levelString = ToolBox.GetAttributeString(element, "level", "");
if (levelString.Contains(","))
{
levelRange = ToolBox.ParseToVector2(levelString, false);
}
else
{
float skillLevel = float.Parse(levelString, System.Globalization.CultureInfo.InvariantCulture);
levelRange = new Vector2(skillLevel, skillLevel);
}
}
}
}

View File

@@ -285,7 +285,7 @@ namespace Subsurface
body.ApplyLinearImpulse((deltaPos - vel * 0.5f) * body.Mass, pullPos);
}
public AttackResult AddDamage(Vector2 position, DamageType damageType, float amount, float bleedingAmount, bool playSound)
public AttackResult AddDamage(Vector2 simPosition, DamageType damageType, float amount, float bleedingAmount, bool playSound)
{
DamageSoundType damageSoundType = (damageType == DamageType.Blunt) ? DamageSoundType.LimbBlunt : DamageSoundType.LimbSlash;
@@ -299,7 +299,7 @@ namespace Subsurface
float mid = (armorLimits.X + armorLimits.Y) / 2.0f;
float angleDiff = MathUtils.GetShortestAngle(MathUtils.VectorToAngle(position - SimPosition), mid);
float angleDiff = MathUtils.GetShortestAngle(MathUtils.VectorToAngle(simPosition - SimPosition), mid);
if (Math.Abs(angleDiff) < (armorSector.Y - armorSector.X) / 2.0f)
{
@@ -310,9 +310,9 @@ namespace Subsurface
}
}
if (playSound)
if (playSound && amount>0.0f)
{
AmbientSoundManager.PlayDamageSound(damageSoundType, amount, position);
AmbientSoundManager.PlayDamageSound(damageSoundType, amount, ConvertUnits.ToDisplayUnits(simPosition));
}
//Bleeding += bleedingAmount;
@@ -322,7 +322,7 @@ namespace Subsurface
for (int i = 0; i < bloodAmount; i++)
{
Vector2 particleVel = SimPosition - position;
Vector2 particleVel = SimPosition - simPosition;
if (particleVel != Vector2.Zero) particleVel = Vector2.Normalize(particleVel);
GameMain.ParticleManager.CreateParticle("blood",

View File

@@ -320,7 +320,7 @@ namespace Subsurface
}
}
if (Character.Controlled != null && cam!=null) Character.Controlled.DrawHud(spriteBatch, cam);
if (Character.Controlled != null && cam!=null) Character.Controlled.DrawHUD(spriteBatch, cam);
if (GameMain.NetworkMember != null) GameMain.NetworkMember.Draw(spriteBatch);
DrawMessages(spriteBatch, (float)deltaTime);

View File

@@ -47,6 +47,11 @@ namespace Subsurface
}
public GUIImage(Rectangle rect, Sprite sprite, Alignment alignment, GUIComponent parent = null)
: this(rect, sprite.SourceRect, sprite, alignment, parent)
{
}
public GUIImage(Rectangle rect, Rectangle sourceRect, Sprite sprite, Alignment alignment, GUIComponent parent = null)
: base(null)
{
this.rect = rect;
@@ -60,12 +65,12 @@ namespace Subsurface
Scale = 1.0f;
this.sprite = sprite;
if (rect.Width == 0) this.rect.Width = (int)sprite.size.X;
if (rect.Height == 0) this.rect.Height = (int)Math.Min(sprite.size.Y, sprite.size.Y * (this.rect.Width / sprite.size.X));
sourceRect = sprite.SourceRect;
this.sourceRect = sourceRect;
if (parent != null)
parent.AddChild(this);
}

View File

@@ -131,13 +131,11 @@ namespace Subsurface.Items.Components
public override bool Use(float deltaTime, Character activator = null)
{
//character = activator;
//foreach (MapEntity e in item.linkedTo)
//{
// Item linkedItem = e as Item;
// if (linkedItem == null) continue;
// linkedItem.Use(deltaTime, activator);
//}
if (character.SelectedConstruction != item)
{
character = null;
return false;
}
item.SendSignal("1", "trigger_out");
@@ -149,6 +147,11 @@ namespace Subsurface.Items.Components
public override void SecondaryUse(float deltaTime, Character character = null)
{
if (character == null) return;
if (character.SelectedConstruction!=item)
{
character = null;
return;
}
foreach (Connection c in item.Connections)
{

View File

@@ -420,7 +420,7 @@ namespace Subsurface
{
foreach (Item containedItem in containedItems)
{
if (containedItem == null || containedItem.condition==0.0f) continue;
if (containedItem == null) continue;
if (effect.TargetNames != null && !effect.TargetNames.Contains(containedItem.Name)) continue;
hasTargets = true;
@@ -719,7 +719,7 @@ namespace Subsurface
return;
}
if (!HasInGameEditableProperties)
if (HasInGameEditableProperties)
{
if (editingHUD == null || editingHUD.UserData as Item != this)
{

View File

@@ -60,8 +60,6 @@ namespace Subsurface
Rand.Vector(Rand.Range(50f, 100.0f)), 0.0f);
}
float displayRange = ConvertUnits.ToDisplayUnits(attack.Range);
light = new LightSource(displayPosition, displayRange, Color.LightYellow);

View File

@@ -239,7 +239,6 @@ namespace Subsurface
public override void Update(Camera cam, float deltaTime)
{
soundVolume = soundVolume + ((flowForce.Length() < 100.0f) ? -deltaTime * 0.5f : deltaTime * 0.5f);
soundVolume = MathHelper.Clamp(soundVolume, 0.0f, 1.0f);
@@ -254,7 +253,6 @@ namespace Subsurface
UpdateOxygen();
if (linkedTo.Count == 1)
{
//gap leading from a room to outside
@@ -266,7 +264,7 @@ namespace Subsurface
UpdateRoomToRoom(deltaTime);
}
lerpedFlowForce = Vector2.Lerp(lerpedFlowForce, flowForce, 0.1f);
lerpedFlowForce = Vector2.Lerp(lerpedFlowForce, flowForce, 0.05f);
if (FlowForce.Length() > 150.0f && flowTargetHull != null && flowTargetHull.Volume < flowTargetHull.FullVolume)
{

View File

@@ -147,7 +147,7 @@ namespace Subsurface
+ " However, UPnP isn't supported by all routers, so you may need to setup port forwards manually"
+" if players are unable to join the server (see the readme for instructions).";
GUIButton hostButton = new GUIButton(new Rectangle(0, 0, 200, 30), "Start", Alignment.BottomRight, GUI.Style, menuTabs[(int)Tabs.HostServer]);
GUIButton hostButton = new GUIButton(new Rectangle(0, 0, 100, 30), "Start", Alignment.BottomRight, GUI.Style, menuTabs[(int)Tabs.HostServer]);
hostButton.OnClicked = HostServerClicked;
this.game = game;

View File

@@ -27,6 +27,8 @@ namespace Subsurface
private GUIFrame playerFrame;
private GUIFrame jobInfoFrame;
private float camAngle;
public bool IsServer;
@@ -305,7 +307,7 @@ namespace Subsurface
if (IsServer && GameMain.Server != null)
{
var playYourself = new GUITickBox(new Rectangle(0, -20, 20, 20), "Play yourself", Alignment.TopLeft, playerFrame);
var playYourself = new GUITickBox(new Rectangle(-30, -30, 20, 20), "Play yourself", Alignment.TopLeft, playerFrame);
playYourself.Selected = GameMain.Server.CharacterInfo != null;
playYourself.OnSelected = TogglePlayYourself;
playYourself.UserData = "playyourself";
@@ -332,21 +334,25 @@ namespace Subsurface
new GUITextBlock(new Rectangle(0, 150, 200, 30), "Job preferences:", GUI.Style, playerFrame);
jobList = new GUIListBox(new Rectangle(0, 180, 180, 0), GUI.Style, playerFrame);
jobList = new GUIListBox(new Rectangle(0, 180, 250, 0), GUI.Style, playerFrame);
jobList.Enabled = false;
int i = 1;
foreach (JobPrefab job in JobPrefab.List)
{
GUITextBlock jobText = new GUITextBlock(new Rectangle(0, 0, 0, 20), i + ". " + job.Name, GUI.Style, Alignment.Left, Alignment.Right, jobList);
GUITextBlock jobText = new GUITextBlock(new Rectangle(0, 0, 0, 20), i + ". " + job.Name+" ", GUI.Style, Alignment.Left, Alignment.Right, jobList);
jobText.UserData = job;
GUIButton upButton = new GUIButton(new Rectangle(0, 0, 15, 15), "u", GUI.Style, jobText);
GUIButton infoButton = new GUIButton(new Rectangle(0, 0, 15, 15), "?", GUI.Style, jobText);
infoButton.UserData = -1;
infoButton.OnClicked += ViewJobInfo;
GUIButton upButton = new GUIButton(new Rectangle(30, 0, 15, 15), "^", GUI.Style, jobText);
upButton.UserData = -1;
upButton.OnClicked += ChangeJobPreference;
GUIButton downButton = new GUIButton(new Rectangle(25, 0, 15, 15), "d", GUI.Style, jobText);
GUIButton downButton = new GUIButton(new Rectangle(50, 0, 15, 15), "˅", GUI.Style, jobText);
downButton.UserData = 1;
downButton.OnClicked += ChangeJobPreference;
}
@@ -460,6 +466,8 @@ namespace Subsurface
GameMain.GameScreen.Cam.MoveCamera((float)deltaTime);
menu.Update((float)deltaTime);
if (jobInfoFrame != null) jobInfoFrame.Update((float)deltaTime);
//durationBar.BarScroll = Math.Max(durationBar.BarScroll, 1.0f / 60.0f);
}
@@ -474,6 +482,8 @@ namespace Subsurface
menu.Draw(spriteBatch);
if (jobInfoFrame != null) jobInfoFrame.Draw(spriteBatch);
//if (previewPlayer!=null) previewPlayer.Draw(spriteBatch);
GUI.Draw((float)deltaTime, spriteBatch, null);
@@ -531,17 +541,14 @@ namespace Subsurface
private bool SwitchGender(GUIButton button, object obj)
{
try
{
Gender gender = (Gender)obj;
GameMain.Client.CharacterInfo.Gender = gender;
GameMain.Client.SendCharacterData();
Gender gender = (Gender)obj;
GameMain.NetworkMember.CharacterInfo.Gender = gender;
GameMain.Client.SendCharacterData();
//CreatePreviewCharacter();
}
catch {}
//CreatePreviewCharacter();
UpdatePreviewPlayer(GameMain.Client.CharacterInfo);
UpdatePreviewPlayer(GameMain.NetworkMember.CharacterInfo);
return true;
}
@@ -594,6 +601,25 @@ namespace Subsurface
return true;
}
private bool ViewJobInfo(GUIButton button, object obj)
{
GUIComponent jobText = button.Parent;
JobPrefab jobPrefab = jobText.UserData as JobPrefab;
if (jobPrefab == null) return false;
jobInfoFrame = jobPrefab.CreateInfoFrame();
GUIButton closeButton = new GUIButton(new Rectangle(0,0,100,20), "Close", Alignment.BottomRight, GUI.Style, jobInfoFrame);
closeButton.OnClicked = CloseJobInfo;
return true;
}
private bool CloseJobInfo(GUIButton button, object obj)
{
jobInfoFrame = null;
return true;
}
private bool ChangeJobPreference(GUIButton button, object obj)
{
GUIComponent jobText = button.Parent;