-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPlayerGuild.cs
More file actions
199 lines (175 loc) · 6.69 KB
/
PlayerGuild.cs
File metadata and controls
199 lines (175 loc) · 6.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
using UnityEngine;
using Mirror;
using TMPro;
namespace uMMORPG
{
[RequireComponent(typeof(PlayerChat))]
[DisallowMultipleComponent]
public class PlayerGuild : NetworkBehaviour
{
[Header("Components")]
public Player player;
public PlayerChat chat;
[Header("Text Meshes")]
public TextMeshPro overlay;
public string overlayPrefix = "[";
public string overlaySuffix = "]";
// .guild is a copy for easier reading/syncing. Use GuildSystem to manage
// guilds!
[Header("Guild")]
[SyncVar, HideInInspector] public string inviteFrom = "";
[SyncVar, HideInInspector] public Guild guild; // TODO SyncToOwner later but need to sync guild name to everyone!
public float inviteWaitSeconds = 3;
void Start()
{
// do nothing if not spawned (=for character selection previews)
if (!isServer && !isClient) return;
// notify guild members that we are online. this also updates the client's
// own guild info via targetrpc automatically
// -> OnStartServer is too early because it's not spawned there yet
if (isServer)
SetOnline(true);
}
void Update()
{
// update overlays in any case, except on server-only mode
// (also update for character selection previews etc. then)
if (!isServerOnly)
{
if (overlay != null)
overlay.text = !string.IsNullOrWhiteSpace(guild.name) ? overlayPrefix + guild.name + overlaySuffix : "";
}
}
void OnDestroy()
{
// do nothing if not spawned (=for character selection previews)
if (!isServer && !isClient) return;
// notify guild members that we are offline
if (isServer)
SetOnline(false);
}
// guild ///////////////////////////////////////////////////////////////////
public bool InGuild() => !string.IsNullOrWhiteSpace(guild.name);
// ServerCALLBACk to ignore the warning if it's called while server isn't
// active, which happens if OnDestroy->SetOnline(false) is called while
// shutting down.
[ServerCallback]
public void SetOnline(bool online)
{
// validate
if (InGuild())
GuildSystem.SetGuildOnline(guild.name, name, online);
}
[Command]
public void CmdInviteTarget()
{
// validate
if (player.target != null &&
player.target is Player targetPlayer &&
InGuild() && !targetPlayer.guild.InGuild() &&
guild.CanInvite(name, targetPlayer.name) &&
NetworkTime.time >= player.nextRiskyActionTime &&
Utils.ClosestDistance(player, targetPlayer) <= player.interactionRange)
{
// send an invite
targetPlayer.guild.inviteFrom = name;
Debug.Log(name + " invited " + player.target.name + " to guild");
}
// reset risky time no matter what. even if invite failed, we don't want
// players to be able to spam the invite button and mass invite random
// players.
player.nextRiskyActionTime = NetworkTime.time + inviteWaitSeconds;
}
[Command]
public void CmdInviteAccept()
{
// valid invitation?
// note: no distance check because sender might be far away already
if (!InGuild() && inviteFrom != "" &&
Player.onlinePlayers.TryGetValue(inviteFrom, out Player sender) &&
sender.guild.InGuild())
{
// try to add. GuildSystem does all the checks.
GuildSystem.AddToGuild(sender.guild.guild.name, sender.name, name, player.level.current);
}
// reset guild invite in any case
inviteFrom = "";
}
[Command]
public void CmdInviteDecline()
{
inviteFrom = "";
}
[Command]
public void CmdKick(string memberName)
{
// validate
if (InGuild())
GuildSystem.KickFromGuild(guild.name, name, memberName);
}
[Command]
public void CmdPromote(string memberName)
{
// validate
if (InGuild())
GuildSystem.PromoteMember(guild.name, name, memberName);
}
[Command]
public void CmdDemote(string memberName)
{
// validate
if (InGuild())
GuildSystem.DemoteMember(guild.name, name, memberName);
}
[Command]
public void CmdSetNotice(string notice)
{
// validate
// (only allow changes every few seconds to avoid bandwidth issues)
if (InGuild() && NetworkTime.time >= player.nextRiskyActionTime)
{
// try to set notice
GuildSystem.SetGuildNotice(guild.name, name, notice);
}
// reset risky time no matter what. even if set notice failed, we don't
// want people to spam attempts all the time.
player.nextRiskyActionTime = NetworkTime.time + GuildSystem.NoticeWaitSeconds;
}
// helper function to check if we are near a guild manager npc
public bool IsGuildManagerNear()
{
return player.target != null &&
player.target is Npc npc &&
npc.guildManagement != null && // only if Npc offers guild management
Utils.ClosestDistance(player, player.target) <= player.interactionRange;
}
[Command]
public void CmdTerminate()
{
// validate
if (InGuild() && IsGuildManagerNear())
GuildSystem.TerminateGuild(guild.name, name);
}
[Command]
public void CmdCreate(string guildName)
{
// validate
if (player.health.current > 0 && player.gold >= GuildSystem.CreationPrice &&
!InGuild() && IsGuildManagerNear())
{
// try to create the guild. pay for it if it worked.
if (GuildSystem.CreateGuild(name, player.level.current, guildName))
player.gold -= GuildSystem.CreationPrice;
else
chat.TargetMsgInfo("Guild name invalid!");
}
}
[Command]
public void CmdLeave()
{
// validate
if (InGuild())
GuildSystem.LeaveGuild(guild.name, name);
}
}
}