/********************************************************************** * Title: space_dungeon * Description: Handles functionality/travel for space dungeons **********************************************************************/ /***** INCLUDES ********************************************************/ include library.callable; include library.player_structure; include library.utils; include java.util.Iterator; include library.pclib; include library.space_dungeon_data; include library.pet_lib; include library.cloninglib; include library.trial; include library.gm; include library.locations; /***** CONSTANTS *******************************************************/ // Ticket Template const string TEMPLATE_TICKET = "object/tangible/travel/travel_ticket/dungeon_ticket.iff"; // Scripts const string TRAVEL_DUNGEON = "item.travel_ticket.travel_space_dungeon"; const string PLAYER_TRAVEL_DUNGEON = "item.travel_ticket.travel_player_space_dungeon"; const string DUNGEON_CONTROLLER = "theme_park.dungeon.space_dungeon_controller"; // System constants ***************** const int MAXIMUM_TICKET_COLLECTOR_DISTANCE_GROUND = 15; const int MAXIMUM_TICKET_COLLECTOR_DISTANCE_SPACE = 1000; const int MAXIMUM_TRAVEL_GROUP_DISTANCE_GROUND = 50; const int MAXIMUM_TRAVEL_GROUP_DISTANCE_SPACE = 100000; // effectively unlimit the travel distance in space // ObjVars / ScriptVars ****************** // Tickets const string VAR_TICKET_ROOT = "space_dungeon.ticket"; const string VAR_TICKET_PLANET = "space_dungeon.ticket.planet"; const string VAR_TICKET_POINT = "space_dungeon.ticket.point"; const string VAR_TICKET_DUNGEON = "space_dungeon.ticket.dungeon"; const string VAR_TICKET_QUEST_TYPE = "space_dungeon.ticket.quest_type"; // Dungeons const string VAR_DUNGEON_NAME = "space_dungeon.name"; const string VAR_BUILDOUT_AREA = "space_dungeon.buildout_area"; const string VAR_BUILDOUT_ROW = "space_dungeon.buildout_row"; const string VAR_IS_ACTIVE = "space_dungeon.is_active"; const string VAR_SESSION_ID = "space_dungeon.session_id"; const string VAR_PARTICIPANT_IDS = "space_dungeon.participant_ids"; const string SCRIPT_VAR_TIME_REMAINING = "space_dungeon.time_remaining"; const string VAR_QUEST_TYPE = "space_dungeon.quest_type"; const string VAR_REGISTERED_OBJECTS = "space_dungeon.registered_objects"; const string VAR_DUNGEON_START_TIME = "space_dungeon.session_start_time"; const string VAR_DUNGEON_END_TIME = "space_dungeon.session_end_time"; // Dungeon string names const string KASH_SLAVE_CAMP = "trando_slave_camp"; const string KASH_THE_BET = "the_bet_bocctyyy"; const string KASH_MONSTER_ISLAND = "monster_island_hracca"; const string KASH_THE_ARENA = "kash_the_arena"; const string CORVETTE_REBEL = ""; const string CORVETTE_IMPERIAL = ""; const string CORVETTE_NEUTRAL = ""; // Terminal/Ticket Collector const string SCRIPT_VAR_TRAVELERS = "space_dungeon.travelers_"; // Player const string VAR_TICKET_USED = "space_dungeon.ticket_used"; const string VAR_DUNGEON_ID = "space_dungeon.dungeon_id"; const string VAR_PILOT_ID = "space_dungeon.pilot_id"; const string VAR_PILOT_SHIP_ID = "space_dungeon.pilot_ship_id"; const string VAR_PILOT_PREVIOUS_LOCATION = "space_dungeon.pilot_previous_location"; const string VAR_PASSENGER_IDS = "space_dungeon.passenger_ids"; const string VAR_RESET_DUNGEON = "space_dungeon.reset_dungeon"; const string VAR_EJECT_OVERRIDE = "space_dungeon.eject_override"; const string SCRIPT_VAR_VALID_TICKETS = "space_dungeon.valid_tickets"; const string SCRIPT_VAR_DUNGEON_PENDING = "space_dungeon.dungeon_pending"; const string SCRIPT_VAR_DUNGEON_ID_PENDING = "space_dungeon.dungeon_id_pending"; const string SCRIPT_VAR_DUNGEON_VALIDATED = "space_dungeon.dungeon_validated"; const string SCRIPT_VAR_DUNGEON_POSITION = "space_dungeon.dungeon_position"; const string PLAYER_ID = "playerId"; // SIDs const string_id SID_UNABLE_TO_FIND_DUNGEON = new string_id("dungeon/space_dungeon", "unable_to_find_dungeon"); const string_id SID_ILLEGAL_TICKET = new string_id("dungeon/space_dungeon", "illegal_ticket"); const string_id SID_VALIDATING_TICKET = new string_id("dungeon/space_dungeon", "validating_ticket"); const string_id SID_REQUEST_TRAVEL_OUTSTANDING = new string_id("dungeon/space_dungeon", "request_travel_outstanding"); const string_id SID_NO_TICKET = new string_id("dungeon/space_dungeon", "no_ticket"); const string_id SID_NOT_AUTHORIZED = new string_id("dungeon/space_dungeon", "not_authorized"); const string_id SID_NO_ROOM_REMAINING = new string_id("dungeon/space_dungeon", "no_room_remaining"); const string_id SID_SESSION_TIME_ENDED = new string_id("dungeon/space_dungeon", "session_time_expired"); const string_id SID_PILOT_LANDING_AT_DUNGEON = new string_id("dungeon/space_dungeon", "pilot_landing_at_dungeon"); const string_id SID_YOUR_PILOT_EJECTED = new string_id("dungeon/space_dungeon", "your_pilot_ejected"); const string_id SID_YOU_LEFT_A_PASSENGER_BEHIND = new string_id("dungeon/space_dungeon", "you_left_a_passenger_behind"); const string_id SID_PASSENGER_HAS_EJECTED = new string_id("dungeon/space_dungeon", "passenger_has_ejected"); const string_id SID_COPASSENGER_HAS_EJECTED = new string_id("dungeon/space_dungeon", "copassenger_has_ejected"); const string_id SID_FIND_ESCAPE_POD = new string_id("dungeon/space_dungeon", "find_escape_pod"); const string_id SID_YOU_DID_NOT_PILOT = new string_id("dungeon/space_dungeon", "you_did_not_pilot"); const string_id SID_CATCH_A_RIDE_WITH_PILOT = new string_id("dungeon/space_dungeon", "catch_a_ride_with_pilot"); const string_id SID_PILOT_HAS_LEFT_YOU = new string_id("dungeon/space_dungeon", "pilot_has_left_you"); const string_id SID_PASSENGER_NO_LONGER_WITH_YOU = new string_id("dungeon/space_dungeon", "passenger_no_longer_with_you"); const string_id SID_PILOT_LAUNCHED_WITHOUT_YOU = new string_id("dungeon/space_dungeon", "pilot_launched_without_you"); const string_id SID_PASSENGER_LEFT_BEHIND = new string_id("dungeon/space_dungeon", "passenger_left_behind"); const string_id SID_PASSENGER_CANNOT_COME = new string_id("dungeon/space_dungeon", "passenger_cannot_come"); const string_id SID_DOESNT_THINK_YOUR_A_PILOT = new string_id("dungeon/space_dungeon", "doesnt_think_your_a_pilot"); const string_id SID_NOW_BOARDING_PASSENGER = new string_id("dungeon/space_dungeon", "now_boarding_passenger"); const string_id SID_YOU_ARE_NOW_BOARDING = new string_id("dungeon/space_dungeon", "you_are_now_boarding"); const string_id SID_SUI_SELECT_DESTINATION_TITLE = new string_id("dungeon/space_dungeon", "sui_select_destination_title"); const string_id SID_AUTH_TO_TRAVEL_OFFER = new string_id("dungeon/space_dungeon", "auth_to_travel_offer"); //INSTANCE CONTROLLER const string INSTANCE_ID = "currentInstanceControllerId"; const string DUNGEON_STF = "dungeon/space_dungeon"; const string_id SID_LOCKOUT_MESSAGE = new string_id(DUNGEON_STF, "lockout_remaining"); const string_id SID_LOCKOUT_TITLE = new string_id(DUNGEON_STF, "lockout_title"); const string_id SID_GROUP_BODY = new string_id(DUNGEON_STF, "group_lockout_body"); const string_id SID_SELF_BODY = new string_id(DUNGEON_STF, "self_lockout_body"); const string_id SID_NO_LOCKOUT = new string_id(DUNGEON_STF, "no_lockouts"); //Space Dungeon Lockout Timers const string LIST_DUNGEON_LOCKOUT = "space_dungeon.lockout_timer."; const boolean LOGGING = false; /***** TRIGGERS ********************************************************/ /***** MESSAGEHANDLERS *************************************************/ /***** COMMANDHANDLERS *************************************************/ /***** FUNCTIONS *******************************************************/ /*********************************************************************** * @brief registers the space dungeon and cleans up old objvars. * * @param obj_id dungeon * * @return boolean ***********************************************************************/ boolean intializeSpaceDungeon(obj_id dungeon) { LOG("space_dungeon", "space_dungeon.intializeSpaceDungeon -- " + dungeon); if (!isIdValid(dungeon)) { LOG("space_dungeon", "space_dungeon.initializeSpaceDungeon -- dungeon obj_id is invalid"); return false; } if (!hasObjVar(dungeon, VAR_DUNGEON_NAME)) { LOG("space_dungeon", "space_dungeon.initializeSpaceDungeon -- dungeon " + dungeon + " does not have a name."); return false; } if (!hasObjVar(dungeon, VAR_IS_ACTIVE) || getIntObjVar(dungeon, VAR_IS_ACTIVE) != 1) { LOG("space_dungeon", "space_dungeon.initializeSpaceDungeon -- ignoring dungeon " + dungeon + " because it is not marked as active."); return false; } if (isIdValid(dungeon) && isGameObjectTypeOf(getGameObjectType(dungeon), GOT_ship)) setOwner(dungeon, null); string name = getDungeonInstanceName(dungeon); string buildout_area = locations.getBuildoutAreaName(dungeon); int buildout_row = locations.getBuildoutAreaRow(dungeon); setObjVar(dungeon, VAR_BUILDOUT_AREA, buildout_area); setObjVar(dungeon, VAR_BUILDOUT_ROW, buildout_row); messageTo(dungeon, "dungeonCleanup", null, 0, false); if (hasObjVar(dungeon, space_dungeon.VAR_PARTICIPANT_IDS)) removeObjVar(dungeon, space_dungeon.VAR_PARTICIPANT_IDS); if (hasObjVar(dungeon, space_dungeon.VAR_DUNGEON_START_TIME)) removeObjVar(dungeon, space_dungeon.VAR_DUNGEON_START_TIME); if (hasObjVar(dungeon, space_dungeon.VAR_DUNGEON_END_TIME)) removeObjVar(dungeon, space_dungeon.VAR_DUNGEON_END_TIME); // Reset the dungeon session id. int session_id = getDungeonSessionId(dungeon); if (session_id != -1) { // releaseClusterWideDataLock("dungeon", session_id); setObjVar(dungeon, VAR_SESSION_ID, -1); } if (hasObjVar(dungeon, space_dungeon.VAR_QUEST_TYPE)) removeObjVar(dungeon, space_dungeon.VAR_QUEST_TYPE); if (hasObjVar(dungeon, "space_dungeon.lock_key")) removeObjVar(dungeon, "space_dungeon.lock_key"); // Get the latest data and update it. getClusterWideData("dungeon", name, true, dungeon); return true; } /*********************************************************************** * @brief returns whether or not a structure is a space dungeon. * * @param obj_id structure * * @return return boolean ***********************************************************************/ boolean isSpaceDungeon(obj_id structure) { if (!isIdValid(structure)) { LOG("space_dungeon", "space_dungeon.isSpaceDungeon -- structure is invalid."); return false; } if (hasScript(structure, DUNGEON_CONTROLLER)) return true; else return false; } /*********************************************************************** * @brief Overload for getDungeonMaxPlayers * * @param obj_id dungeon * * @return int -1 on failure ***********************************************************************/ int getDungeonMaxPlayers(obj_id dungeon) { if (!isIdValid(dungeon)) { LOG("space_dungeon", "space_dungeon.getDungeonMaxPlayers -- dungeon is invalid."); return -1; } return space_dungeon_data.getDungeonMaxPlayers(getDungeonName(dungeon)); } /*********************************************************************** * @brief Overload for getDungeonExitLocation * * @param obj_id dungeon * * @return location null on failure ***********************************************************************/ location getDungeonExitLocation(obj_id dungeon) { if (!isIdValid(dungeon)) { LOG("space_dungeon", "space_dungeon.getDungeonExitLocation -- dungeon is invalid."); return null; } return space_dungeon_data.getDungeonExitLocation(getDungeonName(dungeon)); } /*********************************************************************** * @brief Returns the dungeon name * * @param obj_id dungeon * * @return string null on failure ***********************************************************************/ string getDungeonName(obj_id dungeon) { if (!isIdValid(dungeon)) { LOG("space_dungeon", "space_dungeon.getDungeonName -- dungeon is invalid."); return null; } if (hasObjVar(dungeon, VAR_DUNGEON_NAME)) return getStringObjVar(dungeon, VAR_DUNGEON_NAME); else { LOG("space_dungeon", "space_dungeon.getDungeonName -- dungeon " + dungeon + " does not have a name."); return null; } } /*********************************************************************** * @brief Returns the dungeon name as a string_id * * @param string dungeon_name * * @return string_id null on failure ***********************************************************************/ string_id getDungeonNameStringId(string name) { if (name == null || name.length() < 1) { LOG("space_dungeon", "space_dungeon.getDungeonNameStringId -- name is null or empty."); return null; } return utils.unpackString("@dungeon/space_dungeon:" + name); } /*********************************************************************** * @brief Returns the dungeon name instance which is its dungeon * name followed by its obj_id. * * @param obj_id dungeon * * @return string null on failure ***********************************************************************/ string getDungeonInstanceName(obj_id dungeon) { if (!isIdValid(dungeon)) { LOG("space_dungeon", "space_dungeon.getDungeonInstanceName -- dungeon is invalid."); return null; } string name = getDungeonName(dungeon); if (name == null) { LOG("space_dungeon", "space_dungeon.getDungeonInstanceName -- dungeon " + dungeon + " does not have a name."); return null; } return name + "-" + dungeon; } /*********************************************************************** * @brief Overload for getDungeonPlayerScript. * * @param obj_id dungeon * * @return string null on failure or no script ***********************************************************************/ string getDungeonPlayerScript(obj_id dungeon) { if (!isIdValid(dungeon)) { LOG("space_dungeon", "space_dungeon.getDungeonPlayerScript -- dungeon is invalid."); return null; } return space_dungeon_data.getDungeonPlayerScript(getDungeonName(dungeon)); } /*********************************************************************** * @brief Gets the player initiating travel given the request_id * * @param obj_id ticket_collector * @param int request_id (gotten from a getClusterWideData) * * @return obj_id null on failure ***********************************************************************/ obj_id getDungeonTraveler(obj_id ticket_collector, int request_id) { if (!isIdValid(ticket_collector)) { LOG("space_dungeon", "space_dungeon.getDungeonTraveler -- ticket_collect is not valid"); return null; } if (request_id < 0) { LOG("space_dungeon", "space_dungeon.getDungeonTraveler -- request_id has an illegal value: " + request_id); return null; } string script_var_name = SCRIPT_VAR_TRAVELERS + request_id; if (utils.hasScriptVar(ticket_collector, script_var_name)) { obj_id player = utils.getObjIdScriptVar(ticket_collector, script_var_name); if (isIdValid(player) && player.isAuthoritative()) return player; else return null; } else return null; } /*********************************************************************** * @brief Removes the given request id from the ticket collector * script vars * * @param obj_id ticket_collector * @param int request_id (gotten from a getClusterWideData) * * @return boolean ***********************************************************************/ boolean removeDungeonTraveler(obj_id ticket_collector, int request_id) { if (!isIdValid(ticket_collector)) { LOG("space_dungeon", "space_dungeon.removeDungeonTraveler -- ticket_collect is not valid"); return false; } if (request_id < 0) { LOG("space_dungeon", "space_dungeon.removeDungeonTraveler -- request_id has an illegal value: " + request_id); return false; } string script_var_name = SCRIPT_VAR_TRAVELERS + request_id; if (utils.hasScriptVar(ticket_collector, script_var_name)) { utils.removeScriptVar(ticket_collector, script_var_name); return true; } else return false; } /*********************************************************************** * @brief Returns the session id of a player or dungeon * * @param obj_id item * * @return int -1 on fail or no id ***********************************************************************/ int getDungeonSessionId(obj_id item) { if (!isIdValid(item)) { LOG("space_dungeon", "space_dungeon.getDungeonSessionId -- item is not valid"); return -1; } if (utils.hasObjVar(item, VAR_SESSION_ID)) return utils.getIntObjVar(item, VAR_SESSION_ID); else return -1; } /*********************************************************************** * @brief Returns the dungeon id a player is currently adventuring in * * @param obj_id item * * @return int -1 on fail or no id ***********************************************************************/ obj_id getDungeonIdForPlayer(obj_id player) { if (hasObjVar(player, VAR_DUNGEON_ID)) return utils.getObjIdObjVar(player, VAR_DUNGEON_ID); if (hasObjVar(player, INSTANCE_ID)) return utils.getObjIdObjVar(player, INSTANCE_ID); return utils.getObjIdObjVar(player, VAR_DUNGEON_ID); } /*********************************************************************** * @brief creates a dungeon ticket and gives it to the specified player * * @param obj_id player player to whom to give the ticket * @param string start_planet planet of the transport location * @param string start_point point name of the transport location * @param string dungeon name of the dunegon to which to transport * * @return obj_id created ticket. Null on error. ***********************************************************************/ obj_id createTicket(obj_id player, string start_planet, string start_point, string dungeon) { return createTicket(player, start_planet, start_point, dungeon, TEMPLATE_TICKET); } obj_id createTicket(obj_id player, string start_planet, string start_point, string dungeon, string ticket_template) { if (!isIdValid(player)) { LOG("space_dungeon", "space_dungeon.createTicket -- player is null."); return null; } if (start_planet == null || start_planet.length() < 1) { LOG("space_dungeon", "space_dungeon.createTicket -- start_planet is null or empty."); return null; } if (start_point == null || start_point.length() < 1) { LOG("space_dungeon", "space_dungeon.createTicket -- start_point is null or empty."); return null; } if (dungeon == null || dungeon.length() < 1) { LOG("space_dungeon", "space_dungeon.createTicket -- dungeon is null or empty."); return null; } obj_id inv = getObjectInSlot(player, "inventory"); if (inv == null) { LOG("space_dungeon", "space_dungeon.createTicket -- player " + player + " inventory is null."); return null; } int free_space = getVolumeFree(inv); if (free_space < 1) { LOG("space_dungeon", "space_dungeon.createTicket -- player " + player + " inventory is full."); return null; } obj_id ticket = createObject(ticket_template, inv, ""); // Set up the data setObjVar(ticket, VAR_TICKET_PLANET, start_planet); setObjVar(ticket, VAR_TICKET_POINT, start_point); setObjVar(ticket, VAR_TICKET_DUNGEON, dungeon); attachScript(ticket, "item.travel_ticket.dungeon_ticket"); return ticket; } /*********************************************************************** * @brief Gets the dungeon name from a dungeon ticket or collector * * @param obj_id ticket * * @return string null on failure ***********************************************************************/ string getTicketDungeonName(obj_id ticket) { if (!isIdValid(ticket)) { LOG("space_dungeon", "space_dungeon.getTicketDungeonName -- ticket is not valid."); return null; } if (hasObjVar(ticket, VAR_TICKET_DUNGEON)) return getStringObjVar(ticket, VAR_TICKET_DUNGEON); else return null; } /*********************************************************************** * @brief Gets the point name from a dungeon ticket or collector * * @param obj_id ticket * * @return string null on failure ***********************************************************************/ string getTicketPointName(obj_id ticket) { if (!isIdValid(ticket)) { LOG("space_dungeon", "space_dungeon.getTicketPointName -- ticket is not valid."); return null; } if (hasObjVar(ticket, VAR_TICKET_POINT)) return getStringObjVar(ticket, VAR_TICKET_POINT); else return null; } /*********************************************************************** * @brief Gets the planet name from a dungeon ticket * * @param obj_id ticket * * @return string null on failure ***********************************************************************/ string getTicketPlanetName(obj_id ticket) { if (!isIdValid(ticket)) { LOG("space_dungeon", "space_dungeon.getTicketPlanetName -- ticket is not valid."); return null; } if (hasObjVar(ticket, VAR_TICKET_PLANET)) return getStringObjVar(ticket, VAR_TICKET_PLANET); else return null; } /*********************************************************************** * @brief Finds a ticket that coresponds to a given dungeon for a given * ticket collector. * * @param obj_id ticket_collector * @param int request_id (gotten from a getClusterWideData) * * @return obj_id[] null on failure ***********************************************************************/ obj_id[] findValidDungeonTickets(obj_id player, obj_id ticket_collector) { if (!isIdValid(player)) { LOG("space_dungeon", "space_dungeon.findDungeonTicket -- player is not valid."); return null; } if (!isIdValid(ticket_collector)) { LOG("space_dungeon", "space_dungeon.findDungeonTicket -- ticket_collector is not valid."); return null; } // Get the ticket collect information string collector_dungeon = getTicketDungeonName(ticket_collector); if (collector_dungeon == null || collector_dungeon.length() < 1) { LOG("space_dungeon", "travel_space_dungeon.OnObjectMenuSelect -- ticket collecter " + ticket_collector + " does not have a dungeon name."); return null; } string collector_point = getTicketPointName(ticket_collector); if (collector_point == null || collector_point.length() < 1) { LOG("space_dungeon", "travel_space_dungeon.OnObjectMenuSelect -- ticket collecter " + ticket_collector + " does not have a point name."); return null; } string collector_planet = getCurrentSceneName(); // Look for a ticket that the collector will accept. obj_id inv = getObjectInSlot(player, "inventory"); if (inv == null) { LOG("space_dungeon", "space_dungeon.findDungeonTicket -- player " + player + " inventory is null."); return null; } obj_id[] inv_contents = utils.getContents(inv, false); resizeable obj_id[] valid_tickets = new obj_id[0]; if (inv_contents != null) { for (int i = 0; i < inv_contents.length; i++) { if (hasObjVar(inv_contents[i], VAR_TICKET_ROOT)) { // Check for matching point name string ticket_point = getTicketPointName(inv_contents[i]); if (ticket_point != null && ticket_point.equals(collector_point)) { // Check for matching planets string ticket_planet = getTicketPlanetName(inv_contents[i]); if (ticket_planet != null && ticket_planet.equals(collector_planet)) { // Check for matching dungeons string ticket_dungeon = getTicketDungeonName(inv_contents[i]); if (ticket_dungeon != null && ticket_dungeon.equals(collector_dungeon)) { utils.addElement(valid_tickets, inv_contents[i]); } } } } } } if (valid_tickets.length > 0) return valid_tickets; else return null; } /*********************************************************************** * @brief Gets a nearby dungeon ticket collector * * @param obj_id player * @param string dungeon_name null for any dungeon collector * * @return obj_id null on failure or no collector nearby ***********************************************************************/ obj_id getDungeonTicketCollector(obj_id player, string point_name) { if (!isIdValid(player)) { LOG("space_dungeon", "space_dungeon.getDungeonTicketCollector -- player is invalid."); return null; } location loc = getLocation(player); float maxTicketCollectorDistance = isSpaceScene() ? MAXIMUM_TICKET_COLLECTOR_DISTANCE_SPACE : MAXIMUM_TICKET_COLLECTOR_DISTANCE_GROUND; obj_id[] items = getObjectsInRange(loc, maxTicketCollectorDistance); for (int i = 0; i < items.length; i++) { if (hasScript(items[i], TRAVEL_DUNGEON)) { if (point_name == null) return items[i]; else { string collector_point = getTicketPointName(items[i]); //LOG("space_dungeon", "!!!!!!!!!!!!!!!" + collector_point + " " + point_name); if ((collector_point != null) && collector_point.equals(point_name)) return items[i]; } } } return null; } /*********************************************************************** * @brief Performs the ticket selecting logic. Use this method * when you want to have the ticket selection process occur * via the conversation tree and not as a radial menu option * * @param obj_id ticket_collector * @param obj_id player * * @return boolean ***********************************************************************/ boolean selectDungeonTicket(obj_id ticket_collector, obj_id player) { LOG("space_dungeon", "space_dungeon.selectDungeonTicket collector=" + ticket_collector + ", player=" + player); // Ignore if the player already has the ticket selection sui if (utils.hasScriptVar(player, space_dungeon.SCRIPT_VAR_VALID_TICKETS)) return false; string name = space_dungeon.getTicketDungeonName(ticket_collector); if (name == null || name.length() < 1) { LOG("space_dungeon", "travel_space_dungeon.OnObjectMenuSelect -- ticket collecter " + ticket_collector + " does not have a dungeon name."); return false; } if (hasObjVar(player, space_dungeon.VAR_TICKET_USED) || hasObjVar(player, space_dungeon.VAR_TICKET_DUNGEON)) { sendSystemMessage(player, SID_REQUEST_TRAVEL_OUTSTANDING); return false; } obj_id[] valid_tickets = space_dungeon.findValidDungeonTickets(player, ticket_collector); if (valid_tickets != null) { // If the player only has one ticket, use that one. if (valid_tickets.length == 1) space_dungeon.activateDungeonTicket(player, valid_tickets[0], ticket_collector); else { // Display the selection UI string[] dsrc = new string[valid_tickets.length]; for (int i = 0; i < valid_tickets.length; i++) { string dungeon_name = space_dungeon.getTicketDungeonName(valid_tickets[i]); string dungeon_name_loc = localize(space_dungeon.getDungeonNameStringId(dungeon_name)); dsrc[i] = dungeon_name_loc; } utils.setScriptVar(player, space_dungeon.SCRIPT_VAR_VALID_TICKETS, valid_tickets); string title = utils.packStringId(SID_SUI_SELECT_DESTINATION_TITLE); sui.listbox(player, player, title, sui.OK_CANCEL, title, dsrc, "msgSelectDungeonTicket"); return true; } } else { prose_package pp = prose.getPackage(SID_NO_TICKET, space_dungeon.getDungeonNameStringId(name)); sendSystemMessageProse(player, pp); } return false; } /*********************************************************************** * @brief Uses a dungeon ticket, transporting the player and his * party to the dungeon. * * @param obj_id player * @param obj_id ticket * @param obj_id ticket_collector * * @return boolean ***********************************************************************/ boolean activateDungeonTicket(obj_id player, obj_id ticket, obj_id ticket_collector) { if (!isIdValid(player)) { LOG("space_dungeon", "space_dungeon.activateDungeonTicket -- player is null."); return false; } if (!isIdValid(ticket)) { LOG("space_dungeon", "space_dungeon.activateDungeonTicket -- ticket is invalid."); return false; } string dungeon_name = getTicketDungeonName(ticket); string point_name = getTicketPointName(ticket); string planet_name = getTicketPlanetName(ticket); if (dungeon_name == null || point_name == null || planet_name == null) { LOG("space_dungeon", "space_dungeon.activateDungeonTicket -- dungeon name on ticket " + ticket + " has one or more null travel values."); return false; } string collector_name = getTicketDungeonName(ticket_collector); string collector_point = getTicketPointName(ticket_collector); string collector_planet = getCurrentSceneName(); // Validate that the ticket will work with the given collector. if (!dungeon_name.equals(collector_name) || !point_name.equals(collector_point) || !planet_name.equals(collector_planet)) { sendSystemMessage(player, SID_ILLEGAL_TICKET); return false; } // Get the dungeon information. This is returned in travel_space_dungeon.OnClusterWideDataResponse int request_id = getClusterWideData("dungeon", dungeon_name + "*", true, ticket_collector); if (request_id < 1) { string_id fail = space_dungeon_data.getDungeonFailureString(dungeon_name); if (fail != null) sendSystemMessage(player, fail); else sendSystemMessage(player, SID_UNABLE_TO_FIND_DUNGEON); return false; } // Mark the player with the ticket that he used. setObjVar(player, VAR_TICKET_USED, ticket); // Mark the ticket collector with this request_id. string script_var_name = SCRIPT_VAR_TRAVELERS + request_id; utils.setScriptVar(ticket_collector, script_var_name, player); //attachScript (player, "theme_park.dungeon.corvette.timer"); sendSystemMessage(player, SID_VALIDATING_TICKET); return true; } /*********************************************************************** * @brief Transporting the player and his * party to the dungeon without a ticket * * @param obj_id player * @param * @param obj_id ticket_collector * * @return boolean ***********************************************************************/ boolean sendGroupToDungeonWithoutTicket(obj_id player, string dungeon_name, string point_name, string planet_name, string quest_type, obj_id ticket_collector) { if (!isIdValid(player)) { LOG("space_dungeon", "space_dungeon.activateDungeonTicket -- player is null."); return false; } if (!isDungeonLockoutTimerExpired(player, dungeon_name)) { displayDungeonLockoutTimerSUI(player, dungeon_name); return false; } string collector_name = getTicketDungeonName(ticket_collector); string collector_point = getTicketPointName(ticket_collector); string collector_planet = getCurrentSceneName(); // Validate that the ticket will work with the given collector. if (!dungeon_name.equals(collector_name) || !point_name.equals(collector_point) || !planet_name.equals(collector_planet)) { sendSystemMessage(player, SID_ILLEGAL_TICKET); return false; } // Get the dungeon information. This is returned in travel_space_dungeon.OnClusterWideDataResponse int request_id = getClusterWideData("dungeon", dungeon_name + "*", true, ticket_collector); if (request_id < 1) { string_id fail = space_dungeon_data.getDungeonFailureString(dungeon_name); if (fail != null) sendSystemMessage(player, fail); else sendSystemMessage(player, SID_UNABLE_TO_FIND_DUNGEON); return false; } // Mark the player with the data that he used. setObjVar(player, VAR_TICKET_USED, player); setObjVar(player, VAR_TICKET_PLANET, planet_name); setObjVar(player, VAR_TICKET_POINT, point_name); setObjVar(player, VAR_TICKET_DUNGEON, dungeon_name); setObjVar(player, VAR_TICKET_QUEST_TYPE, quest_type); // Mark the ticket collector with this request_id. string script_var_name = SCRIPT_VAR_TRAVELERS + request_id; utils.setScriptVar(ticket_collector, script_var_name, player); //attachScript (player, "theme_park.dungeon.corvette.timer"); sendSystemMessage(player, SID_VALIDATING_TICKET); return true; } /*********************************************************************** * @brief Transporting a player * to a dungeon without a ticket collector * assumes the player plays the role of the collector * (has script.item.travel_ticket.travel_player_space_dungeon) * * @param obj_id player * @param * @param obj_id ticket_collector * * @return boolean ***********************************************************************/ boolean sendGroupToDungeonWithoutTicketCollector(obj_id player, string dungeon_name, string quest_type) { if (!isIdValid(player)) { LOG("space_dungeon", "space_dungeon.sendGroupToDungeonWithoutTicketCollector -- player is null."); return false; } if (!hasScript(player, "item.travel_ticket.travel_player_space_dungeon") && !hasScript(player, "npe.travel_player_space_dungeon_falcon")) { LOG("space_dungeon", "space_dungeon.sendGroupToDungeonWithoutTicketCollector -- player " + player + " does not have script to act as its own ticket collector"); return false; } // Get the dungeon information. This is returned in travel_space_dungeon.OnClusterWideDataResponse int request_id = getClusterWideData("dungeon", dungeon_name + "*", true, player); if (request_id < 1) { string_id fail = space_dungeon_data.getDungeonFailureString(dungeon_name); if (fail != null) sendSystemMessage(player, fail); else sendSystemMessage(player, SID_UNABLE_TO_FIND_DUNGEON); return false; } location start_loc = space_dungeon_data.getDungeonStartLocation(dungeon_name); if (start_loc == null) { LOG("space_dungeon", "space_dungeon.sendGroupToDungeonWithoutTicketCollector -- couldn't get start location for " + dungeon_name); return false; } string point_name = getCurrentSceneName(); // Mark the player with the data that he used. setObjVar(player, VAR_TICKET_USED, player); setObjVar(player, VAR_TICKET_PLANET, start_loc.area); setObjVar(player, VAR_TICKET_POINT, point_name); setObjVar(player, VAR_TICKET_DUNGEON, dungeon_name); setObjVar(player, VAR_TICKET_QUEST_TYPE, quest_type); // Mark the player with this request_id. string script_var_name = SCRIPT_VAR_TRAVELERS + request_id; utils.setScriptVar(player, script_var_name, player); return true; } void cleanupPlayerDungeonObjvars(obj_id player) { removeObjVar(player, VAR_SESSION_ID); removeObjVar(player, VAR_DUNGEON_ID); removeObjVar(player, INSTANCE_ID); removeObjVar(player, space_dungeon.VAR_PILOT_ID); removeObjVar(player, space_dungeon.VAR_PASSENGER_IDS); removeObjVar(player, VAR_PILOT_PREVIOUS_LOCATION); cleanupPlayerTicketObjvars(player); } void cleanupPlayerTicketObjvars(obj_id player) { removeObjVar(player, VAR_TICKET_USED); removeObjVar(player, VAR_TICKET_PLANET); removeObjVar(player, VAR_TICKET_POINT); removeObjVar(player, VAR_TICKET_DUNGEON); removeObjVar(player, VAR_TICKET_QUEST_TYPE); } /*********************************************************************** * @brief Takes the player's ticket and moves him and his group to a dungeon. * * @param obj_id player * @param obj_id dungeon * @param string dungeon_name * @param float[] dungeon_pos x,y,z position of the dungeon object * * @return boolean ***********************************************************************/ boolean movePlayerGroupToDungeon(obj_id player, obj_id dungeon, string dungeon_name, location dungeon_position) { return movePlayerGroupToDungeon(player, dungeon, dungeon_name, dungeon_position, true); } boolean movePlayerGroupToDungeon(obj_id player, obj_id dungeon, string dungeon_name, location dungeon_position, boolean checkLockoutTimer) { LOG("space_dungeon", "space_dungeon.movePlayerGroupToDungeon"); if (!isIdValid(player)) { LOG("space_dungeon", "space_dungeon.movePlayerToDungeon -- player is null."); return false; } if (!isIdValid(dungeon)) { LOG("space_dungeon", "space_dungeon.movePlayerToDungeon -- dungeon is invalid."); cleanupPlayerTicketObjvars(player); return false; } if (dungeon_name == null || dungeon_name.length() < 1) { LOG("space_dungeon", "space_dungeon.movePlayerToDungeon -- dungeon_name is null or empty."); cleanupPlayerTicketObjvars(player); return false; } if (!isDungeonLockoutTimerExpired(player, dungeon_name)) { displayDungeonLockoutTimerSUI(player, dungeon_name); return false; } boolean isSpaceScene = isSpaceScene(); obj_id playerPilotedShip = isSpaceScene ? getPilotedShip(player) : null; if (isSpaceScene && null == playerPilotedShip) { LOG("space_dungeon", "space_dungeon.movePlayerToDungeon -- in space, only pilots may initiate travel to space dungeons."); cleanupPlayerTicketObjvars(player); return false; } // Get the session id for this dungeon travel. int session_id = getDungeonSessionId(player); if (session_id == -1) { LOG("space_dungeon", "space_dungeon.movePlayerToDungeon -- player " + player + " does not have a valid session id."); cleanupPlayerTicketObjvars(player); return false; } // Need to get the cell name as a string string start_cell = space_dungeon_data.getDungeonStartCellName(dungeon_name); if (start_cell == null) { LOG("space_dungeon", "space_dungeon.movePlayerToDungeon -- start_cell is null."); cleanupPlayerTicketObjvars(player); return false; } float maxTravelGroupDistance = isSpaceScene ? MAXIMUM_TRAVEL_GROUP_DISTANCE_SPACE : MAXIMUM_TRAVEL_GROUP_DISTANCE_GROUND; // Check to see if the player is part of a group. If so, give each member the opportunity of traveling to the dungeon. obj_id group = getGroupObject(player); //-- move all the ship passengers, if applicable if (isSpaceScene && null != playerPilotedShip) { Vector passengers = space_transition.getContainedPlayers(playerPilotedShip); if (null != passengers) { LOG("space_dungeon", "space_dungeon.movePlayerToDungeon [" + player + "] moving <= [" + passengers.size() + "] passengers."); setObjVar(player, VAR_PASSENGER_IDS, passengers); for (Iterator it = passengers.iterator(); it.hasNext(); ) { obj_id passenger = (obj_id)it.next(); if (!player.equals(passenger)) { //-- all passengers are forced to go to the dungeon setObjVar(passenger, VAR_PILOT_ID, player); setObjVar(passenger, VAR_SESSION_ID, session_id); prose_package ppPilotLanding = prose.getPackage(SID_PILOT_LANDING_AT_DUNGEON); prose.setTT(ppPilotLanding, player); prose.setTO(ppPilotLanding, dungeon_name); sendSystemMessageProse(passenger, ppPilotLanding); moveSinglePlayerIntoDungeon(passenger, dungeon, dungeon_name, dungeon_position); } } } } //-- offer group members a chance to go location playerLocation = getLocation(player); if (isIdValid(group) && group.isLoaded()) { obj_id[] group_members = getGroupMemberIds(group); if (group_members != null && group_members.length > 0) { for (int i = 0; i < group_members.length; i++) { if (!player.equals(group_members[i])) { // Send each member a chance to travel to the dungeon. if (group_members[i].isAuthoritative()) { //-- group member is inside the pilot's ship, they have already been forced to go to the dungeon if (isSpaceScene) { if (playerPilotedShip.equals(getTopMostContainer(group_members[i]))) continue; //-- skip passengers if (null == getPilotedShip(group_members[i])) continue; } if (!utils.hasScriptVar(group_members[i], SCRIPT_VAR_DUNGEON_PENDING)) { //-- otherwise the group member has a choice about the matter if (playerLocation.distance(getLocation(group_members[i])) <= maxTravelGroupDistance) { utils.setScriptVar(group_members[i], SCRIPT_VAR_DUNGEON_PENDING, dungeon_name); utils.setScriptVar(group_members[i], SCRIPT_VAR_DUNGEON_ID_PENDING, dungeon); setObjVar(group_members[i], VAR_SESSION_ID, session_id); // We need to keep track of the dungeon's position to prevent the case of the player warping to // 0,0,0 after the server first starts. utils.setScriptVar(group_members[i], SCRIPT_VAR_DUNGEON_POSITION, dungeon_position); string dungeon_name_local = localize(getDungeonNameStringId(dungeon_name)); prose_package ppAuthToTravel = prose.getPackage(SID_AUTH_TO_TRAVEL_OFFER); prose.setTT(ppAuthToTravel, player); prose.setTO(ppAuthToTravel, dungeon_name_local); string prompt = " \0" + packOutOfBandProsePackage(null, ppAuthToTravel); int pid = sui.msgbox(group_members[i], group_members[i], prompt, sui.YES_NO, "msgDungeonTravelConfirmed"); // The offer is only good for 30 seconds. dictionary d = new dictionary(); d.put("pid", pid); messageTo(group_members[i], "msgCloseDungeonTravel", d, 30.0f, false); } } } } } } } moveSinglePlayerIntoDungeon(player, dungeon, dungeon_name, dungeon_position); return true; } /*********************************************************************** * @brief Removes a player from a dungeon and sticks him at the exit location * * @param obj_id player * * @return boolean ***********************************************************************/ void moveSinglePlayerIntoDungeon(obj_id player, obj_id dungeon, string dungeon_name, location dungeon_position) { if (!isDungeonLockoutTimerExpired(player, dungeon_name)) { displayDungeonLockoutTimerSUI(player, dungeon_name); return; } LOG("space_dungeon", "space_dungeon.moveSinglePlayerIntoDungeon [" + player + "] -> [" + dungeon + "]."); boolean isSpaceScene = isSpaceScene(); if (isSpaceScene) { if (!hasObjVar(player, VAR_PILOT_ID)) { obj_id playerPilotedShip = isSpaceScene ? getPilotedShip(player) : null; if (null != playerPilotedShip) { location shipPreviousLocation = getLocation(playerPilotedShip); setObjVar(player, VAR_PILOT_ID, player); setObjVar(player, VAR_PILOT_SHIP_ID, playerPilotedShip); setObjVar(player, VAR_PILOT_PREVIOUS_LOCATION, shipPreviousLocation); LOG("space_dungeon", "space_dungeon.moveSinglePlayerIntoDungeon -- Pilot objvar set for self [" + player + "]."); } } } // Get the start location information location start_loc = space_dungeon_data.getDungeonStartLocationRandomized(dungeon_name); string start_cell = space_dungeon_data.getDungeonStartCellName(dungeon_name); // Now warp the player that initiated the travel. LOG("space_dungeon", "space_dungeon.movePlayerGroupToDungeon: area ->" + dungeon_position.area + " " + dungeon_position.x + "/" + dungeon_position.y + "/" + dungeon_position.z + " " + start_loc.x + "/" + start_loc.y + "/" + start_loc.z + " (" + start_cell + ")"); setObjVar(player, VAR_DUNGEON_ID, dungeon); utils.dismountRiderJetpackCheck(player); callable.storeCallables(player); dictionary dict = new dictionary(); dict.put(PLAYER_ID, player); messageTo(dungeon, "addPlayerToParticipantIdList", dict, 0, false); setInstanceControllerIdOnPlayer(player, dungeon); if (start_cell == "") { //-- warp to a position relative to the dungeon object vector post = new vector(dungeon_position.x + start_loc.x, dungeon_position.y + start_loc.y, dungeon_position.z + start_loc.z); warpPlayer(player, dungeon_position.area, post.x, post.y, post.z, obj_id.NULL_ID, 0.0f /*x*/, 0.0f /*y*/, 0.0f /*z*/, "msgDungeonTravelComplete", true); } else { //-- warp into the dungeon object building warpPlayer(player, dungeon_position.area, dungeon_position.x, dungeon_position.y, dungeon_position.z, dungeon, start_cell, start_loc.x, start_loc.y, start_loc.z, "msgDungeonTravelComplete", true); } } /************************************************************************ * Validate the dungeon lockout timers on an instance for the selected character * param obj_id dungeon The dungeon we are attempting to send the player to * param obj_id player, the player who * * return boolean *************************************************************************/ /*********************************************************************** * @brief Removes a player from a dungeon and sticks him at the exit location * * @param obj_id player * * @return boolean ***********************************************************************/ boolean ejectPlayerFromDungeon(obj_id player) { LOG("space_dungeon", "space_dungeon.ejectPlayerFromDungeon"); if (gm.isInstanceAuthorized(player)) { sendSystemMessageTestingOnly(player, "You are negating the eject call due to authrization override"); return false; } if (!preCheckEjectStatus(player, true)) { LOG("space_dungeon", "space_dungeon.ejectPlayerFromDungeon -- preCheckEjectStatus failed"); return performEmergencyEject(player); } obj_id dungeon = findValidDungeonForEject(player); if (dungeon == null) { performEmergencyEject(player); return true; } boolean wasValidatedForDungeon = deValidatePlayerForDungeon(player, dungeon); LOG("space_dungeon", "space_dungeon.ejectPlayerFromDungeon -- player [" + player + "] was validated [" + wasValidatedForDungeon + "] for this dungeon"); boolean dungeonEmpty = false; // if the player is the fake owner of this ship, set the owner to null if (isIdValid(dungeon) && isGameObjectTypeOf(getGameObjectType(dungeon), GOT_ship) && player == getOwner(dungeon)) setOwner(dungeon, null); // Check to make sure the player has a valid session number to be in this dungeon. if (wasValidatedForDungeon) { dungeonEmpty = decrementDungeonParticipantCounter(dungeon, player); if (!dungeonEmpty) handlePilotPassengerEject(player); } CustomerServiceLog("travel", getFirstName(player) + " (" + player + ") is leaving dungeon " + getDungeonName(dungeon)); location exit_loc = getDungeonExitLocation(dungeon); //Don't warp players if they are on a different server from the instnace controller //Since they are obviously not in the instance if (exists(dungeon)) { if (hasObjVar(player, VAR_DUNGEON_ID)) removeObjVar(player, VAR_DUNGEON_ID); // special case if the player has this objvar, we call a messageHandler on them to clean themselves up if (hasObjVar(player, VAR_EJECT_OVERRIDE)) { dictionary d = new dictionary(); d.put("pid", player); messageTo(player, "msgEjectedFromDungeon", d, 0.0f, true); } if (exit_loc == null) { LOG("space_dungeon", "space_dungeon.ejectPlayerFromDungeon -- dungeon " + dungeon + " has no exit location. Using default."); location playerLoc = getLocation(player); string playerScene = playerLoc.area; // Drop player in Kachirho if this is a kashyyyk dungeon if (playerScene.startsWith("kashyyyk")) { warpPlayer(player, "kashyyyk_main", -670, 18, -137, null, -670, 18, -137); } else if (playerScene.equals("mustafar")) { warpPlayer(player, "mustafar", -2526, 224, 1659, null, -2526, 224, 1659); } else warpPlayer(player, "tatooine", 3387, 0, -4333, null, 0, 0, 0); } else { LOG("space_dungeon", "space_dungeon.ejectPlayerFromDungeon -- dungeon [" + dungeon + "] warping player to " + exit_loc); if (exit_loc.area == "tutorial") sendPlayerToTutorial(player); else warpPlayer(player, exit_loc.area, exit_loc.x, exit_loc.y, exit_loc.z, null, 0, 0, 0); } } if (dungeonEmpty) { LOG("space_dungeon", "space_dungeon.ejectPlayerFromDungeon dungeon [" + dungeon + "] is empty, reinitializing"); intializeSpaceDungeon(dungeon); } return true; } /***********************************************************************/ boolean performEmergencyEject(obj_id player) { location playerLoc = getLocation(player); string playerScene = playerLoc.area; //Only work in the instance areas of Kashyyyk if (playerScene.equals("kashyyyk_main") || playerScene.equals("kashyyyk_dead_forest") || playerScene.equals("kashyyyk_dead_forest")) return false; if (playerScene.startsWith("kashyyyk")) { warpPlayer(player, "kashyyyk_main", -670, 18, -137, null, 0, 0, 0); return true; } //Only work on the corvette or on mustafar if (!playerScene.equals("dungeon1") && !playerScene.equals("mustafar")) { return false; } else if (playerScene.equals("mustafar")) { warpPlayer(player, "mustafar", -2526, 224, 1659, null, 0, 0, 0); return true; } else { warpPlayer(player, "tatooine", 3387, 0, -4333, null, 0, 0, 0); return true; } } /***********************************************************************/ boolean preCheckEjectStatus(obj_id player, boolean allowGod) { if (!isIdValid(player)) { LOG("space_dungeon", "space_dungeon.preCheckEjectStatus -- player is invalid."); return false; } if (!isPlayer(player)) { LOG("space_dungeon", "space_dungeon.preCheckEjectStatus -- " + player + " is not a player."); return false; } if (!allowGod && isGod(player)) { LOG("space_dungeon", "space_dungeon.preCheckEjectStatus -- " + player + " is a god, skipping eject."); return false; } return true; } /***********************************************************************/ boolean leaveKashyyykArena(obj_id player) { warpPlayer(player, "kashyyyk_dead_forest", -302, 38, -208, null, 0, 0, 0); return true; } /***********************************************************************/ obj_id findValidDungeonForEject(obj_id player) { obj_id dungeon = getDungeonIdForPlayer(player); if (!isIdValid(dungeon)) { obj_id anyDungeon = getFirstObjectWithScript(getLocation(player), 1000.0f, "theme_park.dungeon.space_dungeon_controller"); if (!isIdValid(anyDungeon)) return null; } return dungeon; } /***********************************************************************/ boolean deValidatePlayerForDungeon(obj_id player, obj_id dungeon) { LOG("space_dungeon", "space_dungeon.deValidatePlayerForDungeon -- player [" + player + "], dungeon [" + dungeon + "]"); removeInstanceControllerId(player); removeObjVar(player, VAR_DUNGEON_ID); removeObjVar(player, VAR_SESSION_ID); removeObjVar(player, VAR_BUILDOUT_AREA); removeObjVar(player, VAR_BUILDOUT_ROW); removeObjVar(player, space_dungeon.VAR_PILOT_ID); removeObjVar(player, space_dungeon.VAR_PASSENGER_IDS); removeObjVar(player, VAR_PILOT_PREVIOUS_LOCATION); space_dungeon.cleanupPlayerTicketObjvars(player); removePlayerScriptsForDungeon(player); boolean wasValidatedForDungeon = false; // Remove validation dictionary dict = new dictionary(); dict.put(PLAYER_ID, player); if (isIdValid(dungeon)) messageTo(dungeon, "removePlayerFromParticipantIdList", dict, 0, false); if (utils.hasScriptVar(player, space_dungeon.SCRIPT_VAR_DUNGEON_VALIDATED)) { obj_id validatedDungeonId = utils.getObjIdScriptVar(player, space_dungeon.SCRIPT_VAR_DUNGEON_VALIDATED); if (dungeon.equals(validatedDungeonId)) { wasValidatedForDungeon = true; } else { LOG("space_dungeon", "space_dungeon.deValidatePlayerForDungeon -- player [" + player + "] is flagged validated for [" + validatedDungeonId + "] but is in dungeon [" + dungeon + "]"); } utils.removeScriptVar(player, space_dungeon.SCRIPT_VAR_DUNGEON_VALIDATED); } else LOG("space_dungeon", "space_dungeon.deValidatePlayerForDungeon -- player [" + player + "] was not flagged validated"); return wasValidatedForDungeon; } /***********************************************************************/ boolean removePlayerScriptsForDungeon(obj_id player, obj_id dungeon) { return removePlayerScriptsForDungeon(player); } /***********************************************************************/ boolean removePlayerScriptsForDungeon(obj_id player) { // Remove all dungeon scripts string[] dungeonScriptList = dataTableGetStringColumn(space_dungeon_data.DUNGEON_DATATABLE, "player_script"); if (dungeonScriptList != null && dungeonScriptList.length > 0) { for (int i=0;i= 0) { LOG("space_dungeon", "space_dungeon.incrementDungeonParticipantCounter dungeon=" + dungeon + ", player=" + player + ", ALREADY ON on participant id vector=" + participantIdVector.size()); return; } participantIdVector.add(player); setObjVar(dungeon, VAR_PARTICIPANT_IDS, participantIdVector, resizeableArrayTypeobj_id); } /** ************************************************************************ Use: Sets the Start and Finish time objvars on a controller object for a private isntance Params: obj_id controllerId: The controller object for the private instance returns: Void ************************************************************************** **/ void setDungeonTimeObjVars(obj_id controllerId) { setObjVar(controllerId, VAR_DUNGEON_START_TIME, getGameTime()); int dungeonSessionMaxTime = space_dungeon_data.getMaxDungeonSesssionTime(getDungeonName(controllerId)); int sessionEnd = getGameTime() + dungeonSessionMaxTime; setObjVar(controllerId, VAR_DUNGEON_END_TIME, sessionEnd); } /***********************************************************************/ boolean isDungeonFull(obj_id dungeon) { Vector participantIdVector = getResizeableObjIdArrayObjVar(dungeon, VAR_PARTICIPANT_IDS); int participants = (null == participantIdVector) ? 0 : participantIdVector.size(); int max_participants = space_dungeon.getDungeonMaxPlayers(dungeon); return max_participants < participants; } /***********************************************************************/ void handlePilotPassengerEject(obj_id player) { //-- notify the pilot & passengers obj_id pilot = getObjIdObjVar(player, VAR_PILOT_ID); if (null != pilot) { //-- pilot is ejecting if (pilot.equals(player)) { Vector passengers = getResizeableObjIdArrayObjVar(pilot, VAR_PASSENGER_IDS); for (Iterator it = passengers.iterator(); it.hasNext();) { obj_id passenger = (obj_id)it.next(); if (!pilot.equals(passenger)) { prose_package ppPilotEjected = prose.getPackage(SID_YOUR_PILOT_EJECTED); prose.setTT(ppPilotEjected, pilot); sendSystemMessageProse(passenger, ppPilotEjected); prose_package ppPassBehind = prose.getPackage(SID_YOU_LEFT_A_PASSENGER_BEHIND); prose.setTT(ppPassBehind, passenger); sendSystemMessageProse(player, ppPassBehind); removeObjVar(passenger, VAR_PILOT_ID); } } } //-- a passenger is ejecting else { prose_package ppPassEjected = prose.getPackage(SID_PASSENGER_HAS_EJECTED); prose.setTT(ppPassEjected, player); sendSystemMessageProse(pilot, ppPassEjected); Vector passengers = getResizeableObjIdArrayObjVar(pilot, VAR_PASSENGER_IDS); for (Iterator it = passengers.iterator(); it.hasNext();) { obj_id passenger = (obj_id)it.next(); if (player.equals(passenger)) { it.remove(); continue; } if (passenger != pilot) { prose_package ppCoEject = prose.getPackage(SID_COPASSENGER_HAS_EJECTED); prose.setTT(ppCoEject, player); sendSystemMessageProse(passenger, ppCoEject); } } setObjVar(pilot, VAR_PASSENGER_IDS, passengers, resizeableArrayTypeobj_id); } dictionary d = new dictionary(); d.put("pid", player); messageTo(pilot, "msgNotifyPilotEjectFromDungeon", d, 0.0f, false); } } /***********************************************************************/ boolean handlePilotLaunch(obj_id player, obj_id dungeon) { LOG("space_dungeon", "space_dungeon.handlePilotLaunch -- player [" + player + "], dungeon [" + dungeon + "]"); //-- notify the pilot & passengers obj_id pilot = getObjIdObjVar(player, VAR_PILOT_ID); if (null == pilot) { LOG("space_dungeon", "space_dungeon.handlePilotLaunch -- player [" + player + "] does not have a VAR_PILOT_ID objvar"); sendSystemMessage(player, SID_FIND_ESCAPE_POD); return false; } if (pilot != player) { LOG("space_dungeon", "space_dungeon.handlePilotLaunch -- player [" + player + "] is not a pilot"); sendSystemMessage(player, SID_YOU_DID_NOT_PILOT); if (isValidId(pilot)) { prose_package ppRideOut = prose.getPackage(SID_CATCH_A_RIDE_WITH_PILOT); prose.setTT(ppRideOut, pilot); sendSystemMessageProse(player, ppRideOut); } else sendSystemMessage(player, SID_PILOT_HAS_LEFT_YOU); return false; } location pilotLocation = getLocation(player); resizeable obj_id[] passengersToLaunch = new obj_id[]; //-- pilot is launching Vector passengers = getResizeableObjIdArrayObjVar(pilot, VAR_PASSENGER_IDS); if (null == passengers) { LOG("space_dungeon", "space_dungeon.handlePilotLaunch -- player [" + player + "] has no potential passengers"); } else { LOG("space_dungeon", "space_dungeon.handlePilotLaunch -- player [" + player + "] has [" + passengers.size() + "] potential passengers"); for (Iterator it = passengers.iterator(); it.hasNext();) { obj_id passenger = (obj_id)it.next(); if (!isIdValid(passenger)) { sendSystemMessage(pilot, SID_PASSENGER_NO_LONGER_WITH_YOU); continue; } if (passenger.equals(pilot)) continue; location passengerLocation = getLocation(passenger); float distanceToPilot = pilotLocation.distance(passengerLocation); if (distanceToPilot > 16.0f) { sendSystemMessage(passenger, SID_PILOT_LAUNCHED_WITHOUT_YOU); removeObjVar(passenger, VAR_PILOT_ID); prose_package ppLeftBehind = prose.getPackage(SID_PASSENGER_LEFT_BEHIND); prose.setTT(ppLeftBehind, passenger); sendSystemMessageProse(pilot, ppLeftBehind); continue; } obj_id passengerDungeon = findValidDungeonForEject(passenger); if (dungeon != passengerDungeon) { LOG("space_dungeon", "space_dungeon.handlePilotLaunch -- passenger [" + passenger + "] is not in the same dungeon as pilot"); prose_package ppCannotCome = prose.getPackage(SID_PASSENGER_CANNOT_COME); prose.setTT(ppCannotCome, passenger); sendSystemMessageProse(pilot, ppCannotCome); } else { obj_id passengerPilotId = getObjIdObjVar(passenger, VAR_PILOT_ID); if (passengerPilotId != player) { LOG("space_dungeon", "space_dungeon.handlePilotLaunch -- passenger [" + passenger + "] pilot mismatch"); prose_package ppNotPilot = prose.getPackage(SID_DOESNT_THINK_YOUR_A_PILOT); prose.setTT(ppNotPilot, passenger); sendSystemMessageProse(pilot, ppNotPilot); } else { prose_package ppNowBoardingPass = prose.getPackage(SID_NOW_BOARDING_PASSENGER); prose.setTT(ppNowBoardingPass, passenger); sendSystemMessageProse(pilot, ppNowBoardingPass); prose_package ppNowBoarding = prose.getPackage(SID_YOU_ARE_NOW_BOARDING); prose.setTT(ppNowBoarding, pilot); sendSystemMessageProse(passenger, ppNowBoarding); boolean wasValidatedForDungeon = deValidatePlayerForDungeon(passenger, dungeon); LOG("space_dungeon", "space_dungeon.handlePilotLaunch -- passenger [" + passenger + "] was validated [" + wasValidatedForDungeon + "] for this dungeon"); removePlayerScriptsForDungeon(passenger, dungeon); if (wasValidatedForDungeon) decrementDungeonParticipantCounter(dungeon, player); removeObjVar(passenger, VAR_PILOT_ID); removeObjVar(passenger, VAR_SESSION_ID); passengersToLaunch = utils.addElement(passengersToLaunch, passenger); } } } } LOG("space_dungeon", "space_dungeon.handlePilotLaunch -- player [" + player + "] computed [" + passengersToLaunch.length + "] potential passengers"); location pilotPreviousLocation = getLocationObjVar(player, VAR_PILOT_PREVIOUS_LOCATION); if (null == pilotPreviousLocation) { LOG("space_dungeon", "space_dungeon.handlePilotLaunch -- player [" + player + "] pilotPreviousLocation invalid"); pilotPreviousLocation = new location(); pilotPreviousLocation.area = "space_tatooine"; pilotPreviousLocation.x = 0.0f; pilotPreviousLocation.y = 0.0f; pilotPreviousLocation.z = 0.0f; } obj_id ship = getObjIdObjVar(player, VAR_PILOT_SHIP_ID); removeObjVar(player, VAR_PASSENGER_IDS); removeObjVar(player, VAR_PILOT_ID); removeObjVar(player, VAR_PILOT_SHIP_ID); removeObjVar(player, VAR_PILOT_PREVIOUS_LOCATION); removeObjVar(player, VAR_SESSION_ID); location groundLoc = getLocation(player); space_transition.launch(player, ship, utils.toStaticObjIdArray(passengersToLaunch), pilotPreviousLocation, groundLoc); boolean dungeonEmpty = decrementDungeonParticipantCounter(dungeon, player); if (dungeonEmpty) { LOG("space_dungeon", "space_dungeon.handlePilotLaunch dungeon [" + dungeon + "] is empty, reinitializing"); intializeSpaceDungeon(dungeon); } deValidatePlayerForDungeon(player, dungeon); return true; // dictionary d = new dictionary(); // d.put("pid", player); // messageTo(pilot, "msgNotifyPilotEjectFromDungeon", d, 0.0f, false); } /*********************************************************************** * @brief Removes a player from a dungeon and sticks him at the exit location * * @param obj_id player * * @return boolean ***********************************************************************/ boolean launchPlayerFromDungeon(obj_id player) { LOG("space_dungeon", "space_dungeon.launchPlayerFromDungeon"); if (!preCheckEjectStatus(player, true)) { LOG("space_dungeon", "space_dungeon.launchPlayerFromDungeon -- preCheckEjectStatus failed"); return false; } obj_id dungeon = findValidDungeonForEject(player); if (null == dungeon) { LOG("space_dungeon", "space_dungeon.launchPlayerFromDungeon -- dungeon is null"); return false; } boolean dungeonEmpty = false; if (!handlePilotLaunch(player, dungeon)) utils.setScriptVar(player, space_dungeon.SCRIPT_VAR_DUNGEON_VALIDATED, dungeon); return false; } /*********************************************************************** * @brief Ends the dungeon session, ejecting all players. * * @param obj_id dungeon * * @return boolean ***********************************************************************/ boolean endDungeonSession(obj_id dungeon) { if (!isIdValid(dungeon)) { LOG("space_dungeon", "space_dungeon.endDungeonSession -- dungeon is invalid"); return false; } obj_id[] players = getParticipantIds(dungeon); if (players != null && players.length > 0) { for (int i = 0; i < players.length; i++) { if (exists(players[i])) { sendSystemMessage(players[i], SID_SESSION_TIME_ENDED); ejectPlayerFromDungeon(players[i]); } } } intializeSpaceDungeon(dungeon); return true; } /*********************************************************************** * @brief Verify that the player is allowed to be in this dungeon. Typically called when a player re-logs into a dungeon * Also called to clean up objvars and validate dungeon sessions for players that have left the dungeon * @param obj_id dungeon * * @return boolean ***********************************************************************/ boolean verifyPlayerSession(obj_id dungeon, obj_id player) { return verifyPlayerSession(player); } boolean verifyPlayerSession(obj_id player) { location playerLoc = getLocation(trial.getTop(player)); obj_id top = getTopMostContainer(player); string template = getTemplateName(top); boolean isCorvette = false; if(template.indexOf("dungeon_corellian_corvette") > -1 ) isCorvette = true; string buildout_table = "datatables/buildout/areas_"+playerLoc.area+".iff"; float locX = playerLoc.x; float locZ = playerLoc.z; obj_id dungeon = findValidDungeonForEject(player); //Player is in an area without a defined buildout table and not the corvette if (!dataTableOpen(buildout_table) && !isCorvette) { deValidatePlayerForDungeon(player, dungeon); return false; } int rows = dataTableGetNumRows(buildout_table); string area_name = locations.getBuildoutAreaName(playerLoc); string player_saved_area = getStringObjVar(player, VAR_BUILDOUT_AREA); // Player is not in a buildout region and not in the corvette. if (area_name == null && !isCorvette) { deValidatePlayerForDungeon(player, dungeon); return false; } int dungeon_row = dataTableSearchColumnForString(area_name, "dungeon_area", space_dungeon_data.DUNGEON_DATATABLE); //Player is not in an instance or is in the corvette instance. if (dungeon_row == -1 && !isCorvette) { deValidatePlayerForDungeon(player, dungeon); return false; } //Player is in an instance but does not have a saved area. if ((player_saved_area == null || player_saved_area == "") && dungeon_row > -1 && !isCorvette) { ejectPlayerFromDungeon(player); return false; } string dungeon_area = dataTableGetString(space_dungeon_data.DUNGEON_DATATABLE, dungeon_row, "dungeon_area"); //Player saved area does not match the buildout he is in or his saved area does not match the dungeon saved area. //BTW, area name and dungeon_area should never be different, but why not check anyhow. if ((player_saved_area != null && player_saved_area != "") &&(player_saved_area != area_name) && (player_saved_area != dungeon_area) && !isCorvette) { ejectPlayerFromDungeon(player); return false; } //Now that we know you are in the right buildout name, lets check your buildoutrow //If they dont' match, then you left your area and went to a neighboring instance. if (!isCorvette) { int playerBuildoutRow = getIntObjVar(player, VAR_BUILDOUT_ROW); int locationRow = locations.getBuildoutAreaRow(player); //Go away Mack, this ain't your part of town if (playerBuildoutRow != locationRow) { ejectPlayerFromDungeon(player); return false; } } obj_id dungeonController = getDungeonIdForPlayer(player); if (!isIdValid(dungeonController) || !exists(dungeonController) || !hasScript(dungeonController, "theme_park.dungeon.space_dungeon_controller")) { ejectPlayerFromDungeon(player); return false; } int dungeon_session_id = space_dungeon.getDungeonSessionId(dungeonController); int player_session_id = space_dungeon.getDungeonSessionId(player); if (dungeon_session_id == -1 || dungeon_session_id != player_session_id) { ejectPlayerFromDungeon(player); return false; } utils.setScriptVar(player, space_dungeon.SCRIPT_VAR_DUNGEON_VALIDATED, dungeonController); return true; } boolean isInSpaceDungeon(obj_id subject) { string area_name = locations.getBuildoutAreaName(getLocation(subject)); int dungeon_row = dataTableSearchColumnForString(area_name, "dungeon_area", space_dungeon_data.DUNGEON_DATATABLE); return dungeon_row > -1; } /***********************************************************************/ void registerObjectWithDungeon(obj_id dungeon, obj_id registeringObject) { Vector registered = utils.getResizeableObjIdArrayScriptVar(dungeon, VAR_REGISTERED_OBJECTS); if (null == registered) { registered = new Vector(); } registered.add(registeringObject); utils.setScriptVar(dungeon, VAR_REGISTERED_OBJECTS, registered); } /***********************************************************************/ obj_id[] getRegisteredObjects(obj_id dungeon) { Vector registered = utils.getResizeableObjIdArrayScriptVar(dungeon, VAR_REGISTERED_OBJECTS); if (null == registered) return null; return utils.toStaticObjIdArray(registered); } /***********************************************************************/ obj_id[] getParticipantIds(obj_id dungeon) { resizeable obj_id[] participantId = getResizeableObjIdArrayObjVar(dungeon, VAR_PARTICIPANT_IDS); if (null == participantId || participantId.length == 0) return null; obj_id[] returnList = participantId; return returnList; } /***********************************************************************/ void playMusicInInstance(obj_id dungeon, string sound) { obj_id[] players = getParticipantIds(dungeon); if (players == null || players.length == 0) return; for (int r=0;r 10) { if (sessionTimeRemaining > 60) { if (sessionTimeRemaining > 300) { if (sessionTimeRemaining > 600) { if (sessionTimeRemaining > 900) { if (sessionTimeRemaining > 1800) { if (sessionTimeRemaining > 3600) { return ((sessionEnd - 3600) - currentTime); } return ((sessionEnd - 1800) - currentTime); } return ((sessionEnd - 900) - currentTime); } return ((sessionEnd - 600) - currentTime); } return ((sessionEnd - 300) - currentTime); } return ((sessionEnd - 60) - currentTime); } return ((sessionEnd - 10) - currentTime); } return sessionEnd - currentTime; } //--------------Handlers for instance dungeon respawn----------------- void setInstanceControllerIdOnPlayer(obj_id player, obj_id controllerObject) { setObjVar(player, INSTANCE_ID, controllerObject); } void removeInstanceControllerId(obj_id player) { if (hasObjVar(player, INSTANCE_ID)) removeObjVar(player, INSTANCE_ID); } obj_id getInstanceControllerId(obj_id player) { if (hasObjVar(player, INSTANCE_ID)) return getObjIdObjVar(player, INSTANCE_ID); else return obj_id.NULL_ID; } boolean validateInstanceControllerId(obj_id player) { //If you don't have the ObjVar then you are not in an instance... hopefully if (!hasObjVar(player, INSTANCE_ID)) { doLogging("validateInstanceControllerId", "Player did not have the instance objvar, and thus is not in an instance"); return false; } obj_id controllerObject = getObjIdObjVar(player, INSTANCE_ID); doLogging("validateInstanceControllerId", "controllerObject = "+controllerObject); //If you are not loaded, then I am on a different server. doLogging("validateInstanceControllerId", "exists precheck: "+exists(controllerObject)); if (!exists(controllerObject) || controllerObject == obj_id.NULL_ID) { doLogging("validateInstanceControllerId", "controller object does not exist on this server or null. Removing objvar"); removeObjVar(player, INSTANCE_ID); return false; } return true; } boolean isCloningInstance(obj_id player) { if (!validateInstanceControllerId(player)) return false; string dataTable = cloninglib.DATATABLE_CLONE_SPAWN; obj_id controllerId = getInstanceControllerId(player); string template = getTemplateName(controllerId); if (dataTableSearchColumnForString(template, 0, dataTable) > -1) return true; else return false; } boolean isInValidInstance(obj_id player) { return validateInstanceControllerId(player); } void handleInstanceClone(obj_id player) { string dataTable = cloninglib.DATATABLE_CLONE_SPAWN; if (!hasObjVar(player, INSTANCE_ID)) { debugConsoleMsg(player, "Instance Cloning.handleInstanceClone -- Player is calling for an instance clone but does not have a valid controller objVar"); sendSystemMessageTestingOnly(player, "You died without knowning your controller. Did you enter the instance properly?"); location currentLoc = getLocation(player); warpPlayer(player, currentLoc.area, currentLoc.x, currentLoc.y, currentLoc.z, null, currentLoc.x, currentLoc.y, currentLoc.z, "handleInstanceRessurect", true); } obj_id controllerId = getInstanceControllerId(player); string template = getTemplateName(controllerId); location controllerLoc = getLocation(controllerId); if (dataTableSearchColumnForString(template, 0, dataTable) > -1) { float locX = dataTableGetFloat(dataTable, template, "X"); float locY = dataTableGetFloat(dataTable, template, "Y"); float locZ = dataTableGetFloat(dataTable, template, "Z"); string cell = dataTableGetString(dataTable, template, "CELL"); if (cell.equals("") || cell == null) { locX += controllerLoc.x; locY += controllerLoc.y; locZ += controllerLoc.z; warpPlayer(player, controllerLoc.area, locX, locY, locZ, null, locX, locY, locZ, "handleInstanceRessurect", true); } else { warpPlayer(player, controllerLoc.area, locX, locY, locZ, controllerId, cell, locX, locY, locZ, "handleInstanceRessurect", true); } } else { doLogging("handleInstanceClone", "Controller was not in the spawn table. Respawning at location."); debugConsoleMsg(player, "Instance CloninghandleInstanceClone -- Players("+player+") controller object("+template+"/"+controllerId+") was not in the cloning table"); string[] cellNames = getCellNames(controllerId); if (cellNames == null || cellNames.length < 1) { doLogging("handleInstanceClone", "Controller object has no cell, spawning at object"); warpPlayer(player, controllerLoc.area, controllerLoc.x, controllerLoc.y, controllerLoc.z, null, 0, 0, 0, "handleInstanceRessurect", true); } else { doLogging("handleInstanceClone", "Spawning in 1st cell"); warpPlayer(player, controllerLoc.area, 0, 0, 0, controllerId, cellNames[0], 0, 0, 0, "handleInstanceRessurect", true); } } } void doLogging(string section, string message) { if (LOGGING) LOG("logging/library.space_dungeon/"+section, message); } //-------------------------------------------------------------------- int pollZoneOccupantsForInstancePopulation(obj_id controller) { int numberOfPlayers = 0; obj_id[] players = getPlayerCreaturesInRange(controller, 32000); if (players != null && players.length > 0) { for (int i=0;i 0) { for (int i=0;i 0) { obj_id[] convertedList = playersInInstance; return convertedList; } else { return null; } } //---------End population counters for public instances----------------------- /************************************************************************/ /************************************************************************ * * Sets a lockout time for a particular dungeon, using either a user specified time * or a value derived from the space dungeon datatable. * * ***********************************************************************/ void setDungeonLockoutTimer(obj_id player, obj_id dungeon, int lockoutTime) { string dungeonName = getDungeonName(dungeon); setDungeonLockoutTimer(player, dungeonName, lockoutTime); } void setDungeonLockoutTimer(obj_id player, string dungeonName, int lockoutTime) { lockoutTime = getGameTime() + lockoutTime; if (isIdValid(player) && exists(player)) { setObjVar(player, LIST_DUNGEON_LOCKOUT+dungeonName, lockoutTime); } } void setDungeonLockoutTimer(obj_id player, obj_id dungeon) { string dungeonName = getDungeonName(dungeon); int lockoutTime = dataTableGetInt(space_dungeon_data.DUNGEON_DATATABLE, dungeonName, "lockoutTimer"); setDungeonLockoutTimer(player, dungeon, lockoutTime); } void setDungeonLockoutTimer(obj_id[] players, obj_id dungeon) { if (players == null || players.length == 0 || !isIdValid(dungeon)) return; for (int i=0;i= endLockoutTime) return true; else return false; } boolean isDungeonLockoutTimerExpired(obj_id player, obj_id dungeon) { if (!isIdValid(player) || !isIdValid(dungeon)) return false; obj_id groupId = getGroupObject(player); string dungeonName = getDungeonName(dungeon); if (!isIdValid(groupId)) { return validateInstanceTimerForPlayer(player, dungeonName); } else { obj_id[] members = getGroupMemberIds(groupId); return isDungeonLockoutTimerExpired(members, dungeonName); } } boolean isDungeonLockoutTimerExpired(obj_id player, string dungeonName) { if (!isIdValid(player)) return false; obj_id groupId = getGroupObject(player); if (!isIdValid(groupId)) { return validateInstanceTimerForPlayer(player, dungeonName); } else { obj_id[] members = getGroupMemberIds(groupId); return isDungeonLockoutTimerExpired(members, dungeonName); } } boolean isDungeonLockoutTimerExpired(obj_id players[], string dungeonName) { if (players == null || players.length == 0) return false; for (int i = 0;i