Merge pull request #1157 from ScrawnyRonnie/squads

Reintroduce Squads (Not Perfect)
This commit is contained in:
Fate-JH 2024-02-12 18:36:34 -05:00 committed by GitHub
commit c705a0fb56
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 61 additions and 68 deletions

View file

@ -55,17 +55,17 @@ class SessionSquadHandlers(
/* packet */
def handleSquadDefinitionAction(pkt: SquadDefinitionActionMessage): Unit = {
// val SquadDefinitionActionMessage(u1, u2, action) = pkt
// squadService ! SquadServiceMessage(player, continent, SquadServiceAction.Definition(u1, u2, action))
val SquadDefinitionActionMessage(u1, u2, action) = pkt
squadService ! SquadServiceMessage(player, continent, SquadServiceAction.Definition(u1, u2, action))
}
def handleSquadMemberRequest(pkt: SquadMembershipRequest): Unit = {
// val SquadMembershipRequest(request_type, char_id, unk3, player_name, unk5) = pkt
// squadService ! SquadServiceMessage(
// player,
// continent,
// SquadServiceAction.Membership(request_type, char_id, unk3, player_name, unk5)
// )
val SquadMembershipRequest(request_type, char_id, unk3, player_name, unk5) = pkt
squadService ! SquadServiceMessage(
player,
continent,
SquadServiceAction.Membership(request_type, char_id, unk3, player_name, unk5)
)
}
def handleSquadWaypointRequest(pkt: SquadWaypointRequest): Unit = {
@ -336,19 +336,19 @@ class SessionSquadHandlers(
sendResponse(CharacterKnowledgeMessage(charId, Some(CharacterKnowledgeInfo(name, certs, u1, u2, zone))))
case SquadResponse.SquadSearchResults(results) =>
//TODO positive squad search results message?
if(results.nonEmpty) {
results.foreach { guid =>
sendResponse(SquadDefinitionActionMessage(
guid,
0,
SquadAction.SquadListDecorator(SquadListDecoration.SearchResult))
)
}
} else {
sendResponse(SquadDefinitionActionMessage(player.GUID, 0, SquadAction.NoSquadSearchResults()))
}
sendResponse(SquadDefinitionActionMessage(player.GUID, 0, SquadAction.CancelSquadSearch()))
//TODO positive squad search results message?
// if(results.nonEmpty) {
// results.foreach { guid =>
// sendResponse(SquadDefinitionActionMessage(
// guid,
// 0,
// SquadAction.SquadListDecorator(SquadListDecoration.SearchResult))
// )
// }
// } else {
// sendResponse(SquadDefinitionActionMessage(player.GUID, 0, SquadAction.NoSquadSearchResults()))
// }
// sendResponse(SquadDefinitionActionMessage(player.GUID, 0, SquadAction.CancelSquadSearch()))
case SquadResponse.InitWaypoints(char_id, waypoints) =>
waypoints.foreach {

View file

@ -165,7 +165,7 @@ class SquadInvitationManager(subs: SquadSubscriptionEntity, parent: ActorRef) {
val availableForJoiningSquad = notLimitedByEnrollmentInSquad(invitedPlayerSquadOpt, invitedPlayer)
acceptedInvite match {
case Some(RequestRole(petitioner, features, position))
if availableForJoiningSquad && canEnrollInSquad(features, petitioner.CharId) =>
if canEnrollInSquad(features, petitioner.CharId) =>
//player requested to join a squad's specific position
//invitedPlayer is actually the squad leader; petitioner is the actual "invitedPlayer"
if (JoinSquad(petitioner, features, position)) {
@ -174,7 +174,7 @@ class SquadInvitationManager(subs: SquadSubscriptionEntity, parent: ActorRef) {
}
case Some(IndirectInvite(recruit, features))
if availableForJoiningSquad && canEnrollInSquad(features, recruit.CharId) =>
if canEnrollInSquad(features, recruit.CharId) =>
//tplayer / invitedPlayer is actually the squad leader
val recruitCharId = recruit.CharId
HandleVacancyInvite(features, recruitCharId, invitedPlayer, recruit) match {
@ -426,14 +426,14 @@ class SquadInvitationManager(subs: SquadSubscriptionEntity, parent: ActorRef) {
Refused(rejectingPlayer, invitingPlayerCharId)
(Some(rejectingPlayer), Some(invitingPlayerCharId))
case Some(VacancyInvite(leader, _, features))
if notLeaderOfThisSquad(squadsToLeaders, features.Squad.GUID, rejectingPlayer) =>
case Some(VacancyInvite(leader, _, _))
/*if notLeaderOfThisSquad(squadsToLeaders, features.Squad.GUID, rejectingPlayer)*/ =>
//rejectingPlayer is the would-be squad member; the squad leader sent the request and was rejected
Refused(rejectingPlayer, leader)
(Some(rejectingPlayer), Some(leader))
case Some(ProximityInvite(_, features, position))
if notLeaderOfThisSquad(squadsToLeaders, features.Squad.GUID, rejectingPlayer) =>
/*if notLeaderOfThisSquad(squadsToLeaders, features.Squad.GUID, rejectingPlayer)*/ =>
//rejectingPlayer is the would-be squad member; the squad leader sent the request and was rejected
ReloadProximityInvite(
tplayer.Zone.Players,
@ -456,7 +456,7 @@ class SquadInvitationManager(subs: SquadSubscriptionEntity, parent: ActorRef) {
(Some(rejectingPlayer), Some(leaderCharId))
case Some(RequestRole(rejected, features, _))
if notLeaderOfThisSquad(squadsToLeaders, features.Squad.GUID, rejectingPlayer) =>
if notLeaderOfThisSquad(squadsToLeaders, features.Squad.GUID, rejected.CharId) =>
//rejected is the would-be squad member; rejectingPlayer is the squad leader who rejected the request
features.DeniedPlayers(rejected.CharId)
(Some(rejectingPlayer), None)
@ -2028,7 +2028,8 @@ class SquadInvitationManager(subs: SquadSubscriptionEntity, parent: ActorRef) {
avatar.lookingForSquad &&
!deniedAndExcluded.contains(charId) &&
!refused(charId).contains(squadLeader) &&
requirementsToMeet.intersect(avatar.certifications) == requirementsToMeet
requirementsToMeet.intersect(avatar.certifications) == requirementsToMeet &&
charId != invitingPlayerCharId //don't send invite to yourself. can cause issues if rejected
} match {
case None =>
None

View file

@ -6,7 +6,7 @@ import java.io.{PrintWriter, StringWriter}
import scala.collection.concurrent.TrieMap
import scala.collection.mutable
//
import net.psforever.objects.{Default, LivePlayerList, Player}
import net.psforever.objects.{LivePlayerList, Player}
import net.psforever.objects.teamwork.{Member, Squad, SquadFeatures}
import net.psforever.objects.avatar.{Avatar, Certification}
import net.psforever.objects.definition.converter.StatConverter
@ -76,7 +76,7 @@ class SquadService extends Actor {
//squads and members (users)
squadFeatures.foreach {
case (_, features) =>
CloseSquad(features.Squad)
DisbandSquad(features)
}
memberToSquad.clear()
publishedLists.clear()
@ -377,7 +377,7 @@ class SquadService extends Actor {
SquadActionMembershipCancel(cancellingPlayer)
case SquadAction.Membership(SquadRequestType.Promote, promotingPlayer, Some(_promotedPlayer), promotedName, _) =>
SquadActionMembershipPromote(promotingPlayer, _promotedPlayer, promotedName, SquadServiceMessage(tplayer, zone, action), sender())
//SquadActionMembershipPromote(promotingPlayer, _promotedPlayer, promotedName, SquadServiceMessage(tplayer, zone, action), sender())
case SquadAction.Membership(event, _, _, _, _) =>
debug(s"SquadAction.Membership: $event is not yet supported")
@ -686,10 +686,10 @@ class SquadService extends Actor {
}
None
case search: SearchForSquadsWithParticularRole =>
SquadActionDefinitionSearchForSquadsWithParticularRole(tplayer, search)
// SquadActionDefinitionSearchForSquadsWithParticularRole(tplayer, search)
None
case _: CancelSquadSearch =>
SquadActionDefinitionCancelSquadSearch(tplayer.CharId)
// SquadActionDefinitionCancelSquadSearch(tplayer.CharId)
None
case _: DisplaySquad =>
GetSquad(guid) match {
@ -863,6 +863,11 @@ class SquadService extends Actor {
val sguid = GetNextSquadId()
val squad = new Squad(sguid, faction)
val leadPosition = squad.Membership(0)
//keep publishedLists clear of old squads. PR 1157 for details
val factionListings = publishedLists(faction)
val guidsToRemove = factionListings.filterNot(squadFeatures.contains).toList
guidsToRemove.foreach(factionListings -= _)
leadPosition.Name = name
leadPosition.CharId = player.CharId
leadPosition.Health = StatConverter.Health(player.Health, player.MaxHealth, min = 1, max = 64)
@ -902,9 +907,8 @@ class SquadService extends Actor {
val squad = features.Squad
subs.UserEvents.get(charId) match {
case Some(events)
if !memberToSquad.contains(charId) &&
squad.Leader.CharId != charId &&
squad.isAvailable(position, player.avatar.certifications) =>
if squad.isAvailable(position, player.avatar.certifications) &&
EnsureEmptySquad(charId) =>
memberToSquad(charId) = squad.GUID
subs.MonitorSquadDetails.subtractOne(charId)
invitations.handleCleanup(charId)
@ -951,6 +955,7 @@ class SquadService extends Actor {
membership.find { case (_member, _) => _member.CharId == charId } match {
case Some(_) if squad.Leader.CharId != charId =>
memberToSquad.remove(charId)
subs.MonitorSquadDetails.subtractOne(charId)
features.Switchboard ! SquadSwitchboard.Leave(charId)
true
case _ =>
@ -1010,6 +1015,10 @@ class SquadService extends Actor {
subs.Publish(charId, SquadResponse.Detail(PlanetSideGUID(0), completelyBlankSquadDetail))
}
UpdateSquadListWhenListed(features.Stop, None)
//remove from list of squads
squadFeatures -= guid
//really make sure it is removed from listed squads
publishedLists(squad.Faction) -= guid
}
/**
@ -1083,6 +1092,7 @@ class SquadService extends Actor {
pSquadOpt match {
//member of the squad; leave the squad
case Some(features) =>
LeaveSquad(charId, features) //adding this fixed issue of rejoining the squad on login.
val squad = features.Squad
val size = squad.Size
subs.UserEvents.remove(charId) match {
@ -1093,25 +1103,8 @@ class SquadService extends Actor {
if (size > 2) {
GetLeadingSquad(charId, pSquadOpt) match {
case Some(_) =>
//leader of a squad; search for a suitable substitute leader
squad.Membership.drop(1).find { _.CharId > 0 } match {
case Some(member) =>
//leader was shifted into a subordinate position and will retire from duty
SquadActionMembershipPromote(
charId,
member.CharId,
features,
SquadServiceMessage(null, null, SquadAction.Membership(SquadRequestType.Promote, charId, Some(member.CharId), "", None)),
Default.Actor
)
LeaveSquad(charId, features)
case _ =>
//the squad will be disbanded
PanicDisbandSquad(
features,
squad.Membership.collect { case member if member.CharId > 0 && member.CharId != charId => member.CharId }
)
}
//leader of a squad; the squad will be disbanded. Same logic as when a SL uses /leave and the squad is disbanded.
DisbandSquad(features)
case None =>
//not the leader of a full squad; tell other members that we are leaving
SquadSwitchboard.PanicLeaveSquad(
@ -1125,10 +1118,7 @@ class SquadService extends Actor {
}
} else {
//with only two members before our leave, the squad will be disbanded
PanicDisbandSquad(
features,
squad.Membership.collect { case member if member.CharId > 0 && member.CharId != charId => member.CharId }
)
DisbandSquad(features)
}
case None =>
//not a member of any squad; nothing really to do here
@ -1136,7 +1126,8 @@ class SquadService extends Actor {
}
subs.SquadEvents.unsubscribe(sender) //just to make certain
searchData.remove(charId)
TryResetSquadId()
//todo turn this back on. See PR 1157 for why it was commented out.
//TryResetSquadId()
}
/**

View file

@ -171,13 +171,12 @@ class SquadSwitchboard(
//update for leader
features.InitialAssociation = false
subscriptions.Publish(leaderId, SquadResponse.IdentifyAsSquadLeader(squad.GUID))
subscriptions.Publish(leaderId, SquadResponse.CharacterKnowledge(charId, role.Name, role.Certifications, 40, 5, role.ZoneId))
subscriptions.Publish(leaderId, SquadResponse.CharacterKnowledge(charId, role.Name, role.Certifications, player.avatar.br.value, player.avatar.cr.value, role.ZoneId))
//everyone
subscriptions.InitSquadDetail(features)
} else {
//joining an active squad; different people update differently
//new member gets full squad UI updates
subscriptions.InitSquadDetail(squad.GUID, Seq(charId), squad)
subscriptions.Publish(
charId,
SquadResponse.Join(
@ -201,8 +200,9 @@ class SquadSwitchboard(
)
subscriptions.Publish(toChannel, SquadResponse.Join(squad, List(position), "", self), Seq(charId))
//update for leader
subscriptions.Publish(leaderId, SquadResponse.CharacterKnowledge(charId, role.Name, role.Certifications, 40, 5, role.ZoneId))
subscriptions.Publish(leaderId, SquadResponse.CharacterKnowledge(charId, role.Name, role.Certifications, player.avatar.br.value, player.avatar.cr.value, role.ZoneId))
subscriptions.SquadEvents.subscribe(sendTo, s"/$toChannel/Squad")
subscriptions.InitSquadDetail(squad.GUID, Seq(charId), squad)
}
context.parent ! SquadService.UpdateSquadListWhenListed(
features,
@ -653,7 +653,7 @@ class SquadSwitchboard(
if (squad.Leader.CharId == char_id) {
membership.lift(position) match {
case Some(toMember) =>
SquadActionMembershipPromote(char_id, toMember.CharId)
//SquadActionMembershipPromote(char_id, toMember.CharId)
case _ => ;
}
} else {
@ -684,7 +684,7 @@ class SquadSwitchboard(
def SquadActionMembership(action: Any): Unit = {
action match {
case SquadAction.Membership(SquadRequestType.Promote, promotingPlayer, Some(promotedPlayer), _, _) =>
SquadActionMembershipPromote(promotingPlayer, promotedPlayer)
//SquadActionMembershipPromote(promotingPlayer, promotedPlayer)
case SquadAction.Membership(event, _, _, _, _) =>
log.debug(s"SquadAction.Membership: $event is not supported here")
@ -729,6 +729,7 @@ class SquadSwitchboard(
_.CharId == promotedPlayer
}
.foreach { member =>
//todo: get member br & cr to replace 40, 5
subscriptions.Publish(promotedPlayer, SquadResponse.CharacterKnowledge(member.CharId, member.Name, member.Certifications, 40, 5, member.ZoneId))
}
//to old and to new squad leader
@ -904,18 +905,18 @@ class SquadSwitchboard(
if (leaderCharId != charId) {
subscriptions.Publish(
leaderCharId,
SquadResponse.CharacterKnowledge(charId, member.Name, certifications, 40, 5, zoneNumber)
SquadResponse.CharacterKnowledge(charId, member.Name, certifications, player.avatar.br.value, player.avatar.cr.value, zoneNumber)
)
}
context.parent ! SquadServiceMessage(player, player.Zone, SquadAction.ReloadDecoration())
} else if (zoneBefore != zoneNumber && leaderCharId != charId) {
subscriptions.Publish(
leaderCharId,
SquadResponse.CharacterKnowledge(charId, member.Name, certifications, 40, 5, 0)
SquadResponse.CharacterKnowledge(charId, member.Name, certifications, player.avatar.br.value, player.avatar.cr.value, 0)
)
subscriptions.Publish(
leaderCharId,
SquadResponse.CharacterKnowledge(charId, member.Name, certifications, 40, 5, zoneNumber)
SquadResponse.CharacterKnowledge(charId, member.Name, certifications, player.avatar.br.value, player.avatar.cr.value, zoneNumber)
)
}
if (features.LocationFollowsSquadLead) {