mirror of
https://bitbucket.org/seefoe/dsrc.git
synced 2026-07-31 01:15:55 -04:00
391 lines
12 KiB
Plaintext
391 lines
12 KiB
Plaintext
/**
|
|
* Copyright (c)2000-2002 Sony Online Entertainment Inc.
|
|
* All Rights Reserved
|
|
*
|
|
* Title: group_object.script
|
|
* Description: script for the group object
|
|
* @author $Author:$
|
|
* @version $Revision:$
|
|
*/
|
|
|
|
/***** INCLUDES ********************************************************/
|
|
include java.util.Hashtable;
|
|
include java.util.Set;
|
|
include java.util.Iterator;
|
|
|
|
trigger OnInitialize()
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
/***** INHERITS ********************************************************/
|
|
|
|
/***** CONSTANTS *******************************************************/
|
|
|
|
/***** TRIGGER *********************************************************/
|
|
|
|
/***** MESSAGEHANDLERS **************************************************/
|
|
|
|
messageHandler volleyTargetDone()
|
|
{
|
|
//LOG("combat", "Group object " + self + " received volleyTargetDone message.");
|
|
obj_id[] members = getGroupMemberIds(self);
|
|
if(members == null || members.length < 1)
|
|
{
|
|
//LOG("combat", "No members in group. Not messaging any members.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
for(int i = 0; i < members.length; i++)
|
|
{
|
|
//LOG("combat", "Messaging 'volleyTargetDone' to " + members[i]);
|
|
messageTo(members[i], "volleyTargetDone", params, 0, false);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler addGroupMember()
|
|
{
|
|
// check the messageTo dictionary parameters
|
|
if(params != null)
|
|
{
|
|
// the group member is set in group_member.script
|
|
obj_id newGroupMember = params.getObjId("memberObjectId");
|
|
if(isIdValid(newGroupMember))
|
|
{
|
|
deltadictionary scriptVars = self.getScriptVars();
|
|
if(scriptVars != null)
|
|
{
|
|
// the new member might have missions closer
|
|
// for the group, run through the mssion select
|
|
// logic
|
|
selectNearestGroupMission(self);
|
|
}
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler removeGroupMember()
|
|
{
|
|
if(params != null)
|
|
{
|
|
// set in group_member.script
|
|
obj_id groupMember = params.getObjId("sender");
|
|
if(isIdValid(groupMember))
|
|
{
|
|
deltadictionary scriptVars = self.getScriptVars();
|
|
if(scriptVars != null)
|
|
{
|
|
// the group member might have had the
|
|
// mission closest to the group. Run the
|
|
// group mission waypoint selection
|
|
selectNearestGroupMission(self);
|
|
}
|
|
}
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
location calculateNearestGroupMission(obj_id self)
|
|
{
|
|
// iterate through the members and mission locations
|
|
// retrieved from the members. Each member 'votes' for
|
|
// the mission that is nearest to them. The location with
|
|
// the most 'votes' becomes the new group mission objective
|
|
location result = new location();
|
|
deltadictionary scriptVars = self.getScriptVars();
|
|
if(scriptVars != null)
|
|
{
|
|
// get the memberLocations and the missionLocations,
|
|
// bail out of either of them are empty (nothing to vote on)
|
|
location[] memberLocations = scriptVars.getLocationArray("memberLocations");
|
|
if((memberLocations == null) || (memberLocations.length < 1))
|
|
{
|
|
return null;
|
|
}
|
|
location[] missionLocations = scriptVars.getLocationArray("missionLocations");
|
|
if((missionLocations == null) || (missionLocations.length < 1))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
// initialize the nearestGroupMission if it already exists
|
|
location nearestGroupMission = scriptVars.getLocation("nearestGroupMission");
|
|
if(nearestGroupMission == null)
|
|
{
|
|
if(missionLocations.length > 0)
|
|
{
|
|
// no nearestGroupMission, start with the first mission
|
|
// in the locations list
|
|
nearestGroupMission = missionLocations[0];
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// this map contains the vote results. It's a map of locations and vote counts
|
|
// (int location, int votes)
|
|
Hashtable bestLocations = new Hashtable();
|
|
|
|
// outer loop iterates over the members
|
|
int memberLocationIndex = 0;
|
|
int preferredIndex = -1;
|
|
for(memberLocationIndex = 0; memberLocationIndex < memberLocations.length; ++memberLocationIndex)
|
|
{
|
|
int missionLocationIndex = 0;
|
|
//location memberPreferredLocation = nearestGroupMission;
|
|
float bestDistance = -1;
|
|
// inner loop iterates over mission locations
|
|
for(missionLocationIndex = 0; missionLocationIndex < missionLocations.length; ++missionLocationIndex)
|
|
{
|
|
// initialize the location under consideration
|
|
location currentLocation = missionLocations[missionLocationIndex];
|
|
|
|
// verify that the mission being considered is on the same
|
|
// planet as the group member
|
|
if(currentLocation.area.equals(memberLocations[memberLocationIndex].area))
|
|
{
|
|
// check the distance between the current location under consideration
|
|
// and the best candidate found so far
|
|
float currentDistance = currentLocation.distance(memberLocations[memberLocationIndex]);
|
|
if(bestDistance < 0 || currentDistance < bestDistance)
|
|
{
|
|
// the current mission is better, promote it to the
|
|
// 'best' candidate location
|
|
preferredIndex = missionLocationIndex;
|
|
bestDistance = currentDistance;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(preferredIndex > -1)
|
|
{
|
|
Integer p = new Integer(preferredIndex);
|
|
// add the most preferred candidate location to the voting results map
|
|
if(bestLocations.containsKey(new Integer(preferredIndex)))
|
|
{
|
|
int votes = ((Integer)bestLocations.get(p)).intValue();
|
|
votes = votes + 1;
|
|
bestLocations.put(p, new Integer(votes));
|
|
}
|
|
else
|
|
{
|
|
Integer votes = new Integer(1);
|
|
bestLocations.put(p, votes);
|
|
}
|
|
}
|
|
}
|
|
|
|
// tally the votes for the new nearest group mission
|
|
Set keySet = bestLocations.keySet();
|
|
Iterator votesIterator = keySet.iterator();
|
|
int mostVotes = 0;
|
|
while(votesIterator.hasNext())
|
|
{
|
|
Integer locationIndex = (Integer)(votesIterator.next());
|
|
//location l = (location)votesIterator.next();
|
|
int votes = ((Integer)bestLocations.get(locationIndex)).intValue();
|
|
|
|
// this location has the most votes(so far)
|
|
if(votes > mostVotes)
|
|
{
|
|
nearestGroupMission = missionLocations[locationIndex.intValue()];
|
|
mostVotes = votes;
|
|
}
|
|
}
|
|
|
|
// update the nearest group mission waypoint for everyone in the group
|
|
result = nearestGroupMission;
|
|
scriptVars.put("nearestGroupMission", nearestGroupMission);
|
|
}
|
|
else
|
|
{
|
|
result = null;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
messageHandler missionLocationResponse()
|
|
{
|
|
// group_member.script has responded to a request
|
|
// for mission location information
|
|
if((params != null) && (params.containsKey("requestMissionLocationsNumber")))
|
|
{
|
|
deltadictionary scriptVars = self.getScriptVars();
|
|
if((scriptVars != null) && (scriptVars.hasKey("requestMissionLocationsNumber")) && (params.getInt("requestMissionLocationsNumber") == scriptVars.getInt("requestMissionLocationsNumber")))
|
|
{
|
|
// retrieve mission and member information
|
|
// from the script parameter dictionary
|
|
obj_id missionHolder = params.getObjId("sender");
|
|
if(isIdValid(missionHolder))
|
|
{
|
|
// get the location of the group member
|
|
location senderLocation = params.getLocation("senderLocation");
|
|
if(senderLocation != null)
|
|
{
|
|
// match against other group member locations
|
|
// and member mission locations, update the
|
|
// nearest group mission and waypoint if necessary
|
|
resizeable location[] memberLocations = scriptVars.getResizeableLocationArray("memberLocations");
|
|
if(memberLocations == null)
|
|
{
|
|
memberLocations = new Vector();
|
|
}
|
|
memberLocations.add(senderLocation);
|
|
scriptVars.put("memberLocations", memberLocations);
|
|
|
|
location[] missionLocation = params.getLocationArray("missionLocation");
|
|
if((missionLocation != null) && (missionLocation.length > 0))
|
|
{
|
|
// mission locations are used in the
|
|
// group calculation (see comments in
|
|
// calculateNearestGroupMission
|
|
resizeable location[] missionLocations = scriptVars.getResizeableLocationArray("missionLocations");
|
|
if(missionLocations == null)
|
|
{
|
|
missionLocations = new Vector();
|
|
}
|
|
|
|
for(int i = 0; i < missionLocation.length; ++i)
|
|
{
|
|
missionLocations.add(missionLocation[i]);
|
|
}
|
|
|
|
scriptVars.put("missionLocations", missionLocations);
|
|
|
|
location nearestGroupMission = scriptVars.getLocation("nearestGroupMission");
|
|
if(nearestGroupMission == null)
|
|
{
|
|
nearestGroupMission = missionLocation[0];
|
|
scriptVars.put("nearestGroupMission", nearestGroupMission);
|
|
}
|
|
}
|
|
|
|
// once all group members have reported, execute the nearestGroupMission
|
|
// calculation and disseminate the results to group members; if members
|
|
// may have joined or left the group while we were accumulating the
|
|
// information which may cause what we have accumulated to be out of
|
|
// sync with the actual state of the group, don't worry about it, since
|
|
// we recalculate whenever someone joins or leaves the group
|
|
if (memberLocations.length >= getPCGroupSize(self))
|
|
tellMembersAboutNearestGroupMission(self, calculateNearestGroupMission(self));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
void tellMembersAboutNearestGroupMission(obj_id self, location nearestGroupMission)
|
|
{
|
|
// bail out early if no nearestGroupMission is available
|
|
if(nearestGroupMission != null)
|
|
{
|
|
deltadictionary scriptVars = self.getScriptVars();
|
|
if(scriptVars != null)
|
|
{
|
|
// update the nearest group mission waypoint for everyone in the group
|
|
// get the members list from scriptVars, use it to dispatch messageTo's
|
|
obj_id[] members = getGroupMemberIds(self);
|
|
int memberIndex = 0;
|
|
|
|
// create the messageTo parameters dictionary and put the
|
|
// nearestGroupMission location in it
|
|
dictionary msgData = new dictionary();
|
|
msgData.put("waypointLocation", nearestGroupMission);
|
|
|
|
// work around a bug/shortcoming of the messaging system. messageTo's
|
|
// are delivered out of sequence in a seemingly random fashion. To
|
|
// ensure that only the most recent update is applied, add a sequence
|
|
// to the message. group_member.script's messageHandler will discard
|
|
// messages with sequence values less than what it has already
|
|
// received.
|
|
int sequence = scriptVars.getInt("updateSequence");
|
|
sequence++;
|
|
scriptVars.put("updateSequence", sequence);
|
|
msgData.put("updateSequence", sequence);
|
|
|
|
// now iterate over the members list and send an updateGroupWaypoint
|
|
// messageTo with the sequence and nearestGroupMission location
|
|
for(memberIndex = 0; memberIndex < members.length; ++memberIndex)
|
|
{
|
|
messageTo(members[memberIndex], "updateGroupWaypoint", msgData, 0, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void selectNearestGroupMission(obj_id self)
|
|
{
|
|
// starts the nearestGroupMission location
|
|
// selection protocol from scracth, removing
|
|
// the current nearestGroupMission locatio
|
|
// and replacing it with the best location
|
|
deltadictionary scriptVars = self.getScriptVars();
|
|
if(scriptVars != null)
|
|
{
|
|
// clear out old mission and member location data
|
|
// this will be refreshed by group member's responding
|
|
// to the requestMissionLocations message
|
|
scriptVars.remove("memberLocations");
|
|
scriptVars.remove("missionLocations");
|
|
scriptVars.remove("nearestGroupMission");
|
|
|
|
// iterate over the group members list and
|
|
// deliver the requestMissionLocations message.
|
|
// group_member.script will query its owner's
|
|
// mission objects for location information
|
|
obj_id[] members = getGroupMemberIds(self);
|
|
if(members != null)
|
|
{
|
|
// a counter to map responses to requestMissionLocations;
|
|
// we use this in cases where selectNearestGroupMission() is called
|
|
// before we have received all responses to a previous
|
|
// selectNearestGroupMission() call, in which case, we'll throw
|
|
// out the "stale" responses to requestMissionLocations
|
|
int requestMissionLocationsNumber = 1;
|
|
if (scriptVars.hasKey("requestMissionLocationsNumber"))
|
|
{
|
|
requestMissionLocationsNumber = scriptVars.getInt("requestMissionLocationsNumber");
|
|
++requestMissionLocationsNumber;
|
|
}
|
|
|
|
scriptVars.put("requestMissionLocationsNumber", requestMissionLocationsNumber);
|
|
|
|
dictionary requestData = new dictionary();
|
|
requestData.put("requestMissionLocationsNumber", requestMissionLocationsNumber);
|
|
|
|
int memberIndex = 0;
|
|
for(memberIndex = 0; memberIndex < members.length; ++memberIndex)
|
|
{
|
|
messageTo(members[memberIndex], "requestMissionLocations", requestData, 0, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
messageHandler recaclulateNearestGroupWaypoint()
|
|
{
|
|
// this message is received from a group member
|
|
// when it has been notified that one of its
|
|
// mission waypoints has been updated
|
|
selectNearestGroupMission(self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
messageHandler removeMissionLocation()
|
|
{
|
|
// this message is sent by a group member
|
|
// when a mission object is no longer
|
|
// available (it's been removed, finished,
|
|
// incomplete, aborted, etc.)
|
|
selectNearestGroupMission(self);
|
|
return SCRIPT_CONTINUE;
|
|
}
|