Skip to content

Commit 775b3f2

Browse files
committed
adding serverside npc logic and clientside entity spawner connections
1 parent a07d946 commit 775b3f2

20 files changed

+785
-34
lines changed

MultiplayerDemo/Assets/Scenes/SampleScene.unity

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ MonoBehaviour:
267267
m_Name:
268268
m_EditorClassIdentifier:
269269
test: 1
270+
testPlayer: {fileID: 1941412218}
270271
--- !u!114 &909546264
271272
MonoBehaviour:
272273
m_ObjectHideFlags: 0
@@ -666,7 +667,7 @@ MonoBehaviour:
666667
timestamp:
667668
x: 0
668669
y: 1.1
669-
z: 0
670+
z: 50
670671
rot:
671672
timestamp:
672673
x: 0

MultiplayerDemo/Assets/Scripts/Networking/Communications/NetworkMessages.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@ public class NetworkMessages {
1212
public static readonly string PLAYER_LEFT = "PLAYER_LEFT";
1313
public static readonly string PLAYER_JOINED = "PLAYER_JOINED";
1414
public static readonly string PLAYER_TRANSFORM_CHANGE = "PLAYER_TRANSFORM_CHANGE";
15+
public static readonly string NPC_SPAWN = "NPC_SPAWN";
16+
public static readonly string NPC_EXIT = "NPC_EXIT";
1517
}
1618
}

MultiplayerDemo/Assets/Scripts/Networking/Controllers/NetworkComponent.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,10 @@ public virtual void Initialize(NetworkManager _manager) {
1919
// These functions to be called for Unity Event Functions 'OnEnable' and 'OnDisable' respectively
2020
public virtual void Enable() {}
2121
public virtual void Disable() {}
22+
23+
protected void Log(string _msg) {
24+
if (!debug) return;
25+
Debug.Log("["+this.GetType()+"]: "+_msg);
26+
}
2227
}
2328
}
Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,36 @@
11
using System.Collections;
22
using System.Collections.Generic;
33
using UnityEngine;
4+
using PlayNet.Models;
45

56
namespace PlayNet.Networking {
67
public class NetworkEntityHandler : NetworkComponent
78
{
9+
private Hashtable m_NPCs;
10+
811
public override void Initialize(NetworkManager _m) {
912
base.Initialize(_m);
10-
13+
m_NPCs = new Hashtable();
1114
}
1215

1316
public override void Enable() {
14-
17+
m_Manager.Listener.npcSpawnEvt.OnEvt += OnNPCSpawn;
18+
m_Manager.Listener.npcExitEvt.OnEvt += OnNPCExit;
1519
}
1620

1721
public override void Disable() {
22+
m_Manager.Listener.npcSpawnEvt.OnEvt -= OnNPCSpawn;
23+
m_Manager.Listener.npcExitEvt.OnEvt -= OnNPCExit;
24+
}
25+
26+
private void OnNPCSpawn(NetworkNPCData _npc) {
27+
if (m_NPCs.ContainsKey(_npc.id)) return; // npc was already spawned
28+
Log("NPC spawned: "+_npc.id);
29+
}
1830

31+
private void OnNPCExit(string _id) {
32+
if (!m_NPCs.ContainsKey(_id)) return; // npc already doesnt exist
33+
Log("NPC exited: "+_id);
1934
}
2035
}
2136
}

MultiplayerDemo/Assets/Scripts/Networking/Controllers/NetworkListener.cs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ public class NetworkListener : NetworkComponent
2727
public NetworkEvent<NetworkPlayerData> playerSpawnEvt {get; private set;}
2828
public NetworkEvent<NetworkTransform> playerTransformEvt {get; private set;}
2929
#endregion
30+
#region NPCs
31+
public NetworkEvent<NetworkNPCData> npcSpawnEvt {get;private set;}
32+
public NetworkEvent<string> npcExitEvt {get;private set;}
33+
#endregion
3034
// Add more events here!
3135
#endregion
3236

@@ -55,23 +59,33 @@ private void Build() {
5559
playerLeaveEvt = new NetworkEvent<NetworkPlayerData>("Player left.", debug);
5660
playerSpawnEvt = new NetworkEvent<NetworkPlayerData>("Player entered range.", debug);
5761
playerTransformEvt = new NetworkEvent<NetworkTransform>("Player transform changed.", debug);
62+
// npc events
63+
npcSpawnEvt = new NetworkEvent<NetworkNPCData>("NPC spawned", debug);
64+
npcExitEvt = new NetworkEvent<string>("NPC exited range", debug);
5865
}
5966

67+
/*
68+
* Subscribe to network events and broadcast to game managers
69+
*/
6070
private void Listen() {
6171
// server events
6272
m_Manager.Socket.On(NetworkMessages.CONNECT, OnNetworkConnected);
6373
m_Manager.Socket.On(NetworkMessages.DISCONNECT, OnNetworkDisconnected);
64-
m_Manager.Socket.On(NetworkMessages.HANDSHAKE, handshakeEvt.HandleEvt);
74+
m_Manager.Socket.On(NetworkMessages.HANDSHAKE, handshakeEvt.Broadcast);
6575

66-
m_Manager.Socket.On(NetworkMessages.INSTANCE, instanceDataEvt.HandleEvt);
67-
m_Manager.Socket.On(NetworkMessages.CHAT, chatEvt.HandleEvt);
76+
m_Manager.Socket.On(NetworkMessages.INSTANCE, instanceDataEvt.Broadcast);
77+
m_Manager.Socket.On(NetworkMessages.CHAT, chatEvt.Broadcast);
6878

6979
// player events
70-
m_Manager.Socket.On(NetworkMessages.PLAYER_SPAWN, playerSpawnEvt.HandleEvt);
71-
m_Manager.Socket.On(NetworkMessages.PLAYER_EXIT, playerExitEvt.HandleEvt);
72-
m_Manager.Socket.On(NetworkMessages.PLAYER_JOINED, playerJoinEvt.HandleEvt);
73-
m_Manager.Socket.On(NetworkMessages.PLAYER_LEFT, playerLeaveEvt.HandleEvt);
74-
m_Manager.Socket.On(NetworkMessages.PLAYER_TRANSFORM_CHANGE, playerTransformEvt.HandleEvt);
80+
m_Manager.Socket.On(NetworkMessages.PLAYER_SPAWN, playerSpawnEvt.Broadcast);
81+
m_Manager.Socket.On(NetworkMessages.PLAYER_EXIT, playerExitEvt.Broadcast);
82+
m_Manager.Socket.On(NetworkMessages.PLAYER_JOINED, playerJoinEvt.Broadcast);
83+
m_Manager.Socket.On(NetworkMessages.PLAYER_LEFT, playerLeaveEvt.Broadcast);
84+
m_Manager.Socket.On(NetworkMessages.PLAYER_TRANSFORM_CHANGE, playerTransformEvt.Broadcast);
85+
86+
// npc events
87+
m_Manager.Socket.On(NetworkMessages.NPC_SPAWN, npcSpawnEvt.Broadcast);
88+
m_Manager.Socket.On(NetworkMessages.NPC_EXIT, npcExitEvt.Broadcast);
7589
}
7690

7791
private void OnNetworkConnected(SocketIOEvent _evt) {

MultiplayerDemo/Assets/Scripts/Networking/Models/NetworkEvent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public NetworkEvent(string _evtLog, bool _debug) {
2929
}
3030
}
3131

32-
public void HandleEvt(SocketIOEvent _evt) {
32+
public void Broadcast(SocketIOEvent _evt) {
3333
if (m_Invalid) return;
3434

3535
string _msg = Regex.Unescape((string)_evt.data.ToDictionary()["message"]);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
namespace PlayNet.Models {
2+
3+
public class NetworkNPCHitInfo : NetworkModel {
4+
public string id;
5+
public string npcName;
6+
public string playerName;
7+
public int dmg;
8+
public bool crit;
9+
public NetworkNPCHitInfo(string _id, string _npcName, int _dmg, bool _crit) {
10+
id = _id;
11+
npcName = _npcName;
12+
dmg = _dmg;
13+
crit = _crit;
14+
}
15+
}
16+
17+
public class NetworkNPCAttackData : NetworkModel {
18+
public string id;
19+
public string npcName;
20+
public string playerName;
21+
}
22+
23+
public class NetworkNPCDeathData : NetworkModel {
24+
public string id;
25+
public string name;
26+
public string[] lootRights; // array of player names who can loot
27+
public NetworkNPCXpAllottment[] xpAllottment;
28+
}
29+
30+
public class NetworkNPCXpAllottment : NetworkModel {
31+
public string playerName;
32+
public int xp;
33+
}
34+
35+
public class NetworkNPCData : NetworkModel {
36+
public string id;
37+
public string name;
38+
public int level;
39+
public int maxHealth;
40+
public int health;
41+
public int maxEnergy;
42+
public int energy;
43+
public float attackSpeed;
44+
public float aggroRange;
45+
public bool inAttackRange;
46+
public bool inCombat;
47+
public bool dead;
48+
public NetworkTransform transform;
49+
50+
public NetworkNPCData() {
51+
transform = new NetworkTransform();
52+
}
53+
}
54+
}

MultiplayerDemo/Assets/Scripts/Networking/Models/NetworkNPCData.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.package-lock.json

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/crypto/README.md

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/crypto/package.json

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"dependencies": {
3+
"crypto": "^1.0.1"
4+
}
5+
}

server/src/game.js

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ class Game {
2121

2222
// use a variable to store all players connected to the game
2323
// Here we initialize the scene that should be loaded for this game server
24-
// The scene object loads in mobs, waypoint graphs, and shop terminals
25-
this._scene = new TestScene(this);
24+
// The scene object loads in npcs, waypoint graphs, and shop terminals
25+
this._scene = TestScene(this);
2626
this._players = [];
2727
this._npcs = this._scene.npcs;
2828

@@ -71,7 +71,44 @@ class Game {
7171
}
7272

7373
/*
74-
* Emits a specific instance of nearby players and nearby mobs for each player..
74+
* NPCs will constantly scan for nearby players
75+
* Also used to determine the range where players can see other players
76+
*/
77+
scanNearbyPlayers(_pos, _radius) {
78+
return filter(this.__obj_data_map__(this._players), _player => {
79+
const _dist = new Vector3(_pos).distanceTo(new Vector3(_player.transform.pos));
80+
return _dist < _radius;
81+
});
82+
}
83+
84+
/*
85+
* Mobs will constantly scan for nearby players
86+
* Also used to determine the range where players can see other players
87+
*/
88+
scanNearbyPlayerSockets(_pos, _radius) {
89+
const _nearbyPlayers = filter(this._players, _player => {
90+
const _dist = new Vector3(_pos).distanceTo(new Vector3(_player.transform.pos));
91+
return _dist < _radius;
92+
});
93+
return map(_nearbyPlayers, _player => {
94+
return _player.socket
95+
});
96+
}
97+
98+
getPlayer(_name) {
99+
return find(this.__obj_data_map__(this._players), _player => {
100+
return _player.name == _name;
101+
});
102+
}
103+
104+
getPlayerRaw(_name) {
105+
return find(this._players, _player => {
106+
return _player.data.name == _name;
107+
});
108+
}
109+
110+
/*
111+
* Emits a specific instance of nearby players and nearby npcs for each player..
75112
* ..based on distance
76113
*/
77114
__emit_tailored_instance__() {

server/src/npcs/defs.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const droid = require('./droid');
2+
3+
module.exports = {
4+
droid
5+
}

server/src/npcs/droid.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
const crypto = require('crypto');
2+
const {Vector3} = require('../util/vector');
3+
4+
const droid = function(_level, _pos, _rot, _nameOverride=null) {
5+
const _id = crypto.randomBytes(5).toString('hex');
6+
_rot.y = Math.random() * 360;
7+
8+
return {
9+
id: _id,
10+
name: _nameOverride || 'Droid',
11+
level: _level,
12+
maxHealth: 40*_level,
13+
health: 40*_level,
14+
maxEnergy: 20*_level,
15+
energy: 20*_level,
16+
attackSpeed: 1,
17+
rechargeSpeed: 1.5,
18+
aggroRange: 8,
19+
retreatRange: 10,
20+
attackRange: 5,
21+
inCombat: false,
22+
inAttackRange: false,
23+
respawnTime: 5, // in seconds
24+
xpReward: 50*_level,
25+
xpRewardVariance: 10*_level,
26+
transform: {
27+
pos: new Vector3(_pos).obj,
28+
rot: new Vector3(_rot).obj
29+
},
30+
inCombat: false,
31+
healDelta: 50,
32+
runSpeed: 2,
33+
lootTime: 120, // 2 minutes
34+
minDamage: 0.01*_level,
35+
maxDamage: 0.01*_level,
36+
hitRate: 0.75,
37+
// !! TODO
38+
// Create mob actions initializer
39+
actions: []
40+
}
41+
}
42+
43+
module.exports = droid;

0 commit comments

Comments
 (0)