Compare commits

..

47 Commits
0.0.2 ... 0.0.4

Author SHA1 Message Date
Pieter-Jan Briers
f0d6680977 Fix accidental integer division. (#349)
AnimatedSpriteComponent.AABB used integer division, fixed now.
2017-08-19 10:23:19 +02:00
Pieter-Jan Briers
49f7b987f5 Refactor entity initialization and fix doc comments. (#346)
Entities now initialize in a few stages. First all their components are added, then entity.PreInitialize() is called, then all components are initialized, then entity.Initialize() is called.

This multi-level initialization system should hopefully be more powerful and make things like prefetching components easier.

Also what the crap WAS the old init system even?
2017-08-19 10:19:22 +02:00
clusterfack
444d0847b6 Fixing the current placement system (#347)
* WIP: Fixing the current placement system

* Placement system sprites come back pls

* HE TURNED THE FREAKING SPRITES GAY

* TECHNICALLY THIS MAKES THE SPRITES NOT GAY

* Mostly Shows sprites correctly

* Finished this bulllllshit

* Rename some things
2017-08-19 08:59:57 +02:00
clusterfack
005bd9e95c Containers (#339)
* #Part 1

Created basic container dictionary and framework for transform parenting

##Work Left until completion

1. Registering containers through a container manager
2. Registering onmove events onto the parents event handler on insertion
3. Removing onmove events from the parent event handler on removal
4. An event called upon insertion and removal from storage objects
5. Redirecting transform getters to use the uppermost parents transform

* Part 2

Creates some basic code for removing entities generally from other entities
Creates code for creating containers
Adds some basic logic for parents overriding transform getters
Adds logic to prevent circular references
Makes Container an abstract class for things to create their own versions from

* Moves container classes to shared so they can be registered on server and client
Registers container classes on server and client
Makes ContainerManager get created properly by the component factory

* Adds missing } and finalizes csproj changes

* Add exception for double containers on one component

* Makes sure parents are attached and detached at the correct time

* Address some issues, cause others perhaps

* Rename Files
Changes Container Class Inheritance
Vague stuff

* Move Icontainer and Icontainermanagercomponent to ss14 server
Make servertransform interface for parents to be serverside only
Deregister containermanager from the client IOC

* Remove Icontainer And Icontainermanager from shared csproj

* Fix

* To get git to recognize this I have to delete them

* And then readd the files, fuck you git

* Be specific you daft cunt
2017-08-18 11:18:42 -06:00
Pieter-Jan Briers
dfcf0349ca Fix F2 on Unix, collision bug and join crash. (#348)
* Make F2 not crash on Unix, fix join crash.

* Fix collision when moving to the bottom or right.

The bug was caused by 1d5ca223de. Collision adds to the AABB's Left and Top properties to do offsets, but when moving to OpenTK, this stopped working, as Right and Bottom now had to be offset too. I missed this, and as such, your hitbox is smaller when moving to the bottom or right. This allows you to clip into walls, but when you're in you can't move the other direction, as your hitbox is also *larger* when moving to the top or left.
2017-08-18 13:07:51 +02:00
Matt Smith
45a7a809db Reduce code complexity (#345) 2017-08-18 10:54:35 +02:00
Acruid
48852c5ee8 Grid Placement Fix (#344)
* Physics works again.

* forgot some SFML stuff.

* Cluwnelib does not depend on 1.0m = 1 tile anymore.

* Fixed bug with tile placement in wrong spot.
Fixed blue box issue.
2017-08-17 15:42:44 -06:00
Acruid
60ac4a9e26 Collision Fix (#340)
* Physics works again.

* forgot some SFML stuff.
2017-08-17 23:20:12 +02:00
h3half
5351f581f1 Removes commented-out code (#343)
Removes most of the commented-out code from sonarqube. There's
definitely more hiding throughout the codebase, but this should be most
of it.
2017-08-17 11:58:37 +02:00
Pieter-Jan Briers
e719dd1440 Make the lighting toggle properly disable all lighting rendering. (#342) 2017-08-16 12:38:55 -06:00
Pieter-Jan Briers
1d5ca223de Replace SFML math types with OpenTK and custom ones. (#341)
* Attempt to messily convert the codebase to use OpenTK math.

* Vector2f is gone. It compiles!

* Fix unit tests.

* Goodbye FloatRect

* Goodbye IntRect, say hello to Box2i.
2017-08-16 11:22:48 -06:00
Silver
3170552b3d Rename LICENSE.TXT to LICENSE-CODE.TXT 2017-08-15 14:44:40 -06:00
dylanstrategie
18692e21a4 Fix issues with Menu Window (#336)
* Fix issues with Menu Window

* Requested changes
2017-08-15 14:17:57 -06:00
Acruid
ae0ccc72b4 Map Manager Refactor (#338)
* Merged Client and Server Map interfaces into a Shared version.
Merged Client and Server MapManager system into a shared version.

* Added some encapsulation to the map system.
Added doc comments to client and server classes.
It compiles, but it DOES NOT WORK.

* Now with 89% more encapsulation.
Added a MapGrid object to the MapManager.

STILL A BUGGY MESS!

* Rendering bugs were fixed.

* Fixed alignment bug with GetTilesIntersecting.

* Cleanup the interfaces a bit.

* Code update.

* Merged client/server MapNetworkManager into shared version.

* Nightly work. Compiles, does not run.

* Shared networking looks like it works.

* Cleanup and remove SFML.
2017-08-14 17:30:57 -06:00
Pieter-Jan Briers
f5eb8cd55b MSBuild MacOS handling. (#337)
* Makes MSBuild distinguish Linux and MacOS.

* Fix TargetOS

* Copy mac natives during build.

* Fix travis

* Fix typo.
2017-08-14 18:54:46 +02:00
Pieter-Jan Briers
db1c71994b Give content access to OpenTK Math and Color types. (#335) 2017-08-14 18:23:46 +02:00
Silver
96df096303 Revert "Gives content access to OpenTK math and color types. (#332)" (#334)
This reverts commit 9669221d37.
2017-08-13 21:34:56 +02:00
Pieter-Jan Briers
9669221d37 Gives content access to OpenTK math and color types. (#332) 2017-08-13 13:33:32 -06:00
Pieter-Jan Briers
480ed6d74c Fixing some compile warnings. (#331)
All the obsoletions from netmessages will be for another PR.
2017-08-13 11:30:23 -06:00
Dan
1d2614d75f Refactor align modes (#330)
* Refactor align modes

* Remove some unnessecary lines
2017-08-13 14:30:55 +02:00
Pieter-Jan Briers
1c5f540751 Remove component instantiation messages. (#324) 2017-08-13 00:46:00 +02:00
Pieter-Jan Briers
f4fe79346e Inverse entity queries. (#322)
* Inverse entity queries.

They now effectively behave like Func<IEntity, bool>.
The actual matching logic is now done on entity queries.

They've also been abstracted, as such there are now multiple entity
query types to pick from.

Also generic clean up.

* Fix doc comment on the exclude list.

* Use Predicate<> instead of Func<>

* Fix compile, Predictae<> doesn't work
2017-08-13 00:31:58 +02:00
Acruid
cb5bfbb3da Component Rework (#325)
* Cleans up base Component.

* Clean up PhysicsComponent.
Merge VelocityComponent with PhysicsComponent.

* Renamed HitBoxComponent to BoundingBoxComponent.
Cleaned up BoundingBoxComponent.
Added Box2 to the serializer and SfmlCompatibility.

* Serverside movement works.

* Removed DirectionComponent.
Everything is broke, time to sleep.

* Removed BasicMoverComponent and SlaveMoverComponent.
Added Parenting skeleton to TransformComponent.

* Move ClickAbleComponent to Input.
Fixed lights.

* More general cleanup.

* Move Physics system into Shared.

* Removed ColliderComponent.

* Fixed AnimatedSprite Rotation.

* Added Vector2i as a type.

* Fixes StackOverflow bug by just not using SFML.Vector2f.

* Should fix Build issues.

* Removed pointless server console resizing.
Fixed Unit tests working in VS.
Updated PrototypeManager_Test.cs tests.

* Adds SS14.Shared/Maths/VecMath.cs helper functions.

* Switched to Angle type.
2017-08-13 00:10:06 +02:00
Pieter-Jan Briers
f41050583e Bit of unit test stuff. (#326)
* Unit test for #294

* Remove empty warning tests.
2017-08-13 00:09:42 +02:00
clusterfack
85fa167e17 Fixes Exceptions on Rejoining (#327)
* Fix server crash on rejoin

* Makes it possible to rejoin without exception

* Proper fix by culling ALL the component lists when the entity manager shuts down
2017-08-12 10:25:33 +02:00
Pieter-Jan Briers
b9723b6504 Content repo can now define console commands. (#321) 2017-08-11 15:44:47 -06:00
Pieter-Jan Briers
2e64de57c6 Makes the main menu pretty. (#320)
>duct tape logo

INSTAMERGE
2017-08-11 14:37:31 -06:00
Pieter-Jan Briers
feaf4160e8 Load unatlassed images from disk as sprites (#319)
This'll allow content to add sprites.
2017-08-11 08:23:23 +02:00
Pieter-Jan Briers
93fd0014b4 Fix content entry invocations, whitelist types. (#317) 2017-08-09 21:50:45 -06:00
Pieter-Jan Briers
22f07e3649 Adds OS targeting to the build setup (#316)
* Adds OS targeting to the build setup

Will make cross platform builds (Linux -> Windows) easier.

* Rename Windows_NT to Windows and explicitly do Linux.
2017-08-10 00:04:31 +02:00
clusterfack
398a3917dc Returns runclient and runserver 2017-08-09 08:26:08 -05:00
Pieter-Jan Briers
04fa16902f Fix SFML memory leak. (#315) 2017-08-09 07:39:19 +02:00
Jordan Brown
b0e42ef650 Removes support for resource pack passwords (#314) 2017-08-08 21:36:53 +02:00
Pieter-Jan Briers
b0d7ee16c1 Deprecate resource pack temporarily. (#312)
* Deprecate resource pack temporarily.

Temporarily being until we actually need content downloading from server.
Resources now get copied to the output directories directly.

* Move prototypes around.
2017-08-08 14:48:15 +02:00
Pieter-Jan Briers
b9ece2888b Repo cleanup (#310)
* Reduce build size by removing redundant files.

22 MB of the build output was OpenTK.xml, the doc file for it.
This commit removes a lot of files like PDB files from the build output
on Release, cutting build size down to 13 MB.

Also deleted a ton of dead third party files in Third-Party, and the two
spare copies of CSFML...

* Remove more dead files.

* Even more!

* Generic repo cleanup. Removing dead files all over.

What the hell was filesystemeditor.exe supposed to be?
2017-08-08 12:47:31 +02:00
Pieter-Jan Briers
d1b29a6f94 Update NetSerializer, move to NuGet with it. (#311)
NetSerializer has been updated and moved to the latest version. This
means that the static nonsense it previously had is fixed and we can
properly use ISS14Serializer.
2017-08-08 12:47:18 +02:00
clusterfack
a43da12f9b Fixes a rare out of bounds exception (#313)
* Fixes a rare crash

Fixes a crash that occurs from the following
>return AngleDirections[(int)Math.Floor(angle/45f)];

System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'

That occurs most likely due to a float rounding error

* Apparently this works fine
2017-08-08 11:51:38 +02:00
Pieter-Jan Briers
4607a106d0 Of course it works a lot different on the client. 2017-08-06 14:47:20 +02:00
Pieter-Jan Briers
de9fd0cbaf Fix resource pack on client, regression in #306 2017-08-06 12:56:12 +02:00
Acruid
2e3315cd39 CompState Cleanup (#308)
* Changed GameObjects.Component namespace back to GameObjects.Components namespace to prevent colliding with GameObjects.Component class.

* Changed IComponent.HandleComponentState to use polymorphism instead of dynamic keyword.
Cleaned up nesting in each implementation of IComponent.HandleComponentState.

* Moved all shared ComponentStates to the SS14.Shared.GameObjects namespace to be more in line with client & server components.
Made all ComponentStates immutable, as they should be.
2017-08-06 12:16:47 +02:00
Acruid
f7b1b9c4b6 Client Timing (#309)
* Appease lord Sonar.

* Client timing *should* work.
2017-08-05 17:15:33 -06:00
Pieter-Jan Briers
2572bc94c7 Increase default logging verbosity to DEBUG. (#307) 2017-08-05 23:32:57 +02:00
Pieter-Jan Briers
47f1aa6565 Unhardcode content pack locations. (#306)
* Unhardcode content pack locations.

The previous hardcoded path was causing problems for the content repo.
Now the content packs are loaded from the executable directory.
The build system copies the pack from the Resources/ folder now.

* Fix CI
2017-08-05 23:32:44 +02:00
Pieter-Jan Briers
fdde14b93e Makes client and server load shared assembly too. (#304)
Also fixes #303
2017-08-05 23:32:28 +02:00
Pieter-Jan Briers
975eea832d Clean up build targets and output dirs. (#302)
* Clean up build targets and output dirs.

All old Any CPU targets and mixed ones have been removed. They wouldn't have worked anyways due to SFML.

Cleaned up all the build output directories to be neat and clean.

* Fix Travis
2017-08-04 07:11:28 -06:00
Pieter-Jan Briers
09ecdade70 Fix sonar E rating by removing dead Lidgren code.
Specifically, dead encryption systems like DES which are useless in 2017.
2017-08-03 20:32:16 +02:00
Pieter-Jan Briers
e8b40f6091 Make references in projects solution-relative, fixing content#3. (#300)
* Make package references in project files solution-relative.

Fixes https://github.com/space-wizards/space-station-14-content/issues/3 with the SolutionDir msbuild property.

* Fix openTK post-merge
2017-08-03 08:49:57 -06:00
389 changed files with 7326 additions and 14922 deletions

View File

@@ -15,6 +15,7 @@ install:
- ps: if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { cinst msbuild-sonarqube-runner }
before_build:
- cmd: py -3.5 Resources\buildResourcePack.py --resources-dir .\Resources --out .\Resources\ResourcePack.zip --atlas-tool .\Tools\AtlasTool.exe --no-animations --to-stderr
- cmd: nuget restore SpaceStation14.sln
- ps: if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { MSBuild.SonarQube.Runner.exe begin /k:"ss14" /d:"sonar.host.url=https://sonarqube.com" /d:"sonar.login=$env:sonarqubekey" /d:"sonar.organization=space-wizards" }
@@ -25,4 +26,3 @@ build:
after_build:
- ps: if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { MSBuild.SonarQube.Runner.exe end /d:"sonar.login=$env:sonarqubekey" }
- cmd: py -3.5 Resources\buildResourcePack.py --resources-dir .\Resources --out .\Resources\ResourcePack.zip --atlas-tool .\Tools\AtlasTool.exe --no-animations --to-stderr

View File

@@ -1,4 +0,0 @@
{
"phabricator.uri": "http://phab.nexisonline.net",
"project.name": "Space Station 14"
}

View File

@@ -7,5 +7,5 @@ indent_size = 4
trim_trailing_whitespace = true
charset = utf-8-bom
[*.{csproj,xml,yml,dll.config}]
[*.{csproj,xml,yml,dll.config,targets}]
indent_size = 2

5
.gitignore vendored
View File

@@ -75,4 +75,7 @@ project.lock.json
# Created by NUnit.
TestResult.xml
NetSerializerDebug.dll
NetSerializerDebug.dll
# We're not gonna ship Mac extlibs with the repo due to size. (11 MB)
Third-Party/extlibs/Mac/

View File

@@ -11,11 +11,11 @@ before_install:
- if [ $TRAVIS_OS_NAME = osx ]; then brew update && brew install python3; fi
before_script:
- "python3 ./Resources/buildResourcePack.py --resources-dir ./Resources --out ./Resources/ResourcePack.zip --no-atlas --no-animations --to-stderr"
- "nuget restore SpaceStation14.sln"
script:
- "msbuild /p:Configuration=Release /p:HEADLESS=1 SpaceStation14.sln"
- "python3 ./Resources/buildResourcePack.py --resources-dir ./Resources --out ./Resources/ResourcePack.zip --no-atlas --no-animations --to-stderr"
- "msbuild /p:Configuration=Release /p:HEADLESS=1 /nologo /m /p:AllowMissingMacNatives=yes SpaceStation14.sln"
- "cd packages/NUnit.ConsoleRunner.3.6.1/tools"
- "mono --debug nunit3-console.exe ../../../SS14.UnitTesting/bin/Release/SS14.UnitTesting.dll"
- "mono --debug nunit3-console.exe ../../../bin/UnitTesting/SS14.UnitTesting.dll"

View File

@@ -1,4 +0,0 @@
call "c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
@echo on
call prebuild-2010.cmd
call msbuild SpaceStation14.sln /t:Build /p:Configuration=Release;Platform=x86

View File

@@ -1,10 +0,0 @@
#!/bin/bash
prebuild-nant.sh
nant
#nunit-console Bin/SS14.Test.dll -nodots -xml=NUnit.Results.xml
echo NUnit disabled.
#7za a SS14.7z Bin/*
echo Packaging disabled.

View File

@@ -1,2 +0,0 @@
cd bin\client
start SpaceStation14.exe

View File

@@ -1,2 +0,0 @@
cd bin\server
start SpaceStation14_Server.exe

View File

@@ -1,164 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Lidgren.Network
{
/// <summary>
/// DES encryption
/// </summary>
public class NetDESEncryption : INetEncryption
{
private readonly byte[] m_key;
private readonly byte[] m_iv;
private readonly int m_bitSize;
private static readonly List<int> m_keysizes;
private static readonly List<int> m_blocksizes;
static NetDESEncryption()
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
List<int> temp = new List<int>();
foreach (KeySizes keysize in des.LegalKeySizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
m_keysizes = temp;
temp = new List<int>();
foreach (KeySizes keysize in des.LegalBlockSizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
m_blocksizes = temp;
}
/// <summary>
/// NetDESEncryption constructor
/// </summary>
public NetDESEncryption(byte[] key, byte[] iv)
{
if (!m_keysizes.Contains(key.Length * 8))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes)));
if (!m_blocksizes.Contains(iv.Length * 8))
throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_blocksizes)));
m_key = key;
m_iv = iv;
m_bitSize = m_key.Length * 8;
}
/// <summary>
/// NetDESEncryption constructor
/// </summary>
public NetDESEncryption(string key, int bitsize)
{
if (!m_keysizes.Contains(bitsize))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes)));
byte[] entropy = Encoding.UTF32.GetBytes(key);
// I know hardcoding salts is bad, but in this case I think it is acceptable.
HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL=="));
hmacsha512.Initialize();
for (int i = 0; i < 1000; i++)
{
entropy = hmacsha512.ComputeHash(entropy);
}
int keylen = bitsize / 8;
m_key = new byte[keylen];
Buffer.BlockCopy(entropy, 0, m_key, 0, keylen);
m_iv = new byte[m_blocksizes[0] / 8];
Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length);
m_bitSize = bitsize;
}
/// <summary>
/// NetDESEncryption constructor
/// </summary>
public NetDESEncryption(string key)
: this(key, m_keysizes[0])
{
}
/// <summary>
/// Encrypt outgoing message
/// </summary>
public bool Encrypt(NetOutgoingMessage msg)
{
try
{
// nested usings are fun!
using (DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = desCryptoServiceProvider.CreateEncryptor(m_key, m_iv))
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform,
CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
}
msg.m_data = memoryStream.ToArray();
}
}
}
}
catch
{
return false;
}
return true;
}
/// <summary>
/// Decrypt incoming message
/// </summary>
public bool Decrypt(NetIncomingMessage msg)
{
try
{
// nested usings are fun!
using (DESCryptoServiceProvider desCryptoServiceProvider = new DESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = desCryptoServiceProvider.CreateDecryptor(m_key, m_iv))
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform,
CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
}
msg.m_data = memoryStream.ToArray();
}
}
}
}
catch
{
return false;
}
return true;
}
}
}

View File

@@ -1,165 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Lidgren.Network
{
/// <summary>
/// RC2 encryption
/// </summary>
public class NetRC2Encryption : INetEncryption
{
private readonly byte[] m_key;
private readonly byte[] m_iv;
private readonly int m_bitSize;
private static readonly List<int> m_keysizes;
private static readonly List<int> m_blocksizes;
static NetRC2Encryption()
{
RC2CryptoServiceProvider rc2 = new RC2CryptoServiceProvider();
List<int> temp = new List<int>();
foreach (KeySizes keysize in rc2.LegalKeySizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
m_keysizes = temp;
temp = new List<int>();
foreach (KeySizes keysize in rc2.LegalBlockSizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
m_blocksizes = temp;
}
/// <summary>
/// NetRC2Encryption constructor
/// </summary>
public NetRC2Encryption(byte[] key, byte[] iv)
{
if (!m_keysizes.Contains(key.Length * 8))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes)));
if (!m_blocksizes.Contains(iv.Length * 8))
throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_blocksizes)));
m_key = key;
m_iv = iv;
m_bitSize = m_key.Length * 8;
}
/// <summary>
/// NetRC2Encryption constructor
/// </summary>
public NetRC2Encryption(string key, int bitsize)
{
if (!m_keysizes.Contains(bitsize))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes)));
byte[] entropy = Encoding.UTF32.GetBytes(key);
// I know hardcoding salts is bad, but in this case I think it is acceptable.
HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL=="));
hmacsha512.Initialize();
for (int i = 0; i < 1000; i++)
{
entropy = hmacsha512.ComputeHash(entropy);
}
int keylen = bitsize / 8;
m_key = new byte[keylen];
Buffer.BlockCopy(entropy, 0, m_key, 0, keylen);
m_iv = new byte[m_blocksizes[0] / 8];
Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length);
m_bitSize = bitsize;
}
/// <summary>
/// NetRC2Encryption constructor
/// </summary>
/// <param name="key"></param>
public NetRC2Encryption(string key)
: this(key, m_keysizes[0])
{
}
/// <summary>
/// Encrypt outgoing message
/// </summary>
public bool Encrypt(NetOutgoingMessage msg)
{
try
{
// nested usings are fun!
using (RC2CryptoServiceProvider rc2CryptoServiceProvider = new RC2CryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = rc2CryptoServiceProvider.CreateEncryptor(m_key, m_iv))
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform,
CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
}
msg.m_data = memoryStream.ToArray();
}
}
}
}
catch
{
return false;
}
return true;
}
/// <summary>
/// Decrypt incoming message
/// </summary>
public bool Decrypt(NetIncomingMessage msg)
{
try
{
// nested usings are fun!
using (RC2CryptoServiceProvider rc2CryptoServiceProvider = new RC2CryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = rc2CryptoServiceProvider.CreateDecryptor(m_key, m_iv))
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform,
CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
}
msg.m_data = memoryStream.ToArray();
}
}
}
}
catch
{
return false;
}
return true;
}
}
}

View File

@@ -1,164 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Lidgren.Network
{
/// <summary>
/// Triple DES encryption
/// </summary>
public class NetTripleDESEncryption : INetEncryption
{
private readonly byte[] m_key;
private readonly byte[] m_iv;
private readonly int m_bitSize;
private static readonly List<int> m_keysizes;
private static readonly List<int> m_blocksizes;
static NetTripleDESEncryption()
{
TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
List<int> temp = new List<int>();
foreach (KeySizes keysize in tripleDES.LegalKeySizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
m_keysizes = temp;
temp = new List<int>();
foreach (KeySizes keysize in tripleDES.LegalBlockSizes)
{
for (int i = keysize.MinSize; i <= keysize.MaxSize; i += keysize.SkipSize)
{
if (!temp.Contains(i))
temp.Add(i);
if (i == keysize.MaxSize)
break;
}
}
m_blocksizes = temp;
}
/// <summary>
/// NetTriplsDESEncryption constructor
/// </summary>
public NetTripleDESEncryption(byte[] key, byte[] iv)
{
if (!m_keysizes.Contains(key.Length * 8))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes)));
if (!m_blocksizes.Contains(iv.Length * 8))
throw new NetException(string.Format("Not a valid iv size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_blocksizes)));
m_key = key;
m_iv = iv;
m_bitSize = m_key.Length * 8;
}
/// <summary>
/// NetTriplsDESEncryption constructor
/// </summary>
public NetTripleDESEncryption(string key, int bitsize)
{
if (!m_keysizes.Contains(bitsize))
throw new NetException(string.Format("Not a valid key size. (Valid values are: {0})", NetUtility.MakeCommaDelimitedList(m_keysizes)));
byte[] entropy = Encoding.UTF32.GetBytes(key);
// I know hardcoding salts is bad, but in this case I think it is acceptable.
HMACSHA512 hmacsha512 = new HMACSHA512(Convert.FromBase64String("i88NEiez3c50bHqr3YGasDc4p8jRrxJAaiRiqixpvp4XNAStP5YNoC2fXnWkURtkha6M8yY901Gj07IRVIRyGL=="));
hmacsha512.Initialize();
for (int i = 0; i < 1000; i++)
{
entropy = hmacsha512.ComputeHash(entropy);
}
int keylen = bitsize / 8;
m_key = new byte[keylen];
Buffer.BlockCopy(entropy, 0, m_key, 0, keylen);
m_iv = new byte[m_blocksizes[0] / 8];
Buffer.BlockCopy(entropy, entropy.Length - m_iv.Length - 1, m_iv, 0, m_iv.Length);
m_bitSize = bitsize;
}
/// <summary>
/// NetTriplsDESEncryption constructor
/// </summary>
public NetTripleDESEncryption(string key)
: this(key, m_keysizes[0])
{
}
/// <summary>
/// Encrypt outgoing message
/// </summary>
public bool Encrypt(NetOutgoingMessage msg)
{
try
{
// nested usings are fun!
using (TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider = new TripleDESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = tripleDESCryptoServiceProvider.CreateEncryptor(m_key, m_iv))
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform,
CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
}
msg.m_data = memoryStream.ToArray();
}
}
}
}
catch
{
return false;
}
return true;
}
/// <summary>
/// Decrypt incoming message
/// </summary>
public bool Decrypt(NetIncomingMessage msg)
{
try
{
// nested usings are fun!
using (TripleDESCryptoServiceProvider tripleDESCryptoServiceProvider = new TripleDESCryptoServiceProvider { KeySize = m_bitSize, Mode = CipherMode.CBC })
{
using (ICryptoTransform cryptoTransform = tripleDESCryptoServiceProvider.CreateDecryptor(m_key, m_iv))
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform,
CryptoStreamMode.Write))
{
cryptoStream.Write(msg.m_data, 0, msg.m_data.Length);
}
msg.m_data = memoryStream.ToArray();
}
}
}
}
catch
{
return false;
}
return true;
}
}
}

View File

@@ -1,58 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Lidgren.Network
{
/// <summary>
/// Example class; not very good encryption
/// </summary>
public class NetXorEncryption : INetEncryption
{
private byte[] m_key;
/// <summary>
/// NetXorEncryption constructor
/// </summary>
public NetXorEncryption(byte[] key)
{
m_key = key;
}
/// <summary>
/// NetXorEncryption constructor
/// </summary>
public NetXorEncryption(string key)
{
m_key = Encoding.UTF8.GetBytes(key);
}
/// <summary>
/// Encrypt an outgoing message
/// </summary>
public bool Encrypt(NetOutgoingMessage msg)
{
int numBytes = msg.LengthBytes;
for (int i = 0; i < numBytes; i++)
{
int offset = i % m_key.Length;
msg.m_data[i] = (byte)(msg.m_data[i] ^ m_key[offset]);
}
return true;
}
/// <summary>
/// Decrypt an incoming message
/// </summary>
public bool Decrypt(NetIncomingMessage msg)
{
int numBytes = msg.LengthBytes;
for (int i = 0; i < numBytes; i++)
{
int offset = i % m_key.Length;
msg.m_data[i] = (byte)(msg.m_data[i] ^ m_key[offset]);
}
return true;
}
}
}

View File

@@ -39,7 +39,7 @@
<DebugSymbols>True</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<Optimize>False</Optimize>
<OutputPath>..\bin\</OutputPath>
<OutputPath>$(SolutionDir)bin\Lidgren\</OutputPath>
<RegisterForComInterop>False</RegisterForComInterop>
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
@@ -62,7 +62,7 @@
<DebugSymbols>False</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<Optimize>True</Optimize>
<OutputPath>..\bin\</OutputPath>
<OutputPath>$(SolutionDir)bin\Lidgren\</OutputPath>
<RegisterForComInterop>False</RegisterForComInterop>
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<TreatWarningsAsErrors>False</TreatWarningsAsErrors>
@@ -107,18 +107,6 @@
<Compile Include="Encryption\NetBlockEncryptionBase.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Encryption\NetDESEncryption.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Encryption\NetRC2Encryption.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Encryption\NetTripleDESEncryption.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Encryption\NetXorEncryption.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Encryption\NetXteaEncryption.cs">
<SubType>Code</SubType>
</Compile>

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Text;
using System.Collections;
using System.Diagnostics;
@@ -70,7 +70,6 @@ namespace Lidgren.Network
if (i == mag.Length)
{
// sign = 0;
m_magnitude = ZeroMagnitude;
}
else
@@ -241,17 +240,6 @@ namespace Lidgren.Network
}
}
// Note: This is the previous (slower) algorithm
// while (index < value.Length)
// {
// char c = value[index];
// string s = c.ToString();
// int i = Int32.Parse(s, style);
//
// b = b.Multiply(r).Add(ValueOf(i));
// index++;
// }
m_magnitude = b.m_magnitude;
}
@@ -390,7 +378,6 @@ namespace Lidgren.Network
if (sign == 0)
{
//sign = 0;
m_magnitude = ZeroMagnitude;
}
else
@@ -727,7 +714,6 @@ namespace Lidgren.Network
int cBitLength = yBitLength;
if (shift > 0)
{
// iCount = ShiftLeft(One.magnitude, shift);
iCount = new int[(shift >> 5) + 1];
iCount[0] = 1 << (shift % 32);
@@ -758,8 +744,7 @@ namespace Lidgren.Network
if (++xStart == x.Length)
return count;
}
//xBitLength = calcBitLength(xStart, x);
xBitLength = 32 * (x.Length - xStart - 1) + BitLen(x[xStart]);
if (xBitLength <= yBitLength)
@@ -797,8 +782,7 @@ namespace Lidgren.Network
cBitLength -= shift;
iCount = ShiftRightInPlace(iCountStart, iCount, shift);
}
//cStart = c.Length - ((cBitLength + 31) / 32);
while (c[cStart] == 0)
{
++cStart;
@@ -1000,7 +984,6 @@ namespace Lidgren.Network
if (x.m_sign < 0)
{
x.m_sign = 1;
//x = m.Subtract(x);
x.m_magnitude = doSubBigLil(m.m_magnitude, x.m_magnitude);
}
@@ -1105,7 +1088,6 @@ namespace Lidgren.Network
{
if (m_magnitude.Length <= m.m_magnitude.Length)
{
//zAccum = new int[m.magnitude.Length * 2];
zVal = new int[m.m_magnitude.Length];
m_magnitude.CopyTo(zVal, zVal.Length - m_magnitude.Length);
}
@@ -1115,8 +1097,7 @@ namespace Lidgren.Network
// in normal practice we'll never see ..
//
NetBigInteger tmp = Remainder(m);
//zAccum = new int[m.magnitude.Length * 2];
zVal = new int[m.m_magnitude.Length];
tmp.m_magnitude.CopyTo(zVal, zVal.Length - tmp.m_magnitude.Length);
}
@@ -1225,10 +1206,6 @@ namespace Lidgren.Network
int[] w,
int[] x)
{
// Note: this method allows w to be only (2 * x.Length - 1) words if result will fit
// if (w.Length != 2 * x.Length)
// throw new ArgumentException("no I don't think so...");
ulong u1, u2, c;
int wBase = w.Length - 1;
@@ -1649,8 +1626,7 @@ namespace Lidgren.Network
if (++xStart == x.Length)
return x;
}
//xBitLength = calcBitLength(xStart, x);
xBitLength = 32 * (x.Length - xStart - 1) + BitLen(x[xStart]);
if (xBitLength <= yBitLength)
@@ -1686,8 +1662,7 @@ namespace Lidgren.Network
c = ShiftRightInPlace(cStart, c, shift);
cBitLength -= shift;
}
//cStart = c.Length - ((cBitLength + 31) / 32);
while (c[cStart] == 0)
{
++cStart;
@@ -1919,12 +1894,6 @@ namespace Lidgren.Network
if (n >= BitLength)
return (m_sign < 0 ? One.Negate() : Zero);
// int[] res = (int[]) magnitude.Clone();
//
// res = ShiftRightInPlace(0, res, n);
//
// return new BigInteger(sign, res, true);
int resultLength = (BitLength - n + 31) >> 5;
int[] res = new int[resultLength];
@@ -1980,8 +1949,7 @@ namespace Lidgren.Network
{
m = (x[--iT] & IMASK) - (y[--iV] & IMASK) + borrow;
x[iT] = (int)m;
// borrow = (m < 0) ? -1 : 0;
borrow = (int)(m >> 63);
}
while (iV > yStart);

View File

@@ -1,4 +1,4 @@
//#define UNSAFE
//#define UNSAFE
//#define BIGENDIAN
/* Copyright (c) 2010 Michael Lidgren
@@ -39,7 +39,7 @@ namespace Lidgren.Network
NetException.Assert(((numberOfBits > 0) && (numberOfBits < 9)), "Read() can only read between 1 and 8 bits");
int bytePtr = readBitOffset >> 3;
int startReadAtIndex = readBitOffset - (bytePtr * 8); // (readBitOffset % 8);
int startReadAtIndex = readBitOffset - (bytePtr * 8);
if (startReadAtIndex == 0 && numberOfBits == 8)
return fromBuffer[bytePtr];
@@ -70,7 +70,7 @@ namespace Lidgren.Network
public static void ReadBytes(byte[] fromBuffer, int numberOfBytes, int readBitOffset, byte[] destination, int destinationByteOffset)
{
int readPtr = readBitOffset >> 3;
int startReadAtIndex = readBitOffset - (readPtr * 8); // (readBitOffset % 8);
int startReadAtIndex = readBitOffset - (readPtr * 8);
if (startReadAtIndex == 0)
{

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2010 Michael Lidgren
/* Copyright (c) 2010 Michael Lidgren
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without
@@ -181,7 +181,6 @@ namespace Lidgren.Network
public UInt32 PeekUInt32(int numberOfBits)
{
NetException.Assert((numberOfBits > 0 && numberOfBits <= 32), "ReadUInt() can only read between 1 and 32 bits");
//NetException.Assert(m_bitLength - m_readBitPtr >= numberOfBits, "tried to read past buffer size");
UInt32 retval = NetBitWriter.ReadUInt32(m_data, numberOfBits, m_readPosition);
return retval;

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
@@ -255,7 +255,6 @@ namespace Lidgren.Network
public UInt32 ReadUInt32(int numberOfBits)
{
NetException.Assert(numberOfBits > 0 && numberOfBits <= 32, "ReadUInt32(bits) can only read between 1 and 32 bits");
//NetException.Assert(m_bitLength - m_readBitPtr >= numberOfBits, "tried to read past buffer size");
UInt32 retval = NetBitWriter.ReadUInt32(m_data, numberOfBits, m_readPosition);
m_readPosition += numberOfBits;
@@ -470,9 +469,6 @@ namespace Lidgren.Network
int num2 = 0;
while (true)
{
//if (num2 == 0x23)
// throw new FormatException("Bad 7-bit encoded integer");
byte num3 = this.ReadByte();
num1 |= ((UInt64)num3 & 0x7f) << num2;
num2 += 7;

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Text;
@@ -94,8 +94,6 @@ namespace Lidgren.Network
{
m_peer.VerifyNetworkThread();
//m_peer.LogDebug("Executing disconnect");
// clear send queues
for (int i = 0; i < m_sendChannels.Length; i++)
{

View File

@@ -1,4 +1,4 @@
using System;
using System;
namespace Lidgren.Network
{
@@ -131,8 +131,6 @@ namespace Lidgren.Network
rchan.m_resendDelay = resendDelay;
}
// m_peer.LogVerbose("Timeout deadline pushed to " + m_timeoutDeadline);
// notify the application that average rtt changed
if (m_peer.m_configuration.IsMessageTypeEnabled(NetIncomingMessageType.ConnectionLatencyUpdated))
{

View File

@@ -1,4 +1,4 @@
using System;
using System;
namespace Lidgren.Network
{
@@ -74,13 +74,11 @@ namespace Lidgren.Network
{
// we've never encountered failure; expand by 25% each time
tryMTU = (int)((float)m_currentMTU * 1.25f);
//m_peer.LogDebug("Trying MTU " + tryMTU);
}
else
{
// we HAVE encountered failure; so try in between
tryMTU = (int)(((float)m_smallestFailedMTU + (float)m_largestSuccessfulMTU) / 2.0f);
//m_peer.LogDebug("Trying MTU " + m_smallestFailedMTU + " <-> " + m_largestSuccessfulMTU + " = " + tryMTU);
}
if (tryMTU > c_protocolMaxMTU)
@@ -88,7 +86,6 @@ namespace Lidgren.Network
if (tryMTU == m_largestSuccessfulMTU)
{
//m_peer.LogDebug("Found optimal MTU - exiting");
FinalizeMTU(m_largestSuccessfulMTU);
return;
}
@@ -107,8 +104,6 @@ namespace Lidgren.Network
bool ok = m_peer.SendMTUPacket(len, m_remoteEndPoint);
if (ok == false)
{
//m_peer.LogDebug("Send MTU failed for size " + size);
// failure
if (m_smallestFailedMTU == -1 || size < m_smallestFailedMTU)
{
@@ -149,9 +144,7 @@ namespace Lidgren.Network
int len = om.Encode(m_peer.m_sendBuffer, 0, 0);
bool connectionReset;
m_peer.SendPacket(len, m_remoteEndPoint, 1, out connectionReset);
// m_peer.LogDebug("Received MTU expand request for " + size + " bytes");
m_statistics.PacketSent(len, 1);
}
@@ -162,11 +155,9 @@ namespace Lidgren.Network
if (size < m_currentMTU)
{
//m_peer.LogDebug("Received low MTU expand success (size " + size + "); current mtu is " + m_currentMTU);
return;
}
//m_peer.LogDebug("Expanding MTU to " + size);
m_currentMTU = size;
ExpandMTU(now, true);

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Net;
using System.Threading;
using System.Diagnostics;
@@ -204,8 +204,6 @@ namespace Lidgren.Network
NetTuple<NetMessageType, int> tuple;
m_queuedOutgoingAcks.TryDequeue(out tuple);
//m_peer.LogVerbose("Sending ack for " + tuple.Item1 + "#" + tuple.Item2);
sendBuffer[m_sendBufferWritePtr++] = (byte)tuple.Item1;
sendBuffer[m_sendBufferWritePtr++] = (byte)tuple.Item2;
sendBuffer[m_sendBufferWritePtr++] = (byte)(tuple.Item2 >> 8);
@@ -228,7 +226,6 @@ namespace Lidgren.Network
NetTuple<NetMessageType, int> incAck;
while (m_queuedIncomingAcks.TryDequeue(out incAck))
{
//m_peer.LogVerbose("Received ack for " + acktp + "#" + seqNr);
NetSenderChannelBase chan = m_sendChannels[(int)incAck.Item1 - 1];
if (chan == null)
chan = CreateSenderChannel(incAck.Item1);

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2010 Michael Lidgren
/* Copyright (c) 2010 Michael Lidgren
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without
@@ -91,8 +91,6 @@ namespace Lidgren.Network
/// </summary>
public int ResentMessages { get { return m_resentMessagesDueToHole + m_resentMessagesDueToDelay; } }
// public double LastSendRespondedTo { get { return m_connection.m_lastSendRespondedTo; } }
#if USE_RELEASE_STATISTICS
internal void PacketSent(int numBytes, int numMessages)
{
@@ -156,7 +154,6 @@ namespace Lidgren.Network
public override string ToString()
{
StringBuilder bdr = new StringBuilder();
//bdr.AppendLine("Average roundtrip time: " + NetTime.ToReadable(m_connection.m_averageRoundtripTime));
bdr.AppendLine("Sent " + m_sentBytes + " bytes in " + m_sentMessages + " messages in " + m_sentPackets + " packets");
bdr.AppendLine("Received " + m_receivedBytes + " bytes in " + m_receivedMessages + " messages in " + m_receivedPackets + " packets");

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
using System.Collections.Generic;
@@ -131,7 +131,6 @@ namespace Lidgren.Network
Buffer.BlockCopy(im.m_data, ptr, info.Data, offset, im.LengthBytes - ptr);
int cnt = info.ReceivedChunks.Count();
//LogVerbose("Found fragment #" + chunkNumber + " in group " + group + " offset " + offset + " of total bits " + totalBits + " (total chunks done " + cnt + ")");
LogVerbose("Received fragment " + chunkNumber + " of " + totalNumChunks + " (" + cnt + " chunks received)");

View File

@@ -1,4 +1,4 @@
#if !__ANDROID__ && !IOS
#if !__ANDROID__ && !IOS
#define IS_MAC_AVAILABLE
#endif
@@ -370,9 +370,6 @@ namespace Lidgren.Network
if (!m_socket.Poll(1000, SelectMode.SelectRead)) // wait up to 1 ms for data to arrive
return;
//if (m_socket == null || m_socket.Available < 1)
// return;
do
{
int bytesReceived = 0;
@@ -398,8 +395,6 @@ namespace Lidgren.Network
if (bytesReceived < NetConstants.HeaderByteSize)
return;
//LogVerbose("Received " + bytesReceived + " bytes");
IPEndPoint ipsender = (IPEndPoint)m_senderRemote;
if (ipsender.Port == 1900)
@@ -648,7 +643,6 @@ namespace Lidgren.Network
internal void AcceptConnection(NetConnection conn)
{
// LogDebug("Accepted connection " + conn);
conn.InitExpandMTU(NetTime.Now);
if (m_handshakes.Remove(conn.m_remoteEndPoint) == false)

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2010 Michael Lidgren
/* Copyright (c) 2010 Michael Lidgren
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without
@@ -63,7 +63,6 @@ namespace Lidgren.Network
if (m == 0.0f && r == 0.0f)
{
// no latency simulation
// LogVerbose("Sending packet " + numBytes + " bytes");
bool wasSent = ActuallySendPacket(m_sendBuffer, numBytes, target, out connectionReset);
// TODO: handle wasSent == false?
return;
@@ -87,8 +86,6 @@ namespace Lidgren.Network
m_delayedPackets.Add(p);
}
// LogVerbose("Sending packet " + numBytes + " bytes - delayed " + NetTime.ToReadable(delay));
}
private void SendDelayedPackets()
@@ -142,8 +139,6 @@ namespace Lidgren.Network
int bytesSent = m_socket.SendTo(data, 0, numBytes, SocketFlags.None, target);
if (numBytes != bytesSent)
LogWarning("Failed to send the full " + numBytes + "; only " + bytesSent + " bytes sent in packet!");
// LogDebug("Sent " + numBytes + " bytes");
}
catch (SocketException sx)
{

View File

@@ -1,4 +1,4 @@
using System;
using System;
namespace Lidgren.Network
{
@@ -80,8 +80,6 @@ namespace Lidgren.Network
// mix some semi-random properties
int seed = (int)Environment.TickCount;
seed ^= forObject.GetHashCode();
//seed ^= (int)(Stopwatch.GetTimestamp());
//seed ^= (int)(Environment.WorkingSet); // will return 0 on mono
int extraSeed = System.Threading.Interlocked.Increment(ref s_extraSeed);
@@ -265,44 +263,6 @@ namespace Lidgren.Network
this.x = x; this.y = y; this.z = z; this.w = w;
}
// /// <summary>
// /// A version of NextBytes that uses a pointer to set 4 bytes of the byte buffer in one operation
// /// thus providing a nice speedup. The loop is also partially unrolled to allow out-of-order-execution,
// /// this results in about a x2 speedup on an AMD Athlon. Thus performance may vary wildly on different CPUs
// /// depending on the number of execution units available.
// ///
// /// Another significant speedup is obtained by setting the 4 bytes by indexing pDWord (e.g. pDWord[i++]=w)
// /// instead of adjusting it dereferencing it (e.g. *pDWord++=w).
// ///
// /// Note that this routine requires the unsafe compilation flag to be specified and so is commented out by default.
// /// </summary>
// /// <param name="buffer"></param>
// public unsafe void NextBytesUnsafe(byte[] buffer)
// {
// if(buffer.Length % 8 != 0)
// throw new ArgumentException("Buffer length must be divisible by 8", "buffer");
//
// uint x=this.x, y=this.y, z=this.z, w=this.w;
//
// fixed(byte* pByte0 = buffer)
// {
// uint* pDWord = (uint*)pByte0;
// for(int i=0, len=buffer.Length>>2; i < len; i+=2)
// {
// uint t=(x^(x<<11));
// x=y; y=z; z=w;
// pDWord[i] = w = (w^(w>>19))^(t^(t>>8));
//
// t=(x^(x<<11));
// x=y; y=z; z=w;
// pDWord[i+1] = w = (w^(w>>19))^(t^(t>>8));
// }
// }
//
// this.x=x; this.y=y; this.z=z; this.w=w;
// }
#endregion
#region Public Methods [Methods not present on System.Random]

View File

@@ -1,4 +1,4 @@
using System;
using System;
namespace Lidgren.Network
{
@@ -32,13 +32,6 @@ namespace Lidgren.Network
if (relate == 0)
{
// Log("Received message #" + message.SequenceNumber + " right on time");
//
// excellent, right on time
//
//m_peer.LogVerbose("Received RIGHT-ON-TIME " + message);
AdvanceWindow();
m_peer.ReleaseMessage(message);

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
namespace Lidgren.Network
@@ -85,8 +85,7 @@ namespace Lidgren.Network
startSlot = m_windowSize - 1;
seqNr--;
}
//m_connection.m_peer.LogVerbose("Resending due to delay #" + seqNr + " " + om.ToString());
m_connection.m_statistics.MessageResent(MessageResendReason.Delay);
m_connection.QueueSendMessage(om, seqNr);
@@ -156,15 +155,10 @@ namespace Lidgren.Network
int relate = NetUtility.RelativeSequenceNumber(seqNr, m_windowStart);
if (relate < 0)
{
//m_connection.m_peer.LogDebug("Received late/dupe ack for #" + seqNr);
return; // late/duplicate ack
}
if (relate == 0)
{
//m_connection.m_peer.LogDebug("Received right-on-time ack for #" + seqNr);
// ack arrived right on time
NetException.Assert(seqNr == m_windowStart);
@@ -175,13 +169,11 @@ namespace Lidgren.Network
// advance window if we already have early acks
while (m_receivedAcks.Get(m_windowStart))
{
//m_connection.m_peer.LogDebug("Using early ack for #" + m_windowStart + "...");
m_receivedAcks[m_windowStart] = false;
DestoreMessage(m_windowStart % m_windowSize);
NetException.Assert(m_storedMessages[m_windowStart % m_windowSize].Message == null); // should already be destored
m_windowStart = (m_windowStart + 1) % NetConstants.NumSequenceNumbers;
//m_connection.m_peer.LogDebug("Advancing window to #" + m_windowStart);
}
return;
@@ -194,8 +186,6 @@ namespace Lidgren.Network
// ... or the ack for that message was lost
//
//m_connection.m_peer.LogDebug("Received early ack for #" + seqNr);
int sendRelate = NetUtility.RelativeSequenceNumber(seqNr, m_sendStart);
if (sendRelate <= 0)
{
@@ -223,12 +213,8 @@ namespace Lidgren.Network
rnr--;
if (rnr < 0)
rnr = NetConstants.NumSequenceNumbers - 1;
if (m_receivedAcks[rnr])
{
// m_connection.m_peer.LogDebug("Not resending #" + rnr + " (since we got ack)");
}
else
if (!m_receivedAcks[rnr])
{
int slot = rnr % m_windowSize;
NetException.Assert(m_storedMessages[slot].Message != null);
@@ -236,7 +222,6 @@ namespace Lidgren.Network
{
// just sent once; resend immediately since we found gap in ack sequence
NetOutgoingMessage rmsg = m_storedMessages[slot].Message;
//m_connection.m_peer.LogVerbose("Resending #" + rnr + " (" + rmsg + ")");
if (now - m_storedMessages[slot].LastSent < (m_resendDelay * 0.35f))
{

View File

@@ -1,4 +1,4 @@
using System;
using System;
namespace Lidgren.Network
{
@@ -29,12 +29,6 @@ namespace Lidgren.Network
if (relate == 0)
{
// Log("Received message #" + message.SequenceNumber + " right on time");
//
// excellent, right on time
//
AdvanceWindow();
m_peer.ReleaseMessage(message);
return;

View File

@@ -1,4 +1,4 @@
using System;
using System;
namespace Lidgren.Network
{
@@ -30,13 +30,6 @@ namespace Lidgren.Network
if (relate == 0)
{
// Log("Received message #" + message.SequenceNumber + " right on time");
//
// excellent, right on time
//
//m_peer.LogVerbose("Received RIGHT-ON-TIME " + message);
AdvanceWindow();
m_peer.ReleaseMessage(message);
@@ -45,16 +38,6 @@ namespace Lidgren.Network
while (m_earlyReceived[nextSeqNr % m_windowSize])
{
//message = m_withheldMessages[nextSeqNr % m_windowSize];
//NetException.Assert(message != null);
// remove it from withheld messages
//m_withheldMessages[nextSeqNr % m_windowSize] = null;
//m_peer.LogVerbose("Releasing withheld message #" + message);
//m_peer.ReleaseMessage(message);
AdvanceWindow();
nextSeqNr++;
}
@@ -78,8 +61,6 @@ namespace Lidgren.Network
}
m_earlyReceived.Set(message.m_sequenceNumber % m_windowSize, true);
//m_peer.LogVerbose("Received " + message + " WITHHOLDING, waiting for " + m_windowStart);
//m_withheldMessages[message.m_sequenceNumber % m_windowSize] = message;
m_peer.ReleaseMessage(message);
}

View File

@@ -1,4 +1,4 @@
#define USE_SHA256
#define USE_SHA256
using System;
using System.Security.Cryptography;
@@ -75,8 +75,7 @@ namespace Lidgren.Network
byte[] total = new byte[innerHash.Length + salt.Length];
Buffer.BlockCopy(salt, 0, total, 0, salt.Length);
Buffer.BlockCopy(innerHash, 0, total, salt.Length, innerHash.Length);
// x ie. H(salt || H(username || ":" || password))
return new NetBigInteger(NetUtility.ToHexString(sha.ComputeHash(total)), 16).ToByteArrayUnsigned();
}
@@ -139,7 +138,7 @@ namespace Lidgren.Network
string one = NetUtility.ToHexString(clientPublicEphemeral);
string two = NetUtility.ToHexString(serverPublicEphemeral);
int len = 66; // Math.Max(one.Length, two.Length);
int len = 66;
string ccstr = one.PadLeft(len, '0') + two.PadLeft(len, '0');
byte[] cc = NetUtility.ToByteArray(ccstr);

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.IO;
using System.Xml;
using System.Net;
@@ -40,9 +40,6 @@ namespace Lidgren.Network
peer.Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
peer.RawSend(arr, 0, arr.Length, new IPEndPoint(IPAddress.Broadcast, 1900));
peer.Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false);
// allow some extra time for router to respond
// System.Threading.Thread.Sleep(50);
}
internal void ExtractServiceUrl(string resp)

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
namespace Lidgren.Network
@@ -94,15 +94,10 @@ namespace Lidgren.Network
int relate = NetUtility.RelativeSequenceNumber(seqNr, m_windowStart);
if (relate < 0)
{
//m_connection.m_peer.LogDebug("Received late/dupe ack for #" + seqNr);
return; // late/duplicate ack
}
if (relate == 0)
{
//m_connection.m_peer.LogDebug("Received right-on-time ack for #" + seqNr);
// ack arrived right on time
NetException.Assert(seqNr == m_windowStart);

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2010 Michael Lidgren
/* Copyright (c) 2010 Michael Lidgren
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without
@@ -107,7 +107,6 @@ namespace Lidgren.Network
{
if (ex.SocketErrorCode == SocketError.HostNotFound)
{
//LogWrite(string.Format(CultureInfo.InvariantCulture, "Failed to resolve host '{0}'.", ipOrHost));
callback(null);
return;
}
@@ -140,7 +139,6 @@ namespace Lidgren.Network
{
if (ex.SocketErrorCode == SocketError.HostNotFound)
{
//LogWrite(string.Format(CultureInfo.InvariantCulture, "Failed to resolve host '{0}'.", ipOrHost));
callback(null);
}
else
@@ -189,7 +187,6 @@ namespace Lidgren.Network
{
if (ex.SocketErrorCode == SocketError.HostNotFound)
{
//LogWrite(string.Format(CultureInfo.InvariantCulture, "Failed to resolve host '{0}'.", ipOrHost));
return null;
}
else
@@ -486,12 +483,6 @@ namespace Lidgren.Network
internal static int RelativeSequenceNumber(int nr, int expected)
{
return (nr - expected + NetConstants.NumSequenceNumbers + (NetConstants.NumSequenceNumbers / 2)) % NetConstants.NumSequenceNumbers - (NetConstants.NumSequenceNumbers / 2);
// old impl:
//int retval = ((nr + NetConstants.NumSequenceNumbers) - expected) % NetConstants.NumSequenceNumbers;
//if (retval > (NetConstants.NumSequenceNumbers / 2))
// retval -= NetConstants.NumSequenceNumbers;
//return retval;
}
/// <summary>

View File

@@ -0,0 +1,9 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
<Target Name="CopyResourcesFromShared">
<ItemGroup>
<_ResourceFiles Include="$(SolutionDir)bin\Shared\Resources\**\*.*" />
</ItemGroup>
<RemoveDir Directories="$(OutputPath)Resources" />
<Copy SourceFiles="@(_ResourceFiles)" DestinationFolder="$(OutputPath)Resources\%(RecursiveDir)" />
</Target>
</Project>

View File

@@ -0,0 +1,27 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
<!-- MSBuild hurts and I can't find a foolproof way to detect platform. -->
<PropertyGroup>
<OS Condition="'$(OS)' == ''">Windows_NT</OS>
</PropertyGroup>
<Choose>
<When Condition="'$(OS)' != 'Unix'">
<PropertyGroup>
<ActualOS>Windows</ActualOS>
</PropertyGroup>
</When>
<!-- Folders that *probably* only exist on MacOS and not Linux. -->
<When Condition="Exists('/Volumes') And Exists('/System') And Exists('/Library')" >
<PropertyGroup>
<ActualOS>MacOS</ActualOS>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<ActualOS>Linux</ActualOS>
</PropertyGroup>
</Otherwise>
</Choose>
<PropertyGroup>
<TargetOS Condition="'$(TargetOS)' == ''">$(ActualOS)</TargetOS>
</PropertyGroup>
</Project>

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<DirectedGraph GraphDirection="LeftToRight" Layout="Sugiyama" xmlns="http://schemas.microsoft.com/vs/2009/dgml">
<Nodes>
<Node Id="Client" Category="Project" Label="Client" />
</Nodes>
<Links />
<Categories>
<Category Id="Project" />
</Categories>
<Properties>
<Property Id="GraphDirection" DataType="Microsoft.VisualStudio.Progression.Layout.GraphDirection" />
<Property Id="Label" Label="Label" Description="Displayable label of an Annotatable object" DataType="System.String" />
<Property Id="Layout" DataType="System.String" />
</Properties>
<Styles>
<Style TargetType="Node" GroupLabel="Project" ValueLabel="True">
<Condition Expression="HasCategory('Project')" />
<Setter Property="Background" Value="Blue" />
</Style>
</Styles>
</DirectedGraph>

View File

@@ -3,8 +3,6 @@
name: Janitor Jumpsuit
components:
- type: Transform
- type: Velocity
- type: Direction
- type: Clickable
- type: WearableAnimatedSprite
sprite: player_jumpsuit_gray
@@ -13,7 +11,7 @@
- type: Icon
icon: janitorsuit
- type: BasicMover
- type: BoundingBox
- type: Physics
mass: 5
@@ -22,8 +20,6 @@
name: Shoes
components:
- type: Transform
- type: Velocity
- type: Direction
- type: Clickable
- type: WearableAnimatedSprite
sprite: player_toolbox
@@ -32,6 +28,6 @@
- type: Icon
icon: shoes
- type: BasicMover
- type: BoundingBox
- type: Physics
mass: 5

View File

@@ -3,9 +3,7 @@
name: Toolbox
components:
- type: Transform
- type: Velocity
- type: Clickable
- type: Direction
- type: WearableAnimatedSprite
sprite: player_toolbox
notWornSprite: toolbox_r
@@ -13,6 +11,6 @@
- type: Icon
icon: toolbox_r
- type: BasicMover
- type: BoundingBox
- type: Physics
mass: 5

View File

@@ -3,8 +3,6 @@
name: Door
components:
- type: Transform
- type: Velocity
- type: Direction
- type: Clickable
- type: Sprite
drawdepth: FloorPlaceable
@@ -15,5 +13,5 @@
- type: Icon
icon: door_ew
- type: BasicMover
- type: BoundingBox
- type: Collidable

View File

@@ -3,8 +3,6 @@
name: Mop
components:
- type: Transform
- type: Velocity
- type: Direction
- type: Clickable
- type: WearableAnimatedSprite
sprite: player_toolbox
@@ -13,5 +11,6 @@
- type: Icon
icon: mop
- type: BoundingBox
- type: Physics
- type: Clickable

View File

@@ -3,8 +3,6 @@
name: Wall Light
components:
- type: Transform
- type: Velocity
- type: Direction
- type: Clickable
- type: Sprite
sprites:
@@ -13,7 +11,6 @@
- type: Icon
icon: wall_light
- type: BasicMover
- type: PointLight
lightoffsetx: 0
lightoffsety: 0

View File

@@ -1,10 +1,8 @@
- type: entity
- type: entity
id: HumanMob
name: Urist McHuman
components:
- type: Transform
- type: Velocity
- type: Direction
- type: Clickable
- type: AnimatedSprite
sprite: player
@@ -12,12 +10,14 @@
- type: Icon
icon: player
- type: BasicMover
- type: BoundingBox
sizeX: 0.9
sizeY: 0.9
- type: ParticleSystem
- type: Physics
mass: 5
- type: Hitbox
sizeX: 25
sizeY: 25
- type: Collidable
DebugColor: "#0000FF"

View File

@@ -1,10 +1,8 @@
- type: entity
- type: entity
id: Worktop
name: Worktop
components:
- type: Transform
- type: Velocity
- type: Direction
- type: Clickable
- type: Sprite
sprites:
@@ -14,11 +12,10 @@
- type: Icon
icon: worktop_single
- type: BasicMover
- type: Hitbox
sizeX: 64
sizeY: 47
offsetY: 8
- type: BoundingBox
sizeX: 2
sizeY: 1.4
offsetY: 0.25
- type: Collidable
DebugColor: "#0000FF"

View File

@@ -3,15 +3,11 @@
name: Extinguisher Cabinet
components:
- type: Transform
- type: Velocity
- type: Direction
- type: Clickable
- type: Sprite
sprites:
- fire_extinguisher
- type: BasicMover
placement:
mode: AlignWall
range: 200
@@ -25,14 +21,11 @@
name: Fire Alarm
components:
- type: Transform
- type: Velocity
- type: Direction
- type: Clickable
- type: Sprite
sprites:
- fire_alarm_off
- type: BasicMover
- type: Icon
icon: fire_alarm_off
@@ -49,14 +42,11 @@
name: Medical Cabinet
components:
- type: Transform
- type: Velocity
- type: Direction
- type: Clickable
- type: Sprite
sprites:
- med_cabinet
- type: BasicMover
- type: Icon
icon: med_cabinet

View File

@@ -1,8 +1,8 @@
using OpenTK.Graphics;
using OpenTK;
using OpenTK.Graphics;
using SFML.Graphics;
using SFML.System;
using SFML.Window;
using SS14.Client.Graphics.Event;
using SS14.Client.Graphics.Render;
using SS14.Client.Graphics.Settings;
using SS14.Client.Graphics.Shader;
@@ -11,7 +11,9 @@ using System;
using System.Reflection;
using SS14.Shared.Network;
using SS14.Shared.Timing;
using SS14.Shared.Maths;
using Vector2i = SS14.Shared.Maths.Vector2i;
using Vector2u = SS14.Shared.Maths.Vector2u;
namespace SS14.Client.Graphics
{
@@ -20,28 +22,35 @@ namespace SS14.Client.Graphics
private static RenderTarget[] renderTargetArray;
public static GameTiming Time { get; private set; }
public static event FrameEventHandler FrameEvent;
public static event EventHandler<FrameEventArgs> FrameEvent;
public static Viewport CurrentClippingViewport;
public delegate void EventHandler();
public static event EventHandler RefreshVideoSettings;
#region Accessors
public static Vector2f WorldCenter { get; set; }
public static Vector2 WorldCenter { get; set; }
public static Vector2u ScreenViewportSize { get; set; }
public static int TileSize { get; set; }
public static FloatRect WorldViewport
/// <summary>
/// Viewport scaling
/// </summary>
public static int TileSize { get; set; } = 32;
public static Box2 WorldViewport
{
get
{
return ScreenToWorld(ScreenViewport);
}
}
public static IntRect ScreenViewport
public static Box2i ScreenViewport
{
get
{
return new IntRect(0, 0, (int)ScreenViewportSize.X, (int)ScreenViewportSize.Y);
return Box2i.FromDimensions(0, 0, (int)ScreenViewportSize.X, (int)ScreenViewportSize.Y);
}
}
@@ -94,7 +103,7 @@ namespace SS14.Client.Graphics
{
Initialize();
}
if ((Screen != null) && (renderTargetArray == null))
throw new InvalidOperationException("Something has gone terribly wrong!");
@@ -147,7 +156,7 @@ namespace SS14.Client.Graphics
Screen = new CluwneWindow(CluwneLib.Video.getVideoMode(), "Developer Station 14", CluwneLib.Video.getWindowStyle());
Screen.SetVerticalSyncEnabled(true);
Screen.SetFramerateLimit(300);
renderTargetArray = new RenderTarget[5];
CurrentClippingViewport = new Viewport(0, 0, Screen.Size.X, Screen.Size.Y);
IsInitialized = true;
@@ -179,7 +188,7 @@ namespace SS14.Client.Graphics
public static void RunIdle(object sender, FrameEventArgs e)
{
FrameEvent(sender, e);
FrameEvent?.Invoke(sender, e);
}
public static void Stop()
@@ -324,7 +333,7 @@ namespace SS14.Client.Graphics
public static void drawHollowCircle(int posX, int posY, int radius,float OutlineThickness, Color OutlineColor)
{
CircleShape Circle = new CircleShape();
Circle.Position = new Vector2f(posX, posY);
Circle.Position = new Vector2f(posX-radius, posY-radius);
Circle.Radius = radius;
Circle.FillColor = Color.Transparent;
Circle.OutlineThickness = OutlineThickness;
@@ -341,7 +350,7 @@ namespace SS14.Client.Graphics
/// <param name="radius"> Radius of Cirle </param>
/// <param name="color"> Fill Color </param>
/// <param name="vector2"></param>
public static void drawCircle(float posX, float posY, int radius, Color color, Vector2f vector2)
public static void drawCircle(float posX, float posY, int radius, Color color, Vector2 vector2)
{
CircleShape Circle = new CircleShape();
Circle.Position = new Vector2f(posX, posY);
@@ -420,9 +429,9 @@ namespace SS14.Client.Graphics
/// <param name="text"> Text to render </param>
/// <param name="size"> Size of the font </param>
/// <param name="textColor"> Color of the text </param>
public static void drawText(float posX, float posY, string text, uint size, Color textColor)
public static void drawText(float posX, float posY, string text, uint size, Color textColor, Font font)
{
Text _text = new Text(text, new Font(@"..\..\Resources\Fonts\bluehigh.ttf"));
Text _text = new Text(text, font);
_text.Position = new SFML.System.Vector2f(posX, posY);
_text.Color = textColor;
_text.CharacterSize = size;
@@ -438,81 +447,70 @@ namespace SS14.Client.Graphics
/// <summary>
/// Transforms a point from the world (tile) space, to screen (pixel) space.
/// </summary>
public static Vector2f WorldToScreen(Vector2f point)
public static Vector2 WorldToScreen(Vector2 point)
{
var center = WorldCenter;
return new Vector2f(
(point.X - center.X) * TileSize + ScreenViewportSize.X / 2,
(point.Y - center.Y) * TileSize + ScreenViewportSize.Y / 2
);
return (point - center) * TileSize + ScreenViewportSize / 2;
}
/// <summary>
/// Transforms a rectangle from the world (tile) space, to screen (pixel) space.
/// </summary>
public static FloatRect WorldToScreen(FloatRect rect)
public static Box2 WorldToScreen(Box2 rect)
{
var center = WorldCenter;
return new FloatRect(
(rect.Left - center.X) * TileSize + ScreenViewportSize.X / 2,
(rect.Top - center.Y) * TileSize + ScreenViewportSize.Y / 2,
rect.Width * TileSize,
rect.Height * TileSize
);
var topLeft = new Vector2(rect.Left, rect.Top);
var bottomRight = new Vector2(rect.Right, rect.Bottom);
return new Box2(
WorldToScreen(topLeft),
WorldToScreen(bottomRight)
);
}
public static Vector2f WorldToTile(Vector2f point)
public static Vector2 WorldToTile(Vector2 point)
{
return new Vector2f(
return new Vector2(
(float)Math.Floor(point.X),
(float)Math.Floor(point.Y)
);
);
}
public static Vector2f TileToWorld(Vector2f point)
public static Vector2 TileToWorld(Vector2 point)
{
return new Vector2f(
return new Vector2(
point.X + 0.5f,
point.Y + 0.5f
);
);
}
/// <summary>
/// Transforms a point from the screen (pixel) space, to world (tile) space.
/// </summary>
public static Vector2f ScreenToWorld(Vector2i point)
public static Vector2 ScreenToWorld(Vector2i point)
{
return new Vector2f(
((float)point.X - ScreenViewportSize.X / 2 ) / TileSize + WorldCenter.X,
((float)point.Y - ScreenViewportSize.Y / 2 ) / TileSize + WorldCenter.Y
);
return ((Vector2)point - ScreenViewportSize / 2) / TileSize + WorldCenter;
}
/// <summary>
/// Transforms a rectangle from the screen (pixel) space, to world (tile) space.
/// </summary>
public static FloatRect ScreenToWorld(IntRect rect)
{
var center = WorldCenter;
return new FloatRect(
((float)rect.Left - ScreenViewportSize.X / 2) / TileSize + center.X,
((float)rect.Top - ScreenViewportSize.Y / 2) / TileSize + center.Y,
rect.Width / TileSize,
rect.Height / TileSize
);
}
public static Box2 ScreenToWorld(Box2i rect)
{
var center = WorldCenter;
return new Box2(
((Vector2)rect.TopLeft - ScreenViewportSize / 2) / TileSize + center,
((Vector2)rect.BottomRight - ScreenViewportSize / 2) / TileSize + center
);
}
/// <summary>
/// Scales a vector from pixel coordinates to tile coordinates.
/// </summary>
/// <param name="size"></param>
/// <returns></returns>
public static Vector2f PixelToTile(Vector2f vec)
public static Vector2 PixelToTile(Vector2 vec)
{
return new Vector2f(
vec.X / TileSize,
vec.Y / TileSize
);
return vec / TileSize;
}
/// <summary>
@@ -520,25 +518,25 @@ namespace SS14.Client.Graphics
/// </summary>
/// <param name="size"></param>
/// <returns></returns>
public static FloatRect PixelToTile(FloatRect rect)
{
return new FloatRect(
rect.Left / TileSize,
rect.Top / TileSize,
rect.Width / TileSize,
rect.Height / TileSize
);
}
public static Box2 PixelToTile(Box2 rect)
{
return new Box2(
rect.Left / TileSize,
rect.Top / TileSize,
rect.Right / TileSize,
rect.Bottom / TileSize
);
}
/// <summary>
/// Takes a point in world (tile) coordinates, and rounds it to the nearest pixel.
/// </summary>
public static Vector2f GetNearestPixel(Vector2f worldPoint)
public static Vector2 GetNearestPixel(Vector2 worldPoint)
{
return new Vector2f(
return new Vector2(
(float)Math.Round(worldPoint.X * TileSize) / TileSize,
(float)Math.Round(worldPoint.Y * TileSize) / TileSize
);
);
}
#endregion

View File

@@ -1,22 +0,0 @@
using System;
namespace SS14.Client.Graphics.Event
{
public delegate void FrameEventHandler(object sender, FrameEventArgs e);
public class FrameEventArgs : EventArgs
{
private float _frameDeltaTime;
public FrameEventArgs(float frameDeltaTime)
{
_frameDeltaTime = frameDeltaTime;
}
public float FrameDeltaTime
{
get { return _frameDeltaTime; }
}
}
}

View File

@@ -1,25 +0,0 @@
<configuration>
<dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
<dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
<dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
<dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
<dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
<dllmap os="linux" dll="libX11" target="libX11.so.6"/>
<dllmap os="linux" dll="libXi" target="libXi.so.6"/>
<dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/>
<dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv1_CM.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
<dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
<dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/>
<!-- XQuartz compatibility (X11 on Mac) -->
<dllmap os="osx" dll="libGL.so.1" target="/usr/X11/lib/libGL.dylib"/>
<dllmap os="osx" dll="libX11" target="/usr/X11/lib/libX11.dylib"/>
<dllmap os="osx" dll="libXcursor.so.1" target="/usr/X11/lib/libXcursor.dylib"/>
<dllmap os="osx" dll="libXi" target="/usr/X11/lib/libXi.dylib"/>
<dllmap os="osx" dll="libXinerama" target="/usr/X11/lib/libXinerama.dylib"/>
<dllmap os="osx" dll="libXrandr.so.2" target="/usr/X11/lib/libXrandr.dylib"/>
</configuration>

View File

@@ -1,4 +1,4 @@
using SFML.Graphics;
using SFML.Graphics;
using SFML.System;
using System;
using System.Diagnostics;
@@ -79,18 +79,6 @@ namespace SS14.Client.Graphics.Render
get { return base.Texture; }
}
public IntRect Crop
{
get;
set;
}
public Vector2f Scale
{
get;
set;
}
public bool UseDepthBuffer
{
get;
@@ -233,15 +221,6 @@ namespace SS14.Client.Graphics.Render
CluwneLib.ResetRenderTarget();
}
/// <summary>
/// Deconstructs and disposes this instance
/// </summary>
protected override void Destroy(bool disposing)
{
GC.Collect();
}
#endregion
#region Drawing Methods
@@ -375,26 +354,7 @@ namespace SS14.Client.Graphics.Render
}
/// <summary>
/// Scale & optionally crop
/// </summary>
/// <param name="destination">The exact rectangle you wish to fill - scales to this size</param>
/// <param name="optionalcrop">To take a subset of the original texture instead of the whole texture</param>
/// <param name="color">Color.</param>
// public void Blit(IntRect destination, IntRect optionalcrop, Color color)
// {
// CluwneSprite _blit;
// Display();
// if (optionalcrop == null)
// _blit = new CluwneSprite("_blit" + key, this);
// else
// _blit = new CluwneSprite("_blit" + key, base.Texture, optionalcrop);
// _blit.Color = color.ToSFMLColor();
// _blit.Draw(destination);
// }
#endregion
}
}

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
<Import Project="..\MSBuild\SS14.Properties.targets" />
<PropertyGroup>
<ProjectType>Local</ProjectType>
<ProjectGuid>{302B877E-0000-0000-0000-000000000000}</ProjectGuid>
@@ -21,6 +22,7 @@
</FileUpgradeFlags>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<TargetFrameworkProfile />
<AllowedReferenceRelatedFileExtensions>.pdb;.dll.config</AllowedReferenceRelatedFileExtensions>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
@@ -31,7 +33,7 @@
<DebugSymbols>True</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<Optimize>false</Optimize>
<OutputPath>..\bin\Graphics\</OutputPath>
<OutputPath>$(SolutionDir)bin\Graphics\</OutputPath>
<RegisterForComInterop>False</RegisterForComInterop>
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<WarningLevel>4</WarningLevel>
@@ -46,19 +48,20 @@
<DefineConstants>TRACE</DefineConstants>
<FileAlignment>4096</FileAlignment>
<Optimize>True</Optimize>
<OutputPath>..\bin\</OutputPath>
<OutputPath>$(SolutionDir)bin\Graphics\</OutputPath>
<RegisterForComInterop>False</RegisterForComInterop>
<RemoveIntegerChecks>False</RemoveIntegerChecks>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
<AllowedReferenceRelatedFileExtensions>.dll.config</AllowedReferenceRelatedFileExtensions>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp">
<Name>Microsoft.CSharp</Name>
</Reference>
<Reference Include="OpenTK, Version=3.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>..\packages\OpenTK.3.0.0-pre\lib\net20\OpenTK.dll</HintPath>
<HintPath>$(SolutionDir)packages\OpenTK.3.0.0-pre\lib\net20\OpenTK.dll</HintPath>
</Reference>
<Reference Include="sfmlnet-graphics-2">
<Name>sfmlnet-graphics-2</Name>
@@ -86,9 +89,6 @@
<Compile Include="Enums\GraphicsEnums.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Event\FrameEvent.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Shader\TechniqueList.cs" />
<Compile Include="Sprite\AnimationInfo.cs" />
<Compile Include="Sprite\SpriteInfo.cs" />
@@ -143,25 +143,22 @@
<Name>SS14.Shared</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="csfml-graphics-2.dll">
<ItemGroup Condition="'$(TargetOS)' == 'Windows'">
<Content Include="..\Third-Party\extlibs\csfml-graphics-2.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="csfml-network-2.dll">
<Content Include="..\Third-Party\extlibs\csfml-system-2.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="csfml-system-2.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="csfml-window-2.dll">
<Content Include="..\Third-Party\extlibs\csfml-window-2.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="OpenTK.dll.config">
<Content Include="$(SolutionDir)packages\OpenTK.3.0.0-pre\content\OpenTK.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</Content>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
@@ -171,4 +168,4 @@
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>
</Project>

View File

@@ -1,3 +1,4 @@
using OpenTK;
using SFML.System;
using SS14.Client.Graphics.Render;
using SS14.Shared.Maths;
@@ -60,7 +61,7 @@ namespace SS14.Client.Graphics.Shader
}
public void SetParameter(string Parameter, Vector4f vec4)
public void SetParameter(string Parameter, Vector4 vec4)
{
base.SetParameter(Parameter, vec4.X, vec4.Y, vec4.Z, vec4.W);
}
@@ -82,15 +83,12 @@ namespace SS14.Client.Graphics.Shader
}
}
public void SetParameter(string Parameter, Vector4f[] vec4array)
public void SetParameter(string Parameter, Vector4[] vec4array)
{
for (int i = 0; i < vec4array.Length; i++)
{
this.SetParameter(Parameter + i, vec4array[i]);
}
}
}
}

View File

@@ -1,11 +1,12 @@
using SFML.Graphics;
using SFML.System;
using SS14.Shared.Maths;
namespace SS14.Client.Graphics
{
public static class SpriteExt
{
public static void SetTransformToRect(this SFML.Graphics.Sprite sprite, IntRect rect)
public static void SetTransformToRect(this SFML.Graphics.Sprite sprite, Box2i rect)
{
sprite.Scale = new SFML.System.Vector2f((float)rect.Width / (float)sprite.TextureRect.Width, (float)rect.Height / (float)sprite.TextureRect.Height);
sprite.Position = new Vector2f(rect.Left, rect.Top);

View File

@@ -1,4 +1,4 @@
using SFML.Graphics;
using SFML.Graphics;
using SFML.System;
using System;
using System.Collections.Generic;
@@ -11,7 +11,7 @@ namespace SS14.Client.Graphics.Sprite
/// </summary>
[DebuggerDisplay("[SpriteBatch] IsDrawing: {Drawing} | ")]
public class SpriteBatch : Drawable
{
{
private QueueItem activeItem;
private List<QueueItem> QueuedTextures = new List<QueueItem>();
@@ -19,15 +19,14 @@ namespace SS14.Client.Graphics.Sprite
private readonly uint Max;
private int count;
private bool Drawing;
private uint queueCount;
public int Count
{
get { return count; }
}
public BlendMode BlendingSettings;
public SpriteBatch(uint maxCapacity = 100000)
{
Max = maxCapacity * 4;
@@ -35,7 +34,7 @@ namespace SS14.Client.Graphics.Sprite
}
public void BeginDrawing()
{
{
count = 0;
// we use these a lot, and the overall number of textures
// remains stable, so recycle them to avoid excess calls into
@@ -52,13 +51,13 @@ namespace SS14.Client.Graphics.Sprite
}
public void EndDrawing()
{
{
Drawing = false;
}
private void Using(Texture texture)
{
if (!Drawing)
if (!Drawing)
throw new Exception("Call Begin first.");
if (activeItem == null || activeItem.Texture != texture)
@@ -71,7 +70,7 @@ namespace SS14.Client.Graphics.Sprite
else
{
activeItem = new QueueItem(texture);
}
}
QueuedTextures.Add(activeItem);
}
}
@@ -88,7 +87,6 @@ namespace SS14.Client.Graphics.Sprite
Using(S.Texture);
Vector2f Scale = new Vector2f(S.Scale.X, S.Scale.Y);
float sin = 0, cos = 1;
//FloatMath.SinCos(rotation, out sin, out cos);
S.Rotation = S.Rotation / 180 * (float)Math.PI;
sin = (float)Math.Sin(S.Rotation);
@@ -117,7 +115,7 @@ namespace SS14.Client.Graphics.Sprite
activeItem.Verticies.Append
(
new Vertex(
new SFML.System.Vector2f(
new SFML.System.Vector2f(
pX * cos - pY * sin + S.Position.X,
pX * sin + pY * cos + S.Position.Y),
S.Color,
@@ -156,65 +154,6 @@ namespace SS14.Client.Graphics.Sprite
);
}
/*
public unsafe void Draw(Texture texture, FloatRect rec, IntRect src, Color color)
{
var index = Create(texture);
fixed (Vertex* fptr = vertices)
{
var ptr = fptr + index;
ptr->Position.X = rec.Left;
ptr->Position.Y = rec.Top;
ptr->TexCoords.X = src.Left;
ptr->TexCoords.Y = src.Top;
ptr->Color = color;
ptr++;
ptr->Position.X = rec.Left + rec.Width;
ptr->Position.Y = rec.Top;
ptr->TexCoords.X = src.Left + src.Width;
ptr->TexCoords.Y = src.Top;
ptr->Color = color;
ptr++;
ptr->Position.X = rec.Left + rec.Width;
ptr->Position.Y = rec.Top + rec.Height;
ptr->TexCoords.X = src.Left + src.Width;
ptr->TexCoords.Y = src.Top + src.Height;
ptr->Color = color;
ptr++;
ptr->Position.X = rec.Left;
ptr->Position.Y = rec.Top + rec.Height;
ptr->TexCoords.X = src.Left;
ptr->TexCoords.Y = src.Top + src.Height;
ptr->Color = color;
}
}
public void Draw(Texture texture, FloatRect rec, Color color)
{
int width = 1, height = 1;
if (texture != null)
{
width = (int)texture.Size.X;
height = (int)texture.Size.Y;
}
Draw(texture, rec, new IntRect(0, 0, width, height), color);
}
public void Draw(Texture texture, Vector2f pos, Color color)
{
if (texture == null) throw new ArgumentNullException();
var width = (int)texture.Size.X;
var height = (int)texture.Size.Y;
Draw(texture, new FloatRect(pos.X, pos.Y, width, height), new IntRect(0, 0, width, height), color);
}
*/
public void Draw(RenderTarget target, RenderStates Renderstates)
{
if (Drawing) throw new Exception("Call End first.");

View File

@@ -1,4 +1,4 @@
using SFML.System;
using OpenTK;
namespace SS14.Client.Graphics.Sprite
{
@@ -10,7 +10,7 @@ namespace SS14.Client.Graphics.Sprite
public struct SpriteInfo
{
public string Name;
public Vector2f Offsets;
public Vector2f Size;
public Vector2 Offsets;
public Vector2 Size;
}
}

View File

@@ -1,6 +1,9 @@
using SFML.Graphics;
using SFML.System;
using OpenTK;
using SS14.Client.Graphics.Interface;
using SS14.Shared.Utility;
using Vector2i = SS14.Shared.Maths.Vector2i;
namespace SS14.Client.Graphics.Sprite
{
@@ -41,19 +44,6 @@ namespace SS14.Client.Graphics.Sprite
_textSprite = new Text(text, font, 14);
}
/// <summary>
/// Creates a TextSprite
/// </summary>
/// <param name="Label"> ID of the TextSprite</param>
/// <param name="x"> position X of TextSprite </param>
/// <param name="y"> Position Y of TextSprite </param>
/// <param name="width"> Width of TextSprite </param>
/// <param name="height"> Height of TextSprite </param>
// public TextSprite(string Label, int x, int y, int width, int height)
// {
// this.Position = new Vector2(x, y);
// }
/// <summary>
/// Draws the TextSprite to the CurrentRenderTarget
/// </summary>
@@ -65,13 +55,13 @@ namespace SS14.Client.Graphics.Sprite
public void Draw()
{
_textSprite.Position = new Vector2f(Position.X, Position.Y); // -(_textSprite.GetLocalBounds().Height/2f));
_textSprite.Position = new Vector2f(Position.X, Position.Y);
_textSprite.Color = Color;
CluwneLib.CurrentRenderTarget.Draw(_textSprite);
if (CluwneLib.Debug.DebugTextboxes)//CluwneLib.Debug()
if (CluwneLib.Debug.DebugTextboxes)
{
FloatRect fr = _textSprite.GetGlobalBounds();
var fr = _textSprite.GetGlobalBounds().Convert();
CluwneLib.drawHollowRectangle((int)fr.Left, (int)fr.Top, (int)fr.Width, (int)fr.Height, 1.0f, Color.Red);
}
}
@@ -96,9 +86,9 @@ namespace SS14.Client.Graphics.Sprite
return MeasureLine(Text);
}
public Vector2f FindCharacterPos(uint index)
public Vector2 FindCharacterPos(uint index)
{
return _textSprite.FindCharacterPos(index);
return _textSprite.FindCharacterPos(index).Convert();
}
#endregion Methods
@@ -109,7 +99,7 @@ namespace SS14.Client.Graphics.Sprite
public Color Color;
public Vector2f ShadowOffset { get; set; }
public Vector2 ShadowOffset { get; set; }
public bool Shadowed
{

View File

@@ -1,337 +0,0 @@
using SFML.Graphics;
using SFML.System;
using SS14.Client.GameObjects;
using SS14.Client.Interfaces.Collision;
using SS14.Client.Interfaces.Map;
using SS14.Shared.GameObjects;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.IoC;
using SS14.Shared.Maths;
using System;
using System.Collections.Generic;
using System.Linq;
namespace SS14.Client.Collision
{
//Its the bucket list!
/// <summary>
/// Here's what is happening here. Each collidable AABB added to this manager gets tossed into
/// a "bucket". The buckets are subdivisions of the world space in 256-unit blocks.
/// </summary>
public class CollisionManager : ICollisionManager
{
private const int BucketSize = 256;
private readonly Dictionary<CollidableAABB, IEntity> _aabbs;
private readonly Dictionary<Vector2i, int> _bucketIndex;
//Indexed in 256-pixel blocks - 0 = 0, 1 = 256, 2 = 512 etc
private readonly Dictionary<int, CollidableBucket> _buckets;
// each bucket represents a 256x256 block of pixelspace
private int _lastIndex;
/// <summary>
/// Constructor
/// </summary>
public CollisionManager()
{
_bucketIndex = new Dictionary<Vector2i, int>();
_buckets = new Dictionary<int, CollidableBucket>();
_aabbs = new Dictionary<CollidableAABB, IEntity>();
}
#region ICollisionManager members
/// <summary>
/// returns true if collider intersects a collidable under management. Does not trigger Bump.
/// </summary>
/// <param name="collider">Rectangle to check for collision</param>
/// <returns></returns>
public bool IsColliding(FloatRect collider)
{
Vector2f[] points =
{
new Vector2f(collider.Left, collider.Top),
new Vector2f(collider.Right(), collider.Top),
new Vector2f(collider.Right(), collider.Bottom()),
new Vector2f(collider.Left, collider.Bottom())
};
//Get the buckets that correspond to the collider's points.
List<CollidableBucket> buckets = points.Select(GetBucket).Distinct().ToList();
//Get all of the points
var cpoints = new List<CollidablePoint>();
foreach (CollidableBucket bucket in buckets)
{
cpoints.AddRange(bucket.GetPoints());
}
//Expand points to distinct AABBs
List<CollidableAABB> aabBs = (cpoints.Select(cp => cp.ParentAABB)).Distinct().ToList();
//try all of the AABBs against the target rect.
bool collided = false;
foreach (CollidableAABB aabb in aabBs.Where(aabb => aabb.Collidable.AABB.Intersects(collider)))
{
if (aabb.IsHardCollider) //If the collider is supposed to prevent movement
{
collided = true;
}
}
return collided || IoCManager.Resolve<IMapManager>().GetTilesIntersecting(collider, true).Any(t => t.Tile.TileDef.IsCollidable);
}
/// <summary>
/// returns true if collider intersects a collidable under management and calls Bump.
/// </summary>
/// <param name="collider">Rectangle to check for collision</param>
/// <returns></returns>
public bool TryCollide(IEntity entity)
{
return TryCollide(entity, new Vector2f());
}
/// <summary>
/// returns true if collider intersects a collidable under management and calls Bump.
/// </summary>
/// <param name="collider">Rectangle to check for collision</param>
/// <returns></returns>
public bool TryCollide(IEntity entity, Vector2f offset, bool bump = true)
{
var collider = entity.GetComponent<ColliderComponent>();
if (collider == null) return false;
var ColliderAABB = collider.WorldAABB;
if (offset.LengthSquared() > 0)
{
ColliderAABB.Left += offset.X;
ColliderAABB.Top += offset.Y;
}
Vector2f[] points =
{
new Vector2f(ColliderAABB.Left, ColliderAABB.Top),
new Vector2f(ColliderAABB.Right(), ColliderAABB.Top),
new Vector2f(ColliderAABB.Right(), ColliderAABB.Bottom()),
new Vector2f(ColliderAABB.Left, ColliderAABB.Bottom())
};
var aabbs =
points
.Select(GetBucket) // Get the buckets that correspond to the collider's points.
.Distinct()
.SelectMany(b => b.GetPoints()) // Get all of the points
.Select(p => p.ParentAABB) // Expand points to distinct AABBs
.Distinct()
.Where(aabb => aabb.Collidable.AABB.Intersects(ColliderAABB)); //try all of the AABBs against the target rect.
//try all of the AABBs against the target rect.
bool collided = false;
foreach (var aabb in aabbs)
{
if (aabb.IsHardCollider) //If the collider is supposed to prevent movement
{
collided = true;
}
if (bump) aabb.Collidable.Bump(entity);
}
return collided || IoCManager.Resolve<IMapManager>().GetTilesIntersecting(ColliderAABB, true).Any(t => t.Tile.TileDef.IsCollidable);
}
/// <summary>
/// Adds a collidable to the manager.
/// </summary>
/// <param name="collidable"></param>
public void AddCollidable(ICollidable collidable)
{
var c = new CollidableAABB(collidable);
foreach (CollidablePoint p in c.Points)
{
AddPoint(p);
}
if (collidable is IComponent comp)
{
_aabbs.Add(c, comp.Owner);
}
else
_aabbs.Add(c, null);
}
/// <summary>
/// Removes a collidable from the manager
/// </summary>
/// <param name="collidable"></param>
public void RemoveCollidable(ICollidable collidable)
{
KeyValuePair<CollidableAABB, IEntity> ourAABB = _aabbs.FirstOrDefault(a => a.Key.Collidable == collidable);
if (ourAABB.Key.Collidable == null)
return;
foreach (CollidablePoint p in ourAABB.Key.Points)
{
RemovePoint(p);
}
_aabbs.Remove(ourAABB.Key);
}
/// <summary>
/// Updates the collidable in the manager.
/// </summary>
/// <param name="collidable"></param>
public void UpdateCollidable(ICollidable collidable)
{
RemoveCollidable(collidable);
AddCollidable(collidable);
}
#endregion ICollisionManager members
/// <summary>
/// Adds an AABB point to a buckets
/// </summary>
/// <param name="point"></param>
private void AddPoint(CollidablePoint point)
{
CollidableBucket b = GetBucket(point.Coordinates);
b.AddPoint(point);
}
/// <summary>
/// Removes an AABB point from a bucket
/// </summary>
/// <param name="point"></param>
private void RemovePoint(CollidablePoint point)
{
CollidableBucket b = GetBucket(point.Coordinates);
b.RemovePoint(point);
}
/// <summary>
/// Gets a bucket given a point coordinate
/// </summary>
/// <param name="coordinate"></param>
/// <returns></returns>
private CollidableBucket GetBucket(Vector2f coordinate)
{
var key = GetBucketCoordinate(coordinate);
return _bucketIndex.ContainsKey(key)
? _buckets[_bucketIndex[key]]
: CreateBucket(key);
}
private static Vector2i GetBucketCoordinate(Vector2f coordinate)
{
var x = (int)Math.Floor(coordinate.X / BucketSize);
var y = (int)Math.Floor(coordinate.Y / BucketSize);
return new Vector2i(x, y);
}
private CollidableBucket CreateBucket(Vector2i coordinate)
{
if (_bucketIndex.ContainsKey(coordinate))
return _buckets[_bucketIndex[coordinate]];
var b = new CollidableBucket(_lastIndex, coordinate);
_buckets.Add(_lastIndex, b);
_bucketIndex.Add(coordinate, _lastIndex);
_lastIndex++;
return b;
}
}
/// <summary>
/// This class holds points of collision AABBs. It represents a square in the world.
/// </summary>
internal class CollidableBucket
{
private readonly List<CollidablePoint> _points;
private readonly Vector2i _coordinates;
private readonly int _index;
public CollidableBucket(int index, Vector2i coordinates)
{
_index = index;
_coordinates = coordinates;
_points = new List<CollidablePoint>();
}
/// <summary>
/// Adds a CollidablePoint to this bucket
/// </summary>
/// <param name="point"></param>
public void AddPoint(CollidablePoint point)
{
_points.Add(point);
}
/// <summary>
/// Removes a CollidablePoint from this bucket, if it exists.
/// </summary>
/// <param name="point"></param>
public void RemovePoint(CollidablePoint point)
{
if (_points.Contains(point))
_points.Remove(point);
}
public IEnumerable<CollidablePoint> GetPoints()
{
return _points;
}
}
/// <summary>
/// This represents a point of a collision AABB
/// </summary>
internal struct CollidablePoint
{
public Vector2f Coordinates;
public CollidablePointIndex Index;
public CollidableAABB ParentAABB;
public CollidablePoint(CollidablePointIndex index, Vector2f coordinates, CollidableAABB parentAABB)
{
Index = index;
Coordinates = coordinates;
ParentAABB = parentAABB;
}
}
internal enum CollidablePointIndex
{
TopLeft,
TopRight,
BottomRight,
BottomLeft
}
/// <summary>
/// This is our representation of an AABB.
/// </summary>
internal struct CollidableAABB
{
public ICollidable Collidable;
public bool IsHardCollider;
public CollidablePoint[] Points;
public CollidableAABB(ICollidable collidable)
{
Collidable = collidable;
IsHardCollider = Collidable.IsHardCollidable;
Points = new CollidablePoint[4];
float top = Collidable.AABB.Top;
float bottom = Collidable.AABB.Bottom();
float left = Collidable.AABB.Left;
float right = Collidable.AABB.Right();
Points[0] = new CollidablePoint(CollidablePointIndex.TopLeft, new Vector2f(left, top), this);
Points[1] = new CollidablePoint(CollidablePointIndex.TopRight, new Vector2f(right, top), this);
Points[2] = new CollidablePoint(CollidablePointIndex.BottomRight, new Vector2f(right, bottom), this);
Points[3] = new CollidablePoint(CollidablePointIndex.BottomLeft, new Vector2f(left, bottom), this);
}
}
}

View File

@@ -22,7 +22,7 @@ namespace SS14.Client.Console
{
var entitymanager = IoCManager.Resolve<IEntityManager>();
foreach (IEntity e in entitymanager.GetEntities(new EntityQuery()))
foreach (IEntity e in entitymanager.GetEntities(new ComponentEntityQuery()))
{
console.AddLine($"entity {e.Uid}, {e.Prototype.Name}.", Color.White);
}

View File

@@ -37,7 +37,7 @@ namespace SS14.Client.Console
return false;
}
// TODO: Maybe have a server side help?
return false; // return true;
return false;
}
IConsoleCommand command = console.Commands[commandname];
console.AddLine(string.Format("{0} - {1}", command.Command, command.Description), Color.White);

View File

@@ -1,76 +0,0 @@
// TODO: Re-add these.
/*
switch (command)
{
case "addparticles": //This is only clientside.
if (args.Count >= 3)
{
Entity target = null;
if (args[1].ToLowerInvariant() == "player")
{
var plrMgr = IoCManager.Resolve<IPlayerManager>();
if (plrMgr != null)
if (plrMgr.ControlledEntity != null) target = plrMgr.ControlledEntity;
}
else
{
var entMgr = IoCManager.Resolve<IEntityManagerContainer>();
if (entMgr != null)
{
int entUid = int.Parse(args[1]);
target = entMgr.EntityManager.GetEntity(entUid);
}
}
if (target != null)
{
if (!target.HasComponent(ComponentFamily.Particles))
{
var entMgr = IoCManager.Resolve<IEntityManagerContainer>();
var compo = (IParticleSystemComponent)entMgr.EntityManager.ComponentFactory.GetComponent("ParticleSystemComponent");
target.AddComponent(ComponentFamily.Particles, compo);
}
else
{
var entMgr = IoCManager.Resolve<IEntityManagerContainer>();
var compo = (IParticleSystemComponent)entMgr.EntityManager.ComponentFactory.GetComponent("ParticleSystemComponent");
target.AddComponent(ComponentFamily.Particles, compo);
}
}
}
SendServerConsoleCommand(text); //Forward to server.
break;
case "removeparticles":
if (args.Count >= 3)
{
Entity target = null;
if (args[1].ToLowerInvariant() == "player")
{
var plrMgr = IoCManager.Resolve<IPlayerManager>();
if (plrMgr != null)
if (plrMgr.ControlledEntity != null) target = plrMgr.ControlledEntity;
}
else
{
var entMgr = IoCManager.Resolve<IEntityManagerContainer>();
if (entMgr != null)
{
int entUid = int.Parse(args[1]);
target = entMgr.EntityManager.GetEntity(entUid);
}
}
if (target != null)
{
if (target.HasComponent(ComponentFamily.Particles))
{
IParticleSystemComponent compo = (IParticleSystemComponent)target.GetComponent(ComponentFamily.Particles);
compo.RemoveParticleSystem(args[2]);
}
}
}
SendServerConsoleCommand(text); //Forward to server.
break;
}*/

View File

@@ -1,11 +1,10 @@
using SFML.Graphics;
using OpenTK;
using SFML.Graphics;
using SFML.Window;
using SFML.System;
using SS14.Client.Graphics;
using SS14.Client.Graphics.Event;
using SS14.Client.Graphics.Render;
using SS14.Client.Interfaces.Input;
using SS14.Client.Interfaces.Map;
using SS14.Client.Interfaces.Network;
using SS14.Client.Interfaces.Resource;
using SS14.Client.Interfaces.State;
@@ -13,6 +12,7 @@ using SS14.Client.Interfaces.UserInterface;
using SS14.Client.Interfaces;
using SS14.Client.State.States;
using SS14.Shared.Interfaces.Configuration;
using SS14.Shared.Interfaces.Map;
using SS14.Shared.Interfaces.Serialization;
using SS14.Shared.Configuration;
using SS14.Shared.GameObjects;
@@ -37,7 +37,6 @@ namespace SS14.Client
[Dependency]
readonly private IConfigurationManager _configurationManager;
// private Input _input;
[Dependency]
readonly private INetworkGrapher _netGrapher;
[Dependency]
@@ -49,8 +48,6 @@ namespace SS14.Client
[Dependency]
readonly private IResourceCache _resourceCache;
[Dependency]
readonly private IEntityNetworkManager _entityNetworkManager;
[Dependency]
readonly private ITileDefinitionManager _tileDefinitionManager;
[Dependency]
readonly private ISS14Serializer _serializer;
@@ -58,12 +55,18 @@ namespace SS14.Client
private readonly IGameTiming _time;
[Dependency]
private readonly IResourceManager _resourceManager;
[Dependency]
private readonly IMapManager _mapManager;
#endregion Fields
#region Methods
#region Constructors
private TimeSpan _lastTick;
private TimeSpan _lastKeepUpAnnounce;
public void Run()
{
Logger.Debug("Initializing GameController.");
@@ -71,47 +74,17 @@ namespace SS14.Client
_configurationManager.LoadFromFile(PathHelpers.ExecutableRelativeFile("client_config.toml"));
_resourceCache.LoadBaseResources();
// Load resources used by splash screen and main menu.
LoadSplashResources();
ShowSplashScreen();
_resourceCache.LoadLocalResources();
LoadContentAssembly<GameShared>("Shared");
LoadContentAssembly<GameClient>("Client");
// get the assembly from the file system
if (_resourceManager.TryContentFileRead(@"Assemblies/Content.Client.dll", out MemoryStream gameDll))
{
Logger.Info("[ENG] Loading Client Content DLL");
// see if debug info is present
if (_resourceManager.TryContentFileRead(@"Assemblies/Content.Client.pdb", out MemoryStream gamePdb))
{
try
{
// load the assembly into the process, and bootstrap the GameServer entry point.
AssemblyLoader.LoadGameAssembly<GameServer>(gameDll.ToArray(), gamePdb.ToArray());
}
catch (Exception e)
{
Logger.Info($"[ENG] Exception loading DLL Content.Client.dll, {e.Message}");
}
}
else
{
try
{
// load the assembly into the process, and bootstrap the GameServer entry point.
AssemblyLoader.LoadGameAssembly<GameServer>(gameDll.ToArray());
}
catch (Exception e)
{
Logger.Info($"[ENG] Exception loading DLL Content.Client.dll, {e.Message}");
}
}
}
else
{
Logger.Warning("[ENG] Could not find Client Content DLL");
}
// Call Init in game assemblies.
AssemblyLoader.BroadcastRunLevel(AssemblyLoader.RunLevel.Init);
//Setup Cluwne first, as the rest depends on it.
SetupCluwne();
@@ -122,31 +95,82 @@ namespace SS14.Client
_serializer.Initialize();
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
prototypeManager.LoadDirectory(PathHelpers.ExecutableRelativeFile("Prototypes"));
prototypeManager.LoadDirectory(PathHelpers.ExecutableRelativeFile("Resources/Prototypes"));
prototypeManager.Resync();
_networkManager.Initialize(false);
_netGrapher.Initialize();
_userInterfaceManager.Initialize();
_mapManager.Initialize();
_stateManager.RequestStateChange<MainScreen>();
FrameEventArgs _frameEvent;
// EventArgs _frameEventArgs;
var _clock = new Clock();
#region GameLoop
// maximum number of ticks to queue before the loop slows down.
const int maxTicks = 5;
_time.ResetRealTime();
var maxTime = TimeSpan.FromTicks(_time.TickPeriod.Ticks * maxTicks);
while (CluwneLib.IsRunning)
{
//TODO: The client needs a real game loop...
var accumulator = _time.RealTime - _lastTick;
// If the game can't keep up, limit time.
if (accumulator > maxTime)
{
// limit accumulator to max time.
accumulator = maxTime;
// pull lastTick up to the current realTime
// This will slow down the simulation, but if we are behind from a
// lag spike hopefully it will be able to catch up.
_lastTick = _time.RealTime - maxTime;
// announce we are falling behind
if ((_time.RealTime - _lastKeepUpAnnounce).TotalSeconds >= 15.0)
{
Logger.Warning("[SRV] MainLoop: Cannot keep up!");
_lastKeepUpAnnounce = _time.RealTime;
}
}
_time.StartFrame();
var lastFrameTime = _clock.ElapsedTime.AsSeconds();
_clock.Restart();
_frameEvent = new FrameEventArgs(lastFrameTime);
CluwneLib.ClearCurrentRendertarget(Color.Black);
CluwneLib.Screen.DispatchEvents();
CluwneLib.RunIdle(this, _frameEvent);
CluwneLib.Screen.Display();
var realFrameEvent = new FrameEventArgs((float)_time.RealFrameTime.TotalSeconds);
// process Net/KB/Mouse input
Process(realFrameEvent);
_time.InSimulation = true;
// run the simulation for every accumulated tick
while (accumulator >= _time.TickPeriod)
{
accumulator -= _time.TickPeriod;
_lastTick += _time.TickPeriod;
// only run the sim if unpaused, but still use up the accumulated time
if (!_time.Paused)
{
// update the simulation
var simFrameEvent = new FrameEventArgs((float) _time.FrameTime.TotalSeconds);
Update(simFrameEvent);
_time.CurTick++;
}
}
// if not paused, save how close to the next tick we are so interpolation works
if (!_time.Paused)
_time.TickRemainder = accumulator;
_time.InSimulation = false;
// render the simulation
Render(realFrameEvent);
}
#endregion
_networkManager.ClientDisconnect("Client disconnected from game.");
CluwneLib.Terminate();
Logger.Info("GameController terminated.");
@@ -154,6 +178,100 @@ namespace SS14.Client
IoCManager.Resolve<IConfigurationManager>().SaveToFile();
}
private void LoadContentAssembly<T>(string name) where T: GameShared
{
// get the assembly from the file system
if (_resourceManager.TryContentFileRead($@"Assemblies/Content.{name}.dll", out MemoryStream gameDll))
{
Logger.Debug($"[SRV] Loading {name} Content DLL");
// see if debug info is present
if (_resourceManager.TryContentFileRead($@"Assemblies/Content.{name}.pdb", out MemoryStream gamePdb))
{
try
{
// load the assembly into the process, and bootstrap the GameServer entry point.
AssemblyLoader.LoadGameAssembly<T>(gameDll.ToArray(), gamePdb.ToArray());
}
catch (Exception e)
{
Logger.Error($"[SRV] Exception loading DLL Content.{name}.dll: {e}");
}
}
else
{
try
{
// load the assembly into the process, and bootstrap the GameServer entry point.
AssemblyLoader.LoadGameAssembly<T>(gameDll.ToArray());
}
catch (Exception e)
{
Logger.Error($"[SRV] Exception loading DLL Content.{name}.dll: {e}");
}
}
}
else
{
Logger.Warning($"[ENG] Could not find {name} Content DLL");
}
}
/// <summary>
/// Processes all simulation I/O. Keyboard/Mouse/Network code gets called here.
/// </summary>
private void Process(FrameEventArgs e)
{
//TODO: Keyboard/Mouse input needs to be processed here.
}
/// <summary>
/// Runs a tick of the simulation.
/// </summary>
/// <param name="e">Current GameTiming.FrameTime</param>
private void Update(FrameEventArgs e)
{
_networkManager.ProcessPackets();
CluwneLib.RunIdle(this, e);
_stateManager.Update(e);
}
/// <summary>
/// Renders the view of the simulation.
/// </summary>
/// <param name="e">Current GameTiming.RealFrameTime</param>
private void Render(FrameEventArgs e)
{
CluwneLib.ClearCurrentRendertarget(Color.Black);
CluwneLib.Screen.DispatchEvents();
// draw everything
_stateManager.Render(e);
// interface runs in realtime, so it is updated here
_userInterfaceManager.Update(e);
_userInterfaceManager.Render(e);
_netGrapher.Update();
// swap buffers to show the screen
CluwneLib.Screen.Display();
}
private void LoadSplashResources()
{
var logoTexture = _resourceCache.LoadTextureFrom("ss14_logo", _resourceManager.ContentFileRead(@"Textures/Logo/logo.png"));
_resourceCache.LoadSpriteFromTexture("ss14_logo", logoTexture);
var backgroundTexture = _resourceCache.LoadTextureFrom("ss14_logo_background", _resourceManager.ContentFileRead(@"Textures/Logo/background.png"));
_resourceCache.LoadSpriteFromTexture("ss14_logo_background", backgroundTexture);
var nanotrasenTexture = _resourceCache.LoadTextureFrom("ss14_logo_nt", _resourceManager.ContentFileRead(@"Textures/Logo/nanotrasen.png"));
_resourceCache.LoadSpriteFromTexture("ss14_logo_nt", nanotrasenTexture);
}
private void ShowSplashScreen()
{
// Do nothing when we're on DEBUG builds.
@@ -161,25 +279,19 @@ namespace SS14.Client
#if !DEBUG
const uint SIZE_X = 600;
const uint SIZE_Y = 300;
// Size of the NT logo in the bottom left.
// Size of the NT logo in the bottom right.
const float NT_SIZE_X = SIZE_X / 10f;
const float NT_SIZE_Y = SIZE_Y / 10f;
CluwneWindow window = CluwneLib.ShowSplashScreen(new VideoMode(SIZE_X, SIZE_Y));
var logoTexture = new Texture(_resourceManager.ContentFileRead(@"Textures/Logo/logo.png"));
var logo = new SFML.Graphics.Sprite(logoTexture);
var logoSize = logoTexture.Size;
logo.Position = new Vector2f(SIZE_X / 2 - logoSize.X / 2, SIZE_Y / 2 - logoSize.Y / 2);
var logo = _resourceCache.GetSprite("ss14_logo");
logo.Position = new Vector2f(SIZE_X / 2 - logo.TextureRect.Width / 2, SIZE_Y / 2 - logo.TextureRect.Height / 2);
var backgroundTexture = new Texture(_resourceManager.ContentFileRead(@"Textures/Logo/background.png"));
var background = new SFML.Graphics.Sprite(backgroundTexture);
var backgroundSize = backgroundTexture.Size;
background.Scale = new Vector2f((float)SIZE_X / backgroundSize.X, (float)SIZE_Y / backgroundSize.Y);
var background = _resourceCache.GetSprite("ss14_logo_background");
background.Scale = new Vector2f((float)SIZE_X / background.TextureRect.Width, (float)SIZE_Y / background.TextureRect.Height);
var nanotrasenTexture = new Texture(_resourceManager.ContentFileRead(@"Textures/Logo/nanotrasen.png"));
var nanotrasen = new SFML.Graphics.Sprite(nanotrasenTexture);
var nanotrasenSize = nanotrasenTexture.Size;
nanotrasen.Scale = new Vector2f(NT_SIZE_X / nanotrasenSize.X, NT_SIZE_Y / nanotrasenSize.Y);
var nanotrasen = _resourceCache.GetSprite("ss14_logo_nt");
nanotrasen.Scale = new Vector2f(NT_SIZE_X / nanotrasen.TextureRect.Width, NT_SIZE_Y / nanotrasen.TextureRect.Height);
nanotrasen.Position = new Vector2f(SIZE_X - NT_SIZE_X - 5, SIZE_Y - NT_SIZE_Y - 5);
nanotrasen.Color = new Color(255, 255, 255, 64);
@@ -203,17 +315,6 @@ namespace SS14.Client
#region EventHandlers
private void CluwneLibIdle(object sender, FrameEventArgs e)
{
_networkManager.ProcessPackets();
_stateManager.Update(e);
_userInterfaceManager.Update(e);
_userInterfaceManager.Render(e);
_netGrapher.Update();
}
private void MainWindowLoad(object sender, EventArgs e)
{
_stateManager.RequestStateChange<MainScreen>();
@@ -233,7 +334,7 @@ namespace SS14.Client
CluwneLib.Stop();
}
#region Input Handling
#region Input Handling
/// <summary>
/// Handles any keydown events.
@@ -338,11 +439,11 @@ namespace SS14.Client
_stateManager.TextEntered(e);
}
#endregion Input Handling
#endregion Input Handling
#endregion EventHandlers
#endregion EventHandlers
#region Privates
#region Privates
bool onetime = true;
@@ -367,7 +468,6 @@ namespace SS14.Client
{
//every time the video settings change we close the old screen and create a new one
//SetupCluwne Gets called to reset the event handlers to the new screen
CluwneLib.FrameEvent += CluwneLibIdle;
CluwneLib.RefreshVideoSettings += SetupCluwne;
onetime = false;
}
@@ -389,8 +489,8 @@ namespace SS14.Client
IoCManager.Resolve<IKeyBindingManager>().Initialize();
}
#endregion Privates
#endregion Privates
#endregion Methods
#endregion Methods
}
}

View File

@@ -1,4 +1,5 @@
using SFML.Graphics;
using SFML.Graphics;
using OpenTK;
using SS14.Client.Graphics.Collection;
using SS14.Client.Graphics.States;
using SS14.Client.Interfaces.Resource;
@@ -6,6 +7,7 @@ using SS14.Shared;
using System;
using System.Collections.Generic;
using System.Linq;
using SS14.Shared.Maths;
namespace SS14.Client.Graphics.Sprite
{
@@ -42,25 +44,25 @@ namespace SS14.Client.Graphics.Sprite
}
}
public FloatRect AverageAABB
public Box2 AverageAABB
{
get
{
if (_currentSprite != null)
return _averageAABBs[_currentAnimationState.Name][Direction];
return new FloatRect();
return new Box2();
}
}
#region Sprite passthrough methods
public IntRect AABB
public Box2i AABB
{
get
{
if (_currentSprite != null)
return _currentSprite.TextureRect;
return new IntRect();
return new Box2i();
}
}
@@ -77,7 +79,7 @@ namespace SS14.Client.Graphics.Sprite
/// </summary>
private readonly Dictionary<string, Dictionary<Direction, SFML.Graphics.Sprite[]>> _sprites = new Dictionary<string, Dictionary<Direction, SFML.Graphics.Sprite[]>>();
private readonly Dictionary<string, Dictionary<Direction, FloatRect>> _averageAABBs = new Dictionary<string, Dictionary<Direction, FloatRect>>();
private readonly Dictionary<string, Dictionary<Direction, Box2>> _averageAABBs = new Dictionary<string, Dictionary<Direction, Box2>>();
private SFML.Graphics.Sprite _currentSprite;
private Direction _direction = Direction.South;
@@ -96,7 +98,7 @@ namespace SS14.Client.Graphics.Sprite
_sprites.Add(info.Name, new Dictionary<Direction, SFML.Graphics.Sprite[]>());
//Because we have a shitload of frames, we're going to store the average size as the AABB for each direction and each animation
_averageAABBs.Add(info.Name, new Dictionary<Direction, FloatRect>());
_averageAABBs.Add(info.Name, new Dictionary<Direction, Box2>());
var sprites = _sprites[info.Name];
var averageAABBs = _averageAABBs[info.Name];
@@ -117,7 +119,7 @@ namespace SS14.Client.Graphics.Sprite
h += bounds.Height;
t++;
}
averageAABBs.Add(dir, new FloatRect(x / t, y / t, w / t, h / t));
averageAABBs.Add(dir, Box2.FromDimensions(x / t, y / t, w / t, h / t));
t = 0;
x = 0;
y = 0;

View File

@@ -2,7 +2,6 @@
using SS14.Client.Interfaces.GameObjects.Components;
using SS14.Shared.GameObjects;
using SS14.Shared.Interfaces.GameObjects.Components;
using System.Collections.Generic;
namespace SS14.Client.GameObjects
{
@@ -11,32 +10,19 @@ namespace SS14.Client.GameObjects
public ClientComponentFactory()
{
Register<CollidableComponent>();
Register<TriggerableComponent>();
RegisterReference<CollidableComponent, ICollidableComponent>();
Register<IconComponent>();
Register<ContextMenuComponent>();
Register<KeyBindingInputComponent>();
Register<PointLightComponent>();
Register<PhysicsComponent>();
Register<ColliderComponent>();
Register<TransformComponent>();
RegisterReference<TransformComponent, ITransformComponent>();
RegisterReference<TransformComponent, IClientTransformComponent>();
Register<DirectionComponent>();
RegisterReference<DirectionComponent, IDirectionComponent>();
Register<BasicMoverComponent>();
RegisterReference<BasicMoverComponent, IMoverComponent>();
Register<SlaveMoverComponent>();
RegisterReference<SlaveMoverComponent, IMoverComponent>();
Register<PlayerInputMoverComponent>();
RegisterReference<PlayerInputMoverComponent, IMoverComponent>();
Register<HitboxComponent>();
Register<VelocityComponent>();
RegisterReference<VelocityComponent, IVelocityComponent>();
Register<BoundingBoxComponent>();
Register<AnimatedSpriteComponent>();
RegisterReference<AnimatedSpriteComponent, IClickTargetComponent>();

View File

@@ -1,4 +1,5 @@
using SFML.System;
using OpenTK;
using SFML.System;
using SS14.Client.Interfaces.GameObjects;
using SS14.Shared.GameObjects;
using SS14.Shared.Interfaces.GameObjects;
@@ -8,6 +9,7 @@ using SS14.Shared.Maths;
using System;
using System.Collections.Generic;
using System.Linq;
using SS14.Shared.Utility;
namespace SS14.Client.GameObjects
{
@@ -16,26 +18,65 @@ namespace SS14.Client.GameObjects
/// </summary>
public class ClientEntityManager : EntityManager, IClientEntityManager
{
public IEnumerable<IEntity> GetEntitiesInRange(Vector2f position, float Range)
public IEnumerable<IEntity> GetEntitiesInRange(Vector2 position, float Range)
{
Range *= Range; // Square it here to avoid Sqrt
return from e in _entities.Values
where
(position -
e.GetComponent<ITransformComponent>().Position).
LengthSquared() < Range
select e;
foreach (var entity in _entities.Values)
{
var transform = entity.GetComponent<ITransformComponent>();
var relativePosition = position - transform.Position;
if (relativePosition.LengthSquared <= Range)
{
yield return entity;
}
}
}
public override void InitializeEntities()
public void Initialize()
{
if (Initialized)
{
throw new InvalidOperationException("InitializeEntities() called multiple times");
}
base.InitializeEntities();
InitializeEntities();
EntitySystemManager.Initialize();
Initialized = true;
}
public void ApplyEntityStates(IEnumerable<EntityState> entityStates, float serverTime)
{
var entityKeys = new HashSet<int>();
foreach (EntityState es in entityStates)
{
//Todo defer component state result processing until all entities are loaded and initialized...
es.ReceivedTime = serverTime;
entityKeys.Add(es.StateData.Uid);
//Known entities
if (_entities.TryGetValue(es.StateData.Uid, out var entity))
{
entity.HandleEntityState(es);
}
else //Unknown entities
{
IEntity newEntity = SpawnEntity(es.StateData.TemplateName, es.StateData.Uid);
newEntity.Name = es.StateData.Name;
newEntity.HandleEntityState(es);
}
}
//Delete entities that exist here but don't exist in the entity states
int[] toDelete = _entities.Keys.Where(k => !entityKeys.Contains(k)).ToArray();
foreach (int k in toDelete)
{
DeleteEntity(k);
}
// After the first set of states comes in we do the initialization.
if (!Initialized)
{
Initialize();
}
}
}
}

View File

@@ -1,20 +1,20 @@
using Lidgren.Network;
using NetSerializer;
using SS14.Client.Interfaces.Network;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.IoC;
using SS14.Shared.Interfaces.Configuration;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.Network;
using SS14.Shared.Interfaces.Serialization;
using SS14.Shared.IoC;
using System;
using System.Collections.Generic;
using System.IO;
using SS14.Shared.Interfaces.Network;
namespace SS14.Client.GameObjects
{
public class ClientEntityNetworkManager : IEntityNetworkManager
{
[Dependency]
private readonly ISS14Serializer serializer;
[Dependency]
private readonly IClientNetManager _networkManager;
@@ -40,10 +40,12 @@ namespace SS14.Client.GameObjects
NetOutgoingMessage newMsg = CreateEntityMessage();
newMsg.Write((byte)EntityMessage.SystemMessage);
var stream = new MemoryStream();
Serializer.Serialize(stream, message);
newMsg.Write((int)stream.Length);
newMsg.Write(stream.ToArray());
using (var stream = new MemoryStream())
{
serializer.Serialize(stream, message);
newMsg.Write((int)stream.Length);
newMsg.Write(stream.ToArray());
}
//Send the message
_networkManager.ClientSendMessage(newMsg, method);

View File

@@ -1,59 +0,0 @@
using System;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.IoC;
using SS14.Shared.Reflection;
namespace SS14.Client.GameObjects
{
/// <summary>
/// Sub type of <see cref="Component"/> that handles some client-specific things.
/// </summary>
[Reflect(false)]
public abstract class ClientComponent : Component
{
public override ComponentReplyMessage ReceiveMessage(object sender, ComponentMessageType type,
params object[] list)
{
ComponentReplyMessage reply = base.ReceiveMessage(sender, type, list);
if (sender == this) //Don't listen to our own messages!
return reply;
if (type == ComponentMessageType.Initialize)
{
SendComponentInstantiationMessage();
}
return reply;
}
public override void OnAdd(IEntity owner)
{
base.OnAdd(owner);
if (Owner.Initialized)
{
SendComponentInstantiationMessage();
}
}
/// <summary>
/// Client message to server saying component has been instantiated and needs initial data
/// </summary>
[Obsolete("Getting rid of this messaging paradigm.")]
public void SendComponentInstantiationMessage()
{
if (NetID == null)
{
return;
}
var manager = IoCManager.Resolve<IEntityNetworkManager>();
manager.SendEntityNetworkMessage(
Owner,
EntityMessage.ComponentInstantiationMessage,
NetID.Value);
}
}
}

View File

@@ -1,231 +0,0 @@
using Lidgren.Network;
using SFML.Graphics;
using SS14.Client.Interfaces.Collision;
using SS14.Client.Interfaces.GameObjects;
using SS14.Client.Interfaces.Map;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.GameObjects.Components.Collidable;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
using SS14.Shared.Maths;
using SS14.Shared.Utility;
using System;
using System.Collections.Generic;
using YamlDotNet.RepresentationModel;
namespace SS14.Client.GameObjects
{
public class CollidableComponent : ClientComponent, ICollidable
{
public override string Name => "Collidable";
public override uint? NetID => NetIDs.COLLIDABLE;
public SFML.Graphics.Color DebugColor { get; set; } = Color.Red;
private bool collisionEnabled = true;
private FloatRect currentAABB;
protected bool isHardCollidable = true;
public override Type StateType => typeof(CollidableComponentState);
/// <summary>
/// X - Top | Y - Right | Z - Bottom | W - Left
/// </summary>
private Vector4f TweakAABB { get; set; } = new Vector4f(0, 0, 0, 0);
private FloatRect OffsetAABB
{
get
{
if (Owner.TryGetComponent<ITransformComponent>(out var ownerTransform))
{
return
new FloatRect(
currentAABB.Left +
ownerTransform.Position.X -
(currentAABB.Width / 2) + TweakAABB.W,
currentAABB.Top +
ownerTransform.Position.Y -
(currentAABB.Height / 2) + TweakAABB.X,
currentAABB.Width - (TweakAABB.W - TweakAABB.Y),
currentAABB.Height - (TweakAABB.X - TweakAABB.Z));
}
else
{
return new FloatRect();
}
}
}
#region ICollidable Members
public FloatRect AABB
{
get { return OffsetAABB; }
}
/// <summary>
/// Called when the collidable is bumped into by someone/something
/// </summary>
public void Bump(IEntity ent)
{
OnBump?.Invoke(this, new EventArgs());
Owner.SendMessage(this, ComponentMessageType.Bumped, ent);
Owner.SendComponentNetworkMessage(this, NetDeliveryMethod.ReliableUnordered, ComponentMessageType.Bumped,
ent.Uid);
}
public bool IsHardCollidable
{
get { return isHardCollidable; }
}
#endregion ICollidable Members
public event EventHandler OnBump;
/// <summary>
/// OnAdd override -- gets the AABB from the sprite component and sends it to the collision manager.
/// </summary>
/// <param name="owner"></param>
public override void OnAdd(IEntity owner)
{
base.OnAdd(owner);
GetAABB();
var cm = IoCManager.Resolve<ICollisionManager>();
cm.AddCollidable(this);
}
/// <summary>
/// OnRemove override -- removes the AABB from the collisionmanager.
/// </summary>
public override void OnRemove()
{
var cm = IoCManager.Resolve<ICollisionManager>();
cm.RemoveCollidable(this);
base.OnRemove();
}
/// <summary>
/// Message handler --
/// SpriteChanged means the spritecomponent changed the current sprite.
/// </summary>
/// <param name="sender"></param>
/// <param name="type"></param>
/// <param name="reply"></param>
/// <param name="list"></param>
public override ComponentReplyMessage ReceiveMessage(object sender, ComponentMessageType type,
params object[] list)
{
ComponentReplyMessage reply = base.ReceiveMessage(sender, type, list);
if (sender == this) //Don't listen to our own messages!
return ComponentReplyMessage.Empty;
switch (type)
{
case ComponentMessageType.SpriteChanged:
if (collisionEnabled)
{
GetAABB();
var cm = IoCManager.Resolve<ICollisionManager>();
cm.UpdateCollidable(this);
}
break;
}
return reply;
}
/// <summary>
/// Parameter Setting
/// Settable params:
/// TweakAABB - Vector4
/// </summary>
public override void LoadParameters(YamlMappingNode mapping)
{
var mapManager = IoCManager.Resolve<IMapManager>();
YamlNode node;
if (mapping.TryGetNode("tweakAABB", out node))
{
TweakAABB = node.AsVector4f() / mapManager.TileSize;
}
if (mapping.TryGetNode("TweakAABBtop", out node))
{
TweakAABB = new Vector4f(node.AsFloat() / mapManager.TileSize, TweakAABB.Y, TweakAABB.Z, TweakAABB.W);
}
if (mapping.TryGetNode("TweakAABBright", out node))
{
TweakAABB = new Vector4f(TweakAABB.X, node.AsFloat() / mapManager.TileSize, TweakAABB.Z, TweakAABB.W);
}
if (mapping.TryGetNode("TweakAABBbottom", out node))
{
TweakAABB = new Vector4f(TweakAABB.X, TweakAABB.Y, node.AsFloat() / mapManager.TileSize, TweakAABB.W);
}
if (mapping.TryGetNode("TweakAABBleft", out node))
{
TweakAABB = new Vector4f(TweakAABB.X, TweakAABB.Y, TweakAABB.Z, node.AsFloat() / mapManager.TileSize);
}
if (mapping.TryGetNode("DebugColor", out node))
{
DebugColor = ColorUtils.FromHex(node.AsString(), Color.Red);
}
}
/// <summary>
/// Enables collidable
/// </summary>
private void EnableCollision()
{
collisionEnabled = true;
var cm = IoCManager.Resolve<ICollisionManager>();
cm.AddCollidable(this);
}
/// <summary>
/// Disables Collidable
/// </summary>
private void DisableCollision()
{
collisionEnabled = false;
var cm = IoCManager.Resolve<ICollisionManager>();
cm.RemoveCollidable(this);
}
/// <summary>
/// Gets the current AABB from the sprite component.
/// </summary>
private void GetAABB()
{
var component = Owner.GetComponent<ISpriteRenderableComponent>();
var tileSize = IoCManager.Resolve<IMapManager>().TileSize;
currentAABB = new FloatRect(
component.AABB.Left / tileSize,
component.AABB.Top / tileSize,
component.AABB.Width / tileSize,
component.AABB.Height / tileSize);
}
public override void HandleComponentState(dynamic state)
{
if (state.CollisionEnabled != collisionEnabled)
{
if (state.CollisionEnabled)
EnableCollision();
else
DisableCollision();
}
}
}
}

View File

@@ -1,14 +0,0 @@
using SS14.Shared.GameObjects.Components;
namespace SS14.Client.GameObjects
{
public class TriggerableComponent : CollidableComponent
{
public override string Name => "Triggerable";
public override uint? NetID => NetIDs.TRIGGERABLE;
public TriggerableComponent()
{
isHardCollidable = false;
}
}
}

View File

@@ -1,75 +0,0 @@
using SFML.Graphics;
using SFML.System;
using SS14.Client.Interfaces.Collision;
using SS14.Client.Interfaces.GameObjects;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
using SS14.Shared.Utility;
using System.Collections.Generic;
using YamlDotNet.RepresentationModel;
namespace SS14.Client.GameObjects
{
public class ColliderComponent : ClientComponent
{
public override string Name => "Collider";
public override uint? NetID => NetIDs.COLLIDER;
public SFML.Graphics.Color DebugColor { get; set; } = Color.Blue;
private FloatRect AABB
{
get
{
if (Owner.HasComponent<HitboxComponent>())
{
return Owner.GetComponent<HitboxComponent>().AABB;
}
else if (Owner.HasComponent<IRenderableComponent>())
{
return Owner.GetComponent<IRenderableComponent>().AverageAABB;
}
else
{
return new FloatRect();
}
}
}
public FloatRect WorldAABB
{
get
{
var trans = Owner.GetComponent<ITransformComponent>();
if (trans == null)
{
return AABB;
}
else
{
return new FloatRect(
AABB.Left + trans.X,
AABB.Top + trans.Y,
AABB.Width,
AABB.Height);
}
}
}
public bool TryCollision(Vector2f offset, bool bump = false)
{
return IoCManager.Resolve<ICollisionManager>().TryCollide(Owner, offset, bump);
}
public override void LoadParameters(YamlMappingNode mapping)
{
YamlNode node;
if (mapping.TryGetNode("debugColor", out node))
{
DebugColor = node.AsHexColor(Color.Blue);
}
}
}
}

View File

@@ -1,71 +0,0 @@
using SFML.System;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.GameObjects.Components.Direction;
using SS14.Shared.Maths;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
using System;
namespace SS14.Client.GameObjects
{
public class DirectionComponent : ClientComponent, IDirectionComponent
{
public override string Name => "Direction";
public override uint? NetID => NetIDs.DIRECTION;
private Direction _lastDeterminedDirection = Direction.South;
public Direction Direction { get; set; } = Direction.South;
public override Type StateType => typeof(DirectionComponentState);
public override void OnAdd(IEntity owner)
{
base.OnAdd(owner);
owner.GetComponent<ITransformComponent>().OnMove += HandleOnMove;
}
public override void OnRemove()
{
Owner.GetComponent<ITransformComponent>().OnMove -= HandleOnMove;
base.OnRemove();
}
public void HandleOnMove(object sender, VectorEventArgs args)
{
if (!Owner.HasComponent<PlayerInputMoverComponent>())
{
return;
}
if (args.VectorFrom == args.VectorTo)
return;
SetMoveDir(DetermineDirection(args.VectorFrom, args.VectorTo));
}
private Direction DetermineDirection(Vector2f from, Vector2f to)
{
Vector2f delta = to - from;
if (delta.Length() < 0.1)
{
return _lastDeterminedDirection;
}
_lastDeterminedDirection = from.DirectionTo(to, fallback: _lastDeterminedDirection);
return _lastDeterminedDirection;
}
private void SetMoveDir(Direction movedir)
{
Direction = movedir;
Owner.SendMessage(this, ComponentMessageType.MoveDirection, movedir);
}
public override void HandleComponentState(dynamic state)
{
var dir = (Direction)state.Direction;
SetMoveDir(dir);
}
}
}

View File

@@ -1,68 +0,0 @@
using SFML.Graphics;
using SFML.System;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.GameObjects.Components.Hitbox;
using SS14.Shared.IoC;
using System;
namespace SS14.Client.GameObjects
{
public class HitboxComponent : ClientComponent
{
public override string Name => "Hitbox";
public override uint? NetID => NetIDs.HITBOX;
public FloatRect AABB { get; set; }
public Vector2f Size
{
get
{
return new Vector2f(AABB.Width, AABB.Height);
}
set
{
AABB = new FloatRect(
AABB.Left + (AABB.Width - value.X),
AABB.Top + (AABB.Height - value.Y),
value.X,
value.Y
);
}
}
public Vector2f Offset
{
get
{
return new Vector2f(AABB.Left + AABB.Width / 2f, AABB.Top + AABB.Height / 2f);
}
set
{
AABB = new FloatRect(
value.X - AABB.Width / 2f,
value.Y - AABB.Height / 2f,
AABB.Width,
AABB.Height
);
}
}
public HitboxComponent()
{
Size = new Vector2f();
Offset = new Vector2f();
}
public override Type StateType
{
get
{
return typeof(HitboxComponentState);
}
}
public override void HandleComponentState(dynamic state)
{
AABB = state.AABB;
}
}
}

View File

@@ -1,62 +0,0 @@
using SFML.System;
using SS14.Client.Interfaces.GameObjects;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.GameObjects.Components.Mover;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
using System;
namespace SS14.Client.GameObjects
{
/// <summary>
/// Receives movement data from the server and updates the entity's position accordingly.
/// </summary>
public class BasicMoverComponent : ClientComponent, IMoverComponent
{
public override string Name => "BasicMover";
public override uint? NetID => NetIDs.BASIC_MOVER;
public override bool NetworkSynchronizeExistence => true;
private bool interpolating;
private float movedtime; // Amount of time we've been moving since the last update packet.
private const float movetime = 0.05f; // Milliseconds it should take to move.
private Vector2f startPosition;
private Vector2f targetPosition;
public override void Update(float frameTime)
{
base.Update(frameTime);
if (interpolating)
{
movedtime = movedtime + frameTime;
if (movedtime >= movetime)
{
Owner.GetComponent<ITransformComponent>().Position = targetPosition;
startPosition = targetPosition;
interpolating = false;
}
else
{
float X = Ease(movedtime, startPosition.X, targetPosition.X, movetime);
float Y = Ease(movedtime, startPosition.Y, targetPosition.Y, movetime);
Owner.GetComponent<ITransformComponent>().Position = new Vector2f(X, Y);
}
}
}
/// <summary>
/// Returns a float position eased from a start position to an end position.
/// </summary>
/// <param name="time">elapsed time since the start of the easing</param>
/// <param name="start">start position</param>
/// <param name="end">end position</param>
/// <param name="duration">duration of the movement</param>
/// <returns>current position</returns>
private float Ease(float time, float start, float end, float duration = 1) // duration is in ms.
{
time = time / duration; // - 1;
return time * (end - start) + start;
}
}
}

View File

@@ -1,183 +0,0 @@
using Lidgren.Network;
using SFML.System;
using SS14.Client.Interfaces.GameObjects;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
namespace SS14.Client.GameObjects
{
//Moves an entity based on key binding input
public class PlayerInputMoverComponent : ClientComponent, IMoverComponent
{
public override string Name => "PlayerInputMover";
public override uint? NetID => NetIDs.PLAYER_INPUT_MOVER;
public override bool NetworkSynchronizeExistence => true;
private const float BaseMoveSpeed = Constants.HumanWalkSpeed;
public const float FastMoveSpeed = Constants.HumanRunSpeed;
private const float MoveRateLimit = .06666f; // 15 movements allowed to be sent to the server per second.
private float _currentMoveSpeed = BaseMoveSpeed;
private bool _moveDown;
private bool _moveLeft;
private bool _moveRight;
private float _moveTimeCache;
private bool _moveUp;
public bool ShouldSendPositionUpdate;
private Vector2f Velocity
{
get => Owner.GetComponent<IVelocityComponent>().Velocity;
set => Owner.GetComponent<IVelocityComponent>().Velocity = value;
}
public override void HandleNetworkMessage(IncomingEntityComponentMessage message, NetConnection sender)
{
/*var x = (float)message.MessageParameters[0];
var y = (float)message.MessageParameters[1];
if((bool)message.MessageParameters[2]) //"forced" parameter -- if true forces position update
PlainTranslate((float)x, (float)y);*/
}
public override ComponentReplyMessage ReceiveMessage(object sender, ComponentMessageType type,
params object[] list)
{
ComponentReplyMessage reply = base.ReceiveMessage(sender, type, list);
if (sender == this) //Don't listen to our own messages!
return ComponentReplyMessage.Empty;
switch (type)
{
case ComponentMessageType.BoundKeyChange:
HandleKeyChange(list);
break;
}
return reply;
}
/// <summary>
/// Handles a changed keystate message
/// </summary>
/// <param name="list">0 - Function, 1 - Key State</param>
private void HandleKeyChange(params object[] list)
{
var function = (BoundKeyFunctions)list[0];
var state = (BoundKeyState)list[1];
bool setting = state == BoundKeyState.Down;
ShouldSendPositionUpdate = true;
/*if (state == BoundKeyState.Up)
SendPositionUpdate(Owner.GetComponent<TransformComponent>(ComponentFamily.Transform).Position);*/
// Send a position update so that the server knows what position the client ended at.
if (function == BoundKeyFunctions.MoveDown)
_moveDown = setting;
if (function == BoundKeyFunctions.MoveUp)
_moveUp = setting;
if (function == BoundKeyFunctions.MoveLeft)
_moveLeft = setting;
if (function == BoundKeyFunctions.MoveRight)
_moveRight = setting;
if (function == BoundKeyFunctions.Run)
{
_currentMoveSpeed = setting ? FastMoveSpeed : BaseMoveSpeed;
}
}
/// <summary>
/// Update function. Processes currently pressed keys and does shit etc.
/// </summary>
/// <param name="frameTime"></param>
public override void Update(float frameTime)
{
_moveTimeCache += frameTime;
base.Update(frameTime);
if (_moveUp && !_moveLeft && !_moveRight && !_moveDown) // Move Up
{
Velocity = new Vector2f(0, -1) * _currentMoveSpeed;
}
else if (_moveDown && !_moveLeft && !_moveRight && !_moveUp) // Move Down
{
Velocity = new Vector2f(0, 1) * _currentMoveSpeed;
}
else if (_moveLeft && !_moveRight && !_moveUp && !_moveDown) // Move Left
{
Velocity = new Vector2f(-1, 0) * _currentMoveSpeed;
}
else if (_moveRight && !_moveLeft && !_moveUp && !_moveDown) // Move Right
{
Velocity = new Vector2f(1, 0) * _currentMoveSpeed;
}
else if (_moveUp && _moveRight && !_moveLeft && !_moveDown) // Move Up & Right
{
Velocity = new Vector2f(0.7071f, -0.7071f) * _currentMoveSpeed;
}
else if (_moveUp && _moveLeft && !_moveRight && !_moveDown) // Move Up & Left
{
Velocity = new Vector2f(-0.7071f, -0.7071f) * _currentMoveSpeed;
}
else if (_moveDown && _moveRight && !_moveLeft && !_moveUp) // Move Down & Right
{
Velocity = new Vector2f(0.7071f, 0.7071f) * _currentMoveSpeed;
}
else if (_moveDown && _moveLeft && !_moveRight && !_moveUp) // Move Down & Left
{
Velocity = new Vector2f(-0.7071f, 0.7071f) * _currentMoveSpeed;
}
else
{
Velocity = new Vector2f(0f, 0f);
}
/*Vector2 translationVector = Velocity*frameTime;
var velcomp = Owner.GetComponent<VelocityComponent>(ComponentFamily.Velocity);
bool translated = TryTranslate(translationVector, false); //Only bump once...
bool translatedx = false, translatedy = false;
if (!translated)
translatedx = TryTranslate(new Vector2(translationVector.X, 0), true);
if (!translated && !translatedx)
translatedy = TryTranslate(new Vector2(0, translationVector.Y), true);
if (!translated)
{
if (!translatedx)
{
velcomp.Velocity = new Vector2(0, velcomp.Velocity.Y);
}
if (!translatedy)
velcomp.Velocity = new Vector2(velcomp.Velocity.X, 0);
if (!translatedx && !translatedy)
velcomp.Velocity = Vector2.Zero;
translationVector = new Vector2(translatedx?translationVector.X:0, translatedy?translationVector.Y:0);
}
if (_moveTimeCache >= MoveRateLimit)
{
var nextPosition = Owner.GetComponent<TransformComponent>(ComponentFamily.Transform).Position + translationVector;
SendPositionUpdate(nextPosition);
_moveTimeCache = 0;
}*/
}
public virtual void SendPositionUpdate(Vector2f nextPosition)
{
var velocity = Owner.GetComponent<IVelocityComponent>();
Owner.SendComponentNetworkMessage(this,
NetDeliveryMethod.ReliableUnordered,
nextPosition.X,
nextPosition.Y,
velocity.Velocity.X,
velocity.Velocity.Y);
}
}
}

View File

@@ -1,80 +0,0 @@
using SFML.System;
using SS14.Client.Interfaces.GameObjects;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.GameObjects.Components.Mover;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
using System;
namespace SS14.Client.GameObjects
{
/// <summary>
/// Mover component that responds to movement by an entity.
/// </summary>
public class SlaveMoverComponent : ClientComponent, IMoverComponent
{
public override string Name => "SlaveMover";
public override uint? NetID => NetIDs.SLAVE_MOVER;
public override bool NetworkSynchronizeExistence => true;
private IEntity _master;
public override Type StateType => typeof(SlaveMoverComponentState);
public override void OnRemove()
{
Detach();
base.OnRemove();
}
private void Attach(int uid)
{
_master = Owner.EntityManager.GetEntity(uid);
// TODO handle this using event queue so that these sorts of interactions are deferred until we can be sure the target entity exists
_master.GetComponent<ITransformComponent>().OnMove += HandleOnMove;
Translate(_master.GetComponent<ITransformComponent>().Position);
}
private void Detach()
{
if (_master == null) return;
_master.GetComponent<ITransformComponent>().OnMove -= HandleOnMove;
_master = null;
}
private void HandleOnMove(object sender, VectorEventArgs args)
{
Translate(args.VectorTo);
}
private void Translate(Vector2f toPosition)
{
Owner.GetComponent<ITransformComponent>().Position = toPosition;
}
public override void HandleComponentState(dynamic state)
{
SetNewState(state);
}
private void SetNewState(SlaveMoverComponentState state)
{
if (_master == null && state.Master != null)
{
Attach((int)state.Master);
}
if (_master != null && state.Master == null)
{
Detach();
}
if (_master != null && state.Master != null && _master.Uid != state.Master)
{
Detach();
Attach((int)state.Master);
}
}
}
}

View File

@@ -1,22 +0,0 @@
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.GameObjects.Components.Physics;
using SS14.Shared.IoC;
using System;
namespace SS14.Client.GameObjects
{
internal class PhysicsComponent : ClientComponent
{
public override string Name => "Physics";
public override uint? NetID => NetIDs.PHYSICS;
public float Mass { get; set; }
public override Type StateType => typeof(PhysicsComponentState);
public override void HandleComponentState(dynamic state)
{
Mass = state.Mass;
}
}
}

View File

@@ -1,99 +0,0 @@
using SFML.System;
using SS14.Client.Interfaces.GameObjects.Components;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.GameObjects.Components.Transform;
using SS14.Shared.Interfaces.Configuration;
using SS14.Shared.IoC;
using System;
using System.Collections.Generic;
using System.Linq;
namespace SS14.Client.GameObjects
{
public class TransformComponent : ClientComponent, IClientTransformComponent
{
public override string Name => "Transform";
public override uint? NetID => NetIDs.TRANSFORM;
private Vector2f _position = new Vector2f();
private List<TransformComponentState> states = new List<TransformComponentState>();
private TransformComponentState lastState;
public TransformComponentState lerpStateFrom { get; private set; }
public TransformComponentState lerpStateTo { get; private set ; }
public override Type StateType => typeof(TransformComponentState);
#region ITransformComponent Members
public event EventHandler<VectorEventArgs> OnMove;
public Vector2f Position
{
get => _position;
set
{
Vector2f oldPosition = _position;
_position = value;
OnMove?.Invoke(this, new VectorEventArgs(oldPosition, _position));
}
}
public float X
{
get => Position.X;
set => Position = new Vector2f(value, Position.Y);
}
public float Y
{
get => Position.Y;
set => Position = new Vector2f(Position.X, value);
}
public void Offset(Vector2f offset)
{
Position += offset;
}
#endregion
public override void Shutdown()
{
Position = new Vector2f();
}
public override void HandleComponentState(dynamic state)
{
SetNewState(state);
}
private void SetNewState(TransformComponentState state)
{
lastState = state;
states.Add(state);
var interp = IoCManager.Resolve<IConfigurationManager>().GetCVar<float>("net.interpolation");
//Remove all states older than the one just before the interp time.
lerpStateFrom = states.Where(s => s.ReceivedTime <= state.ReceivedTime - interp).OrderByDescending(s => s.ReceivedTime).FirstOrDefault();
if (lerpStateFrom != null)
{
lerpStateTo =
states.Where(s => s.ReceivedTime > lerpStateFrom.ReceivedTime).OrderByDescending(s => s.ReceivedTime).
LastOrDefault();
if (lerpStateTo == null)
lerpStateTo = lerpStateFrom;
states.RemoveAll(s => s.ReceivedTime < lerpStateFrom.ReceivedTime);
}
else
{
lerpStateFrom = state;
lerpStateTo = state;
}
if (lastState.ForceUpdate)
{
Position = state.Position;
}
}
}
}

View File

@@ -0,0 +1,54 @@
using System;
using OpenTK;
using SFML.Graphics;
using SS14.Shared.GameObjects;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.Utility;
namespace SS14.Client.GameObjects
{
/// <summary>
/// Holds an Axis Aligned Bounding Box (AABB) for the entity. Using this component adds the entity
/// to the physics system as a static (non-movable) entity.
/// </summary>
public class BoundingBoxComponent : Component
{
/// <inheritdoc />
public override string Name => "BoundingBox";
/// <inheritdoc />
public override uint? NetID => NetIDs.BOUNDING_BOX;
/// <summary>
/// Local Axis Aligned Bounding Box of the entity.
/// </summary>
public Box2 AABB { get; private set; }
/// <summary>
/// World Axis Aligned Bounding Box of the entity.
/// </summary>
public Box2 WorldAABB
{
get
{
var trans = Owner.GetComponent<ITransformComponent>();
var bounds = AABB;
return new FloatRect(
bounds.Left + trans.Position.X,
bounds.Top + trans.Position.Y,
bounds.Width,
bounds.Height).Convert();
}
}
/// <inheritdoc />
public override Type StateType => typeof(BoundingBoxComponentState);
/// <inheritdoc />
public override void HandleComponentState(ComponentState state)
{
AABB = ((BoundingBoxComponentState) state).AABB;
}
}
}

View File

@@ -0,0 +1,147 @@
using System;
using OpenTK;
using SFML.Graphics;
using SS14.Shared.GameObjects;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.Interfaces.Physics;
using SS14.Shared.IoC;
namespace SS14.Client.GameObjects
{
public class CollidableComponent : Component, ICollidableComponent
{
// no client side collision support for now
private bool collisionEnabled;
public Color DebugColor { get; } = Color.Red;
/// <inheritdoc />
public override string Name => "Collidable";
/// <inheritdoc />
public override uint? NetID => NetIDs.COLLIDABLE;
/// <inheritdoc />
public override Type StateType => typeof(CollidableComponentState);
/// <inheritdoc />
Box2 ICollidable.WorldAABB => Owner.GetComponent<BoundingBoxComponent>().WorldAABB;
/// <inheritdoc />
Box2 ICollidable.AABB => Owner.GetComponent<BoundingBoxComponent>().AABB;
/// <summary>
/// Called when the collidable is bumped into by someone/something
/// </summary>
void ICollidable.Bump(IEntity ent)
{
OnBump?.Invoke(this, new EventArgs());
Owner.SendMessage(this, ComponentMessageType.Bumped, ent);
}
/// <inheritdoc />
public bool IsHardCollidable { get; } = true;
/// <summary>
/// gets the AABB from the sprite component and sends it to the CollisionManager.
/// </summary>
/// <param name="owner"></param>
public override void OnAdd(IEntity owner)
{
base.OnAdd(owner);
if (collisionEnabled)
{
var cm = IoCManager.Resolve<ICollisionManager>();
cm.AddCollidable(this);
}
}
/// <summary>
/// removes the AABB from the CollisionManager.
/// </summary>
public override void OnRemove()
{
if (collisionEnabled)
{
var cm = IoCManager.Resolve<ICollisionManager>();
cm.RemoveCollidable(this);
}
base.OnRemove();
}
/// <summary>
/// SpriteChanged means the spritecomponent changed the current sprite.
/// </summary>
/// <param name="sender"></param>
/// <param name="type"></param>
/// <param name="reply"></param>
/// <param name="list"></param>
public override ComponentReplyMessage ReceiveMessage(object sender, ComponentMessageType type,
params object[] list)
{
var reply = base.ReceiveMessage(sender, type, list);
if (sender == this) //Don't listen to our own messages!
return ComponentReplyMessage.Empty;
switch (type)
{
case ComponentMessageType.SpriteChanged:
if (collisionEnabled)
{
var cm = IoCManager.Resolve<ICollisionManager>();
cm.UpdateCollidable(this);
}
break;
}
return reply;
}
/// <inheritdoc />
public override void HandleComponentState(ComponentState state)
{
var newState = (CollidableComponentState) state;
// edge triggered
if (newState.CollisionEnabled == collisionEnabled)
return;
if (newState.CollisionEnabled)
EnableCollision();
else
DisableCollision();
}
public bool TryCollision(Vector2 offset, bool bump = false)
{
return IoCManager.Resolve<ICollisionManager>().TryCollide(Owner, offset, bump);
}
public event EventHandler OnBump;
/// <summary>
/// Enables collidable
/// </summary>
private void EnableCollision()
{
collisionEnabled = true;
var cm = IoCManager.Resolve<ICollisionManager>();
cm.AddCollidable(this);
}
/// <summary>
/// Disables Collidable
/// </summary>
private void DisableCollision()
{
collisionEnabled = false;
var cm = IoCManager.Resolve<ICollisionManager>();
cm.RemoveCollidable(this);
}
}
}

View File

@@ -8,7 +8,7 @@ using YamlDotNet.RepresentationModel;
namespace SS14.Client.GameObjects
{
public class IconComponent : ClientComponent
public class IconComponent : Component
{
public override string Name => "Icon";
public Sprite Icon;

View File

@@ -1,9 +1,9 @@
using Lidgren.Network;
using OpenTK;
using Lidgren.Network;
using SFML.System;
using SS14.Client.Interfaces.GameObjects;
using SS14.Client.Interfaces.GameObjects.Components;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
@@ -12,14 +12,14 @@ using System;
namespace SS14.Client.GameObjects
{
// Notice: Most actual logic for clicking is done by the game screen.
public class ClickableComponent : ClientComponent, IClientClickableComponent
public class ClickableComponent : Component, IClientClickableComponent
{
public override string Name => "Clickable";
public override uint? NetID => NetIDs.CLICKABLE;
public event EventHandler<ClickEventArgs> OnClick;
public bool CheckClick(Vector2f worldPos, out int drawdepth)
public bool CheckClick(Vector2 worldPos, out int drawdepth)
{
var component = Owner.GetComponent<IClickTargetComponent>();

View File

@@ -11,7 +11,7 @@ using YamlDotNet.RepresentationModel;
namespace SS14.Client.GameObjects
{
public class ContextMenuComponent : ClientComponent
public class ContextMenuComponent : Component
{
public override string Name => "ContextMenu";
private readonly List<ContextMenuEntry> _entries = new List<ContextMenuEntry>();

View File

@@ -2,7 +2,6 @@
using SS14.Client.Interfaces.Input;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.IoC;
using System.Collections.Generic;
@@ -11,7 +10,7 @@ using System;
namespace SS14.Client.GameObjects
{
public class KeyBindingInputComponent : ClientComponent
public class KeyBindingInputComponent : Component
{
public override string Name => "KeyBindingInput";
public override uint? NetID => NetIDs.KEY_BINDING_INPUT;
@@ -140,11 +139,6 @@ namespace SS14.Client.GameObjects
public virtual void UpdateKeys(float frameTime)
{
//Rate limit
/*TimeSpan timeSinceLastUpdate = entityManager.now - lastKeyUpdate;
if (timeSinceLastUpdate.TotalMilliseconds < 1000 / keyUpdateRateLimit)
return;*/
// So basically we check for active keys with handlers and execute them. This is a linq query.
// Get all of the active keys' handlers
var activeKeyHandlers =
@@ -169,7 +163,6 @@ namespace SS14.Client.GameObjects
else
Owner.SendMessage(this, ComponentMessageType.BoundKeyRepeat, state.Key, BoundKeyState.Repeat);
}
//lastKeyUpdate = entityManager.now;
}
}
}

View File

@@ -1,10 +1,10 @@
using Lidgren.Network;
using OpenTK;
using OpenTK.Graphics;
using Lidgren.Network;
using SFML.System;
using SS14.Client.Interfaces.Lighting;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.GameObjects.Components.Light;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
@@ -15,14 +15,14 @@ using YamlDotNet.RepresentationModel;
namespace SS14.Client.GameObjects
{
public class PointLightComponent : ClientComponent
public class PointLightComponent : Component
{
public override string Name => "PointLight";
public override uint? NetID => NetIDs.POINT_LIGHT;
//Contains a standard light
public ILight _light;
public Vector3f _lightColor = new Vector3f(190, 190, 190);
public Vector2f _lightOffset = new Vector2f(0, 0);
public Color4 _lightColor = new Color4(190, 190, 190, 255);
public Vector2 _lightOffset = Vector2.Zero;
public int _lightRadius = 512;
protected string _mask = "";
public LightModeClass _mode = LightModeClass.Constant;
@@ -38,7 +38,7 @@ namespace SS14.Client.GameObjects
IoCManager.Resolve<ILightManager>().AddLight(_light);
_light.SetRadius(_lightRadius);
_light.SetColor(255, (int)_lightColor.X, (int)_lightColor.Y, (int)_lightColor.Z);
_light.SetColor(255, (int)_lightColor.R, (int)_lightColor.G, (int)_lightColor.B);
_light.Move(Owner.GetComponent<ITransformComponent>().Position + _lightOffset);
_light.SetMask(_mask);
Owner.GetComponent<ITransformComponent>().OnMove += OnMove;
@@ -64,17 +64,17 @@ namespace SS14.Client.GameObjects
if (mapping.TryGetNode("lightColorR", out node))
{
_lightColor.X = node.AsInt();
_lightColor.R = node.AsFloat() / 255f;
}
if (mapping.TryGetNode("lightColorG", out node))
{
_lightColor.Y = node.AsInt();
_lightColor.G = node.AsFloat() / 255f;
}
if (mapping.TryGetNode("lightColorB", out node))
{
_lightColor.Z = node.AsInt();
_lightColor.B = node.AsFloat() / 255f;
}
if (mapping.TryGetNode("mask", out node))
@@ -83,11 +83,6 @@ namespace SS14.Client.GameObjects
}
}
protected void SetState(LightState state)
{
_light.SetState(state);
}
protected void SetMode(LightModeClass mode)
{
IoCManager.Resolve<ILightManager>().SetLightMode(mode, _light);
@@ -102,7 +97,7 @@ namespace SS14.Client.GameObjects
private void OnMove(object sender, VectorEventArgs args)
{
_light.Move(Owner.GetComponent<ITransformComponent>().Position + _lightOffset);
_light.Move(args.VectorTo + _lightOffset);
}
public override void Update(float frameTime)
@@ -116,23 +111,25 @@ namespace SS14.Client.GameObjects
_light.SetMask(mask);
}
public override void HandleComponentState(dynamic state)
/// <inheritdoc />
public override void HandleComponentState(ComponentState state)
{
if (_light.LightState != state.State)
_light.SetState(state.State);
if (_light.Color.R != state.ColorR || _light.Color.G != state.ColorG || _light.Color.B != state.ColorB)
{
SetColor(state.ColorR, state.ColorG, state.ColorB);
}
if (_mode != state.Mode)
SetMode(state.Mode);
var newState = (PointLightComponentState) state;
if (_light.LightState != newState.State)
_light.SetState(newState.State);
if (_light.Color.R != newState.ColorR || _light.Color.G != newState.ColorG || _light.Color.B != newState.ColorB)
SetColor(newState.ColorR, newState.ColorG, newState.ColorB);
if (_mode != newState.Mode)
SetMode(newState.Mode);
}
protected void SetColor(int R, int G, int B)
{
_lightColor.X = R;
_lightColor.Y = G;
_lightColor.Z = B;
_lightColor.R = R/255f;
_lightColor.G = G/255f;
_lightColor.B = B/255f;
_light.SetColor(255, R, G, B);
}
}

View File

@@ -0,0 +1,20 @@
using SS14.Client.Interfaces.GameObjects;
using SS14.Shared.GameObjects;
namespace SS14.Client.GameObjects
{
//Moves an entity based on key binding input
public class PlayerInputMoverComponent : Component, IMoverComponent
{
/// <inheritdoc />
public override string Name => "PlayerInputMover";
/// <inheritdoc />
public override uint? NetID => null;
/// <inheritdoc />
public override bool NetworkSynchronizeExistence => false;
// This does nothing on the client.
}
}

View File

@@ -0,0 +1,53 @@
using System;
using OpenTK;
using SS14.Shared.GameObjects;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Log;
namespace SS14.Client.GameObjects
{
/// <summary>
/// Contains physical properties of the entity. This component registers the entity
/// in the physics system as a dynamic ridged body object that has physics. This behavior overrides
/// the BoundingBoxComponent behavior of making the entity static.
/// </summary>
internal class PhysicsComponent : Component
{
/// <inheritdoc />
public override string Name => "Physics";
/// <inheritdoc />
public override uint? NetID => NetIDs.PHYSICS;
/// <inheritdoc />
public override Type StateType => typeof(PhysicsComponentState);
/// <summary>
/// Current mass of the entity.
/// </summary>
public float Mass { get; private set; }
/// <summary>
/// Current velocity of the entity.
/// </summary>
public Vector2 Velocity { get; private set; }
/// <inheritdoc />
public override void OnAdd(IEntity owner)
{
// This component requires that the entity has an AABB.
if (!owner.HasComponent<BoundingBoxComponent>())
Logger.Error($"[ECS] {owner.Prototype.Name} - {nameof(PhysicsComponent)} requires {nameof(BoundingBoxComponent)}. ");
base.OnAdd(owner);
}
/// <inheritdoc />
public override void HandleComponentState(ComponentState state)
{
var newState = (PhysicsComponentState) state;
Mass = newState.Mass;
Velocity = newState.Velocity;
}
}
}

View File

@@ -1,15 +1,14 @@
using SFML.Graphics;
using OpenTK;
using SFML.Graphics;
using SFML.System;
using SS14.Client.Graphics;
using SS14.Client.Graphics.Sprite;
using SS14.Client.Graphics.TexHelpers;
using SS14.Client.Interfaces.GameObjects;
using SS14.Client.Interfaces.Map;
using SS14.Shared.Interfaces.Map;
using SS14.Client.Interfaces.Resource;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.GameObjects.Components.Renderable;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
@@ -17,11 +16,13 @@ using SS14.Shared.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using SS14.Shared.Maths;
using YamlDotNet.RepresentationModel;
using Vector2i = SFML.System.Vector2i;
namespace SS14.Client.GameObjects
{
public class AnimatedSpriteComponent : ClientComponent, ISpriteRenderableComponent, IClickTargetComponent
public class AnimatedSpriteComponent : Component, ISpriteRenderableComponent, IClickTargetComponent
{
public override string Name => "AnimatedSprite";
public override uint? NetID => NetIDs.ANIMATED_SPRITE;
@@ -45,13 +46,13 @@ namespace SS14.Client.GameObjects
}
}
public FloatRect AverageAABB
public Box2 AverageAABB
{
get
{
var tileSize = IoCManager.Resolve<IMapManager>().TileSize;
var aaabb = sprite.AverageAABB;
return new FloatRect(
return Box2.FromDimensions(
aaabb.Left / tileSize, aaabb.Top / tileSize,
aaabb.Width / tileSize, aaabb.Height / tileSize
);
@@ -60,14 +61,14 @@ namespace SS14.Client.GameObjects
#region ISpriteComponent Members
public FloatRect AABB
public Box2 AABB
{
get
{
var tileSize = IoCManager.Resolve<IMapManager>().TileSize;
return new FloatRect(0, 0, sprite.AABB.Width / tileSize,
sprite.AABB.Height / tileSize);
return Box2.FromDimensions(0, 0, sprite.AABB.Width / (float)tileSize,
sprite.AABB.Height / (float)tileSize);
}
}
@@ -100,11 +101,6 @@ namespace SS14.Client.GameObjects
{
sprite.SetAnimationState(state);
sprite.SetLoop(loop);
/*foreach(AnimatedSpriteComponent s in slaves)
{
s.SetAnimationState(state, loop);
}*/
}
public override ComponentReplyMessage ReceiveMessage(object sender, ComponentMessageType type,
@@ -124,35 +120,6 @@ namespace SS14.Client.GameObjects
case ComponentMessageType.Dropped:
UnsetMaster();
break;
case ComponentMessageType.MoveDirection:
switch ((Direction)list[0])
{
case Direction.North:
sprite.Direction = Direction.North;
break;
case Direction.South:
sprite.Direction = Direction.South;
break;
case Direction.East:
sprite.Direction = Direction.East;
break;
case Direction.West:
sprite.Direction = Direction.West;
break;
case Direction.NorthEast:
sprite.Direction = Direction.NorthEast;
break;
case Direction.NorthWest:
sprite.Direction = Direction.NorthWest;
break;
case Direction.SouthEast:
sprite.Direction = Direction.SouthEast;
break;
case Direction.SouthWest:
sprite.Direction = Direction.SouthWest;
break;
}
break;
case ComponentMessageType.EntitySaidSomething:
ChatChannel channel;
if (Enum.TryParse(list[0].ToString(), true, out channel))
@@ -181,7 +148,7 @@ namespace SS14.Client.GameObjects
return sprite.GetCurrentSprite();
}
public virtual bool WasClicked(Vector2f worldPos)
public virtual bool WasClicked(Vector2 worldPos)
{
if (sprite == null || !visible) return false;
@@ -189,12 +156,12 @@ namespace SS14.Client.GameObjects
var bounds = spriteToCheck.GetLocalBounds();
var AABB =
new FloatRect(
Box2.FromDimensions(
Owner.GetComponent<ITransformComponent>().Position.X -
(bounds.Width / 2),
Owner.GetComponent<ITransformComponent>().Position.Y -
(bounds.Height / 2), bounds.Width, bounds.Height);
if (!AABB.Contains(worldPos.X, worldPos.Y)) return false;
if (!AABB.Contains(new Vector2(worldPos.X, worldPos.Y))) return false;
// Get the sprite's position within the texture
var texRect = spriteToCheck.TextureRect;
@@ -234,7 +201,7 @@ namespace SS14.Client.GameObjects
}
}
public virtual void Render(Vector2f topLeft, Vector2f bottomRight)
public virtual void Render(Vector2 topLeft, Vector2 bottomRight)
{
UpdateSlaves();
@@ -256,7 +223,7 @@ namespace SS14.Client.GameObjects
var ownerPos = Owner.GetComponent<ITransformComponent>().Position;
Vector2f renderPos = CluwneLib.WorldToScreen(ownerPos);
Vector2 renderPos = CluwneLib.WorldToScreen(ownerPos);
SetSpriteCenter(renderPos);
var bounds = sprite.AABB;
@@ -283,20 +250,22 @@ namespace SS14.Client.GameObjects
//Draw AABB
var aabb = AABB;
//CluwneLib.CurrentRenderTarget.Rectangle(renderPos.X - aabb.Width/2, renderPos.Y - aabb.Height / 2, aabb.Width, aabb.Height, Color.Lime);
if (_speechBubble != null)
_speechBubble.Draw(CluwneLib.WorldToScreen(Owner.GetComponent<ITransformComponent>().Position),
new Vector2f(), aabb);
new Vector2(), aabb);
}
/// <inheritdoc />
public override void Update(float frameTime)
{
base.Update(frameTime);
if (sprite != null && !IsSlaved())
{
sprite.Update(frameTime);
}
if (sprite == null || IsSlaved())
return;
sprite.Direction = Owner.GetComponent<TransformComponent>().Rotation.GetDir();
sprite.Update(frameTime);
}
public virtual void UpdateSlaves()
@@ -318,7 +287,7 @@ namespace SS14.Client.GameObjects
}
}
public void SetSpriteCenter(Vector2f center)
public void SetSpriteCenter(Vector2 center)
{
sprite.SetPosition(center.X - (sprite.AABB.Width / 2),
center.Y - (sprite.AABB.Height / 2));
@@ -386,22 +355,21 @@ namespace SS14.Client.GameObjects
slaves.Remove(slavecompo);
}
public override void HandleComponentState(dynamic state)
/// <inheritdoc />
public override void HandleComponentState(ComponentState state)
{
DrawDepth = state.DrawDepth;
visible = state.Visible;
if (sprite.Name != state.Name)
SetSprite(state.Name);
if (sprite.CurrentAnimationStateKey != state.CurrentAnimation)
{
if (state.CurrentAnimation == null)
sprite.SetAnimationState("idle");
else
sprite.SetAnimationState(state.CurrentAnimation);
}
SetMaster((int?)state.MasterUid);
var newState = (AnimatedSpriteComponentState) state;
DrawDepth = newState.DrawDepth;
visible = newState.Visible;
if (sprite.Name != newState.Name)
SetSprite(newState.Name);
sprite.SetLoop(state.Loop);
if (sprite.CurrentAnimationStateKey != newState.CurrentAnimation)
sprite.SetAnimationState(newState.CurrentAnimation ?? "idle");
SetMaster(newState.MasterUid);
sprite.SetLoop(newState.Loop);
}
}
}

View File

@@ -1,15 +1,15 @@
using Lidgren.Network;
using OpenTK;
using Lidgren.Network;
using SFML.Graphics;
using SFML.System;
using SS14.Client.Interfaces.Resource;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.GameObjects.Components.Renderable;
using SS14.Shared.IoC;
using SS14.Shared.Utility;
using System;
using System.Collections.Generic;
using SS14.Shared.Maths;
using YamlDotNet.RepresentationModel;
namespace SS14.Client.GameObjects
@@ -137,7 +137,6 @@ namespace SS14.Client.GameObjects
switch ((ComponentMessageType)message.MessageParameters[0])
{
case ComponentMessageType.SetBaseName:
//basename = (string) message.MessageParameters[1];
break;
}
}
@@ -192,20 +191,22 @@ namespace SS14.Client.GameObjects
}
}
public override bool WasClicked(Vector2f worldPos)
public override bool WasClicked(Vector2 worldPos)
{
return !IsInHand && base.WasClicked(worldPos);
}
public override void HandleComponentState(dynamic state)
/// <inheritdoc />
public override void HandleComponentState(ComponentState state)
{
var newState = (SpriteComponentState) state;
base.HandleComponentState((SpriteComponentState)state);
if (state.BaseName != null && basename != state.BaseName)
{
basename = state.BaseName;
LoadSprites();
}
if (newState.BaseName == null || basename == newState.BaseName)
return;
basename = newState.BaseName;
LoadSprites();
}
}
}

View File

@@ -1,15 +1,15 @@
using SFML.Graphics;
using OpenTK;
using SFML.Graphics;
using SFML.System;
using SS14.Client.Graphics;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.GameObjects.Components.Renderable;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
using SS14.Shared.Utility;
using System;
using System.Collections.Generic;
using SS14.Shared.Maths;
using YamlDotNet.RepresentationModel;
namespace SS14.Client.GameObjects
@@ -114,7 +114,6 @@ namespace SS14.Client.GameObjects
protected override Sprite GetBaseSprite()
{
//return sprites[basename + "_front"];
return currentBaseSprite;
}
@@ -132,7 +131,7 @@ namespace SS14.Client.GameObjects
SetSpriteByKey(_basename + "_front");
}
public override void Render(Vector2f topLeft, Vector2f bottomRight)
public override void Render(Vector2 topLeft, Vector2 bottomRight)
{
if (!visible)
{
@@ -153,18 +152,18 @@ namespace SS14.Client.GameObjects
if (_speechBubble != null)
_speechBubble.Draw(CluwneLib.WorldToScreen(position),
new Vector2f(), currentBaseSprite);
new Vector2(), currentBaseSprite);
}
public override void HandleComponentState(dynamic state)
/// <inheritdoc />
public override void HandleComponentState(ComponentState state)
{
base.HandleComponentState((SpriteComponentState)state);
var newState = (SpriteComponentState) state;
base.HandleComponentState(state);
if (state.BaseName != null && _basename != state.BaseName)
{
_basename = state.BaseName;
LoadSprites();
}
if (newState.BaseName == null || _basename == newState.BaseName) return;
_basename = newState.BaseName;
LoadSprites();
}
}
}

View File

@@ -1,3 +1,4 @@
using OpenTK;
using SFML.Graphics;
using SFML.System;
using SS14.Client.Graphics;
@@ -6,6 +7,7 @@ using SS14.Client.Interfaces.Resource;
using SS14.Shared.GameObjects;
using SS14.Shared.IoC;
using SS14.Shared.Maths;
using SS14.Shared.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -21,22 +23,22 @@ namespace SS14.Client.GameObjects
/// <summary>
/// Particle position relative to the emit position
/// </summary>
public Vector2f Position;
public Vector2 Position;
/// <summary>
/// Where the emitter was when the particle was first emitted
/// </summary>
public Vector2f EmitterPosition;
public Vector2 EmitterPosition;
/// <summary>
/// Particle's x/y velocity
/// </summary>
public Vector2f Velocity;
public Vector2 Velocity;
/// <summary>
/// Particle's x/y acceleration
/// </summary>
public Vector2f Acceleration;
public Vector2 Acceleration;
/// <summary>
/// Particle's radial velocity - relative to EmitterPosition
@@ -91,12 +93,12 @@ namespace SS14.Client.GameObjects
/// <summary>
/// Particle's current color
/// </summary>
public Vector4f Color;
public Vector4 Color;
/// <summary>
/// Rate of change of particle's color
/// </summary>
public Vector4f ColorDelta;
public Vector4 ColorDelta;
/// <summary>
/// Whether or not the particle is currently being drawn
@@ -136,15 +138,15 @@ namespace SS14.Client.GameObjects
//Calculate delta p due to radial velocity
var positionRelativeToEmitter = Position - EmitterPosition;
var deltaRadial = RadialVelocity * frameTime;
var deltaPosition = positionRelativeToEmitter*(deltaRadial/positionRelativeToEmitter.Length());
var deltaPosition = positionRelativeToEmitter*(deltaRadial/positionRelativeToEmitter.Length);
//Calculate delta p due to tangential velocity
var radius = positionRelativeToEmitter.Length();
var radius = positionRelativeToEmitter.Length;
if (radius > 0)
{
var theta = (float)Math.Atan2(positionRelativeToEmitter.Y, positionRelativeToEmitter.X);
theta += TangentialVelocity*frameTime;
deltaPosition += new Vector2f(radius * (float)Math.Cos(theta), radius*(float)Math.Sin(theta))
deltaPosition += new Vector2(radius * (float)Math.Cos(theta), radius*(float)Math.Sin(theta))
- positionRelativeToEmitter;
}
//Calculate delta p due to Velocity
@@ -161,22 +163,22 @@ namespace SS14.Client.GameObjects
/// <summary>
/// Particle position relative to the emit position
/// </summary>
public static Vector2f Position = new Vector2f(0,0);
public static Vector2 Position = new Vector2(0,0);
/// <summary>
/// Where the emitter was when the particle was first emitted
/// </summary>
public static Vector2f EmitterPosition = new Vector2f(0,0);
public static Vector2 EmitterPosition = new Vector2(0,0);
/// <summary>
/// Particle's x/y velocity
/// </summary>
public static Vector2f Velocity = new Vector2f(0,0);
public static Vector2 Velocity = new Vector2(0,0);
/// <summary>
/// Particle's x/y acceleration
/// </summary>
public static Vector2f Acceleration = new Vector2f(0,0);
public static Vector2 Acceleration = new Vector2(0,0);
/// <summary>
/// Particle's radial velocity - relative to EmitterPosition
@@ -231,12 +233,12 @@ namespace SS14.Client.GameObjects
/// <summary>
/// Particle's current color
/// </summary>
public static Vector4f Color = new Vector4f(1,0,0,0);
public static Vector4 Color = new Vector4(1,0,0,0);
/// <summary>
/// Rate of change of particle's color
/// </summary>
public static Vector4f ColorDelta = new Vector4f(-1, 0, 0, 0);
public static Vector4 ColorDelta = new Vector4(-1, 0, 0, 0);
/// <summary>
/// Whether or not the particle is currently being drawn
@@ -260,19 +262,19 @@ namespace SS14.Client.GameObjects
/// Emitter Position;
/// This is the logical position of the emitter object
/// </summary>
public Vector2f EmitterPosition { get; set; }
public Vector2 EmitterPosition { get; set; }
/// <summary>
/// Emission Offset;
/// This is where the particles should be emitted relative to the emitter position.
/// </summary>
public Vector2f EmissionOffset { get; set; }
public Vector2 EmissionOffset { get; set; }
/// <summary>
/// Emit Position
/// This is where the particles will be emitted.
/// </summary>
public Vector2f EmitPosition { get { return EmitterPosition + EmissionOffset; } }
public Vector2 EmitPosition { get { return EmitterPosition + EmissionOffset; } }
/// <summary>
/// Emit
@@ -324,7 +326,7 @@ namespace SS14.Client.GameObjects
/// Velocity Range
/// This controls the particle's initial velocity
/// </summary>
public Vector2f Velocity { get; set; }
public Vector2 Velocity { get; set; }
/// <summary>
/// Velocity Variance
@@ -336,7 +338,7 @@ namespace SS14.Client.GameObjects
/// Acceleration Range
/// This controls the particle's initial acceleration
/// </summary>
public Vector2f Acceleration { get; set; }
public Vector2 Acceleration { get; set; }
/// <summary>
/// Acceleration Variance
@@ -430,7 +432,7 @@ namespace SS14.Client.GameObjects
/// <summary>
/// This controls the color range of the particle over the course of its lifetime
/// </summary>
public SS14.Shared.Utility.Range<Vector4f> ColorRange { get; set; }
public SS14.Shared.Utility.Range<Vector4> ColorRange { get; set; }
/// <summary>
/// This controls how much particle color will vary between particles
@@ -486,26 +488,26 @@ namespace SS14.Client.GameObjects
return (RandomFloat()*(end - start)) + start;
}
private Vector2f RandomRangeVector2(SS14.Shared.Utility.Range<Vector2f> randomRange)
private Vector2 RandomRangeVector2(SS14.Shared.Utility.Range<Vector2> randomRange)
{
return new Vector2f(
return new Vector2(
RandomRangeFloat(randomRange.Start.X, randomRange.End.X),
RandomRangeFloat(randomRange.Start.Y, randomRange.End.Y)
);
}
private Vector3f RandomRangeVector3(SS14.Shared.Utility.Range<Vector3f> randomRange)
private Vector3 RandomRangeVector3(SS14.Shared.Utility.Range<Vector3> randomRange)
{
return new Vector3f(
return new Vector3(
RandomRangeFloat(randomRange.Start.X, randomRange.End.X),
RandomRangeFloat(randomRange.Start.Y, randomRange.End.Y),
RandomRangeFloat(randomRange.Start.Z, randomRange.End.Z)
);
}
private Vector4f RandomRangeVector4(SS14.Shared.Utility.Range<Vector4f> randomRange)
private Vector4 RandomRangeVector4(SS14.Shared.Utility.Range<Vector4> randomRange)
{
return new Vector4f(
return new Vector4(
RandomRangeFloat(randomRange.Start.X, randomRange.End.X),
RandomRangeFloat(randomRange.Start.Y, randomRange.End.Y),
RandomRangeFloat(randomRange.Start.Z, randomRange.End.Z),
@@ -524,43 +526,43 @@ namespace SS14.Client.GameObjects
return Math.Max(val, 0);
}
private Vector2f VariedVector2(Vector2f value, float variance)
private Vector2 VariedVector2(Vector2 value, float variance)
{
return new Vector2f(
return new Vector2(
VariedFloat(value.X, variance),
VariedFloat(value.Y, variance)
);
}
private Vector2f VariedPositiveVector2(Vector2f value, float variance)
private Vector2 VariedPositiveVector2(Vector2 value, float variance)
{
return new Vector2f(
return new Vector2(
VariedPositiveFloat(value.X, variance),
VariedPositiveFloat(value.Y, variance)
);
}
private Vector3f VariedVector3(Vector3f value, float variance)
private Vector3 VariedVector3(Vector3 value, float variance)
{
return new Vector3f(
return new Vector3(
VariedFloat(value.X, variance),
VariedFloat(value.Y, variance),
VariedFloat(value.Z, variance)
);
}
private Vector3f VariedPositiveVector3(Vector3f value, float variance)
private Vector3 VariedPositiveVector3(Vector3 value, float variance)
{
return new Vector3f(
return new Vector3(
VariedPositiveFloat(value.X, variance),
VariedPositiveFloat(value.Y, variance),
VariedPositiveFloat(value.Z, variance)
);
}
private Vector4f VariedVector4(Vector4f value, float variance)
private Vector4 VariedVector4(Vector4 value, float variance)
{
return new Vector4f(
return new Vector4(
VariedFloat(value.X, variance),
VariedFloat(value.Y, variance),
VariedFloat(value.Z, variance),
@@ -568,9 +570,9 @@ namespace SS14.Client.GameObjects
);
}
private Vector4f VariedPositiveVector4(Vector4f value, float variance)
private Vector4 VariedPositiveVector4(Vector4 value, float variance)
{
return new Vector4f(
return new Vector4(
VariedPositiveFloat(value.X, variance),
VariedPositiveFloat(value.Y, variance),
VariedPositiveFloat(value.Z, variance),
@@ -578,7 +580,7 @@ namespace SS14.Client.GameObjects
);
}
private Vector4f Limit(Vector4f color)
private Vector4 Limit(Vector4 color)
{
if (Math.Max(color.X, Math.Max(color.Y, Math.Max(color.Z, color.W))) <= 255)
return color;
@@ -598,10 +600,10 @@ namespace SS14.Client.GameObjects
}
if (x > 255)
x = 255;
return new Vector4f(x, y, z, w);
return new Vector4(x, y, z, w);
}
private SFML.Graphics.Color ToColor(Vector4f color)
private SFML.Graphics.Color ToColor(Vector4 color)
{
color = Limit(color);
@@ -628,7 +630,7 @@ namespace SS14.Client.GameObjects
var emitRadius = RandomRangeFloat(EmissionRadiusRange);
emitRadius = emitRadius > 0.01f ? emitRadius : 0.1f;
var emitAngle = RandomFloat()*2*Math.PI;
p.Position = EmitPosition + new Vector2f(
p.Position = EmitPosition + new Vector2(
emitRadius*(float)Math.Sin(emitAngle),
emitRadius*(float)Math.Cos(emitAngle)
);
@@ -660,9 +662,9 @@ namespace SS14.Client.GameObjects
this.AccelerationVariance = settings.AccelerationVariance;
//I hope this is correct.
this.ColorRange = new SS14.Shared.Utility.Range<Vector4f>(
new Vector4f(settings.ColorRange.Start.A, settings.ColorRange.Start.R, settings.ColorRange.Start.G, settings.ColorRange.Start.B),
new Vector4f(settings.ColorRange.End.A, settings.ColorRange.End.R, settings.ColorRange.End.G, settings.ColorRange.End.B));
this.ColorRange = new SS14.Shared.Utility.Range<Vector4>(
new Vector4(settings.ColorRange.Start.A, settings.ColorRange.Start.R, settings.ColorRange.Start.G, settings.ColorRange.Start.B),
new Vector4(settings.ColorRange.End.A, settings.ColorRange.End.R, settings.ColorRange.End.G, settings.ColorRange.End.B));
this.ColorVariance = settings.ColorVariance;
this.EmissionOffset = settings.EmissionOffset;
@@ -696,7 +698,7 @@ namespace SS14.Client.GameObjects
/// This moves the emitter's position
/// </remarks>
/// <param name="toPosition"></param>
public void MoveEmitter(Vector2f toPosition)
public void MoveEmitter(Vector2 toPosition)
{
EmitterPosition = toPosition;
}
@@ -708,7 +710,7 @@ namespace SS14.Client.GameObjects
/// This moves the particles, but not the emitter. This changes the particles positions relative to the emitter.
/// </remarks>
/// <param name="toPosition"></param>
public void MoveParticles(Vector2f toPosition)
public void MoveParticles(Vector2 toPosition)
{
var offset = toPosition - EmitterPosition;
MoveParticlesOffset(offset);
@@ -721,7 +723,7 @@ namespace SS14.Client.GameObjects
/// This moves the particles, but not the emitter. This changes the particles positions relative to the emitter.
/// </remarks>
/// <param name="offset"></param>
public void MoveParticlesOffset(Vector2f offset)
public void MoveParticlesOffset(Vector2 offset)
{
Parallel.ForEach(LiveParticles, particle =>
{
@@ -738,7 +740,7 @@ namespace SS14.Client.GameObjects
/// emitter, they "move" as well.
/// </remarks>
/// <param name="toPosition"></param>
public void Move(Vector2f toPosition)
public void Move(Vector2 toPosition)
{
MoveParticles(toPosition);
EmitterPosition = toPosition;
@@ -750,7 +752,6 @@ namespace SS14.Client.GameObjects
{
particle.Update(frameTime);
}
//Parallel.ForEach(LiveParticles, particle => particle.Update(frameTime));
if (!Emit)
return;
@@ -779,30 +780,27 @@ namespace SS14.Client.GameObjects
public void Render()
{
//_batch.Clear();
foreach (var particle in LiveParticles)
{
ParticleSprite.Color = ToColor(particle.Color);
ParticleSprite.Position = particle.Position;
ParticleSprite.Position = particle.Position.Convert();
ParticleSprite.Rotation = (float)(180f / Math.PI) * particle.Spin;
ParticleSprite.Scale = new SFML.System.Vector2f(particle.Size, particle.Size);
//_batch.AddClone(ParticleSprite);
ParticleSprite.Scale = new Vector2f(particle.Size, particle.Size);
ParticleSprite.Draw();
}
//_batch.Draw();
}
#endregion
#region Constructor/Destructors
public ParticleSystem(Sprite particleSprite, Vector2f position)
public ParticleSystem(Sprite particleSprite, Vector2 position)
{
MaximumParticleCount = 200;
//TODO start with sane defaults
Acceleration = new Vector2f();
Acceleration = new Vector2();
AccelerationVariance = 0f;
ColorRange = new SS14.Shared.Utility.Range<Vector4f>(Vector4f.UnitX * 255, Vector4f.Zero);
ColorRange = new SS14.Shared.Utility.Range<Vector4>(Vector4.UnitX * 255, Vector4.Zero);
ColorVariance = 0f;
EmissionOffset = new Vector2f();
EmissionOffset = new Vector2();
EmissionRadiusRange = new SS14.Shared.Utility.Range<float>(0f, 0f);
Emit = false;
EmitRate = 1;
@@ -822,10 +820,10 @@ namespace SS14.Client.GameObjects
TangentialAccelerationVariance = 0;
TangentialVelocity = 0;
TangentialVelocityVariance = 0;
Velocity = new Vector2f();
Velocity = new Vector2();
VelocityVariance = 0;
}
public ParticleSystem(ParticleSettings settings, Vector2f position)
public ParticleSystem(ParticleSettings settings, Vector2 position)
{
LoadParticleSettings(settings);
EmitterPosition = position;

View File

@@ -1,22 +1,22 @@
using SFML.Graphics;
using OpenTK;
using SFML.Graphics;
using SFML.System;
using SS14.Client.Graphics;
using SS14.Client.Interfaces.GameObjects;
using SS14.Client.Interfaces.Resource;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.GameObjects.Components.Particles;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
using System;
using System.Collections.Generic;
using System.Linq;
using SS14.Shared.Utility;
namespace SS14.Client.GameObjects
{
public class ParticleSystemComponent : ClientComponent, IParticleSystemComponent, IRenderableComponent
public class ParticleSystemComponent : Component, IParticleSystemComponent, IRenderableComponent
{
public override string Name => "ParticleSystem";
public override uint? NetID => NetIDs.PARTICLE_SYSTEM;
@@ -29,15 +29,10 @@ namespace SS14.Client.GameObjects
#endregion Variables.
#region Properties
public FloatRect AverageAABB
{
get { return AABB; }
}
public Box2 AverageAABB => AABB;
public Box2 AABB => new Box2();
public FloatRect AABB
{
get { return new FloatRect(); }
}
#endregion Properties
@@ -45,13 +40,12 @@ namespace SS14.Client.GameObjects
public void OnMove(object sender, VectorEventArgs args)
{
var offset = new Vector2f(args.VectorTo.X, args.VectorTo.Y) -
new Vector2f(args.VectorFrom.X, args.VectorFrom.Y);
var offset = new Vector2(args.VectorTo.X, args.VectorTo.Y) -
new Vector2(args.VectorFrom.X, args.VectorFrom.Y);
foreach (KeyValuePair<string, ParticleSystem> particleSystem in _emitters)
{
particleSystem.Value.MoveEmitter(particleSystem.Value.EmitterPosition + offset);
}
//_emitter.MoveEmitter(_emitter.EmitterPosition + offset);
}
public override void OnAdd(IEntity owner)
@@ -77,9 +71,9 @@ namespace SS14.Client.GameObjects
}
}
public virtual void Render(Vector2f topLeft, Vector2f bottomRight)
public virtual void Render(Vector2 topLeft, Vector2 bottomRight)
{
Vector2f renderPos = CluwneLib.WorldToScreen(
Vector2 renderPos = CluwneLib.WorldToScreen(
Owner.GetComponent<ITransformComponent>().Position);
foreach (KeyValuePair<string, ParticleSystem> particleSystem in _emitters)
@@ -94,8 +88,6 @@ namespace SS14.Client.GameObjects
get
{
return Owner.GetComponent<ITransformComponent>().Position.Y;
//return Owner.GetComponent<TransformComponent>(ComponentFamily.Transform).Position.Y +
// (_particleSprite.Height / 2);
}
}
@@ -143,7 +135,7 @@ namespace SS14.Client.GameObjects
ParticleSettings toAdd = IoCManager.Resolve<IResourceCache>().GetParticles(name);
if (toAdd != null)
{
_emitters.Add(name, new ParticleSystem(toAdd, new Vector2f()));
_emitters.Add(name, new ParticleSystem(toAdd, new Vector2()));
_emitters[name].Emit = active;
}
}
@@ -161,19 +153,19 @@ namespace SS14.Client.GameObjects
_emitters[name].Emit = active;
}
public override void HandleComponentState(dynamic _state)
/// <inheritdoc />
public override void HandleComponentState(ComponentState state)
{
ParticleSystemComponentState state = (ParticleSystemComponentState)_state;
var newState = (ParticleSystemComponentState) state;
foreach (var a in state.emitters)
{
foreach (var a in newState.emitters)
if (_emitters.ContainsKey(a.Key))
SetParticleSystemActive(a.Key, a.Value);
else
AddParticleSystem(a.Key, a.Value);
}
foreach (var toRemove in new List<string>(_emitters.Keys.Except<string>(state.emitters.Keys))) //Remove emitters that are not in the new state.
//Remove emitters that are not in the new state.
foreach (var toRemove in new List<string>(_emitters.Keys.Except(newState.emitters.Keys)))
RemoveParticleSystem(toRemove);
}
}

View File

@@ -1,4 +1,5 @@
using SFML.Graphics;
using OpenTK;
using SFML.Graphics;
using SFML.System;
using SS14.Client.Graphics;
using SS14.Client.Graphics.Render;
@@ -44,7 +45,7 @@ namespace SS14.Client.GameObjects
private readonly IResourceCache _resourceCache;
/// <summary>
/// StringBuilder to handle
/// StringBuilder to handle
/// </summary>
private readonly StringBuilder _stringBuilder;
@@ -89,7 +90,7 @@ namespace SS14.Client.GameObjects
#region Publics
public void Draw(Vector2f position, Vector2f windowOrigin, Sprite spriteToDrawAbove)
public void Draw(Vector2 position, Vector2 windowOrigin, Sprite spriteToDrawAbove)
{
if ((DateTime.Now - _buildTime).TotalMilliseconds >= MillisecondsToLive) return;
@@ -103,7 +104,7 @@ namespace SS14.Client.GameObjects
_bubbleSprite.Draw();
}
public void Draw(Vector2f position, Vector2f windowOrigin, FloatRect boundingBox)
public void Draw(Vector2 position, Vector2 windowOrigin, Box2 boundingBox)
{
if ((DateTime.Now - _buildTime).TotalMilliseconds >= MillisecondsToLive) return;
@@ -136,63 +137,9 @@ namespace SS14.Client.GameObjects
private void DrawBubbleSprite()
{
// TODO unfuck this
/*RenderTarget originalTarget = CluwneLib.CurrentRenderTarget;
Sprite cornerSprite = _resourceCache.GetSprite("corners");
//Set up dimensions
_bubbleRender.SetDimensions((int) _textSprite.Size.X + 10, (int) _textSprite.Size.Y + 10);
_bubbleSprite.SetSize(_textSprite.Size.X + 10, _textSprite.Size.Y + 10);
//BEGIN RENDERING
CluwneLib.CurrentRenderTarget = _bubbleRender;
_bubbleRender.Clear(Color.Transparent);
//Draw black triangle at the bottom.
var pointOneBlack = new Vector2((_bubbleRender.Width/2) - 10, _bubbleRender.Height - 10);
var pointTwoBlack = new Vector2((_bubbleRender.Width/2) + 10, _bubbleRender.Height - 10);
var pointThreeBlack = new Vector2((_bubbleRender.Width/2), _bubbleRender.Height);
_bubbleRender.FilledTriangle(pointOneBlack, pointTwoBlack, pointThreeBlack, Color.Black);
//Draw the side lines
_bubbleRender.Line(10, 0, _bubbleRender.Width - 20, 1, Color.Black);
_bubbleRender.Line(_bubbleRender.Width - 1, 10, 1, _bubbleRender.Height - 26, Color.Black);
_bubbleRender.Line(10, _bubbleRender.Height - 7, _bubbleRender.Width - 20, 1, Color.Black);
_bubbleRender.Line(0, 10, 1, _bubbleRender.Height - 26, Color.Black);
//Fill in the middle without polluting the corners.
_bubbleRender.FilledRectangle(3, 1, _bubbleRender.Width - 6, _bubbleRender.Height - 8, Color.White);
_bubbleRender.FilledRectangle(1, 3, _bubbleRender.Width - 2, _bubbleRender.Height - 12, Color.White);
//Draw the white triangle at the bottom.
Vector2 pointOneWhite = pointOneBlack + new Vector2(1, 0);
Vector2 pointTwoWhite = pointTwoBlack - new Vector2(1, 0);
Vector2 pointThreeWhite = pointThreeBlack - new Vector2(0, 1);
_bubbleRender.FilledTriangle(pointOneWhite, pointTwoWhite, pointThreeWhite, Color.White);
//Draw the corners.
cornerSprite.SourceBlend = AlphaBlendOperation.One;
cornerSprite.DestinationBlend = AlphaBlendOperation.Zero;
cornerSprite.VerticalFlip = true;
cornerSprite.SetPosition(0, 0);
cornerSprite.Draw();
cornerSprite.HorizontalFlip = true;
cornerSprite.SetPosition(_bubbleRender.Width - 16, 0);
cornerSprite.Draw();
cornerSprite.VerticalFlip = false;
cornerSprite.SetPosition(_bubbleRender.Width - 16, _bubbleRender.Height - 22);
cornerSprite.Draw();
cornerSprite.HorizontalFlip = false;
cornerSprite.SetPosition(0, _bubbleRender.Height - 22);
cornerSprite.Draw();
_textSprite.Draw();
CluwneLib.CurrentRenderTarget = originalTarget;
_buildTime = DateTime.Now;*/
// TODO implement this
}
#endregion
}
}
}

View File

@@ -1,4 +1,5 @@
using Lidgren.Network;
using OpenTK;
using SFML.Graphics;
using SFML.System;
using SS14.Client.Graphics;
@@ -7,8 +8,6 @@ using SS14.Client.Interfaces.GameObjects;
using SS14.Client.Interfaces.Resource;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.GameObjects.Components.Renderable;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
@@ -16,11 +15,13 @@ using SS14.Shared.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using SS14.Shared.Maths;
using YamlDotNet.RepresentationModel;
using Vector2i = SFML.System.Vector2i;
namespace SS14.Client.GameObjects
{
public class SpriteComponent : ClientComponent, ISpriteRenderableComponent, ISpriteComponent, IClickTargetComponent
public class SpriteComponent : Component, ISpriteRenderableComponent, ISpriteComponent, IClickTargetComponent
{
public override string Name => "Sprite";
public override uint? NetID => NetIDs.SPRITE;
@@ -52,14 +53,14 @@ namespace SS14.Client.GameObjects
#region ISpriteComponent Members
public FloatRect AverageAABB => AABB;
public Box2 AverageAABB => AABB;
public FloatRect AABB
public Box2 AABB
{
get
{
var bounds = GetActiveDirectionalSprite().GetLocalBounds();
return new FloatRect(0, 0, bounds.Width, bounds.Height);
return Box2.FromDimensions(0, 0, bounds.Width, bounds.Height);
}
}
@@ -209,7 +210,7 @@ namespace SS14.Client.GameObjects
string dirName =
(currentBaseSpriteKey + "_" +
Owner.GetComponent<IDirectionComponent>().Direction.ToString()).
Owner.GetComponent<TransformComponent>().Rotation.GetDir().ToString()).
ToLowerInvariant();
if (dirSprites.ContainsKey(dirName))
@@ -218,7 +219,7 @@ namespace SS14.Client.GameObjects
return sprite;
}
public virtual bool WasClicked(Vector2f worldPos)
public virtual bool WasClicked(Vector2 worldPos)
{
if (currentBaseSprite == null || !visible) return false;
@@ -226,10 +227,10 @@ namespace SS14.Client.GameObjects
var bounds = spriteToCheck.GetLocalBounds();
var AABB =
new FloatRect(
Box2.FromDimensions(
Owner.GetComponent<ITransformComponent>().Position.X - (bounds.Width / 2),
Owner.GetComponent<ITransformComponent>().Position.Y - (bounds.Height / 2), bounds.Width, bounds.Height);
if (!AABB.Contains(worldPos.X, worldPos.Y)) return false;
if (!AABB.Contains(new Vector2(worldPos.X, worldPos.Y))) return false;
// Get the sprite's position within the texture
var texRect = spriteToCheck.TextureRect;
@@ -278,7 +279,7 @@ namespace SS14.Client.GameObjects
}
}
public virtual void Render(Vector2f topLeft, Vector2f bottomRight)
public virtual void Render(Vector2 topLeft, Vector2 bottomRight)
{
//Render slaves beneath
IEnumerable<SpriteComponent> renderablesBeneath = from SpriteComponent c in slaves
@@ -298,7 +299,7 @@ namespace SS14.Client.GameObjects
Sprite spriteToRender = GetActiveDirectionalSprite();
Vector2f renderPos = CluwneLib.WorldToScreen(Owner.GetComponent<ITransformComponent>().Position);
Vector2 renderPos = CluwneLib.WorldToScreen(Owner.GetComponent<ITransformComponent>().Position);
var bounds = spriteToRender.GetLocalBounds();
SetSpriteCenter(spriteToRender, renderPos);
@@ -329,12 +330,12 @@ namespace SS14.Client.GameObjects
CluwneLib.drawRectangle((int)(renderPos.X - aabb.Width / 2), (int)(renderPos.Y - aabb.Height / 2), aabb.Width, aabb.Height, new SFML.Graphics.Color(0, 255, 0));
}
public void SetSpriteCenter(string sprite, Vector2f center)
public void SetSpriteCenter(string sprite, Vector2 center)
{
SetSpriteCenter(sprites[sprite], center);
}
public void SetSpriteCenter(Sprite sprite, Vector2f center)
public void SetSpriteCenter(Sprite sprite, Vector2 center)
{
var bounds = GetActiveDirectionalSprite().GetLocalBounds();
sprite.Position = new SFML.System.Vector2f(center.X - (bounds.Width / 2),
@@ -378,16 +379,17 @@ namespace SS14.Client.GameObjects
slaves.Remove(slavecompo);
}
public override void HandleComponentState(dynamic state)
/// <inheritdoc />
public override void HandleComponentState(ComponentState state)
{
DrawDepth = state.DrawDepth;
if (state.SpriteKey != null && sprites.ContainsKey(state.SpriteKey) &&
currentBaseSprite != sprites[state.SpriteKey])
{
SetSpriteByKey(state.SpriteKey);
}
var newState = (SpriteComponentState) state;
DrawDepth = newState.DrawDepth;
visible = state.Visible;
if (newState.SpriteKey != null && sprites.ContainsKey(newState.SpriteKey) &&
currentBaseSprite != sprites[newState.SpriteKey])
SetSpriteByKey(newState.SpriteKey);
visible = newState.Visible;
}
}
}

View File

@@ -1,10 +1,9 @@
using SFML.Graphics;
using OpenTK;
using SFML.Graphics;
using SFML.System;
using SS14.Client.Graphics;
using SS14.Client.Interfaces.Resource;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.GameObjects.Components.Renderable;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
using SS14.Shared.Utility;
@@ -27,10 +26,11 @@ namespace SS14.Client.GameObjects
public override Type StateType => typeof(WearableAnimatedSpriteComponentState);
public override void HandleComponentState(dynamic state)
/// <inheritdoc />
public override void HandleComponentState(ComponentState state)
{
base.HandleComponentState((WearableAnimatedSpriteComponentState)state);
IsCurrentlyWorn = state.IsCurrentlyWorn;
base.HandleComponentState(state);
IsCurrentlyWorn = ((WearableAnimatedSpriteComponentState) state).IsCurrentlyWorn;
}
public void SetNotWornSprite(string spritename)
@@ -59,7 +59,7 @@ namespace SS14.Client.GameObjects
}
}
public override void Render(Vector2f topLeft, Vector2f bottomRight)
public override void Render(Vector2 topLeft, Vector2 bottomRight)
{
if (IsCurrentlyWorn && currentSprite == baseSprite)
{
@@ -92,9 +92,9 @@ namespace SS14.Client.GameObjects
Sprite spriteToRender = NotWornSprite;
var bounds = spriteToRender.GetLocalBounds();
Vector2f renderPos = CluwneLib.WorldToScreen(
Vector2 renderPos = CluwneLib.WorldToScreen(
Owner.GetComponent<ITransformComponent>().Position);
spriteToRender.Position = new SFML.System.Vector2f(renderPos.X - (bounds.Width / 2),
spriteToRender.Position = new Vector2f(renderPos.X - (bounds.Width / 2),
renderPos.Y - (bounds.Height / 2));
if (Owner.GetComponent<ITransformComponent>().Position.X + bounds.Left + bounds.Width < topLeft.X
@@ -103,7 +103,7 @@ namespace SS14.Client.GameObjects
|| Owner.GetComponent<ITransformComponent>().Position.Y > bottomRight.Y)
return;
spriteToRender.Scale = new SFML.System.Vector2f(HorizontalFlip ? -1 : 1, 1);
spriteToRender.Scale = new Vector2f(HorizontalFlip ? -1 : 1, 1);
spriteToRender.Draw();
//Render slaves above
@@ -117,10 +117,6 @@ namespace SS14.Client.GameObjects
{
component.Render(topLeft, bottomRight);
}
//Draw AABB
var aabb = AABB;
CluwneLib.drawRectangle((int)(renderPos.X - aabb.Width / 2), (int)(renderPos.Y - aabb.Height / 2), (int)aabb.Width, (int)aabb.Height, new SFML.Graphics.Color(0, 0, 255));
}
}
}

View File

@@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using OpenTK;
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.Maths;
namespace SS14.Client.GameObjects
{
/// <summary>
/// Stores the position and orientation of the entity.
/// </summary>
public class TransformComponent : Component, ITransformComponent
{
public Vector2 Position { get; private set; }
public Angle Rotation { get; private set; }
public ITransformComponent Parent { get; private set; }
//TODO: Make parenting actually work.
/// <inheritdoc />
public override string Name => "Transform";
/// <inheritdoc />
public override uint? NetID => NetIDs.TRANSFORM;
/// <inheritdoc />
public override Type StateType => typeof(TransformComponentState);
/// <inheritdoc />
public event EventHandler<VectorEventArgs> OnMove;
/// <inheritdoc />
public override void HandleComponentState(ComponentState state)
{
var newState = (TransformComponentState)state;
Rotation = newState.Rotation;
if (Position != newState.Position)
{
OnMove?.Invoke(this, new VectorEventArgs(Position, newState.Position));
Position = newState.Position;
}
if (Parent != newState.Parent)
{
DetachParent();
AttachParent(newState.Parent);
}
}
/// <summary>
/// Detaches this entity from its parent.
/// </summary>
private void DetachParent()
{
// nothing to do
if (Parent == null)
return;
Parent = null;
}
/// <summary>
/// Sets another entity as the parent entity.
/// </summary>
/// <param name="parent"></param>
private void AttachParent(ITransformComponent parent)
{
// nothing to attach to.
if (parent == null)
return;
Parent = parent;
}
public ITransformComponent GetMapTransform()
{
if (Parent != null) //If we are not the final transform, query up the chain of parents
{
return Parent.GetMapTransform();
}
return this;
}
public bool IsMapTransform(ITransformComponent transform)
{
if (transform.Parent != null)
{
return false;
}
return true;
}
/// <summary>
/// Does this entity contain the entity in the argument
/// </summary>
public bool ContainsEntity(ITransformComponent transform)
{
if (IsMapTransform(transform)) //Is the entity on the map
{
if (this == transform.Parent) //Is this the direct container of the entity
{
return true;
}
else
{
return ContainsEntity(transform.Parent); //Recursively search up the entitys containers for this object
}
}
return false;
}
}
}

View File

@@ -1,14 +1,12 @@
using SFML.System;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.Components;
using SS14.Shared.GameObjects.Components.Velocity;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
using System;
namespace SS14.Client.GameObjects
{
public class VelocityComponent : ClientComponent, IVelocityComponent
public class VelocityComponent : Component, IVelocityComponent
{
public override string Name => "Velocity";
public override uint? NetID => NetIDs.VELOCITY;
@@ -16,39 +14,39 @@ namespace SS14.Client.GameObjects
private VelocityComponentState _lastState;
private VelocityComponentState _previousState;
public Vector2f Velocity { get; set; }
public Vector2 Velocity { get; set; }
public override Type StateType => typeof(VelocityComponentState);
public float X
{
get => Velocity.X;
set => Velocity = new Vector2f(value, Velocity.Y);
set => Velocity = new Vector2(value, Velocity.Y);
}
public float Y
{
get => Velocity.Y;
set => Velocity = new Vector2f(Velocity.X, value);
set => Velocity = new Vector2(Velocity.X, value);
}
public override void Shutdown()
{
Velocity = new Vector2f();
Velocity = new Vector2();
}
public override void HandleComponentState(dynamic state)
/// <inheritdoc />
public override void HandleComponentState(ComponentState state)
{
if (!Owner.HasComponent<PlayerInputMoverComponent>())
SetNewState(state);
}
if (Owner.HasComponent<PlayerInputMoverComponent>())
return;
private void SetNewState(VelocityComponentState state)
{
var newState = (VelocityComponentState)state;
if (_lastState != null)
_previousState = _lastState;
_lastState = state;
Velocity = new Vector2f(state.VelocityX, state.VelocityY);
_lastState = newState;
Velocity = new Vector2(newState.VelocityX, newState.VelocityY);
}
}
}

View File

@@ -1,19 +1,29 @@
using SS14.Shared;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.System;
using SS14.Shared.IoC;
using System;
using System.Collections.Generic;
namespace SS14.Client.GameObjects.EntitySystems
{
public class InputSystem : EntitySystem
{
/// <summary>
/// Default constructor.
/// </summary>
public InputSystem()
{
EntityQuery = new EntityQuery();
EntityQuery.OneSet.Add(typeof(KeyBindingInputComponent));
EntityQuery = new ComponentEntityQuery()
{
OneSet = new List<Type>()
{
typeof(KeyBindingInputComponent),
},
};
}
public override void Update(float frametime)
/// <inheritdoc />
public override void Update(float frameTime)
{
var entities = EntityManager.GetEntities(EntityQuery);
foreach (var entity in entities)

View File

@@ -3,6 +3,8 @@ using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.System;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.IoC;
using System;
using System.Collections.Generic;
namespace SS14.Client.GameObjects.EntitySystems
{
@@ -10,8 +12,13 @@ namespace SS14.Client.GameObjects.EntitySystems
{
public ParticleSystem()
{
EntityQuery = new EntityQuery();
EntityQuery.OneSet.Add(typeof(ParticleSystemComponent));
EntityQuery = new ComponentEntityQuery()
{
OneSet = new List<Type>()
{
typeof(ParticleSystemComponent),
},
};
}
public void AddParticleSystem(IEntity ent, string systemName)

View File

@@ -2,6 +2,8 @@
using SS14.Shared.GameObjects.System;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.IoC;
using System;
using System.Collections.Generic;
namespace SS14.Client.GameObjects.EntitySystems
{
@@ -9,11 +11,19 @@ namespace SS14.Client.GameObjects.EntitySystems
{
public PhysicsSystem()
{
EntityQuery = new EntityQuery();
EntityQuery.AllSet.Add(typeof(PhysicsComponent));
EntityQuery.AllSet.Add(typeof(IVelocityComponent));
EntityQuery.AllSet.Add(typeof(ITransformComponent));
EntityQuery.ExclusionSet.Add(typeof(SlaveMoverComponent));
EntityQuery = new ComponentEntityQuery()
{
AllSet = new List<Type>()
{
typeof(PhysicsComponent),
typeof(ITransformComponent),
typeof(IVelocityComponent),
},
ExclusionSet = new List<Type>()
{
typeof(SlaveMoverComponent),
},
};
}
/// <summary>

Some files were not shown because too many files have changed in this diff Show More