Progress on tutorial, gap tweaking (water flows faster from room to room), UPnP error messages, input keys in array, underwater aiming tweaking, tons of misc stuff commit more often ffs
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
#----------------------------- Global Properties ----------------------------#
|
||||
|
||||
/outputDir:bin/$(Platform)
|
||||
/intermediateDir:obj/$(Platform)
|
||||
/platform:Windows
|
||||
/config:
|
||||
/profile:Reach
|
||||
/compress:False
|
||||
|
||||
#-------------------------------- References --------------------------------#
|
||||
|
||||
|
||||
#---------------------------------- Content ---------------------------------#
|
||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
||||
<locationtypes>
|
||||
<None
|
||||
commonness="3"
|
||||
symbol="Content\Map\beaconSymbol.png">
|
||||
symbol="Content/Map/beaconSymbol.png">
|
||||
<nameformats
|
||||
f0="[name]"
|
||||
f1="[name]"
|
||||
@@ -12,7 +12,7 @@
|
||||
<City
|
||||
commonness="3"
|
||||
hireablecharacters="true"
|
||||
symbol="Content\Map\citySymbol.png">
|
||||
symbol="Content/Map/citySymbol.png">
|
||||
<nameformats
|
||||
f0="The City of [name]"
|
||||
f1="[name] City"
|
||||
@@ -23,7 +23,7 @@
|
||||
<Military
|
||||
commonness="1"
|
||||
hireablecharacters="true"
|
||||
symbol="Content\Map\militarySymbol.png">
|
||||
symbol="Content/Map/militarySymbol.png">
|
||||
<nameformats
|
||||
f0="[name] Outpost"
|
||||
f1="[name] Facility"
|
||||
@@ -34,7 +34,7 @@
|
||||
<Research
|
||||
commonness="1"
|
||||
hireablecharacters="true"
|
||||
symbol="Content\Map\researchSymbol.png">
|
||||
symbol="Content/Map/researchSymbol.png">
|
||||
<nameformats
|
||||
f0="[name] Research Facility"
|
||||
f1="[name] Research Center"
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
colorchange="0.0, 0.0, 0.0, -0.5"
|
||||
lifetime="3"
|
||||
deleteonhit="true"
|
||||
inwater="true"
|
||||
drawtarget="water"
|
||||
velocitychange="0.0, 0.1">
|
||||
<sprite texture="Content/Particles/bubbles.png"/>
|
||||
</bubbles>
|
||||
@@ -67,7 +67,7 @@
|
||||
startcolor="0.5, 0.0, 0.0" startalpha="1.0"
|
||||
colorchange="0.0, 0.0, 0.0, -0.25"
|
||||
lifetime="5.0"
|
||||
inwater="true"
|
||||
drawtarget="water"
|
||||
velocitychange="0.0, 0.0">
|
||||
<sprite texture="Content/Particles/spatter.png"/>
|
||||
</waterblood>
|
||||
@@ -79,7 +79,7 @@
|
||||
startcolor="1.0, 1.0, 1.0" startalpha="1.0"
|
||||
colorchange="-0.4, -0.4, -0.4, -0.3"
|
||||
lifetime="5.0"
|
||||
inwater="false"
|
||||
drawtarget="air"
|
||||
deleteonhit="true"
|
||||
velocitychange="0.0, 0.5">
|
||||
<sprite texture="Content/Particles/explosion.png"/>
|
||||
@@ -91,7 +91,7 @@
|
||||
startcolor="1.0, 1.0, 1.0" startalpha="1.0"
|
||||
colorchange="0.0, 0.0, 0.0, -4.0"
|
||||
lifetime="0.25"
|
||||
inwater="false"
|
||||
drawtarget="both"
|
||||
velocitychange="0.0, 0.0">
|
||||
<sprite texture="Content/Particles/flames.png" sourcerect="0,0,128,64" origin="0.15,0.5"/>
|
||||
</weld>
|
||||
@@ -102,7 +102,7 @@
|
||||
startcolor="1.0, 1.0, 1.0" startalpha="1.0"
|
||||
colorchange="0.0, 0.0, 0.0, -4.0"
|
||||
lifetime="0.25"
|
||||
inwater="false"
|
||||
drawtarget="both"
|
||||
velocitychange="0.0, 0.0">
|
||||
<sprite texture="Content/Particles/flames.png" sourcerect="0,64,128,64" origin="0.15,0.5"/>
|
||||
</plasma>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<damagesound file="Content/Sounds/Damage/implode.ogg" damagerange="0.0,100.0" damagesoundtype="Implode"/>
|
||||
|
||||
|
||||
<music file="Content\Sounds\Music\Simplex.ogg" type="default"/>
|
||||
<music file="Content\Sounds\Music\Enter The Maze.ogg" type="repair" priorityrange="40,100"/>
|
||||
<music file="Content\Sounds\Music\Unseen Horrors.ogg" type="monster" priorityrange="40,100"/>
|
||||
<music file="Content/Sounds/Music/Simplex.ogg" type="default"/>
|
||||
<music file="Content/Sounds/Music/Enter the Maze.ogg" type="repair" priorityrange="40,100"/>
|
||||
<music file="Content/Sounds/Music/Unseen Horrors.ogg" type="monster" priorityrange="40,100"/>
|
||||
</sounds>
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
outlinecolor="0.5, 0.57, 0.6, 1.0">
|
||||
|
||||
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
|
||||
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 1.0" sourcerect ="0.0, 0.0, 0.0, 90.0"/>
|
||||
<Sprite texture="Content/UI/uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
|
||||
<Sprite texture="Content/UI/uiBackground.png" size="0.0, 1.0" sourcerect ="0.0, 0.0, 0.0, 90.0"/>
|
||||
</GUIFrame>
|
||||
|
||||
<GUIButton
|
||||
@@ -34,8 +34,8 @@
|
||||
|
||||
textcolor="1.0, 1.0, 1.0, 1.0"
|
||||
outlinecolor="0.5, 0.57, 0.6, 1.0">
|
||||
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
|
||||
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 1.0" sourcerect ="0.0, 0.0, 0.0, 90.0"/>
|
||||
<Sprite texture="Content/UI/uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
|
||||
<Sprite texture="Content/UI/uiBackground.png" size="0.0, 1.0" sourcerect ="0.0, 0.0, 0.0, 90.0"/>
|
||||
</GUIListBox>
|
||||
|
||||
<GUIScrollBar
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
textcolor="1.0, 1.0, 1.0, 1.0"
|
||||
outlinecolor="0.5, 0.57, 0.6, 1.0">
|
||||
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 0.0"/>
|
||||
<Sprite texture="Content/UI/uiBackground.png" size="0.0, 0.0"/>
|
||||
</GUIScrollBar>
|
||||
|
||||
<GUITextBox
|
||||
@@ -51,14 +51,14 @@
|
||||
|
||||
textcolor="1.0, 1.0, 1.0, 1.0"
|
||||
outlinecolor="0.5, 0.57, 0.6, 1.0">
|
||||
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
|
||||
<Sprite texture="Content/UI/uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
|
||||
</GUITextBox>
|
||||
|
||||
<GUITickBox
|
||||
color="0.5, 0.5, 0.5, 1.0"
|
||||
|
||||
outlinecolor="0.5, 0.57, 0.6, 1.0">
|
||||
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
|
||||
<Sprite texture="Content/UI/uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
|
||||
</GUITickBox>
|
||||
|
||||
<GUIMessageBox
|
||||
@@ -72,8 +72,8 @@
|
||||
|
||||
outlinecolor="0.5, 0.57, 0.6, 1.0">
|
||||
|
||||
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
|
||||
<Sprite texture="Content\UI\uiBackground.png" size="0.0, 1.0" sourcerect ="0.0, 0.0, 0.0, 90.0"/>
|
||||
<Sprite texture="Content/UI/uiBackground.png" size="0.0, 0.0" sourcerect ="0.0, 90.0, 0.0, 100.0"/>
|
||||
<Sprite texture="Content/UI/uiBackground.png" size="0.0, 1.0" sourcerect ="0.0, 0.0, 0.0, 90.0"/>
|
||||
</GUIMessageBox>
|
||||
|
||||
</style>
|
||||
Binary file not shown.
@@ -1,24 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Randomevents>
|
||||
<MonsterEvent name="Under attack" description=""
|
||||
characterfile="Content/Characters/Crawler/Crawler.xml"
|
||||
characterfile="Content/Characters/Crawler/crawler.xml"
|
||||
commonness="10"
|
||||
difficulty="15"
|
||||
minamount="2" maxamount="3"
|
||||
starttimemin="15" starttimemax="20"
|
||||
musictype="monster"/>
|
||||
|
||||
<MonsterEvent name="Under attack" description=""
|
||||
characterfile="Content/Characters/TigerThresher/tigerthresher.xml"
|
||||
commonness="10"
|
||||
difficulty="30"
|
||||
starttimemin="15" starttimemax="20"
|
||||
musictype="monster"/>
|
||||
|
||||
<MonsterEvent name="Under attack" description=""
|
||||
characterfile="Content/Characters/Moloch/moloch.xml"
|
||||
commonness="10"
|
||||
difficulty="50"
|
||||
starttimemin="15" starttimemax="20"
|
||||
musictype="monster"/>
|
||||
</Randomevents>
|
||||
@@ -34,6 +34,7 @@ namespace Subsurface
|
||||
public AiState State
|
||||
{
|
||||
get { return state; }
|
||||
set { state = value; }
|
||||
}
|
||||
|
||||
public AIController (Character c)
|
||||
|
||||
@@ -469,8 +469,8 @@ namespace Subsurface
|
||||
public override void FillNetworkData(NetOutgoingMessage message)
|
||||
{
|
||||
message.Write((byte)state);
|
||||
|
||||
bool wallAttack = (wallAttackPos!=Vector2.Zero && state == AiState.Attack);
|
||||
|
||||
bool wallAttack = (wallAttackPos != Vector2.Zero && state == AiState.Attack);
|
||||
|
||||
message.Write(wallAttack);
|
||||
|
||||
|
||||
@@ -46,9 +46,11 @@ namespace Subsurface
|
||||
get { return Properties; }
|
||||
}
|
||||
|
||||
protected Key selectKeyHit;
|
||||
protected Key actionKeyHit, actionKeyDown;
|
||||
protected Key secondaryKeyHit, secondaryKeyDown;
|
||||
protected Key[] keys;
|
||||
|
||||
//protected Key selectKeyHit;
|
||||
//protected Key actionKeyHit, actionKeyDown;
|
||||
//protected Key secondaryKeyHit, secondaryKeyDown;
|
||||
|
||||
private Item selectedConstruction;
|
||||
private Item[] selectedItems;
|
||||
@@ -123,10 +125,10 @@ namespace Subsurface
|
||||
get { return cursorPosition; }
|
||||
}
|
||||
|
||||
public AITarget AiTarget
|
||||
{
|
||||
get { return aiTarget; }
|
||||
}
|
||||
//public AITarget AiTarget
|
||||
//{
|
||||
// get { return aiTarget; }
|
||||
//}
|
||||
|
||||
public float SoundRange
|
||||
{
|
||||
@@ -244,31 +246,6 @@ namespace Subsurface
|
||||
get { return closestItem; }
|
||||
}
|
||||
|
||||
public Key SelectKeyHit
|
||||
{
|
||||
get { return selectKeyHit; }
|
||||
}
|
||||
|
||||
public Key ActionKeyHit
|
||||
{
|
||||
get { return actionKeyHit; }
|
||||
}
|
||||
|
||||
public Key ActionKeyDown
|
||||
{
|
||||
get { return actionKeyDown; }
|
||||
}
|
||||
|
||||
public Key SecondaryKeyHit
|
||||
{
|
||||
get { return secondaryKeyHit; }
|
||||
}
|
||||
|
||||
public Key SecondaryKeyDown
|
||||
{
|
||||
get { return secondaryKeyDown; }
|
||||
}
|
||||
|
||||
public AIController AIController
|
||||
{
|
||||
get { return aiController; }
|
||||
@@ -311,11 +288,19 @@ namespace Subsurface
|
||||
|
||||
public Character(string file, Vector2 position, CharacterInfo characterInfo = null, bool isNetworkPlayer = false)
|
||||
{
|
||||
selectKeyHit = new Key(false);
|
||||
actionKeyDown = new Key(true);
|
||||
actionKeyHit = new Key(false);
|
||||
secondaryKeyHit = new Key(false);
|
||||
secondaryKeyDown = new Key(true);
|
||||
keys = new Key[Enum.GetNames(typeof(InputType)).Length];
|
||||
keys[(int)InputType.Select] = new Key(false);
|
||||
keys[(int)InputType.ActionHeld] = new Key(true);
|
||||
keys[(int)InputType.ActionHit] = new Key(false);
|
||||
keys[(int)InputType.SecondaryHit] = new Key(false);
|
||||
keys[(int)InputType.SecondaryHeld] = new Key(true);
|
||||
|
||||
keys[(int)InputType.Left] = new Key(true);
|
||||
keys[(int)InputType.Right] = new Key(true);
|
||||
keys[(int)InputType.Up] = new Key(true);
|
||||
keys[(int)InputType.Down] = new Key(true);
|
||||
|
||||
keys[(int)InputType.Run] = new Key(true);
|
||||
|
||||
selectedItems = new Item[2];
|
||||
|
||||
@@ -426,6 +411,19 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
public bool GetInputState(InputType inputType)
|
||||
{
|
||||
return keys[(int)inputType].State;
|
||||
}
|
||||
|
||||
public void ClearInputs()
|
||||
{
|
||||
foreach (Key key in keys)
|
||||
{
|
||||
key.State = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return (info != null && !string.IsNullOrWhiteSpace(info.Name)) ? info.Name : SpeciesName;
|
||||
@@ -477,6 +475,42 @@ namespace Subsurface
|
||||
{
|
||||
if (isDead) return;
|
||||
|
||||
Vector2 targetMovement = Vector2.Zero;
|
||||
if (GetInputState(InputType.Left)) targetMovement.X -= 1.0f;
|
||||
if (GetInputState(InputType.Right)) targetMovement.X += 1.0f;
|
||||
if (GetInputState(InputType.Up)) targetMovement.Y += 1.0f;
|
||||
if (GetInputState(InputType.Down)) targetMovement.Y -= 1.0f;
|
||||
|
||||
//the vertical component is only used for falling through platforms and climbing ladders when not in water,
|
||||
//so the movement can't be normalized or the character would walk slower when pressing down/up
|
||||
if (AnimController.InWater)
|
||||
{
|
||||
float length = targetMovement.Length();
|
||||
if (length > 0.0f) targetMovement = targetMovement / length;
|
||||
}
|
||||
|
||||
if (Math.Sign(targetMovement.X) == Math.Sign(AnimController.Dir) && GetInputState(InputType.Run))
|
||||
targetMovement *= 3.0f;
|
||||
|
||||
AnimController.TargetMovement = targetMovement;
|
||||
AnimController.IsStanding = true;
|
||||
|
||||
if (AnimController.onGround &&
|
||||
!AnimController.InWater &&
|
||||
AnimController.Anim != AnimController.Animation.UsingConstruction)
|
||||
{
|
||||
Limb head = AnimController.GetLimb(LimbType.Head);
|
||||
|
||||
if (cursorPosition.X < head.Position.X - 10.0f)
|
||||
{
|
||||
AnimController.TargetDir = Direction.Left;
|
||||
}
|
||||
else if (cursorPosition.X > head.Position.X + 10.0f)
|
||||
{
|
||||
AnimController.TargetDir = Direction.Right;
|
||||
}
|
||||
}
|
||||
|
||||
//find the closest item if selectkey has been hit, or if the character is being
|
||||
//controlled by the player (in order to highlight it)
|
||||
if (controlled == this)
|
||||
@@ -487,7 +521,7 @@ namespace Subsurface
|
||||
if (closestItem != null)
|
||||
{
|
||||
closestItem.IsHighlighted = true;
|
||||
if (selectKeyHit.State && closestItem.Pick(this, forcePick))
|
||||
if (GetInputState(InputType.Select) && closestItem.Pick(this, forcePick))
|
||||
{
|
||||
new NetworkEvent(NetworkEventType.PickItem, ID, true, closestItem.ID);
|
||||
}
|
||||
@@ -497,7 +531,7 @@ namespace Subsurface
|
||||
if (closestCharacter != selectedCharacter) selectedCharacter = null;
|
||||
if (closestCharacter!=null)
|
||||
{
|
||||
if (selectKeyHit.State) selectedCharacter = (selectedCharacter==null) ? closestCharacter : null;
|
||||
if (GetInputState(InputType.Select)) selectedCharacter = (selectedCharacter == null) ? closestCharacter : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -506,23 +540,22 @@ namespace Subsurface
|
||||
if (selectedItems[i] == null) continue;
|
||||
if (i == 1 && selectedItems[0] == selectedItems[1]) continue;
|
||||
|
||||
if (actionKeyDown.State) selectedItems[i].Use(deltaTime, this);
|
||||
if (secondaryKeyDown.State && selectedItems[i] != null) selectedItems[i].SecondaryUse(deltaTime, this);
|
||||
if (GetInputState(InputType.ActionHeld)) selectedItems[i].Use(deltaTime, this);
|
||||
if (GetInputState(InputType.SecondaryHeld) && selectedItems[i] != null) selectedItems[i].SecondaryUse(deltaTime, this);
|
||||
}
|
||||
|
||||
if (selectedConstruction != null)
|
||||
{
|
||||
if (actionKeyDown.State) selectedConstruction.Use(deltaTime, this);
|
||||
if (secondaryKeyDown.State) selectedConstruction.SecondaryUse(deltaTime, this);
|
||||
if (GetInputState(InputType.ActionHeld)) selectedConstruction.Use(deltaTime, this);
|
||||
if (GetInputState(InputType.SecondaryHeld)) selectedConstruction.SecondaryUse(deltaTime, this);
|
||||
}
|
||||
|
||||
if (IsNetworkPlayer)
|
||||
{
|
||||
selectKeyHit.Reset();
|
||||
actionKeyHit.Reset();
|
||||
actionKeyDown.Reset();
|
||||
secondaryKeyHit.Reset();
|
||||
secondaryKeyDown.Reset();
|
||||
foreach (Key key in keys)
|
||||
{
|
||||
key.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -574,44 +607,29 @@ namespace Subsurface
|
||||
|
||||
Lights.LightManager.ViewPos = ConvertUnits.ToDisplayUnits(head.SimPosition);
|
||||
|
||||
Vector2 targetMovement = Vector2.Zero;
|
||||
|
||||
if (!DisableControls)
|
||||
{
|
||||
if (PlayerInput.KeyDown(Keys.W)) targetMovement.Y += 1.0f;
|
||||
if (PlayerInput.KeyDown(Keys.S)) targetMovement.Y -= 1.0f;
|
||||
if (PlayerInput.KeyDown(Keys.A)) targetMovement.X -= 1.0f;
|
||||
if (PlayerInput.KeyDown(Keys.D)) targetMovement.X += 1.0f;
|
||||
keys[(int)InputType.Left].SetState(PlayerInput.KeyDown(Keys.A));
|
||||
keys[(int)InputType.Right].SetState(PlayerInput.KeyDown(Keys.D));
|
||||
keys[(int)InputType.Up].SetState(PlayerInput.KeyDown(Keys.W));
|
||||
keys[(int)InputType.Down].SetState(PlayerInput.KeyDown(Keys.S));
|
||||
|
||||
//the vertical component is only used for falling through platforms and climbing ladders when not in water,
|
||||
//so the movement can't be normalized or the character would walk slower when pressing down/up
|
||||
if (AnimController.InWater)
|
||||
{
|
||||
float length = targetMovement.Length();
|
||||
if (length > 0.0f) targetMovement = targetMovement / length;
|
||||
}
|
||||
keys[(int)InputType.Select].SetState(PlayerInput.KeyHit(Keys.E));
|
||||
keys[(int)InputType.ActionHit].SetState(PlayerInput.LeftButtonClicked());
|
||||
keys[(int)InputType.ActionHeld].SetState(PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed);
|
||||
keys[(int)InputType.SecondaryHit].SetState(PlayerInput.RightButtonClicked());
|
||||
keys[(int)InputType.SecondaryHeld].SetState(PlayerInput.GetMouseState.RightButton == ButtonState.Pressed);
|
||||
|
||||
if (Keyboard.GetState().IsKeyDown(Keys.LeftShift) && Math.Sign(targetMovement.X) == Math.Sign(AnimController.Dir))
|
||||
targetMovement *= 3.0f;
|
||||
|
||||
selectKeyHit.SetState(PlayerInput.KeyHit(Keys.E));
|
||||
actionKeyHit.SetState(PlayerInput.LeftButtonClicked());
|
||||
actionKeyDown.SetState(PlayerInput.GetMouseState.LeftButton == ButtonState.Pressed);
|
||||
secondaryKeyHit.SetState(PlayerInput.RightButtonClicked());
|
||||
secondaryKeyDown.SetState(PlayerInput.GetMouseState.RightButton == ButtonState.Pressed);
|
||||
keys[(int)InputType.Run].SetState(PlayerInput.KeyDown(Keys.LeftShift));
|
||||
}
|
||||
else
|
||||
{
|
||||
selectKeyHit.SetState(false);
|
||||
actionKeyHit.SetState(false);
|
||||
actionKeyDown.SetState(false);
|
||||
secondaryKeyHit.SetState(false);
|
||||
secondaryKeyDown.SetState(false);
|
||||
foreach (Key key in keys)
|
||||
{
|
||||
key.SetState(false);
|
||||
}
|
||||
}
|
||||
|
||||
AnimController.TargetMovement = targetMovement;
|
||||
AnimController.IsStanding = true;
|
||||
|
||||
if (moveCam)
|
||||
{
|
||||
cam.TargetPos = ConvertUnits.ToDisplayUnits(AnimController.limbs[0].SimPosition);
|
||||
@@ -634,20 +652,6 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
if (AnimController.onGround &&
|
||||
!AnimController.InWater &&
|
||||
AnimController.Anim != AnimController.Animation.UsingConstruction)
|
||||
{
|
||||
if (mouseSimPos.X < head.SimPosition.X-1.0f)
|
||||
{
|
||||
AnimController.TargetDir = Direction.Left;
|
||||
}
|
||||
else if (mouseSimPos.X > head.SimPosition.X + 1.0f)
|
||||
{
|
||||
AnimController.TargetDir = Direction.Right;
|
||||
}
|
||||
}
|
||||
|
||||
DisableControls = false;
|
||||
}
|
||||
|
||||
@@ -810,7 +814,7 @@ namespace Subsurface
|
||||
|
||||
Color color = Color.Orange;
|
||||
|
||||
if (closestCharacter != null && closestCharacter.isDead)
|
||||
if (closestCharacter != null && closestCharacter.isDead && closestCharacter.isHumanoid)
|
||||
{
|
||||
Vector2 startPos = Position + (closestCharacter.Position - Position) * 0.7f;
|
||||
startPos = cam.WorldToScreen(startPos);
|
||||
@@ -840,10 +844,10 @@ namespace Subsurface
|
||||
textPos.Y += 50.0f;
|
||||
foreach (ColoredText coloredText in closestItem.GetHUDTexts(Controlled))
|
||||
{
|
||||
textPos.X = startPos.X - GUI.Font.MeasureString(coloredText.text).X / 2;
|
||||
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);
|
||||
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;
|
||||
}
|
||||
@@ -919,13 +923,7 @@ namespace Subsurface
|
||||
Limb torso= AnimController.GetLimb(LimbType.Torso);
|
||||
if (torso == null) torso = AnimController.GetLimb(LimbType.Head);
|
||||
|
||||
Vector2 centerOfMass = Vector2.Zero;
|
||||
foreach (Limb limb in AnimController.limbs)
|
||||
{
|
||||
centerOfMass += limb.Mass * limb.SimPosition;
|
||||
}
|
||||
|
||||
centerOfMass /= AnimController.Mass;
|
||||
Vector2 centerOfMass = AnimController.GetCenterOfMass();
|
||||
|
||||
health = 0.0f;
|
||||
|
||||
@@ -1022,34 +1020,44 @@ namespace Subsurface
|
||||
}
|
||||
else if (type == NetworkEventType.KillCharacter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (type== NetworkEventType.NotMoving)
|
||||
{
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
var hasInputs = (GetInputState(InputType.Left) ||
|
||||
GetInputState(InputType.Right) ||
|
||||
GetInputState(InputType.Up) ||
|
||||
GetInputState(InputType.Down) ||
|
||||
GetInputState(InputType.ActionHeld) ||
|
||||
GetInputState(InputType.SecondaryHeld));
|
||||
|
||||
//if (type == Networking.NetworkEventType.KeyHit)
|
||||
//{
|
||||
// message.Write(selectKeyHit.Dequeue);
|
||||
message.Write(actionKeyDown.Dequeue);
|
||||
message.Write(secondaryKeyDown.Dequeue);
|
||||
//}
|
||||
message.Write(hasInputs || LargeUpdateTimer <= 0);
|
||||
|
||||
message.Write((float)NetTime.Now);
|
||||
|
||||
// Write byte = move direction
|
||||
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.X, -10.0f, 10.0f), -10.0f, 10.0f, 8);
|
||||
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.Y, -10.0f, 10.0f), -10.0f, 10.0f, 8);
|
||||
message.Write(keys[(int)InputType.ActionHeld].Dequeue);
|
||||
message.Write(keys[(int)InputType.SecondaryHeld].Dequeue);
|
||||
|
||||
message.Write(keys[(int)InputType.Left].Dequeue);
|
||||
message.Write(keys[(int)InputType.Right].Dequeue);
|
||||
|
||||
message.Write(AnimController.TargetDir==Direction.Right);
|
||||
message.Write(keys[(int)InputType.Up].Dequeue);
|
||||
message.Write(keys[(int)InputType.Down].Dequeue);
|
||||
|
||||
message.Write(keys[(int)InputType.Run].Dequeue);
|
||||
|
||||
// Write byte = move direction
|
||||
//message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.X, -10.0f, 10.0f), -10.0f, 10.0f, 8);
|
||||
//message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.Y, -10.0f, 10.0f), -10.0f, 10.0f, 8);
|
||||
|
||||
if (aiController==null)
|
||||
{
|
||||
message.Write(cursorPosition.X);
|
||||
message.Write(cursorPosition.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
message.Write(AnimController.TargetDir == Direction.Right);
|
||||
}
|
||||
|
||||
message.Write(LargeUpdateTimer <= 0);
|
||||
|
||||
@@ -1070,7 +1078,7 @@ namespace Subsurface
|
||||
}
|
||||
|
||||
message.WriteRangedSingle(MathHelper.Clamp(AnimController.StunTimer,0.0f,60.0f), 0.0f, 60.0f, 8);
|
||||
message.Write((byte)health);
|
||||
message.Write((byte)((health/maxHealth)*255.0f));
|
||||
|
||||
if (aiController != null) aiController.FillNetworkData(message);
|
||||
|
||||
@@ -1122,40 +1130,39 @@ namespace Subsurface
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (type == NetworkEventType.NotMoving)
|
||||
{
|
||||
AnimController.TargetMovement = Vector2.Zero;
|
||||
actionKeyDown.State = false;
|
||||
secondaryKeyDown.State = false;
|
||||
return;
|
||||
}
|
||||
|
||||
bool actionKeyState = false;
|
||||
bool secondaryKeyState = false;
|
||||
float sendingTime = 0.0f;
|
||||
Vector2 targetMovement = Vector2.Zero;
|
||||
float sendingTime = 0.0f;
|
||||
//Vector2 targetMovement = Vector2.Zero;
|
||||
bool targetDir = false;
|
||||
Vector2 cursorPos = Vector2.Zero;
|
||||
|
||||
bool leftKeyState = false, rightKeyState = false;
|
||||
bool upKeyState = false, downKeyState = false;
|
||||
|
||||
bool runState = false;
|
||||
|
||||
try
|
||||
{
|
||||
bool hasInputs = message.ReadBoolean();
|
||||
if (!hasInputs)
|
||||
{
|
||||
ClearInputs();
|
||||
return;
|
||||
}
|
||||
|
||||
sendingTime = message.ReadFloat();
|
||||
|
||||
actionKeyState = message.ReadBoolean();
|
||||
secondaryKeyState = message.ReadBoolean();
|
||||
|
||||
sendingTime = message.ReadFloat();
|
||||
leftKeyState = message.ReadBoolean();
|
||||
rightKeyState = message.ReadBoolean();
|
||||
upKeyState = message.ReadBoolean();
|
||||
downKeyState = message.ReadBoolean();
|
||||
|
||||
targetMovement = new Vector2(message.ReadRangedSingle(-10.0f, 10.0f, 8), message.ReadRangedSingle(-10.0f, 10.0f, 8));
|
||||
targetMovement.X = MathUtils.Round(targetMovement.X, 0.1f);
|
||||
targetMovement.Y = MathUtils.Round(targetMovement.Y, 0.1f);
|
||||
|
||||
targetDir = message.ReadBoolean();
|
||||
|
||||
if (aiController==null)
|
||||
{
|
||||
cursorPos = new Vector2(
|
||||
message.ReadFloat(),
|
||||
message.ReadFloat());
|
||||
}
|
||||
runState = message.ReadBoolean();
|
||||
}
|
||||
|
||||
catch
|
||||
@@ -1165,22 +1172,52 @@ namespace Subsurface
|
||||
|
||||
AnimController.IsStanding = true;
|
||||
|
||||
actionKeyDown.State = actionKeyState;
|
||||
secondaryKeyDown.State = secondaryKeyState;
|
||||
keys[(int)InputType.ActionHeld].State = actionKeyState;
|
||||
keys[(int)InputType.SecondaryHeld].State = secondaryKeyState;
|
||||
|
||||
if (sendingTime <= LastNetworkUpdate) return;
|
||||
|
||||
cursorPosition = cursorPos;
|
||||
|
||||
AnimController.TargetMovement= targetMovement;
|
||||
AnimController.TargetDir = (targetDir) ? Direction.Right : Direction.Left;
|
||||
keys[(int)InputType.Left].State = leftKeyState;
|
||||
keys[(int)InputType.Right].State = rightKeyState;
|
||||
|
||||
keys[(int)InputType.Up].State = upKeyState;
|
||||
keys[(int)InputType.Down].State = downKeyState;
|
||||
|
||||
keys[(int)InputType.Run].State = runState;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
if (aiController == null)
|
||||
{
|
||||
cursorPos = new Vector2(
|
||||
message.ReadFloat(),
|
||||
message.ReadFloat());
|
||||
}
|
||||
else
|
||||
{
|
||||
targetDir = message.ReadBoolean();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (aiController == null)
|
||||
{
|
||||
cursorPosition = cursorPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
AnimController.TargetDir = (targetDir) ? Direction.Right : Direction.Left;
|
||||
}
|
||||
|
||||
if (message.ReadBoolean())
|
||||
{
|
||||
foreach (Limb limb in AnimController.limbs)
|
||||
{
|
||||
Vector2 pos = Vector2.Zero, vel = Vector2.Zero;
|
||||
float rotation = 0.0f, angularVel = 0.0f;
|
||||
float rotation = 0.0f;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -1213,7 +1250,7 @@ namespace Subsurface
|
||||
try
|
||||
{
|
||||
newStunTimer = message.ReadRangedSingle(0.0f, 60.0f, 8);
|
||||
newHealth = message.ReadByte();
|
||||
newHealth = (message.ReadByte() / 255.0f) * maxHealth;
|
||||
}
|
||||
catch { return; }
|
||||
|
||||
|
||||
@@ -368,7 +368,7 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
float midX = (leftX + rightX) / 2.0f;
|
||||
float midX = GetCenterOfMass().X;
|
||||
|
||||
foreach (Limb l in limbs)
|
||||
{
|
||||
|
||||
@@ -9,6 +9,8 @@ namespace Subsurface
|
||||
{
|
||||
class HumanoidAnimController : AnimController
|
||||
{
|
||||
private bool aiming;
|
||||
|
||||
public HumanoidAnimController(Character character, XElement element)
|
||||
: base(character, element)
|
||||
{
|
||||
@@ -144,6 +146,7 @@ namespace Subsurface
|
||||
limb.Disabled = false;
|
||||
}
|
||||
|
||||
aiming = false;
|
||||
}
|
||||
|
||||
void UpdateStanding()
|
||||
@@ -398,7 +401,7 @@ namespace Subsurface
|
||||
rotation = MathHelper.ToDegrees(rotation);
|
||||
if (rotation < 0.0f) rotation += 360;
|
||||
|
||||
if (!character.IsNetworkPlayer)
|
||||
if (!character.IsNetworkPlayer && !aiming)
|
||||
{
|
||||
if (rotation > 20 && rotation < 170)
|
||||
TargetDir = Direction.Left;
|
||||
@@ -413,12 +416,17 @@ namespace Subsurface
|
||||
|
||||
//if trying to head to the opposite direction, apply torque
|
||||
//to the torso to flip the ragdoll around
|
||||
if (Math.Sign(TargetMovement.X) != Dir && TargetMovement.X != 0.0f)
|
||||
{
|
||||
float torque = torso.Mass * 10.0f;
|
||||
torque *= (rotation > 90 && rotation < 270) ? -Dir : Dir;
|
||||
//if (Math.Sign(TargetMovement.X) != Dir && TargetMovement.X != 0.0f)
|
||||
//{
|
||||
// float torque = torso.Mass * 10.0f;
|
||||
// torque *= (rotation > 90 && rotation < 270) ? -Dir : Dir;
|
||||
|
||||
torso.body.ApplyTorque(torque);
|
||||
// torso.body.ApplyTorque(torque);
|
||||
//}
|
||||
|
||||
if (targetSpeed > 0.1f && !aiming)
|
||||
{
|
||||
torso.body.SmoothRotate(MathUtils.VectorToAngle(TargetMovement)-MathHelper.PiOver2);
|
||||
}
|
||||
|
||||
movement = MathUtils.SmoothStep(movement, TargetMovement, 0.3f);
|
||||
@@ -578,7 +586,7 @@ namespace Subsurface
|
||||
|
||||
handPos = new Vector2(
|
||||
ladderSimPos.X,
|
||||
head.SimPosition.Y + 0.5f + movement.Y * 0.1f - ladderSimPos.Y);
|
||||
head.SimPosition.Y + 0.0f + movement.Y * 0.1f - ladderSimPos.Y);
|
||||
|
||||
MoveLimb(leftHand,
|
||||
new Vector2(handPos.X,
|
||||
@@ -595,7 +603,7 @@ namespace Subsurface
|
||||
|
||||
footPos = new Vector2(
|
||||
handPos.X - Dir*0.05f,
|
||||
head.SimPosition.Y - stepHeight * 2.7f - ladderSimPos.Y);
|
||||
head.SimPosition.Y - stepHeight * 2.7f - ladderSimPos.Y - 0.7f);
|
||||
|
||||
//if (movement.Y < 0) footPos.Y += 0.05f;
|
||||
|
||||
@@ -679,10 +687,10 @@ namespace Subsurface
|
||||
Limb rightHand = GetLimb(LimbType.RightHand);
|
||||
Limb rightArm = GetLimb(LimbType.RightArm);
|
||||
|
||||
Vector2 itemPos = character.SecondaryKeyDown.State ? aimPos : holdPos;
|
||||
Vector2 itemPos = character.GetInputState(InputType.SecondaryHeld) ? aimPos : holdPos;
|
||||
|
||||
float itemAngle;
|
||||
if (character.SecondaryKeyDown.State && itemPos != Vector2.Zero)
|
||||
if (character.GetInputState(InputType.SecondaryHeld) && itemPos != Vector2.Zero)
|
||||
{
|
||||
Vector2 mousePos = ConvertUnits.ToSimUnits(character.CursorPosition);
|
||||
|
||||
@@ -697,9 +705,11 @@ namespace Subsurface
|
||||
|
||||
if (TargetMovement == Vector2.Zero && inWater)
|
||||
{
|
||||
torso.body.SmoothRotate(0.2f * Dir);
|
||||
torso.body.AngularVelocity -= torso.body.AngularVelocity * 0.1f;
|
||||
torso.body.ApplyForce(torso.body.LinearVelocity * -0.5f);
|
||||
}
|
||||
|
||||
aiming = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@ using FarseerPhysics.Dynamics.Contacts;
|
||||
using FarseerPhysics.Dynamics.Joints;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Subsurface.Networking;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
@@ -39,7 +40,7 @@ namespace Subsurface
|
||||
|
||||
//a movement vector that overrides targetmovement if trying to steer
|
||||
//a character to the position sent by server in multiplayer mode
|
||||
public Vector2 correctionMovement;
|
||||
private Vector2 correctionMovement;
|
||||
|
||||
protected float floorY;
|
||||
protected float surfaceY;
|
||||
@@ -73,11 +74,7 @@ namespace Subsurface
|
||||
}
|
||||
set
|
||||
{
|
||||
if (float.IsNaN(value.X) || float.IsNaN(value.Y))
|
||||
{
|
||||
targetMovement = Vector2.Zero;
|
||||
return;
|
||||
}
|
||||
if (!MathUtils.IsValid(value)) return;
|
||||
targetMovement.X = MathHelper.Clamp(value.X, -3.0f, 3.0f);
|
||||
targetMovement.Y = MathHelper.Clamp(value.Y, -3.0f, 3.0f);
|
||||
}
|
||||
@@ -408,10 +405,24 @@ namespace Subsurface
|
||||
new Vector2(
|
||||
-limbs[i].pullJoint.LocalAnchorA.X,
|
||||
limbs[i].pullJoint.LocalAnchorA.Y);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 GetCenterOfMass()
|
||||
{
|
||||
Vector2 centerOfMass = Vector2.Zero;
|
||||
foreach (Limb limb in limbs)
|
||||
{
|
||||
centerOfMass += limb.Mass * limb.SimPosition;
|
||||
}
|
||||
|
||||
centerOfMass /= Mass;
|
||||
|
||||
return centerOfMass;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -567,10 +578,10 @@ namespace Subsurface
|
||||
if (refLimb.body.TargetPosition == Vector2.Zero) return;
|
||||
|
||||
//if the limb is further away than resetdistance, all limbs are immediately snapped to their targetpositions
|
||||
float resetDistance = 1.5f;
|
||||
float resetDistance = NetConfig.ResetRagdollDistance;
|
||||
|
||||
//if the limb is closer than alloweddistance, limb positions aren't updated
|
||||
float allowedDistance = 0.1f;
|
||||
//if the limb is closer than alloweddistance, just ignore the difference
|
||||
float allowedDistance = NetConfig.AllowedRagdollDistance;
|
||||
|
||||
float dist = Vector2.Distance(limbs[0].body.Position, refLimb.body.TargetPosition);
|
||||
bool resetAll = (dist > resetDistance && character.LargeUpdateTimer == 1);
|
||||
@@ -596,8 +607,7 @@ namespace Subsurface
|
||||
}
|
||||
else
|
||||
{
|
||||
correctionMovement = Vector2.Normalize(newMovement) * ((targetMovement == Vector2.Zero) ? 1.0f : targetMovement.Length());
|
||||
|
||||
correctionMovement = Vector2.Normalize(newMovement) * Math.Min(1.0f + dist, 3.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,13 +637,13 @@ namespace Subsurface
|
||||
foreach (MapEntity e in MapEntity.mapEntityList)
|
||||
{
|
||||
Gap gap = e as Gap;
|
||||
if (gap == null || gap.FlowTargetHull!=currentHull ||gap.FlowForce == Vector2.Zero) continue;
|
||||
if (gap == null || gap.FlowTargetHull != currentHull || gap.FlowForce == Vector2.Zero) continue;
|
||||
|
||||
Vector2 gapPos = gap.SimPosition;
|
||||
|
||||
float dist = Vector2.Distance(limbPos, gapPos);
|
||||
|
||||
force += Vector2.Normalize(gap.FlowForce)*(Math.Max(gap.FlowForce.Length() - dist, 0.0f)/1000.0f);
|
||||
force += Vector2.Normalize(gap.FlowForce) * (Math.Max(gap.FlowForce.Length() - dist, 0.0f) / 500.0f);
|
||||
}
|
||||
|
||||
if (force.Length() > 20.0f) return force;
|
||||
|
||||
@@ -57,13 +57,14 @@ namespace Subsurface
|
||||
{
|
||||
XDocument doc = ToolBox.TryLoadXml(filePath);
|
||||
|
||||
Path = filePath;
|
||||
|
||||
if (doc==null)
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't load content package ''"+filePath+"''!");
|
||||
return;
|
||||
}
|
||||
|
||||
Path = filePath;
|
||||
|
||||
name = ToolBox.GetAttributeString(doc.Root, "name", "");
|
||||
|
||||
@@ -81,7 +82,7 @@ namespace Subsurface
|
||||
|
||||
public static ContentPackage CreatePackage(string name)
|
||||
{
|
||||
ContentPackage newPackage = new ContentPackage();
|
||||
ContentPackage newPackage = new ContentPackage("Content/Data/"+name);
|
||||
newPackage.name = name;
|
||||
newPackage.Path = Folder + name;
|
||||
list.Add(newPackage);
|
||||
@@ -150,8 +151,6 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//string str = sb.ToString();
|
||||
byte[] bytes = new byte[hashes.Count()*16];
|
||||
for (int i = 0; i < hashes.Count; i++ )
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.Text;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
enum Status
|
||||
enum CoroutineStatus
|
||||
{
|
||||
Running, Success, Failure
|
||||
}
|
||||
@@ -24,6 +24,13 @@ namespace Subsurface
|
||||
Coroutines.Add(func.GetEnumerator());
|
||||
}
|
||||
|
||||
public static void StopCoroutine(string name)
|
||||
{
|
||||
IEnumerator<object> coroutine = Coroutines.FirstOrDefault(c => c.ToString().Contains(name));
|
||||
|
||||
if (coroutine != null) Coroutines.Remove(coroutine);
|
||||
}
|
||||
|
||||
// Updating just means stepping through all the coroutines
|
||||
public static void Update(float deltaTime)
|
||||
{
|
||||
@@ -39,12 +46,12 @@ namespace Subsurface
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ((Status)Coroutines[i].Current)
|
||||
switch ((CoroutineStatus)Coroutines[i].Current)
|
||||
{
|
||||
case Status.Success:
|
||||
case CoroutineStatus.Success:
|
||||
Coroutines.RemoveAt(i);
|
||||
continue;
|
||||
case Status.Failure:
|
||||
case CoroutineStatus.Failure:
|
||||
DebugConsole.ThrowError("Coroutine ''" + Coroutines[i]+ "'' has failed");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -10,13 +10,17 @@ namespace Subsurface
|
||||
{
|
||||
struct ColoredText
|
||||
{
|
||||
public string text;
|
||||
public Color color;
|
||||
public string Text;
|
||||
public Color Color;
|
||||
|
||||
public readonly string Time;
|
||||
|
||||
public ColoredText(string text, Color color)
|
||||
{
|
||||
this.text = text;
|
||||
this.color = color;
|
||||
this.Text = text;
|
||||
this.Color = color;
|
||||
|
||||
Time = DateTime.Now.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +100,7 @@ namespace Subsurface
|
||||
if (selectedIndex < 0) selectedIndex = messageCount - 1;
|
||||
selectedIndex = selectedIndex % messageCount;
|
||||
|
||||
textBox.Text = messages[selectedIndex].text;
|
||||
textBox.Text = messages[selectedIndex].Text;
|
||||
}
|
||||
|
||||
public static void Draw(SpriteBatch spriteBatch)
|
||||
@@ -127,7 +131,7 @@ namespace Subsurface
|
||||
Vector2 messagePos = new Vector2(x + margin * 2, y + height - 70 - messages.Count()*20);
|
||||
foreach (ColoredText message in messages)
|
||||
{
|
||||
spriteBatch.DrawString(GUI.Font, message.text, messagePos, message.color);
|
||||
spriteBatch.DrawString(GUI.Font, message.Text, messagePos, message.Color);
|
||||
messagePos.Y += 20;
|
||||
}
|
||||
|
||||
@@ -227,6 +231,16 @@ namespace Subsurface
|
||||
it.Condition = 100.0f;
|
||||
}
|
||||
break;
|
||||
case "fixhull":
|
||||
case "fixwalls":
|
||||
foreach (Structure w in Structure.wallList)
|
||||
{
|
||||
for (int i = 0 ; i < w.SectionCount; i++)
|
||||
{
|
||||
w.AddDamage(i, -100000.0f);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "shake":
|
||||
Game1.GameScreen.Cam.Shake = 10.0f;
|
||||
break;
|
||||
|
||||
@@ -157,16 +157,19 @@ namespace EventInput
|
||||
throw new InvalidOperationException("TextInput.Initialize can only be called once!");
|
||||
|
||||
hookProcDelegate = HookProc;
|
||||
prevWndProc = (IntPtr)SetWindowLong(window.Handle, GWL_WNDPROC,
|
||||
(int)Marshal.GetFunctionPointerForDelegate(hookProcDelegate));
|
||||
#if WINDOWS
|
||||
prevWndProc = (IntPtr)SetWindowLong(window.Handle, GWL_WNDPROC,
|
||||
(int)Marshal.GetFunctionPointerForDelegate(hookProcDelegate));
|
||||
|
||||
hIMC = ImmGetContext(window.Handle);
|
||||
#endif
|
||||
|
||||
hIMC = ImmGetContext(window.Handle);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
static IntPtr HookProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
IntPtr returnCode = CallWindowProc(prevWndProc, hWnd, msg, wParam, lParam);
|
||||
IntPtr returnCode = CallWindowProc(prevWndProc, hWnd, msg, wParam, lParam);
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
@@ -200,7 +203,10 @@ namespace EventInput
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return returnCode;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,10 +18,10 @@ namespace Subsurface
|
||||
characterFile = ToolBox.GetAttributeString(element, "characterfile", "");
|
||||
|
||||
minAmount = ToolBox.GetAttributeInt(element, "minamount", 1);
|
||||
maxAmount = Math.Max(ToolBox.GetAttributeInt(element, "maxamount", 1),minAmount);
|
||||
maxAmount = Math.Max(ToolBox.GetAttributeInt(element, "maxamount", 1), minAmount);
|
||||
}
|
||||
|
||||
protected override void Start()
|
||||
private void SpawnMonsters()
|
||||
{
|
||||
WayPoint randomWayPoint = WayPoint.GetRandom(SpawnType.Enemy);
|
||||
|
||||
@@ -40,22 +40,26 @@ namespace Subsurface
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
if (monsters == null) SpawnMonsters();
|
||||
|
||||
if (!isStarted) return;
|
||||
|
||||
if (!isFinished)
|
||||
//base.Update(deltaTime);
|
||||
|
||||
//if (!isStarted) return;
|
||||
|
||||
if (isFinished) return;
|
||||
|
||||
bool monstersDead = true;
|
||||
for (int i = 0; i < monsters.Length; i++)
|
||||
{
|
||||
bool monstersDead = true;
|
||||
for (int i = 0; i < monsters.Length; i++)
|
||||
{
|
||||
if (monsters[i].IsDead) continue;
|
||||
if (monsters[i].IsDead) continue;
|
||||
|
||||
if (!isStarted && monsters[i].SimPosition != Vector2.Zero && monsters[i].SimPosition.Length() < 20.0) isStarted = true;
|
||||
|
||||
monstersDead = false;
|
||||
break;
|
||||
}
|
||||
if (monstersDead) Finished();
|
||||
monstersDead = false;
|
||||
break;
|
||||
}
|
||||
if (monstersDead) Finished();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Subsurface
|
||||
|
||||
public override void Start(Level level)
|
||||
{
|
||||
Vector2 position = level.PositionsOfInterest[Rand.Int(level.PositionsOfInterest.Count)];
|
||||
Vector2 position = level.PositionsOfInterest[Rand.Int(level.PositionsOfInterest.Count, false)];
|
||||
|
||||
monster = new Character(monsterFile, ConvertUnits.ToSimUnits(position+level.Position));
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace Subsurface
|
||||
|
||||
try
|
||||
{
|
||||
t = Type.GetType("Subsurface." + type + ", Subsurface", true, true);
|
||||
t = Type.GetType("Subsurface." + type, true, true);
|
||||
if (t == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + configFile + "! Could not find a quest class of the type ''" + type + "''.");
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace Subsurface
|
||||
|
||||
try
|
||||
{
|
||||
t = Type.GetType("Subsurface." + type + ", Subsurface", true, true);
|
||||
t = Type.GetType("Subsurface." + type, true, true);
|
||||
if (t == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + configFile + "! Could not find an event class of the type ''" + type + "''.");
|
||||
|
||||
@@ -6,6 +6,11 @@
|
||||
|
||||
private bool prevStarted;
|
||||
|
||||
public override bool IsStarted
|
||||
{
|
||||
get { return scriptedEvent.IsStarted; }
|
||||
}
|
||||
|
||||
public ScriptedTask(ScriptedEvent scriptedEvent)
|
||||
: base(scriptedEvent.Difficulty, scriptedEvent.Name)
|
||||
{
|
||||
|
||||
@@ -34,6 +34,11 @@ namespace Subsurface
|
||||
get { return isFinished; }
|
||||
}
|
||||
|
||||
public virtual bool IsStarted
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public Task(float priority, string name)
|
||||
{
|
||||
if (Game1.GameSession==null || Game1.GameSession.taskManager == null) return;
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Subsurface
|
||||
|
||||
private List<Task> tasks;
|
||||
|
||||
private GUIListBox taskListBox;
|
||||
//private GUIListBox taskListBox;
|
||||
|
||||
public List<Task> Tasks
|
||||
{
|
||||
@@ -34,7 +34,7 @@ namespace Subsurface
|
||||
{
|
||||
tasks = new List<Task>();
|
||||
|
||||
taskListBox = new GUIListBox(new Rectangle(Game1.GraphicsWidth - 250, 50, 250, 500), Color.Transparent);
|
||||
//taskListBox = new GUIListBox(new Rectangle(Game1.GraphicsWidth - 250, 50, 250, 500), Color.Transparent);
|
||||
//taskListBox.ScrollBarEnabled = false;
|
||||
//taskListBox.Padding = GUI.style.smallPadding;
|
||||
}
|
||||
@@ -50,24 +50,24 @@ namespace Subsurface
|
||||
{
|
||||
CreateScriptedEvents(level);
|
||||
|
||||
taskListBox.ClearChildren();
|
||||
//taskListBox.ClearChildren();
|
||||
}
|
||||
|
||||
|
||||
public void EndShift()
|
||||
{
|
||||
taskListBox.ClearChildren();
|
||||
//taskListBox.ClearChildren();
|
||||
tasks.Clear();
|
||||
}
|
||||
|
||||
private void CreateScriptedEvents(Level level)
|
||||
{
|
||||
Random rand = new Random(level.Seed.GetHashCode());
|
||||
Random rand = new Random(ToolBox.StringToInt(level.Seed));
|
||||
|
||||
float totalDifficulty = level.Difficulty;
|
||||
|
||||
int tries = 0;
|
||||
do
|
||||
while (tries < 5)
|
||||
{
|
||||
ScriptedEvent scriptedEvent = ScriptedEvent.LoadRandom(rand);
|
||||
if (scriptedEvent==null || scriptedEvent.Difficulty > totalDifficulty)
|
||||
@@ -79,36 +79,36 @@ namespace Subsurface
|
||||
AddTask(new ScriptedTask(scriptedEvent));
|
||||
totalDifficulty -= scriptedEvent.Difficulty;
|
||||
tries = 0;
|
||||
} while (tries < 5);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void TaskStarted(Task task)
|
||||
{
|
||||
Color color = Color.Red;
|
||||
int width = 250;
|
||||
if (task.Priority < 30.0f)
|
||||
{
|
||||
width = 200;
|
||||
color = Color.Yellow;
|
||||
}
|
||||
else if (task.Priority < 60)
|
||||
{
|
||||
width = 220;
|
||||
color = Color.Orange;
|
||||
}
|
||||
//Color color = Color.Red;
|
||||
//int width = 250;
|
||||
//if (task.Priority < 30.0f)
|
||||
//{
|
||||
// width = 200;
|
||||
// color = Color.Yellow;
|
||||
//}
|
||||
//else if (task.Priority < 60)
|
||||
//{
|
||||
// width = 220;
|
||||
// color = Color.Orange;
|
||||
//}
|
||||
|
||||
GUIFrame frame = new GUIFrame(new Rectangle(0,0,width,40), Color.Transparent, Alignment.Right, null, taskListBox);
|
||||
frame.UserData = task;
|
||||
frame.Padding = new Vector4(0.0f, 5.0f, 5.0f, 5.0f);
|
||||
//GUIFrame frame = new GUIFrame(new Rectangle(0,0,width,40), Color.Transparent, Alignment.Right, null, taskListBox);
|
||||
//frame.UserData = task;
|
||||
//frame.Padding = new Vector4(0.0f, 5.0f, 5.0f, 5.0f);
|
||||
|
||||
GUIFrame colorFrame = new GUIFrame(new Rectangle(0, 0, 0, 0), color * 0.5f, Alignment.Right, null, frame);
|
||||
GUITextBlock textBlock = new GUITextBlock(new Rectangle(5, 5, 0, 20), task.Name, Color.Transparent, Color.Black, Alignment.Right, null, colorFrame);
|
||||
//GUIFrame colorFrame = new GUIFrame(new Rectangle(0, 0, 0, 0), color * 0.5f, Alignment.Right, null, frame);
|
||||
//GUITextBlock textBlock = new GUITextBlock(new Rectangle(5, 5, 0, 20), task.Name, Color.Transparent, Color.Black, Alignment.Right, null, colorFrame);
|
||||
//textBlock.Padding = new Vector4(10.0f, 10.0f, 0.0f, 0.0f);
|
||||
|
||||
//colorFrame.AddChild(textBlock);
|
||||
|
||||
taskListBox.children.Sort((x, y) => ((Task)y.UserData).Priority.CompareTo(((Task)x.UserData).Priority));
|
||||
//taskListBox.children.Sort((x, y) => ((Task)y.UserData).Priority.CompareTo(((Task)x.UserData).Priority));
|
||||
}
|
||||
|
||||
public void TaskFinished(Task task)
|
||||
@@ -121,23 +121,22 @@ namespace Subsurface
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
Task removeTask = null;
|
||||
GUIComponent removeComponent = null;
|
||||
foreach (Task task in tasks)
|
||||
{
|
||||
if (task.IsFinished)
|
||||
{
|
||||
foreach (GUIComponent comp in taskListBox.children)
|
||||
{
|
||||
if (comp.UserData as Task != task) continue;
|
||||
comp.Rect = new Rectangle(comp.Rect.X, comp.Rect.Y, comp.Rect.Width, comp.Rect.Height - 1);
|
||||
comp.children[0].ClearChildren();
|
||||
if (comp.Rect.Height < 1)
|
||||
{
|
||||
removeComponent = comp;
|
||||
//foreach (GUIComponent comp in taskListBox.children)
|
||||
//{
|
||||
// if (comp.UserData as Task != task) continue;
|
||||
// comp.Rect = new Rectangle(comp.Rect.X, comp.Rect.Y, comp.Rect.Width, comp.Rect.Height - 1);
|
||||
// comp.children[0].ClearChildren();
|
||||
// if (comp.Rect.Height < 1)
|
||||
// {
|
||||
// removeComponent = comp;
|
||||
removeTask = task;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// }
|
||||
// break;
|
||||
//}
|
||||
|
||||
}
|
||||
else
|
||||
@@ -146,18 +145,14 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
if (removeComponent!= null)
|
||||
if (removeTask!= null)
|
||||
{
|
||||
taskListBox.RemoveChild(removeComponent);
|
||||
//taskListBox.RemoveChild(removeComponent);
|
||||
tasks.Remove(removeTask);
|
||||
}
|
||||
|
||||
//endShiftButton.Enabled = finished || Game1.server!=null;
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
taskListBox.Draw(spriteBatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,12 +18,12 @@ namespace Subsurface
|
||||
|
||||
public string Text
|
||||
{
|
||||
get { return coloredText.text; }
|
||||
get { return coloredText.Text; }
|
||||
}
|
||||
|
||||
public Color Color
|
||||
{
|
||||
get { return coloredText.color; }
|
||||
get { return coloredText.Color; }
|
||||
}
|
||||
|
||||
public Vector2 Pos
|
||||
|
||||
@@ -15,6 +15,11 @@ namespace Subsurface
|
||||
//GUIFrame frame;
|
||||
public GUIButton[] Buttons;
|
||||
|
||||
public static GUIMessageBox VisibleBox
|
||||
{
|
||||
get { return MessageBoxes.Count==0 ? null : MessageBoxes.Peek(); }
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
get { return (children[1] as GUITextBlock).Text; }
|
||||
@@ -63,8 +68,8 @@ namespace Subsurface
|
||||
public bool Close(GUIButton button, object obj)
|
||||
{
|
||||
if (parent != null) parent.RemoveChild(this);
|
||||
if (MessageBoxes.Contains(this)) MessageBoxes.Dequeue();
|
||||
|
||||
MessageBoxes.Dequeue();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+14
-14
@@ -174,42 +174,42 @@ namespace Subsurface
|
||||
|
||||
Hull.renderer = new WaterRenderer(GraphicsDevice);
|
||||
loadState = 1.0f;
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
GUI.LoadContent(GraphicsDevice);
|
||||
loadState = 2.0f;
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
MapEntityPrefab.Init();
|
||||
loadState = 10.0f;
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
JobPrefab.LoadAll(SelectedPackage.GetFilesOfType(ContentType.Jobs));
|
||||
loadState = 15.0f;
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
StructurePrefab.LoadAll(SelectedPackage.GetFilesOfType(ContentType.Structure));
|
||||
loadState = 25.0f;
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
ItemPrefab.LoadAll(SelectedPackage.GetFilesOfType(ContentType.Item));
|
||||
loadState = 40.0f;
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
Debug.WriteLine("sounds");
|
||||
CoroutineManager.StartCoroutine(AmbientSoundManager.Init());
|
||||
loadState = 70.0f;
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
GameModePreset.Init();
|
||||
|
||||
Submarine.Preload("Content/SavedMaps");
|
||||
loadState = 80.0f;
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
GameScreen = new GameScreen(Graphics.GraphicsDevice);
|
||||
loadState = 90.0f;
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
MainMenuScreen = new MainMenuScreen(this);
|
||||
LobbyScreen = new LobbyScreen();
|
||||
@@ -220,21 +220,21 @@ namespace Subsurface
|
||||
EditMapScreen = new EditMapScreen();
|
||||
EditCharacterScreen = new EditCharacterScreen();
|
||||
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
ParticleManager = new ParticleManager("Content/Particles/ParticlePrefabs.xml", Cam);
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
GUIComponent.Init(Window);
|
||||
DebugConsole.Init(Window);
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
LocationType.Init("Content/Map/locationTypes.xml");
|
||||
MainMenuScreen.Select();
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
loadState = 100.0f;
|
||||
yield return Status.Success;
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Subsurface
|
||||
{
|
||||
Location[] locations = new Location[2];
|
||||
|
||||
Random rand = new Random(Game1.NetLobbyScreen.LevelSeed.GetHashCode());
|
||||
Random rand = new Random(ToolBox.StringToInt(Game1.NetLobbyScreen.LevelSeed));
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
|
||||
@@ -69,7 +69,17 @@ namespace Subsurface
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
|
||||
if (Character.Controlled!=null && Character.Controlled.IsDead)
|
||||
{
|
||||
Character.Controlled = null;
|
||||
|
||||
CoroutineManager.StopCoroutine("TutorialMode.UpdateState");
|
||||
infoBox = null;
|
||||
CoroutineManager.StartCoroutine(Dead());
|
||||
}
|
||||
|
||||
CrewManager.Update(deltaTime);
|
||||
|
||||
if (infoBox!=null) infoBox.Update(deltaTime);
|
||||
}
|
||||
|
||||
@@ -90,7 +100,7 @@ namespace Subsurface
|
||||
|
||||
while (!tutorialDoor.IsOpen)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(2.0f);
|
||||
@@ -103,14 +113,14 @@ namespace Subsurface
|
||||
|
||||
while (Vector2.Distance(Character.Controlled.Position, reactor.Item.Position)>200.0f)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("Select the reactor by walking next to it and pressing E.");
|
||||
|
||||
while (Character.Controlled.SelectedConstruction != reactor.Item)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
|
||||
@@ -118,7 +128,7 @@ namespace Subsurface
|
||||
|
||||
while (reactor.FissionRate <= 0.0f)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
|
||||
@@ -128,7 +138,7 @@ namespace Subsurface
|
||||
|
||||
while (Math.Abs(reactor.ShutDownTemp-5000.0f) > 400.0f)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
|
||||
@@ -138,7 +148,7 @@ namespace Subsurface
|
||||
|
||||
while (!reactor.AutoTemp)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
|
||||
@@ -150,14 +160,14 @@ namespace Subsurface
|
||||
|
||||
while (Vector2.Distance(Character.Controlled.Position, steering.Item.Position) > 150.0f)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("Select the navigation terminal by walking next to it and pressing E.");
|
||||
|
||||
while (Character.Controlled.SelectedConstruction != steering.Item)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
|
||||
@@ -168,7 +178,7 @@ namespace Subsurface
|
||||
|
||||
while (Character.Controlled.SelectedConstruction == steering.Item)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
|
||||
@@ -178,7 +188,7 @@ namespace Subsurface
|
||||
while (Character.Controlled.SelectedConstruction != steering.Item ||
|
||||
Character.Controlled.SelectedItems.FirstOrDefault(i => i != null && i.Name == "Screwdriver") == null)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
|
||||
@@ -188,7 +198,7 @@ namespace Subsurface
|
||||
|
||||
while (!HasItem("Wire"))
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("Head back to the navigation terminal to fix the wiring.");
|
||||
@@ -199,7 +209,7 @@ namespace Subsurface
|
||||
Character.Controlled.SelectedConstruction != steering.Item) ||
|
||||
Character.Controlled.SelectedItems.FirstOrDefault(i => i != null && i.Name == "Screwdriver") == null)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
if (Character.Controlled.SelectedItems.FirstOrDefault(i => i != null && i.GetComponent<Wire>()!=null) == null)
|
||||
@@ -208,7 +218,7 @@ namespace Subsurface
|
||||
|
||||
while (Character.Controlled.SelectedItems.FirstOrDefault(i => i != null && i.GetComponent<Wire>() != null) == null)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,7 +229,7 @@ namespace Subsurface
|
||||
|
||||
while (steeringConnection.Wires.FirstOrDefault(w => w != null) == null)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
}
|
||||
|
||||
@@ -228,7 +238,7 @@ namespace Subsurface
|
||||
|
||||
while (Character.Controlled.SelectedConstruction!=null)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(2.0f);
|
||||
@@ -239,7 +249,7 @@ namespace Subsurface
|
||||
|
||||
while (radar.Voltage<0.1f)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("Great! Now we should be able to get moving.");
|
||||
@@ -247,23 +257,23 @@ namespace Subsurface
|
||||
|
||||
while (Character.Controlled.SelectedConstruction != steering.Item)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("You can take a look at the area around the sub by pressing ''Activate Radar''.");
|
||||
|
||||
while (!radar.IsActive)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
|
||||
infoBox = CreateInfoFrame("The white box in the middle is the submarine, and the white lines outside it are the walls of an underwater cavern. "
|
||||
+ "Try moving the submarine by clicking somewhere inside the rectangle and draggind the pointer to the direction you want to go to.");
|
||||
|
||||
while (steering.CurrTargetVelocity == Vector2.Zero && steering.CurrTargetVelocity.Length() < 40.0f)
|
||||
while (steering.CurrTargetVelocity == Vector2.Zero && steering.CurrTargetVelocity.Length() < 50.0f)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
yield return new WaitForSeconds(4.0f);
|
||||
|
||||
@@ -276,12 +286,14 @@ namespace Subsurface
|
||||
|
||||
while (Submarine.Loaded.Position.Y > 31000.0f)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
var moloch = new Character("Content/Characters/Moloch/moloch.xml", steering.Item.SimPosition + Vector2.UnitX * 15.0f);
|
||||
var moloch = new Character("Content/Characters/Moloch/moloch.xml", steering.Item.SimPosition + Vector2.UnitX * 25.0f);
|
||||
moloch.PlaySound(AIController.AiState.Attack);
|
||||
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
|
||||
infoBox = CreateInfoFrame("Uh-oh... Something enormous just appeared on the radar.");
|
||||
|
||||
List<Structure> windows = new List<Structure>();
|
||||
@@ -295,13 +307,15 @@ namespace Subsurface
|
||||
bool broken = false;
|
||||
do
|
||||
{
|
||||
Submarine.Loaded.Speed = Vector2.Zero;
|
||||
|
||||
moloch.AIController.SelectTarget(steering.Item.CurrentHull.AiTarget);
|
||||
Vector2 steeringDir = windows[0].Position - moloch.Position;
|
||||
if (steeringDir != Vector2.Zero) steeringDir = Vector2.Normalize(steeringDir);
|
||||
|
||||
foreach (Limb limb in moloch.AnimController.limbs)
|
||||
{
|
||||
limb.body.LinearVelocity = new Vector2(limb.LinearVelocity.X, limb.LinearVelocity.Y + steeringDir.Y*0.01f);
|
||||
limb.body.LinearVelocity = new Vector2(limb.LinearVelocity.X, limb.LinearVelocity.Y + steeringDir.Y*10.0f);
|
||||
}
|
||||
|
||||
moloch.AIController.Steering = steeringDir;
|
||||
@@ -310,7 +324,7 @@ namespace Subsurface
|
||||
{
|
||||
for (int i = 0; i < window.SectionCount; i++)
|
||||
{
|
||||
if (!window.SectionHasHole(i)) continue;
|
||||
if (!window.SectionIsLeaking(i)) continue;
|
||||
broken = true;
|
||||
break;
|
||||
}
|
||||
@@ -336,17 +350,17 @@ namespace Subsurface
|
||||
Door commandDoor2 = Item.itemList.Find(i => i.HasTag("commanddoor2")).GetComponent<Door>();
|
||||
Door commandDoor3 = Item.itemList.Find(i => i.HasTag("commanddoor3")).GetComponent<Door>();
|
||||
|
||||
while (commandDoor1.IsOpen && (commandDoor2.IsOpen || commandDoor3.IsOpen))
|
||||
while (commandDoor1.IsOpen || (commandDoor2.IsOpen || commandDoor3.IsOpen))
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("Great! You should find yourself an diving mask or a diving suit, in case the creature causes more damage. "+
|
||||
infoBox = CreateInfoFrame("You should find yourself an diving mask or a diving suit, in case the creature causes more damage. "+
|
||||
"There are some in the room next to the airlock.");
|
||||
|
||||
while (!HasItem("Diving Mask") && !HasItem("Diving Suit"))
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
if (HasItem("Diving Mask"))
|
||||
@@ -364,7 +378,7 @@ namespace Subsurface
|
||||
|
||||
while (!HasItem("Oxygen Tank"))
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(5.0f);
|
||||
@@ -393,23 +407,153 @@ namespace Subsurface
|
||||
|
||||
var loader = Item.itemList.Find(i => i.Name == "Railgun Loader").GetComponent<ItemContainer>();
|
||||
|
||||
while (Math.Abs(Character.Controlled.Position.Y - loader.Item.Position.Y)>50)
|
||||
while (Math.Abs(Character.Controlled.Position.Y - loader.Item.Position.Y)>80)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("Grab one of the shells. You can load it by selecting the railgun loader and dragging the shell to. "
|
||||
+"one of the free slots.");
|
||||
+"one of the free slots. You need two hands to carry a shell, so make sure you don't have anything else in either hand.");
|
||||
|
||||
while (loader.Item.ContainedItems.FirstOrDefault(i => i != null) != null)
|
||||
while (loader.Item.ContainedItems.FirstOrDefault(i => i != null && i.Name == "Railgun Shell") == null)
|
||||
{
|
||||
capacitor1.Charge += 1.0f;
|
||||
capacitor2.Charge += 1.0f;
|
||||
yield return Status.Running;
|
||||
moloch.Health = 50.0f;
|
||||
|
||||
capacitor1.Charge += 5.0f;
|
||||
capacitor2.Charge += 5.0f;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("Now we're ready to shoot! Select the railgun controller.");
|
||||
|
||||
yield return Status.Success;
|
||||
while (Character.Controlled.SelectedConstruction == null || Character.Controlled.SelectedConstruction.Name != "Railgun Controller")
|
||||
{
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("Use the right mouse button to aim and left to shoot.");
|
||||
|
||||
while (!moloch.IsDead)
|
||||
{
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("The creature has died. Now you should fix the damages in the control room: "+
|
||||
"Grab a welding tool from the closet in the railgun room.");
|
||||
|
||||
while (!HasItem("Welding Tool"))
|
||||
{
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("The welding tool requires fuel to work. Grab a welding fuel tank and attach it to the tool "+
|
||||
"by dragging it into the same slot.");
|
||||
|
||||
do
|
||||
{
|
||||
var weldingTool = Character.Controlled.Inventory.items.FirstOrDefault(i => i != null && i.Name == "Welding Tool");
|
||||
if (weldingTool != null &&
|
||||
weldingTool.ContainedItems.FirstOrDefault(contained => contained != null && contained.Name == "Welding Fuel Tank") != null) break;
|
||||
|
||||
yield return CoroutineStatus.Running;
|
||||
} while (true);
|
||||
|
||||
|
||||
infoBox = CreateInfoFrame("You can aim with the tool using the right mouse button and weld using the left button. "+
|
||||
"Head to the command room to fix the leaks there.");
|
||||
|
||||
do
|
||||
{
|
||||
broken = false;
|
||||
foreach (Structure window in windows)
|
||||
{
|
||||
for (int i = 0; i < window.SectionCount; i++)
|
||||
{
|
||||
if (!window.SectionIsLeaking(i)) continue;
|
||||
broken = true;
|
||||
break;
|
||||
}
|
||||
if (broken) break;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(1.0f);
|
||||
} while (broken);
|
||||
|
||||
infoBox = CreateInfoFrame("Great! However, there's still quite a bit of water inside the sub. It should be pumped out "
|
||||
+"using the pump in the room at the bottom of the submarine.");
|
||||
|
||||
Pump pump = Item.itemList.Find(i => i.HasTag("tutorialpump")).GetComponent<Pump>();
|
||||
|
||||
while (Vector2.Distance(Character.Controlled.Position, pump.Item.Position) > 100.0f)
|
||||
{
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("The two pumps inside the ballast tanks "
|
||||
+"are connected straight to the navigation terminal and can't be manually controlled unless you mess with their wiring, "+
|
||||
"so you should only use the pump in the middle room to pump out the water. Select it, turn it on and adjust the pumping speed "+
|
||||
"to start pumping water out.");
|
||||
|
||||
while (pump.Item.CurrentHull.Volume>1000.0f)
|
||||
{
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
infoBox = CreateInfoFrame("That was all there is to this tutorial! Now you should be able to handle "+
|
||||
"most of the basic tasks on board the submarine.");
|
||||
|
||||
yield return new WaitForSeconds(4.0f);
|
||||
|
||||
float endPreviewLength = 10.0f;
|
||||
|
||||
DateTime endTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, (int)(1000.0f * endPreviewLength));
|
||||
float secondsLeft = endPreviewLength;
|
||||
|
||||
Character.Controlled = null;
|
||||
|
||||
do
|
||||
{
|
||||
secondsLeft = (float)(endTime - DateTime.Now).TotalSeconds;
|
||||
|
||||
float camAngle = (float)((DateTime.Now - endTime).TotalSeconds / endPreviewLength) * MathHelper.TwoPi;
|
||||
Vector2 offset = (new Vector2(
|
||||
(float)Math.Cos(camAngle) * (Submarine.Borders.Width / 2.0f),
|
||||
(float)Math.Sin(camAngle) * (Submarine.Borders.Height / 2.0f)));
|
||||
|
||||
Game1.GameScreen.Cam.TargetPos = offset * 0.8f;
|
||||
//Game1.GameScreen.Cam.MoveCamera((float)deltaTime);
|
||||
|
||||
yield return CoroutineStatus.Running;
|
||||
} while (secondsLeft > 0.0f);
|
||||
|
||||
Submarine.Unload();
|
||||
Game1.MainMenuScreen.Select();
|
||||
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
private IEnumerable<object> Dead()
|
||||
{
|
||||
yield return new WaitForSeconds(3.0f);
|
||||
|
||||
var messageBox = new GUIMessageBox("You have died", "Do you want to try again?", new string[] { "Yes", "No" });
|
||||
|
||||
messageBox.Buttons[0].OnClicked += Restart;
|
||||
messageBox.Buttons[0].OnClicked += messageBox.Close;
|
||||
|
||||
messageBox.Buttons[1].UserData = MainMenuScreen.Tabs.Main;
|
||||
messageBox.Buttons[1].OnClicked = Game1.MainMenuScreen.SelectTab;
|
||||
messageBox.Buttons[1].OnClicked += messageBox.Close;
|
||||
|
||||
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
private bool Restart(GUIButton button, object obj)
|
||||
{
|
||||
TutorialMode.Start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool HasItem(string itemName)
|
||||
@@ -425,6 +569,10 @@ namespace Subsurface
|
||||
{
|
||||
do
|
||||
{
|
||||
enemy.Health = 50.0f;
|
||||
|
||||
enemy.AIController.State = AIController.AiState.None;
|
||||
|
||||
Vector2 targetPos = Character.Controlled.Position + new Vector2(0.0f, 3000.0f);
|
||||
|
||||
Vector2 steering = targetPos - enemy.Position;
|
||||
@@ -432,10 +580,10 @@ namespace Subsurface
|
||||
|
||||
enemy.AIController.Steering = steering*2.0f;
|
||||
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
} while (capacitors.FirstOrDefault(c => c.Charge > 0.4f) == null);
|
||||
|
||||
yield return Status.Success;
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
public override void Draw(SpriteBatch spriteBatch)
|
||||
|
||||
@@ -175,8 +175,7 @@ namespace Subsurface
|
||||
public void Draw(SpriteBatch spriteBatch)
|
||||
{
|
||||
guiRoot.Draw(spriteBatch);
|
||||
taskManager.Draw(spriteBatch);
|
||||
|
||||
|
||||
if (gameMode != null) gameMode.Draw(spriteBatch);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,38 +45,41 @@ namespace Subsurface
|
||||
public void Load(string filePath)
|
||||
{
|
||||
XDocument doc = ToolBox.TryLoadXml(filePath);
|
||||
try
|
||||
|
||||
if (doc == null)
|
||||
{
|
||||
XElement graphicsMode = doc.Root.Element("graphicsmode");
|
||||
GraphicsWidth = int.Parse(graphicsMode.Attribute("width").Value);
|
||||
GraphicsHeight = int.Parse(graphicsMode.Attribute("height").Value);
|
||||
|
||||
FullScreenEnabled = graphicsMode.Attribute("fullscreen").Value == "true";
|
||||
DebugConsole.ThrowError("No config file found");
|
||||
|
||||
MasterServerUrl = ToolBox.GetAttributeString(doc.Root, "masterserverurl", "");
|
||||
|
||||
foreach (XElement subElement in doc.Root.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLower())
|
||||
{
|
||||
case "contentpackage":
|
||||
string path = ToolBox.GetAttributeString(subElement, "path", "");
|
||||
SelectedContentPackage = ContentPackage.list.Find(cp => cp.Path == path);
|
||||
|
||||
if (SelectedContentPackage == null) SelectedContentPackage = new ContentPackage(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
GraphicsWidth = 1024;
|
||||
GraphicsHeight = 768;
|
||||
GraphicsHeight = 678;
|
||||
|
||||
MasterServerUrl = "";
|
||||
|
||||
SelectedContentPackage = new ContentPackage("");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
XElement graphicsMode = doc.Root.Element("graphicsmode");
|
||||
GraphicsWidth = int.Parse(graphicsMode.Attribute("width").Value);
|
||||
GraphicsHeight = int.Parse(graphicsMode.Attribute("height").Value);
|
||||
|
||||
FullScreenEnabled = graphicsMode.Attribute("fullscreen").Value == "true";
|
||||
|
||||
MasterServerUrl = ToolBox.GetAttributeString(doc.Root, "masterserverurl", "");
|
||||
|
||||
foreach (XElement subElement in doc.Root.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLower())
|
||||
{
|
||||
case "contentpackage":
|
||||
string path = ToolBox.GetAttributeString(subElement, "path", "");
|
||||
SelectedContentPackage = ContentPackage.list.Find(cp => cp.Path == path);
|
||||
|
||||
if (SelectedContentPackage == null) SelectedContentPackage = new ContentPackage(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Save(string filePath)
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace Subsurface.Items.Components
|
||||
public override bool Use(float deltaTime, Character character = null)
|
||||
{
|
||||
if (character == null) return false;
|
||||
if (!character.SecondaryKeyDown.State || reload > 0.0f) return false;
|
||||
if (!character.GetInputState(InputType.SecondaryHeld) || reload > 0.0f) return false;
|
||||
isActive = true;
|
||||
reload = 1.0f;
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ 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 (!character.GetInputState(InputType.SecondaryHeld)) return false;
|
||||
|
||||
if (DoesUseFail(character)) return false;
|
||||
|
||||
@@ -126,9 +126,6 @@ namespace Subsurface.Items.Components
|
||||
|
||||
if (targetBody == null || targetBody.UserData == null) return true;
|
||||
|
||||
//ApplyStatusEffects(ActionType.OnUse, 1.0f, character);
|
||||
|
||||
|
||||
Structure targetStructure;
|
||||
Limb targetLimb;
|
||||
Item targetItem;
|
||||
@@ -143,10 +140,19 @@ namespace Subsurface.Items.Components
|
||||
|
||||
targetStructure.AddDamage(sectionIndex, -structureFixAmount);
|
||||
|
||||
//if the next section is small enough, apply the effect to it as well
|
||||
//(to make it easier to fix a small "left-over" section)
|
||||
int nextSectionLength = targetStructure.SectionLength(sectionIndex + 1);
|
||||
if (nextSectionLength > 0 && nextSectionLength < Structure.wallSectionSize * 0.3f)
|
||||
{
|
||||
targetStructure.HighLightSection(sectionIndex + 1);
|
||||
targetStructure.AddDamage(sectionIndex + 1, -structureFixAmount);
|
||||
}
|
||||
|
||||
}
|
||||
else if ((targetLimb = (targetBody.UserData as Limb)) != null)
|
||||
{
|
||||
if (character.SecondaryKeyDown.State)
|
||||
if (character.GetInputState(InputType.SecondaryHeld))
|
||||
{
|
||||
targetLimb.character.Health += limbFixAmount;
|
||||
//isActive = true;
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Subsurface.Items.Components
|
||||
public override bool Use(float deltaTime, Character character = null)
|
||||
{
|
||||
if (character == null) return false;
|
||||
if (!character.SecondaryKeyDown.State || throwing) return false;
|
||||
if (!character.GetInputState(InputType.SecondaryHeld) || throwing) return false;
|
||||
|
||||
throwing = true;
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Subsurface.Items.Components
|
||||
if (!item.body.Enabled) return;
|
||||
if (!picker.HasSelectedItem(item)) isActive = false;
|
||||
|
||||
if (!picker.SecondaryKeyDown.State && !throwing) throwPos = 0.0f;
|
||||
if (!picker.GetInputState(InputType.SecondaryHeld) && !throwing) throwPos = 0.0f;
|
||||
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, picker);
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ namespace Subsurface.Items.Components
|
||||
case "sound":
|
||||
string filePath = ToolBox.GetAttributeString(subElement, "file", "");
|
||||
if (filePath=="") continue;
|
||||
if (!filePath.Contains("\\")) filePath = Path.GetDirectoryName(item.Prefab.ConfigFile)+"\\"+filePath;
|
||||
if (!filePath.Contains("/")) filePath = Path.GetDirectoryName(item.Prefab.ConfigFile)+"/"+filePath;
|
||||
|
||||
ActionType type;
|
||||
|
||||
@@ -594,7 +594,7 @@ namespace Subsurface.Items.Components
|
||||
try
|
||||
{
|
||||
// Get the type of a specified class.
|
||||
t = Type.GetType("Subsurface.Items.Components." + type + ", Subsurface", false, true);
|
||||
t = Type.GetType("Subsurface.Items.Components." + type + "", false, true);
|
||||
if (t == null)
|
||||
{
|
||||
if (errorMessages) DebugConsole.ThrowError("Could not find the component ''" + type + "'' (" + file + ")");
|
||||
|
||||
@@ -67,17 +67,17 @@ namespace Subsurface.Items.Components
|
||||
GUI.DrawRectangle(spriteBatch, hullRect, Color.White);
|
||||
}
|
||||
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (c.AnimController.CurrentHull!=null) continue;
|
||||
//foreach (Character c in Character.CharacterList)
|
||||
//{
|
||||
// if (c.AnimController.CurrentHull!=null) continue;
|
||||
|
||||
Rectangle characterRect = new Rectangle(
|
||||
miniMap.X + (int)((c.Position.X - Submarine.Borders.X) * size),
|
||||
miniMap.Y - (int)((c.Position.Y - Submarine.Borders.Y) * size),
|
||||
5, 5);
|
||||
// Rectangle characterRect = new Rectangle(
|
||||
// miniMap.X + (int)((c.Position.X - Submarine.Borders.X) * size),
|
||||
// miniMap.Y - (int)((c.Position.Y - Submarine.Borders.Y) * size),
|
||||
// 5, 5);
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, characterRect, Color.White, true);
|
||||
}
|
||||
// GUI.DrawRectangle(spriteBatch, characterRect, Color.White, true);
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Subsurface.Items.Components
|
||||
Hull hull1, hull2;
|
||||
|
||||
[HasDefaultValue(0.0f, true)]
|
||||
private float FlowPercentage
|
||||
public float FlowPercentage
|
||||
{
|
||||
get { return flowPercentage; }
|
||||
set
|
||||
@@ -116,21 +116,18 @@ namespace Subsurface.Items.Components
|
||||
item.NewComponentEvent(this, true);
|
||||
}
|
||||
|
||||
spriteBatch.DrawString(GUI.Font, "Flow percentage: " + (int)flowPercentage + " %", new Vector2(x + 20, y + 80), Color.White);
|
||||
|
||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 200, y + 70, 40, 40), "+", false))
|
||||
{
|
||||
FlowPercentage += 10.0f;
|
||||
item.NewComponentEvent(this, true);
|
||||
}
|
||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 250, y + 70, 40, 40), "-", false))
|
||||
spriteBatch.DrawString(GUI.Font, "Pumping speed: " + (int)flowPercentage + " %", new Vector2(x + 20, y + 80), Color.White);
|
||||
|
||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 200, y + 70, 40, 40), "OUT", false))
|
||||
{
|
||||
FlowPercentage -= 10.0f;
|
||||
item.NewComponentEvent(this, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (GUI.DrawButton(spriteBatch, new Rectangle(x + 250, y + 70, 40, 40), "IN", false))
|
||||
{
|
||||
FlowPercentage += 10.0f;
|
||||
item.NewComponentEvent(this, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ReceiveSignal(string signal, Connection connection, Item sender, float power=0.0f)
|
||||
|
||||
@@ -10,7 +10,7 @@ using System.Xml.Linq;
|
||||
|
||||
namespace Subsurface.Items.Components
|
||||
{
|
||||
class Steering : ItemComponent
|
||||
class Steering : Powered
|
||||
{
|
||||
private Vector2 currVelocity;
|
||||
private Vector2 targetVelocity;
|
||||
@@ -67,7 +67,9 @@ namespace Subsurface.Items.Components
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
base.Update(deltaTime, cam);
|
||||
//base.Update(deltaTime, cam);
|
||||
|
||||
//if (voltage < minVoltage) return;
|
||||
|
||||
if (autoPilot)
|
||||
{
|
||||
@@ -112,6 +114,8 @@ namespace Subsurface.Items.Components
|
||||
|
||||
public override void DrawHUD(SpriteBatch spriteBatch, Character character)
|
||||
{
|
||||
//if (voltage < minVoltage) return;
|
||||
|
||||
int width = GuiFrame.Rect.Width, height = GuiFrame.Rect.Height;
|
||||
int x = GuiFrame.Rect.X;
|
||||
int y = GuiFrame.Rect.Y;
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Subsurface.Items.Components
|
||||
{
|
||||
isActive = true;
|
||||
|
||||
barrelSprite = new Sprite(Path.GetDirectoryName(item.Prefab.ConfigFile) + "\\" +element.Attribute("barrelsprite").Value,
|
||||
barrelSprite = new Sprite(Path.GetDirectoryName(item.Prefab.ConfigFile) + "/" +element.Attribute("barrelsprite").Value,
|
||||
ToolBox.GetAttributeVector2(element, "origin", Vector2.Zero));
|
||||
}
|
||||
|
||||
@@ -99,23 +99,8 @@ namespace Subsurface.Items.Components
|
||||
}
|
||||
|
||||
rotation = MathUtils.CurveAngle(rotation, targetRotation, 0.05f);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//public override void SecondaryUse(float deltaTime, Character character = null)
|
||||
//{
|
||||
// if (character == null) return;
|
||||
|
||||
// Vector2 centerPos = new Vector2(item.Rect.X + barrelPos.X, item.Rect.Y - barrelPos.Y);
|
||||
|
||||
// if (character == Character.Controlled && cam!=null)
|
||||
// {
|
||||
// Lights.LightManager.ViewPos = centerPos;
|
||||
// cam.TargetPos = new Vector2(item.Rect.X + barrelPos.X, item.Rect.Y - barrelPos.Y);
|
||||
// }
|
||||
//}
|
||||
|
||||
public override bool Use(float deltaTime, Character character = null)
|
||||
{
|
||||
if (reload > 0.0f) return false;
|
||||
@@ -174,8 +159,6 @@ namespace Subsurface.Items.Components
|
||||
projectile.body.Enabled = true;
|
||||
projectile.SetTransform(ConvertUnits.ToSimUnits(new Vector2(item.Rect.X + barrelPos.X, item.Rect.Y - barrelPos.Y)), -rotation);
|
||||
|
||||
//if (useSounds.Count() > 0) useSounds[Game1.localRandom.Next(useSounds.Count())].Play(1.0f, 800.0f, item.body.FarseerBody);
|
||||
|
||||
projectileComponent.Use(deltaTime);
|
||||
item.RemoveContained(projectile);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Subsurface.Items.Components
|
||||
}
|
||||
|
||||
string spritePath = subElement.Attribute("texture").Value;
|
||||
spritePath = Path.GetDirectoryName( item.Prefab.ConfigFile)+"\\"+spritePath;
|
||||
spritePath = Path.GetDirectoryName( item.Prefab.ConfigFile)+"/"+spritePath;
|
||||
|
||||
var sprite = new Sprite(subElement, "", spritePath);
|
||||
wearableSprite[i] = new WearableSprite(sprite, ToolBox.GetAttributeBool(subElement, "hidelimb", false));
|
||||
|
||||
@@ -126,10 +126,10 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
public AITarget AiTarget
|
||||
{
|
||||
get { return aiTarget; }
|
||||
}
|
||||
//public override AITarget AiTarget
|
||||
//{
|
||||
// get { return aiTarget; }
|
||||
//}
|
||||
|
||||
public bool Updated
|
||||
{
|
||||
|
||||
@@ -129,12 +129,12 @@ namespace Subsurface
|
||||
|
||||
currBrightness -= 0.1f;
|
||||
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
light.Remove();
|
||||
|
||||
yield return Status.Success;
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,12 +249,20 @@ namespace Subsurface
|
||||
{
|
||||
pos.Y = ConvertUnits.ToSimUnits(MathHelper.Clamp(lowerSurface, rect.Y-rect.Height, rect.Y));
|
||||
|
||||
Game1.ParticleManager.CreateParticle("watersplash",
|
||||
var particle = Game1.ParticleManager.CreateParticle("watersplash",
|
||||
new Vector2(pos.X, pos.Y - Rand.Range(0.0f, 0.1f)),
|
||||
new Vector2(flowForce.X * Rand.Range(0.005f, 0.007f), flowForce.Y * Rand.Range(0.005f, 0.007f)));
|
||||
new Vector2(
|
||||
MathHelper.Clamp(flowForce.X, -5000.0f, 5000.0f) * Rand.Range(0.005f, 0.007f),
|
||||
flowForce.Y * Rand.Range(0.005f, 0.007f)));
|
||||
if (particle!=null)
|
||||
{
|
||||
particle.Size = particle.Size * Math.Abs(flowForce.X / 1000.0f);
|
||||
|
||||
}
|
||||
|
||||
pos.Y = ConvertUnits.ToSimUnits(Rand.Range(lowerSurface, rect.Y - rect.Height));
|
||||
Game1.ParticleManager.CreateParticle("bubbles", pos, flowForce / 200.0f);
|
||||
|
||||
Game1.ParticleManager.CreateParticle("bubbles", pos, flowForce / 200.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -312,7 +320,7 @@ namespace Subsurface
|
||||
flowTargetHull = hull1;
|
||||
|
||||
//make sure not to move more than what the room contains
|
||||
delta = Math.Min((hull2.Pressure - hull1.Pressure) * sizeModifier, Math.Min(hull2.Volume, hull2.FullVolume));
|
||||
delta = Math.Min((hull2.Pressure - hull1.Pressure) * 5.0f * sizeModifier, Math.Min(hull2.Volume, hull2.FullVolume));
|
||||
|
||||
//make sure not to place more water to the target room than it can hold
|
||||
delta = Math.Min(delta, hull1.FullVolume + Hull.MaxCompress - (hull1.Volume));
|
||||
@@ -331,7 +339,7 @@ namespace Subsurface
|
||||
flowTargetHull = hull2;
|
||||
|
||||
//make sure not to move more than what the room contains
|
||||
delta = Math.Min((hull1.Pressure - hull2.Pressure) * sizeModifier, Math.Min(hull1.Volume, hull1.FullVolume));
|
||||
delta = Math.Min((hull1.Pressure - hull2.Pressure) * 5.0f * sizeModifier, Math.Min(hull1.Volume, hull1.FullVolume));
|
||||
|
||||
//make sure not to place more water to the target room than it can hold
|
||||
delta = Math.Min(delta, hull2.FullVolume + Hull.MaxCompress - (hull2.Volume));
|
||||
@@ -405,7 +413,7 @@ namespace Subsurface
|
||||
flowTargetHull = hull2;
|
||||
|
||||
//make sure the amount of water moved isn't more than what the room contains
|
||||
float delta = Math.Min(hull1.Volume, deltaTime * 10000f * sizeModifier);
|
||||
float delta = Math.Min(hull1.Volume, deltaTime * 25000f * sizeModifier);
|
||||
//make sure not to place more water to the target room than it can hold
|
||||
delta = Math.Min(delta, (hull2.FullVolume + Math.Max(hull1.Volume - hull1.FullVolume, 0.0f)) - hull2.Volume + Hull.MaxCompress / 4.0f);
|
||||
|
||||
|
||||
@@ -122,8 +122,8 @@ namespace Subsurface
|
||||
|
||||
public static Level CreateRandom(LocationConnection locationConnection)
|
||||
{
|
||||
int seed = locationConnection.Locations[0].GetHashCode() | locationConnection.Locations[1].GetHashCode();
|
||||
return new Level(seed.ToString(), locationConnection.Difficulty, 100000, 40000, 2000);
|
||||
string seed = locationConnection.Locations[0].Name + locationConnection.Locations[1].Name;
|
||||
return new Level(seed, locationConnection.Difficulty, 100000, 40000, 2000);
|
||||
}
|
||||
|
||||
public static Level CreateRandom(string seed = "")
|
||||
@@ -153,7 +153,7 @@ namespace Subsurface
|
||||
|
||||
bodies = new List<Body>();
|
||||
|
||||
Random rand = new Random(seed.GetHashCode());
|
||||
Random rand = new Random(ToolBox.StringToInt(seed));
|
||||
|
||||
float siteVariance = siteInterval * 0.8f;
|
||||
for (int x = siteInterval / 2; x < borders.Width; x += siteInterval)
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace Subsurface.Lights
|
||||
shadowEffect.TextureEnabled = true;
|
||||
//shadowEffect.VertexColorEnabled = true;
|
||||
shadowEffect.LightingEnabled = false;
|
||||
shadowEffect.Texture = Game1.TextureLoader.FromFile("Content/lights/penumbra.png");
|
||||
shadowEffect.Texture = Game1.TextureLoader.FromFile("Content/Lights/penumbra.png");
|
||||
}
|
||||
|
||||
//compute facing of each edge, using N*L
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Subsurface
|
||||
if (iceCraters == null) iceCraters = Game1.TextureLoader.FromFile("Content/Map/iceCraters.png");
|
||||
if (iceCrack == null) iceCrack = Game1.TextureLoader.FromFile("Content/Map/iceCrack.png");
|
||||
|
||||
Rand.SetSyncedSeed(this.seed.GetHashCode());
|
||||
Rand.SetSyncedSeed(ToolBox.StringToInt(this.seed));
|
||||
|
||||
GenerateLocations();
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace Subsurface
|
||||
newLocations[i] = Location.CreateRandom(position);
|
||||
locations.Add(newLocations[i]);
|
||||
}
|
||||
int seed = (newLocations[0].GetHashCode() | newLocations[1].GetHashCode());
|
||||
//int seed = (newLocations[0].GetHashCode() | newLocations[1].GetHashCode());
|
||||
connections.Add(new LocationConnection(newLocations[0], newLocations[1]));
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,11 @@ namespace Subsurface
|
||||
shortHash = GetShortHash(hash);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return hash;
|
||||
}
|
||||
|
||||
private string CalculateHash(FileStream stream)
|
||||
{
|
||||
MD5 md5 = MD5.Create();
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Subsurface
|
||||
|
||||
class Structure : MapEntity, IDamageable
|
||||
{
|
||||
static int wallSectionSize = 100;
|
||||
public static int wallSectionSize = 100;
|
||||
public static List<Structure> wallList = new List<Structure>();
|
||||
|
||||
ConvexHull convexHull;
|
||||
@@ -97,12 +97,7 @@ namespace Subsurface
|
||||
{
|
||||
get { return prefab.MaxHealth; }
|
||||
}
|
||||
|
||||
public AITarget AiTarget
|
||||
{
|
||||
get { return null;}
|
||||
}
|
||||
|
||||
|
||||
public override void Move(Vector2 amount)
|
||||
{
|
||||
base.Move(amount);
|
||||
@@ -368,6 +363,20 @@ namespace Subsurface
|
||||
return (sections[sectionIndex].damage>=prefab.MaxHealth);
|
||||
}
|
||||
|
||||
public bool SectionIsLeaking(int sectionIndex)
|
||||
{
|
||||
if (sectionIndex < 0 || sectionIndex >= sections.Length) return false;
|
||||
|
||||
return (sections[sectionIndex].damage >= prefab.MaxHealth*0.5f);
|
||||
}
|
||||
|
||||
public int SectionLength(int sectionIndex)
|
||||
{
|
||||
if (sectionIndex < 0 || sectionIndex >= sections.Length) return 0;
|
||||
|
||||
return (isHorizontal ? sections[sectionIndex].rect.Width : sections[sectionIndex].rect.Height);
|
||||
}
|
||||
|
||||
public void AddDamage(int sectionIndex, float damage)
|
||||
{
|
||||
if (!prefab.HasBody || prefab.IsPlatform) return;
|
||||
@@ -428,7 +437,7 @@ namespace Subsurface
|
||||
if (!prefab.HasBody) return;
|
||||
|
||||
if (damage != sections[sectionIndex].damage)
|
||||
new NetworkEvent(ID, false);
|
||||
new NetworkEvent(NetworkEventType.UpdateEntity, ID, false, sectionIndex);
|
||||
|
||||
if (damage < prefab.MaxHealth*0.5f)
|
||||
{
|
||||
@@ -615,19 +624,40 @@ namespace Subsurface
|
||||
|
||||
public override void FillNetworkData(NetworkEventType type, NetOutgoingMessage message, object data)
|
||||
{
|
||||
for (int i = 0; i < sections.Length; i++ )
|
||||
int sectionIndex = 0;
|
||||
byte byteIndex = 0;
|
||||
|
||||
try
|
||||
{
|
||||
message.Write(sections[i].damage);
|
||||
sectionIndex = (int)data;
|
||||
byteIndex = (byte)sectionIndex;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
message.Write(byteIndex);
|
||||
message.Write(sections[sectionIndex].damage);
|
||||
}
|
||||
|
||||
public override void ReadNetworkData(NetworkEventType type, NetIncomingMessage message)
|
||||
{
|
||||
for (int i = 0; i < sections.Length; i++)
|
||||
int sectionIndex = 0;
|
||||
float damage = 0.0f;
|
||||
|
||||
try
|
||||
{
|
||||
float damage = message.ReadFloat();
|
||||
if (damage != sections[i].damage) SetDamage(i, damage);
|
||||
sectionIndex = message.ReadByte();
|
||||
damage = message.ReadFloat();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetDamage(sectionIndex, damage);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Subsurface
|
||||
private set;
|
||||
}
|
||||
|
||||
public Md5Hash Hash
|
||||
public Md5Hash MD5Hash
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -115,6 +115,11 @@ namespace Subsurface
|
||||
public Vector2 Speed
|
||||
{
|
||||
get { return speed; }
|
||||
set
|
||||
{
|
||||
if (!MathUtils.IsValid(value)) return;
|
||||
speed = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string FilePath
|
||||
@@ -773,7 +778,7 @@ namespace Subsurface
|
||||
try
|
||||
{
|
||||
// Get the type of a specified class.
|
||||
t = Type.GetType("Subsurface." + typeName + ", Subsurface", true, true);
|
||||
t = Type.GetType("Subsurface." + typeName, true, true);
|
||||
if (t == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error in " + filePath + "! Could not find a entity of the type ''" + typeName + "''.");
|
||||
|
||||
@@ -56,8 +56,13 @@ namespace Subsurface
|
||||
//vertexBuffer.SetData(vertices);
|
||||
|
||||
//effect = Game1.game.Content.Load<Effect>("effects");
|
||||
#if WINDOWS
|
||||
byte[] bytecode = File.ReadAllBytes("Content/effects.mgfx");
|
||||
#endif
|
||||
#if LINUX
|
||||
byte[] bytecode = File.ReadAllBytes("Content/effects_linux.mgfx");
|
||||
#endif
|
||||
|
||||
byte[] bytecode = File.ReadAllBytes("Content/effects.mgfx");
|
||||
effect = new Effect(graphicsDevice, bytecode);
|
||||
|
||||
//Texture2D waterBumpMap = Game1.textureLoader.FromFile("Content/waterbump.jpg");
|
||||
|
||||
@@ -10,9 +10,6 @@ namespace Subsurface.Networking
|
||||
{
|
||||
private NetClient client;
|
||||
|
||||
private Character myCharacter;
|
||||
private CharacterInfo characterInfo;
|
||||
|
||||
private GUIMessageBox reconnectBox;
|
||||
|
||||
private bool connected;
|
||||
@@ -23,17 +20,6 @@ namespace Subsurface.Networking
|
||||
|
||||
private string serverIP;
|
||||
|
||||
public Character Character
|
||||
{
|
||||
get { return myCharacter; }
|
||||
set { myCharacter = value; }
|
||||
}
|
||||
|
||||
public CharacterInfo CharacterInfo
|
||||
{
|
||||
get { return characterInfo; }
|
||||
}
|
||||
|
||||
public int ID
|
||||
{
|
||||
get { return myID; }
|
||||
@@ -56,7 +42,7 @@ namespace Subsurface.Networking
|
||||
if (address.Length==1)
|
||||
{
|
||||
serverIP = hostIP;
|
||||
Port = DefaultPort;
|
||||
Port = NetConfig.DefaultPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -65,7 +51,7 @@ namespace Subsurface.Networking
|
||||
if (!int.TryParse(address[1], out Port))
|
||||
{
|
||||
DebugConsole.ThrowError("Invalid port: "+address[1]+"!");
|
||||
Port = DefaultPort;
|
||||
Port = NetConfig.DefaultPort;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,10 +137,10 @@ namespace Subsurface.Networking
|
||||
|
||||
DateTime timeOut = DateTime.Now + new TimeSpan(0,0,15);
|
||||
|
||||
// Loop untill we are approved
|
||||
// Loop until we are approved
|
||||
while (!CanStart)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
if (DateTime.Now > timeOut) break;
|
||||
|
||||
@@ -171,7 +157,7 @@ namespace Subsurface.Networking
|
||||
if (packetType == (byte)PacketTypes.LoggedIn)
|
||||
{
|
||||
myID = inc.ReadInt32();
|
||||
if (inc.ReadBoolean())
|
||||
if (inc.ReadBoolean() && Screen.Selected != Game1.GameScreen)
|
||||
{
|
||||
new GUIMessageBox("Please wait", "A round is already running. You will have to wait for a new round to start.");
|
||||
}
|
||||
@@ -234,11 +220,11 @@ namespace Subsurface.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Screen.Selected == Game1.MainMenuScreen) Game1.NetLobbyScreen.Select();
|
||||
if (Screen.Selected != Game1.GameScreen) Game1.NetLobbyScreen.Select();
|
||||
connected = true;
|
||||
}
|
||||
|
||||
yield return Status.Success;
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
@@ -274,17 +260,7 @@ namespace Subsurface.Networking
|
||||
}
|
||||
else if (gameStarted)
|
||||
{
|
||||
Vector2 charMovement = myCharacter.AnimController.TargetMovement;
|
||||
if ((charMovement==Vector2.Zero || charMovement.Length()<0.001f) &&
|
||||
!myCharacter.ActionKeyDown.State && !myCharacter.SecondaryKeyDown.State)
|
||||
{
|
||||
new NetworkEvent(NetworkEventType.NotMoving, myCharacter.ID, true);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
new NetworkEvent(myCharacter.ID, true);
|
||||
}
|
||||
new NetworkEvent(myCharacter.ID, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,7 +311,7 @@ namespace Subsurface.Networking
|
||||
if (this.Character != null) Character.Remove();
|
||||
|
||||
int seed = inc.ReadInt32();
|
||||
Rand.SetSyncedSeed(seed);
|
||||
|
||||
|
||||
string levelSeed = inc.ReadString();
|
||||
|
||||
@@ -347,7 +323,7 @@ namespace Subsurface.Networking
|
||||
double durationMinutes = inc.ReadDouble();
|
||||
|
||||
TimeSpan duration = new TimeSpan(0,(int)durationMinutes,0);
|
||||
|
||||
Rand.SetSyncedSeed(seed);
|
||||
//int gameModeIndex = inc.ReadInt32();
|
||||
Game1.GameSession = new GameSession(Submarine.Loaded, "", Game1.NetLobbyScreen.SelectedMode);
|
||||
Game1.GameSession.StartShift(duration, levelSeed);
|
||||
@@ -456,7 +432,7 @@ namespace Subsurface.Networking
|
||||
//Game1.GameScreen.Cam.MoveCamera((float)deltaTime);
|
||||
|
||||
messageBox.Text = endMessage + "\nReturning to lobby in " + (int)secondsLeft + " s";
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
} while (secondsLeft > 0.0f);
|
||||
|
||||
messageBox.Text = endMessage;
|
||||
@@ -469,7 +445,7 @@ namespace Subsurface.Networking
|
||||
|
||||
myCharacter = null;
|
||||
|
||||
yield return Status.Success;
|
||||
yield return CoroutineStatus.Success;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -13,10 +13,12 @@ namespace Subsurface.Networking
|
||||
|
||||
public List<Client> connectedClients = new List<Client>();
|
||||
|
||||
bool started;
|
||||
|
||||
private NetServer server;
|
||||
private NetPeerConfiguration config;
|
||||
|
||||
private TimeSpan SparseUpdateInterval = new TimeSpan(0, 0, 0, 1);
|
||||
private TimeSpan SparseUpdateInterval = new TimeSpan(0, 0, 0, 3);
|
||||
private DateTime sparseUpdateTimer;
|
||||
|
||||
private TimeSpan refreshMasterInterval = new TimeSpan(0, 0, 40);
|
||||
@@ -36,7 +38,6 @@ namespace Subsurface.Networking
|
||||
endRoundButton.OnClicked = EndButtonHit;
|
||||
|
||||
this.name = name;
|
||||
|
||||
this.password = password;
|
||||
|
||||
config = new NetPeerConfiguration("subsurface");
|
||||
@@ -45,7 +46,6 @@ namespace Subsurface.Networking
|
||||
config.SimulatedLoss = 0.2f;
|
||||
config.SimulatedMinimumLatency = 0.3f;
|
||||
#endif
|
||||
|
||||
config.Port = port;
|
||||
Port = port;
|
||||
|
||||
@@ -56,25 +56,52 @@ namespace Subsurface.Networking
|
||||
|
||||
config.MaximumConnections = maxPlayers;
|
||||
|
||||
config.DisableMessageType(NetIncomingMessageType.DebugMessage | NetIncomingMessageType.WarningMessage | NetIncomingMessageType.Receipt
|
||||
| NetIncomingMessageType.ErrorMessage | NetIncomingMessageType.Error);
|
||||
config.DisableMessageType(NetIncomingMessageType.DebugMessage |
|
||||
NetIncomingMessageType.WarningMessage | NetIncomingMessageType.Receipt |
|
||||
NetIncomingMessageType.ErrorMessage | NetIncomingMessageType.Error);
|
||||
|
||||
config.EnableMessageType(NetIncomingMessageType.ConnectionApproval);
|
||||
|
||||
|
||||
CoroutineManager.StartCoroutine(StartServer(isPublic));
|
||||
}
|
||||
|
||||
private IEnumerable<object> StartServer(bool isPublic)
|
||||
{
|
||||
try
|
||||
{
|
||||
server = new NetServer(config);
|
||||
server = new NetServer(config);
|
||||
server.Start();
|
||||
|
||||
if (attemptUPnP)
|
||||
{
|
||||
server.UPnP.ForwardPort(port, "subsurface");
|
||||
}
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Couldn't start the server", e);
|
||||
DebugConsole.ThrowError("Couldn't start the server", e);
|
||||
}
|
||||
|
||||
|
||||
if (config.EnableUPnP)
|
||||
{
|
||||
server.UPnP.ForwardPort(config.Port, "subsurface");
|
||||
|
||||
GUIMessageBox upnpBox = new GUIMessageBox("Please wait...", "Attempting UPnP port forwarding", new string[] {"Cancel"} );
|
||||
upnpBox.Buttons[0].OnClicked = upnpBox.Close;
|
||||
|
||||
DateTime upnpTimeout = DateTime.Now + new TimeSpan(0,0,5);
|
||||
while (server.UPnP.Status == UPnPStatus.Discovering
|
||||
&& GUIMessageBox.VisibleBox == upnpBox)// && upnpTimeout>DateTime.Now)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
upnpBox.Close(null,null);
|
||||
|
||||
if (server.UPnP.Status == UPnPStatus.NotAvailable)
|
||||
{
|
||||
new GUIMessageBox("Error", "UPnP not available");
|
||||
}
|
||||
else if (server.UPnP.Status == UPnPStatus.Discovering)
|
||||
{
|
||||
new GUIMessageBox("Error", "UPnP discovery timed out");
|
||||
}
|
||||
}
|
||||
|
||||
if (isPublic)
|
||||
@@ -86,11 +113,15 @@ namespace Subsurface.Networking
|
||||
updateInterval = new TimeSpan(0, 0, 0, 0, 30);
|
||||
|
||||
DebugConsole.NewMessage("Server started", Color.Green);
|
||||
|
||||
Game1.NetLobbyScreen.Select();
|
||||
started = true;
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
private void RegisterToMasterServer()
|
||||
{
|
||||
var client = new RestClient(NetworkMember.MasterServerUrl);
|
||||
var client = new RestClient(NetConfig.MasterServerUrl);
|
||||
|
||||
var request = new RestRequest("masterserver.php", Method.GET);
|
||||
request.AddParameter("action", "addserver");
|
||||
@@ -120,7 +151,7 @@ namespace Subsurface.Networking
|
||||
|
||||
private IEnumerable<object> RefreshMaster()
|
||||
{
|
||||
var client = new RestClient(NetworkMember.MasterServerUrl);
|
||||
var client = new RestClient(NetConfig.MasterServerUrl);
|
||||
|
||||
var request = new RestRequest("masterserver.php", Method.GET);
|
||||
request.AddParameter("action", "refreshserver");
|
||||
@@ -146,10 +177,10 @@ namespace Subsurface.Networking
|
||||
}
|
||||
System.Diagnostics.Debug.WriteLine("took "+sw.ElapsedMilliseconds+" ms");
|
||||
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
yield return Status.Success;
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
private void MasterServerCallBack(IRestResponse response)
|
||||
@@ -173,6 +204,8 @@ namespace Subsurface.Networking
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
if (!started) return;
|
||||
|
||||
base.Update(deltaTime);
|
||||
|
||||
if (gameStarted) inGameHUD.Update((float)Physics.step);
|
||||
@@ -298,7 +331,7 @@ namespace Subsurface.Networking
|
||||
}
|
||||
|
||||
int id = 1;
|
||||
while (connectedClients.Find(c=>c.ID==id)!=null)
|
||||
while (connectedClients.Find(c => c.ID==id)!=null)
|
||||
{
|
||||
id++;
|
||||
}
|
||||
@@ -458,26 +491,17 @@ namespace Subsurface.Networking
|
||||
|
||||
List<NetConnection> recipients = new List<NetConnection>();
|
||||
|
||||
if (!networkEvent.IsImportant)
|
||||
{
|
||||
Entity e = Entity.FindEntityByID(networkEvent.ID);
|
||||
foreach (Client c in connectedClients)
|
||||
{
|
||||
if (c.character==null) continue;
|
||||
if (Vector2.Distance(e.SimPosition, c.character.SimPosition) > 2000.0f) continue;
|
||||
|
||||
recipients.Add(c.Connection);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (Client c in connectedClients)
|
||||
{
|
||||
if (c.character == null) continue;
|
||||
//if (networkEvent.Type == NetworkEventType.UpdateEntity &&
|
||||
// Vector2.Distance(e.SimPosition, c.character.SimPosition) > NetConfig.UpdateEntityDistance) continue;
|
||||
|
||||
recipients.Add(c.Connection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (recipients.Count == 0) return;
|
||||
|
||||
@@ -510,13 +534,14 @@ namespace Subsurface.Networking
|
||||
return false;
|
||||
}
|
||||
|
||||
int seed = DateTime.Now.Millisecond;
|
||||
Rand.SetSyncedSeed(seed);
|
||||
|
||||
|
||||
AssignJobs();
|
||||
|
||||
//selectedMap.Load();
|
||||
|
||||
int seed = DateTime.Now.Millisecond;
|
||||
Rand.SetSyncedSeed(seed);
|
||||
Game1.GameSession = new GameSession(selectedMap, "", Game1.NetLobbyScreen.SelectedMode);
|
||||
Game1.GameSession.StartShift(Game1.NetLobbyScreen.GameDuration, Game1.NetLobbyScreen.LevelSeed);
|
||||
//EventManager.SelectEvent(Game1.netLobbyScreen.SelectedEvent);
|
||||
@@ -570,7 +595,7 @@ namespace Subsurface.Networking
|
||||
msg.Write(Game1.NetLobbyScreen.LevelSeed);
|
||||
|
||||
msg.Write(Game1.NetLobbyScreen.SelectedMap.Name);
|
||||
msg.Write(Game1.NetLobbyScreen.SelectedMap.Hash.Hash);
|
||||
msg.Write(Game1.NetLobbyScreen.SelectedMap.MD5Hash.Hash);
|
||||
|
||||
msg.Write(Game1.NetLobbyScreen.GameDuration.TotalMinutes);
|
||||
|
||||
@@ -651,7 +676,7 @@ namespace Subsurface.Networking
|
||||
Game1.GameScreen.Cam.TargetPos = offset * 0.8f;
|
||||
//Game1.GameScreen.Cam.MoveCamera((float)deltaTime);
|
||||
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
} while (secondsLeft > 0.0f);
|
||||
|
||||
Submarine.Unload();
|
||||
@@ -660,7 +685,7 @@ namespace Subsurface.Networking
|
||||
|
||||
DebugConsole.ThrowError(endMessage);
|
||||
|
||||
yield return Status.Success;
|
||||
yield return CoroutineStatus.Success;
|
||||
|
||||
}
|
||||
|
||||
@@ -674,7 +699,7 @@ namespace Subsurface.Networking
|
||||
{
|
||||
if (client == null) return;
|
||||
|
||||
if (gameStarted && client.character != null) client.character.Kill(true);
|
||||
if (gameStarted && client.character != null) client.character.ClearInputs();
|
||||
|
||||
if (msg == "") msg = client.name + " has left the server";
|
||||
if (targetmsg == "") targetmsg = "You have left the server";
|
||||
@@ -742,7 +767,7 @@ namespace Subsurface.Networking
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(x,y,width,height), Color.Black*0.7f, true);
|
||||
spriteBatch.DrawString(GUI.Font, "Network statistics:", new Vector2(x+10, y+10), Color.White);
|
||||
|
||||
|
||||
spriteBatch.DrawString(GUI.SmallFont, "Connections: "+server.ConnectionsCount, new Vector2(x + 10, y + 30), Color.White);
|
||||
spriteBatch.DrawString(GUI.SmallFont, "Received bytes: " + server.Statistics.ReceivedBytes, new Vector2(x + 10, y + 45), Color.White);
|
||||
spriteBatch.DrawString(GUI.SmallFont, "Received packets: " + server.Statistics.ReceivedPackets, new Vector2(x + 10, y + 60), Color.White);
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Subsurface.Networking
|
||||
{
|
||||
static class NetConfig
|
||||
{
|
||||
public const int DefaultPort = 14242;
|
||||
|
||||
//UpdateEntity networkevents aren't sent to clients if they're further than this from the entity
|
||||
public const float UpdateEntityDistance = 2500.0f;
|
||||
|
||||
public static string MasterServerUrl = Game1.Config.MasterServerUrl;
|
||||
|
||||
//if a ragdoll is further than this from the correct position, teleport it there
|
||||
//(in sim units)
|
||||
public const float ResetRagdollDistance = 2.0f;
|
||||
|
||||
//if the ragdoll is closer than this, don't try to correct its position
|
||||
public const float AllowedRagdollDistance = 0.1f;
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,7 @@ namespace Subsurface.Networking
|
||||
DropItem = 3,
|
||||
InventoryUpdate = 4,
|
||||
PickItem = 5,
|
||||
UpdateProperty = 6,
|
||||
NotMoving = 7
|
||||
UpdateProperty = 6
|
||||
}
|
||||
|
||||
class NetworkEvent
|
||||
@@ -46,6 +45,11 @@ namespace Subsurface.Networking
|
||||
get { return isImportant[(int)eventType]; }
|
||||
}
|
||||
|
||||
public NetworkEventType Type
|
||||
{
|
||||
get { return eventType; }
|
||||
}
|
||||
|
||||
public NetworkEvent(int id, bool isClient)
|
||||
: this(NetworkEventType.UpdateEntity, id, isClient)
|
||||
{
|
||||
@@ -64,9 +68,9 @@ namespace Subsurface.Networking
|
||||
|
||||
eventType = type;
|
||||
|
||||
foreach (NetworkEvent e in events)
|
||||
if (!isImportant[(int)type])
|
||||
{
|
||||
if (!isImportant[(int)type] && e.id == id && e.eventType == type) return;
|
||||
if (events.Find(e => e.id == id && e.eventType == type) != null) return;
|
||||
}
|
||||
|
||||
this.id = id;
|
||||
|
||||
@@ -31,9 +31,6 @@ namespace Subsurface.Networking
|
||||
|
||||
class NetworkMember
|
||||
{
|
||||
public const int DefaultPort = 14242;
|
||||
|
||||
public static string MasterServerUrl = Game1.Config.MasterServerUrl;
|
||||
|
||||
protected static Color[] messageColor = { Color.White, Color.Red, Color.LightBlue, Color.LightGreen };
|
||||
|
||||
@@ -54,6 +51,21 @@ namespace Subsurface.Networking
|
||||
|
||||
protected bool gameStarted;
|
||||
|
||||
protected Character myCharacter;
|
||||
protected CharacterInfo characterInfo;
|
||||
|
||||
public Character Character
|
||||
{
|
||||
get { return myCharacter; }
|
||||
set { myCharacter = value; }
|
||||
}
|
||||
|
||||
public CharacterInfo CharacterInfo
|
||||
{
|
||||
get { return characterInfo; }
|
||||
set { characterInfo = value; }
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return name; }
|
||||
|
||||
@@ -32,9 +32,9 @@ namespace Subsurface.Particles
|
||||
|
||||
private float checkCollisionTimer;
|
||||
|
||||
public bool InWater
|
||||
public ParticlePrefab.DrawTargetType DrawTarget
|
||||
{
|
||||
get { return prefab.inWater; }
|
||||
get { return prefab.DrawTarget; }
|
||||
}
|
||||
|
||||
public Vector2 yLimits
|
||||
|
||||
@@ -95,14 +95,15 @@ namespace Subsurface.Particles
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, bool inWater)
|
||||
{
|
||||
ParticlePrefab.DrawTargetType drawTarget = inWater ? ParticlePrefab.DrawTargetType.Water : ParticlePrefab.DrawTargetType.Air;
|
||||
|
||||
for (int i = 0; i < particleCount; i++)
|
||||
{
|
||||
if (particles[i].InWater != inWater) continue;
|
||||
if (!particles[i].DrawTarget.HasFlag(drawTarget)) continue;
|
||||
|
||||
particles[i].Draw(spriteBatch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace Subsurface.Particles
|
||||
{
|
||||
class ParticlePrefab
|
||||
{
|
||||
public enum DrawTargetType { Air = 1, Water = 2, Both = 3 }
|
||||
|
||||
public readonly string name;
|
||||
|
||||
public readonly Sprite sprite;
|
||||
@@ -27,7 +29,7 @@ namespace Subsurface.Particles
|
||||
|
||||
public readonly Vector2 velocityChange;
|
||||
|
||||
public readonly bool inWater;
|
||||
public readonly DrawTargetType DrawTarget;
|
||||
|
||||
public readonly bool rotateToDirection;
|
||||
|
||||
@@ -67,8 +69,20 @@ namespace Subsurface.Particles
|
||||
|
||||
rotateToDirection = ToolBox.GetAttributeBool(element, "rotatetodirection", false);
|
||||
|
||||
inWater = ToolBox.GetAttributeBool(element, "inwater", false);
|
||||
|
||||
switch (ToolBox.GetAttributeString(element, "drawtarget", "air").ToLower())
|
||||
{
|
||||
case "air":
|
||||
default:
|
||||
DrawTarget = DrawTargetType.Air;
|
||||
break;
|
||||
case "water":
|
||||
DrawTarget = DrawTargetType.Water;
|
||||
break;
|
||||
case "both":
|
||||
DrawTarget = DrawTargetType.Both;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Subsurface
|
||||
get { return targetPosition; }
|
||||
set
|
||||
{
|
||||
if (float.IsNaN(value.X) || float.IsNaN(value.Y)) return;
|
||||
if (!MathUtils.IsValid(value)) return;
|
||||
targetPosition.X = MathHelper.Clamp(value.X, -10000.0f, 10000.0f);
|
||||
targetPosition.Y = MathHelper.Clamp(value.Y, -10000.0f, 10000.0f);
|
||||
}
|
||||
@@ -60,7 +60,7 @@ namespace Subsurface
|
||||
get { return targetVelocity; }
|
||||
set
|
||||
{
|
||||
if (float.IsNaN(value.X) || float.IsNaN(value.Y)) return;
|
||||
if (!MathUtils.IsValid(value)) return;
|
||||
targetVelocity.X = MathHelper.Clamp(value.X, -100.0f, 100.0f);
|
||||
targetVelocity.Y = MathHelper.Clamp(value.Y, -100.0f, 100.0f);
|
||||
}
|
||||
@@ -71,7 +71,7 @@ namespace Subsurface
|
||||
get { return targetRotation; }
|
||||
set
|
||||
{
|
||||
if (float.IsNaN(value) || float.IsInfinity(value)) return;
|
||||
if (!MathUtils.IsValid(value)) return;
|
||||
targetRotation = value;
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ namespace Subsurface
|
||||
get { return targetAngularVelocity; }
|
||||
set
|
||||
{
|
||||
if (float.IsNaN(value) || float.IsInfinity(value)) return;
|
||||
if (!MathUtils.IsValid(value)) return;
|
||||
targetAngularVelocity = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,25 @@ using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
|
||||
public enum InputType
|
||||
{
|
||||
Select,
|
||||
ActionHit, ActionHeld,
|
||||
SecondaryHit, SecondaryHeld,
|
||||
Left, Right, Up, Down,
|
||||
Run
|
||||
}
|
||||
|
||||
class Key
|
||||
{
|
||||
private bool state, stateQueue;
|
||||
private bool canBeHeld;
|
||||
|
||||
public bool CanBeHeld
|
||||
{
|
||||
get { return canBeHeld; }
|
||||
}
|
||||
|
||||
public Key(bool canBeHeld)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
#region Using Statements
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using System.Management;
|
||||
using System.Windows.Forms;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -19,7 +25,73 @@ namespace Subsurface
|
||||
static void Main()
|
||||
{
|
||||
using (var game = new Game1())
|
||||
game.Run();
|
||||
{
|
||||
#if !DEBUG
|
||||
try
|
||||
{
|
||||
#endif
|
||||
|
||||
game.Run();
|
||||
#if !DEBUG
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
CrashDump(game, "crashreport.txt", e);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void CrashDump(Game1 game, string filePath, Exception exception)
|
||||
{
|
||||
StreamWriter sw = new StreamWriter(filePath);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine("Subsurface crash report (generated on " + DateTime.Now + ")");
|
||||
sb.AppendLine("\n");
|
||||
sb.AppendLine("Subsurface seems to have crashed. Sorry for the inconvenience! ");
|
||||
sb.AppendLine("If you'd like to help fix the bug that caused the crash, please send this file to the developers on the Undertow Games forums.");
|
||||
sb.AppendLine("\n");
|
||||
sb.AppendLine("Subsurface version " + Game1.Version);
|
||||
sb.AppendLine("Selected content package: "+Game1.SelectedPackage.Name);
|
||||
sb.AppendLine("Level seed: "+ ((Level.Loaded == null) ? "no level loaded" : Level.Loaded.Seed));
|
||||
sb.AppendLine("Loaded submarine: " + ((Submarine.Loaded == null) ? "none" : Submarine.Loaded.Name +" ("+Submarine.Loaded.MD5Hash+")"));
|
||||
sb.AppendLine("Selected screen: " + Screen.Selected.ToString());
|
||||
|
||||
if (Game1.Server != null)
|
||||
{
|
||||
sb.AppendLine("Server (" +(Game1.Server.GameStarted ? "Round had started" : "Round hand't been started"));
|
||||
}
|
||||
else if (Game1.Client != null)
|
||||
{
|
||||
sb.AppendLine("Server (" +(Game1.Client.GameStarted ? "Round had started" : "Round hand't been started"));
|
||||
}
|
||||
|
||||
sb.AppendLine("\n");
|
||||
sb.AppendLine("System info:");
|
||||
sb.AppendLine(" Operating system: " + System.Environment.OSVersion + (System.Environment.Is64BitOperatingSystem ? " 64 bit" : " x86"));
|
||||
sb.AppendLine(" Graphics device handle: " + game.GraphicsDevice.Handle.ToString());
|
||||
sb.AppendLine("\n");
|
||||
sb.AppendLine("Exception: "+exception.Message);
|
||||
sb.AppendLine("Target site: " +exception.TargetSite.ToString());
|
||||
sb.AppendLine("Stack trace: ");
|
||||
sb.AppendLine(exception.StackTrace);
|
||||
sb.AppendLine("\n");
|
||||
|
||||
sb.AppendLine("Last debug messages:");
|
||||
for (int i = DebugConsole.messages.Count - 1; i > 0 && i > DebugConsole.messages.Count - 10; i-- )
|
||||
{
|
||||
sb.AppendLine(" "+DebugConsole.messages[i].Time+" - "+DebugConsole.messages[i].Text);
|
||||
}
|
||||
|
||||
|
||||
sw.WriteLine(sb.ToString());
|
||||
|
||||
MessageBox.Show( "A crash report (''crashreport.txt'') was saved in the root folder of the game."+
|
||||
" If you'd like to help fix this bug, please make a bug report on the Undertow Games forum with the report attached.",
|
||||
"Oops! Subsurface just crashed.", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
|
||||
sw.Close();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace Subsurface
|
||||
|
||||
new GUITextBlock(new Rectangle(0, 100, 0, 30), "Server port:", GUI.style, Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tabs.HostServer]);
|
||||
portBox = new GUITextBox(new Rectangle(160, 100, 200, 30), null, null, Alignment.TopLeft, Alignment.Left, GUI.style, menuTabs[(int)Tabs.HostServer]);
|
||||
portBox.Text = NetworkMember.DefaultPort.ToString();
|
||||
portBox.Text = NetConfig.DefaultPort.ToString();
|
||||
portBox.ToolTip = "Server port";
|
||||
|
||||
new GUITextBlock(new Rectangle(0, 150, 100, 30), "Max players:", GUI.style, Alignment.TopLeft, Alignment.Left, menuTabs[(int)Tabs.HostServer]);
|
||||
@@ -210,7 +210,7 @@ namespace Subsurface
|
||||
int port;
|
||||
if (!int.TryParse(portBox.Text, out port) || port < 0 || port > 65535)
|
||||
{
|
||||
portBox.Text = NetworkMember.DefaultPort.ToString();
|
||||
portBox.Text = NetConfig.DefaultPort.ToString();
|
||||
portBox.Flash();
|
||||
|
||||
return false;
|
||||
@@ -219,7 +219,7 @@ namespace Subsurface
|
||||
Game1.NetworkMember = new GameServer(name, port, isPublicBox.Selected, passwordBox.Text, useUpnpBox.Selected, int.Parse(maxPlayersBox.Text));
|
||||
|
||||
Game1.NetLobbyScreen.IsServer = true;
|
||||
Game1.NetLobbyScreen.Select();
|
||||
//Game1.NetLobbyScreen.Select();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -320,7 +320,7 @@ namespace Subsurface
|
||||
}
|
||||
|
||||
private void RemoveSaveFrame()
|
||||
{
|
||||
{
|
||||
GUIComponent prevFrame = null;
|
||||
foreach (GUIComponent child in menuTabs[(int)Tabs.LoadGame].children)
|
||||
{
|
||||
|
||||
@@ -279,23 +279,44 @@ namespace Subsurface
|
||||
durationBar.OnMoved = Game1.Server.UpdateNetLobby;
|
||||
|
||||
if (subList.CountChildren > 0) subList.Select(-1);
|
||||
if (GameModePreset.list.Count > 0) modeList.Select(0);
|
||||
if (GameModePreset.list.Count > 0) modeList.Select(0);
|
||||
|
||||
var playYourself = new GUITickBox(new Rectangle(0, -20, 20, 20), "Play yourself", Alignment.TopLeft, playerFrame);
|
||||
playYourself.OnSelected = TogglePlayYourself;
|
||||
}
|
||||
else if (playerFrame.children.Count==0)
|
||||
{
|
||||
else
|
||||
{
|
||||
UpdatePlayerFrame(Game1.Client.CharacterInfo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
base.Select();
|
||||
}
|
||||
|
||||
private void UpdatePlayerFrame(CharacterInfo characterInfo)
|
||||
{
|
||||
if (playerFrame.children.Count <= 1)
|
||||
{
|
||||
playerFrame.ClearChildren();
|
||||
|
||||
if (IsServer && Game1.Server != null)
|
||||
{
|
||||
var playYourself = new GUITickBox(new Rectangle(0, -20, 200, 30), "Play yourself", Alignment.TopLeft, playerFrame);
|
||||
playYourself.OnSelected = TogglePlayYourself;
|
||||
}
|
||||
|
||||
new GUITextBlock(new Rectangle(60, 0, 200, 30), "Name: ", GUI.style, playerFrame);
|
||||
|
||||
GUITextBox playerName = new GUITextBox(new Rectangle(60, 30, 0, 20),
|
||||
Alignment.TopLeft, GUI.style, playerFrame);
|
||||
playerName.Text = Game1.Client.CharacterInfo.Name;
|
||||
playerName.Text = characterInfo.Name;
|
||||
playerName.OnEnter += ChangeCharacterName;
|
||||
|
||||
new GUITextBlock(new Rectangle(0, 70, 200, 30), "Gender: ", GUI.style, playerFrame);
|
||||
|
||||
GUIButton maleButton = new GUIButton(new Rectangle(0, 100, 70, 20), "Male",
|
||||
Alignment.TopLeft, GUI.style,playerFrame);
|
||||
GUIButton maleButton = new GUIButton(new Rectangle(0, 100, 70, 20), "Male",
|
||||
Alignment.TopLeft, GUI.style, playerFrame);
|
||||
maleButton.UserData = Gender.Male;
|
||||
maleButton.OnClicked += SwitchGender;
|
||||
|
||||
@@ -313,7 +334,7 @@ namespace Subsurface
|
||||
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);
|
||||
@@ -329,10 +350,29 @@ namespace Subsurface
|
||||
|
||||
//UpdatePreviewPlayer(Game1.Client.CharacterInfo);
|
||||
|
||||
UpdatePreviewPlayer(Game1.Client.CharacterInfo);
|
||||
UpdatePreviewPlayer(characterInfo);
|
||||
}
|
||||
}
|
||||
|
||||
base.Select();
|
||||
private bool TogglePlayYourself(object obj)
|
||||
{
|
||||
GUITickBox tickBox = obj as GUITickBox;
|
||||
if (tickBox.Selected)
|
||||
{
|
||||
Game1.Server.CharacterInfo = new CharacterInfo(Character.HumanConfigFile, Game1.Server.Name);
|
||||
UpdatePlayerFrame(Game1.Server.CharacterInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
playerFrame.ClearChildren();
|
||||
|
||||
if (IsServer && Game1.Server != null)
|
||||
{
|
||||
var playYourself = new GUITickBox(new Rectangle(0, -20, 200, 30), "Play yourself", Alignment.TopLeft, playerFrame);
|
||||
playYourself.OnSelected = TogglePlayYourself;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool SelectMap(object obj)
|
||||
@@ -590,10 +630,10 @@ namespace Subsurface
|
||||
}
|
||||
else
|
||||
{
|
||||
if (map.Hash.Hash != md5Hash)
|
||||
if (map.MD5Hash.Hash != md5Hash)
|
||||
{
|
||||
DebugConsole.ThrowError("Your version of the map file ''" + map.Name + "'' doesn't match the server's version!");
|
||||
DebugConsole.ThrowError("Your file: " + map.Name + "(MD5 hash : " + map.Hash.Hash + ")");
|
||||
DebugConsole.ThrowError("Your file: " + map.Name + "(MD5 hash : " + map.MD5Hash.Hash + ")");
|
||||
DebugConsole.ThrowError("Server's file: " + mapName + "(MD5 hash : " + md5Hash + ")");
|
||||
return false;
|
||||
}
|
||||
@@ -618,7 +658,7 @@ namespace Subsurface
|
||||
else
|
||||
{
|
||||
msg.Write(Path.GetFileName(selectedMap.Name));
|
||||
msg.Write(selectedMap.Hash.Hash);
|
||||
msg.Write(selectedMap.MD5Hash.Hash);
|
||||
}
|
||||
|
||||
msg.Write(ServerName);
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace Subsurface
|
||||
|
||||
refreshDisableTimer = DateTime.Now + AllowedRefreshInterval;
|
||||
|
||||
yield return Status.Success;
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
private void UpdateServerList(string masterServerData)
|
||||
@@ -197,14 +197,14 @@ namespace Subsurface
|
||||
RestClient client = null;
|
||||
try
|
||||
{
|
||||
client = new RestClient(NetworkMember.MasterServerUrl);
|
||||
client = new RestClient(NetConfig.MasterServerUrl);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Error while connecting to master server", e);
|
||||
}
|
||||
|
||||
if (client == null) yield return Status.Success;
|
||||
if (client == null) yield return CoroutineStatus.Success;
|
||||
|
||||
|
||||
var request = new RestRequest("masterserver.php", Method.GET);
|
||||
@@ -231,10 +231,10 @@ namespace Subsurface
|
||||
restRequestHandle.Abort();
|
||||
DebugConsole.ThrowError("Couldn't connect to master server (request timed out)");
|
||||
}
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
yield return Status.Success;
|
||||
yield return CoroutineStatus.Success;
|
||||
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ namespace Subsurface
|
||||
while (GUIMessageBox.MessageBoxes.Contains(msgBox))
|
||||
{
|
||||
okButton.Enabled = !string.IsNullOrWhiteSpace(passwordBox.Text);
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
}
|
||||
|
||||
selectedPassword = passwordBox.Text;
|
||||
@@ -305,9 +305,7 @@ namespace Subsurface
|
||||
Game1.NetworkMember = new GameClient(clientNameBox.Text);
|
||||
Game1.Client.ConnectToServer(ip, selectedPassword);
|
||||
|
||||
Game1.NetLobbyScreen.Select();
|
||||
|
||||
yield return Status.Success;
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
|
||||
|
||||
@@ -75,22 +75,22 @@ namespace Subsurface
|
||||
startDrone.Play();
|
||||
|
||||
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
|
||||
waterAmbience = Sound.Load("Content/Sounds/Water/WaterAmbience.ogg");
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
flowSounds[0] = Sound.Load("Content/Sounds/Water/FlowSmall.ogg");
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
flowSounds[1] = Sound.Load("Content/Sounds/Water/FlowMedium.ogg");
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
flowSounds[2] = Sound.Load("Content/Sounds/Water/FlowLarge.ogg");
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
XDocument doc = ToolBox.TryLoadXml("Content/Sounds/Sounds.xml");
|
||||
if (doc == null) yield return Status.Failure;
|
||||
XDocument doc = ToolBox.TryLoadXml("Content/Sounds/sounds.xml");
|
||||
if (doc == null) yield return CoroutineStatus.Failure;
|
||||
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
var xMusic = doc.Root.Elements("music").ToList();
|
||||
|
||||
@@ -100,13 +100,13 @@ namespace Subsurface
|
||||
int i = 0;
|
||||
foreach (XElement element in xMusic)
|
||||
{
|
||||
string file = ToolBox.GetAttributeString(element, "file", "").ToLower();
|
||||
string file = ToolBox.GetAttributeString(element, "file", "");
|
||||
string type = ToolBox.GetAttributeString(element, "type", "").ToLower();
|
||||
Vector2 priority = ToolBox.GetAttributeVector2(element, "priorityrange", new Vector2(0.0f, 100.0f));
|
||||
|
||||
musicClips[i] = new BackgroundMusic(file, type, priority);
|
||||
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
i++;
|
||||
}
|
||||
@@ -120,7 +120,7 @@ namespace Subsurface
|
||||
int i = 0;
|
||||
foreach (XElement element in xDamageSounds)
|
||||
{
|
||||
yield return Status.Running;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
Sound sound = Sound.Load(ToolBox.GetAttributeString(element, "file", ""));
|
||||
if (sound == null) continue;
|
||||
@@ -144,7 +144,7 @@ namespace Subsurface
|
||||
}
|
||||
}
|
||||
|
||||
yield return Status.Success;
|
||||
yield return CoroutineStatus.Success;
|
||||
|
||||
}
|
||||
|
||||
@@ -189,6 +189,7 @@ namespace Subsurface
|
||||
{
|
||||
foreach (Task task in Game1.GameSession.taskManager.Tasks)
|
||||
{
|
||||
if (!task.IsStarted) continue;
|
||||
if (criticalTask == null || task.Priority > criticalTask.Priority)
|
||||
{
|
||||
criticalTask = task;
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Xna.Framework;
|
||||
#if WINDOWS
|
||||
using OpenTK.Audio.OpenAL;
|
||||
#endif
|
||||
using OpenTK.Audio;
|
||||
|
||||
using System;
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace Subsurface
|
||||
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
if (!path.EndsWith("\\")) path += "\\";
|
||||
if (!path.EndsWith("/")) path += "/";
|
||||
}
|
||||
|
||||
file = path + file;
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace Subsurface
|
||||
#endif
|
||||
#if LINUX
|
||||
using (Stream fileStream = File.OpenRead(path))
|
||||
return Texture2D.FromFile(_graphicsDevice, fileStream);// .FromStream(fileStream, preMultiplyAlpha);
|
||||
return Texture2D.FromStream(_graphicsDevice, fileStream);// .FromStream(fileStream, preMultiplyAlpha);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -270,6 +270,15 @@ namespace Subsurface
|
||||
.Select(s => s[Rand.Int(s.Length)])
|
||||
.ToArray());
|
||||
}
|
||||
|
||||
public static int StringToInt(string str)
|
||||
{
|
||||
str = str.Substring(0, Math.Min(str.Length, 32));
|
||||
|
||||
byte[] asciiBytes = Encoding.ASCII.GetBytes(str);
|
||||
|
||||
return BitConverter.ToInt32(asciiBytes, 0);
|
||||
}
|
||||
|
||||
public static string WrapText(string text, float lineLength, SpriteFont font)
|
||||
{
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
<Compile Include="Source\Items\FixRequirement.cs" />
|
||||
<Compile Include="Source\Map\Lights\Light.cs" />
|
||||
<Compile Include="Source\Map\LocationType.cs" />
|
||||
<Compile Include="Source\Networking\NetConfig.cs" />
|
||||
<Compile Include="Source\Screens\ServerListScreen.cs" />
|
||||
<Compile Include="Source\Utils\Rand.cs" />
|
||||
<Compile Include="Source\Events\PropertyTask.cs" />
|
||||
@@ -218,10 +219,6 @@
|
||||
<Compile Include="Source\Map\Hull.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Lidgren.Network, Version=3.3.0.2069, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>.\Lidgren.Network.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MonoGame.Framework">
|
||||
<HintPath>$(MSBuildProgramFiles32)\MonoGame\v3.0\Assemblies\Windows\MonoGame.Framework.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -238,6 +235,7 @@
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
</ItemGroup>
|
||||
@@ -943,6 +941,10 @@
|
||||
<Project>{0aad36e3-51a5-4a07-ab60-5c8a66bd38b7}</Project>
|
||||
<Name>Farseer Physics MonoGame</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Lidgren.Network\Lidgren.Network.csproj">
|
||||
<Project>{49ba1c69-6104-41ac-a5d8-b54fa9f696e8}</Project>
|
||||
<Name>Lidgren.Network</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Subsurface_content\Subsurface_content\Subsurface_content.csproj">
|
||||
<Project>{1e6bf44d-6e31-40cc-8321-3d5958c983e7}</Project>
|
||||
<Name>Subsurface_content</Name>
|
||||
|
||||
Reference in New Issue
Block a user