#include <mudlib.h> #include <ships.h> #include <perms.h> #include <daemons.h> #include <terrain.h> #include <darkwind.h> inherit NEW_VEHICLE; #define DW_PORT WHARF + "port" #define DW_HIDDEN_PORT WHARF + "hidden_port" #define ENV(xx) environment(xx) #define TO this_object() //Saved variables string last_port; // The filename of the last port visited string flag_color; // The current color being flown string captain_long; // Long Desc of Captain's Cabin. status mtDocked; // Is this ship currently docked? status mtStranded; // Was the ship stranded at sea? string msShipName; // Name of the ship string msOwnerName; // Name of the ship's owner string msFleetName; // Name of the ship's fleet string * masPassengers; // Who can board the ship string * masCaptains; // Who can captain the ship string msLastPort; // Last port docked at //string msFlagColor; // Current color of flag string msCaptainLong; // Long description of captain's cabin mapping mmShipAutoLoads; // Mapping takes the form (["key":"path";"roomname";type;arg,]) //Static Variables static object moBridge; // The Bridge static string msSaveFile; // Ship's save file static string msFlagColor; // The current color being flown static string msLong; // Long desc without flag static status mtSails; // Are the sails up? static mapping mmExtraLooks; // Extra looks in the ship object static mapping mmRoomLooks; // Visisble Rooms from outside static object * maoContainers; // Containers on board the ship //static mapping mmWeapons; // Weapons on board the ship //Holdover vars string type; string name; //Functions status is_player(string sPlayer); status is_passenger(string sPlayer); status is_captain(string sPlayer); status is_owner(string sPlayer); void save_ship() { save_object(msSaveFile); } void setup(string sName, string sOwnerName, string sFile, string sLastPort) { msShipName = sName; msOwnerName = sOwnerName; msSaveFile = sFile; msLastPort = sLastPort; mtDocked = 1; save_ship(); } void reset(int arg) { if(!is_clone(this_object())) return; ::reset(arg); if (arg) return; set_necessary_terrains(TER_RIVER | TER_SEA); set_alt_name("ship"); msFlagColor = "green"; masPassengers = ({ }); masCaptains = ({ }); mmExtraLooks = ([]); mmRoomLooks = ([]); mmShipAutoLoads = ([ ]); maoContainers = ({ }); //Defaults in case nothing else is set set_name("malfuctioning ship"); set_short("a malfunctioning ship"); set_long("This ship isn't working right - stay away from it.\n"); set_arrival_msg("The ship arrives."); set_depart_msg("The ship sails"); } void init() { ::init(); add_action("enter_func","board"); } string short() { return (query_short() + (mtDocked == 1 ? " (Docked)" : "")); } //Virtual Functions - Overloaded in "children" string query_ship_class() { return ""; } string query_ship_arrive() { return "arrives.";} string query_ship_depart() { return "sails";} //End virtual functions void restore_autoloads() { int i; string * asKeys; object oObj; object oRoom; if(!mmShipAutoLoads) return; asKeys = m_indices(mmShipAutoLoads); if(!asKeys) return; if(sizeof(asKeys) < 1) return; for(i=0; i<sizeof(asKeys); i++) { oObj = clone_object(mmShipAutoLoads[asKeys[i],0]); oRoom = find_room(mmShipAutoLoads[asKeys[i],1]); if(!oRoom) continue; move_object(oObj,oRoom); oRoom->fill_slot(mmShipAutoLoads[asKeys[i],2]); oObj->init_arg(mmShipAutoLoads[asKeys[i],3]); if(oObj->id("ship_container_object")) maoContainers += ({oObj}); } } void manual_load_autoload(string sKey) { object oObj; object oRoom; if(!mmShipAutoLoads) return; if(!member(mmShipAutoLoads,sKey)) return; oObj = clone_object(mmShipAutoLoads[sKey,0]); oRoom = find_room(mmShipAutoLoads[sKey,1]); if(!oRoom) return; move_object(oObj,oRoom); oRoom->fill_slot(mmShipAutoLoads[sKey,2]); oObj->init_arg(mmShipAutoLoads[sKey,3]); if(oObj->id("ship_container_object")) maoContainers += ({oObj}); } void change_ship_name(string sNewName, string sNewFile) { rm(msSaveFile + ".o"); msShipName = sNewName; msSaveFile = sNewFile; save_ship(); } void clear_fleet_name() { msFleetName = "none"; save_ship(); } void init_ship(string sFile) { msSaveFile = sFile; if (!restore_object(msSaveFile)) return; mtDocked = 1; if (mtStranded) mtDocked = 0; //Setup names even if file did not reload if(!msShipName) msShipName = "Unknown"; if(!msOwnerName || msOwnerName == "unknown") { msOwnerName = SHIP_D->query_owner(msShipName); if(!msOwnerName) msOwnerName = "unknown"; } if(!msFleetName || msFleetName == "unknown") { msFleetName = SHIP_D->query_fleet_name(msOwnerName); if(!msFleetName) msFleetName = "none"; } //Move it back to the port if (!msLastPort) msLastPort = WHARF + "port"; if(catch(move_object(this_object(), msLastPort))) { save_ship(); return; } save_ship(); //Setup descriptions and messages set_name(msShipName); if(msFleetName == "none") reset_short(capitalize(msShipName) + ", an independent " + query_ship_class()); else reset_short(capitalize(msShipName) + ", a " + query_ship_class() + " of the " + capitalize(msFleetName) + " fleet"); set_long(msLong +"The ship is flying a "+ msFlagColor + " flag.\n"); set_arrival_msg("The " + capitalize(msShipName) + " " + query_ship_arrive()); set_depart_msg("The " + capitalize(msShipName) + " " + query_ship_depart()); set_enter_messages(({"You climb onboard the " + capitalize(msShipName), "boards the " + capitalize(msShipName), "comes aboard the " + capitalize(msShipName)})); set_deboard_messages(({"You disembark the " + capitalize(msShipName), "leaves the " + capitalize(msShipName), "disembarks from the " + capitalize(msShipName)})); restore_autoloads(); //Announce the ship's arrival tell_outside("The dockworkers bring the " + capitalize(msShipName) + " \ into port.\n"); } void reset_ship() { if (!msLastPort) msLastPort = WHARF + "port"; move_object(this_object(), msLastPort); mtDocked = 1; save_ship(); } void set_main_long(string sArg) { ::set_long(sArg); msLong = sArg; } status query_docked() { return mtDocked; } void set_docked(status tDocked) { if(!tDocked) { mtDocked = 0; //More hidden port stuff - remove when HPORT is fixed if (environment(this_object()) == find_object(DW_HIDDEN_PORT)) { move_object(this_object(), DW_PORT); } tell_outside("The " + capitalize(msShipName) + " has pushed off.\n"); tell_vehicle("The ship has pushed off.\n"); save_ship(); return; } mtDocked = 1; msLastPort = "/" + object_name(ENV(TO)); tell_outside("The " + capitalize(msShipName) + " has docked.\n"); tell_vehicle("The ship has docked.\n"); //More HPORT garbage if (environment(this_object()) == find_object(DW_PORT)) { msLastPort = DW_HIDDEN_PORT; move_object(this_object(), DW_HIDDEN_PORT); } save_ship(); return; } status set_last_port(string sFile) { object oFile; oFile = find_object(sFile); if(!oFile) { sFile->do_absolutely_nothing(); oFile = find_object(sFile); if(!oFile) return 1; } msLastPort = sFile; save_ship(); return 0; } status query_sails() { return mtSails; } void set_sails(status tSails) { if(!tSails) { mtSails = 0; tell_outside("The " + capitalize(msShipName) + " has lowered its sails.\n"); tell_vehicle("The sails have been lowered.\n"); return; } mtSails = 1; tell_outside("The " + capitalize(msShipName) + " has raised its sails.\n"); tell_vehicle("The sails have been raised.\n"); return; } void vehicle_move_success(string sDirection, int tSilently) { if(!tSilently) { write("The ship sails " + sDirection + " at your command.\n"); say("The ship sails " + sDirection + " at " + this_player()->query_cap_name() + "'s command.\n"); } tell_vehicle("The ship rocks as it sails across the ocean.\n"); ::vehicle_move_success(sDirection,tSilently); } status enter_func(string str) { if(!id(str)) return(0); if (!mtDocked) { write("\n" + capitalize(msShipName) + " \ is currently not docked. You may not board at this time.\n"); return 1; } if(!is_passenger(this_player()->query_real_name())) { write("You are not a registered passenger of this ship.\n"); return 1; } return (::enter_func(str)); } status is_player(string sPlayer) { string sTemp1; string sTemp2; if(sscanf(sPlayer,"%s %s",sTemp1,sTemp2) == 2) { write("Player names can only be one word.\n"); return 0; } if(find_object(PLAYER_INFO_D)) destruct(find_object(PLAYER_INFO_D)); switch (PLAYER_INFO_D->restore_player(sPlayer)) { case -1: write("Player does not exist.\n"); return 0; case 0: write("Error retrieving player information information on " + capitalize(sPlayer) + ".\n"); write("Please tell an Implementor about this.\n"); return 0; default: return 1; } } status add_passenger(string sPlayer) { if(member(masPassengers,sPlayer) != -1) { write("That person is already on your boarding list.\n"); return 1; } if(is_captain(sPlayer)) { write("That person is a captain and already has boarding privilges.\n"); return 1; } if(!is_player(sPlayer)) { write("That is not the name of any player.\n"); return 1; } masPassengers += ({sPlayer}); write("You have added " + capitalize(sPlayer) + " to your passenger list.\n"); if(find_player(sPlayer)) tell_object(find_player(sPlayer),"\ You have been added to the passenger list of the ship " + capitalize(msShipName) + ".\n"); save_ship(); return 1; } status remove_passenger(string sPlayer) { if(sPlayer == msOwnerName) { write("You are already the owner of the ship!\n"); return 1; } if(member(masPassengers,sPlayer) == -1) { write("That person is not on your passenger list.\n"); return 1; } write("You have removed " + capitalize(sPlayer) + " \ from your passenger list.\n"); if(find_player(sPlayer)) tell_object(find_player(sPlayer),"\ You have been removed as a passenger of the ship " + capitalize(msShipName) + ".\n"); masPassengers -= ({sPlayer}); save_ship(); return 1; } void print_passengers() { int iCounter; for(iCounter = 0; iCounter < sizeof(masPassengers); iCounter++) write(capitalize(masPassengers[iCounter]) + "\n"); } status is_passenger(string sPlayer) { if(find_player(sPlayer)) if(IS_APPLICANT(find_player(sPlayer))) return 1; if(member(masPassengers,sPlayer) != -1) return 1; if(is_captain(sPlayer)) return 1; return 0; } string * query_passengers() { return masPassengers; } status add_captain(string sPlayer) { if(sPlayer == msOwnerName) { write("You are already the owner of the ship.\n"); return 1; } if(member(masCaptains,sPlayer) != -1) { write("That person can already captain this ship!\n"); return 1; } if(member(masPassengers,sPlayer) == -1) { write("\ That person is not a passenger! Only passengers can be promoted\n\ to captain.\n"); return 1; } write(capitalize(sPlayer) + " has been promoted to captain.\n"); if(find_player(sPlayer)) tell_object(find_player(sPlayer),"\ You have been promoted to captain of the ship " + capitalize(msShipName) + ".\n"); masCaptains += ({sPlayer}); masPassengers -= ({sPlayer}); save_ship(); return 1; } status remove_captain(string sPlayer) { if(member(masCaptains,sPlayer) == -1) { write("That person is not a captain of this ship!\n"); return 1; } write("You have demoted " + capitalize(sPlayer) + " \ to a passenger.\n"); if(find_player(sPlayer)) tell_object(find_player(sPlayer),"\ You have been demoted to passenger of the ship " + capitalize(msShipName) + ".\n"); masCaptains -= ({sPlayer}); masPassengers += ({sPlayer}); save_ship(); return 1; } void print_captains() { int iCounter; for(iCounter = 0; iCounter < sizeof(masCaptains); iCounter++) write(capitalize(masCaptains[iCounter]) + "\n"); } status is_captain(string sPlayer) { if(find_player(sPlayer)) if(IS_ARCHITECT(find_player(sPlayer))) return 1; if(member(masCaptains,sPlayer) != -1) return 1; if(sPlayer == msOwnerName) return 1; return 0; } string * query_captains() { return masCaptains; } status is_owner(string sPlayer) { if(find_player(sPlayer)) if(IS_ARCHITECT(find_player(sPlayer))) return 1; if(sPlayer == msOwnerName) return 1; return 0; } void set_bridge(object ob) { moBridge = ob; return; } object query_bridge() { return moBridge; } status query_stranded() { return mtStranded; } void set_stranded(status tStranded) { mtStranded == tStranded; save_ship(); return; } void set_capt_long(string sDesc) { msCaptainLong = sDesc; save_ship(); return; } string query_capt_long() { return msCaptainLong; } object is_onboard(string sName) { object oTarget; oTarget = find_player(sName); if(!oTarget) oTarget = find_living(sName); if(!oTarget) oTarget = find_object(sName); if(!oTarget) return 0; if(member(all_environment(oTarget),this_object()) == -1) return 0; return oTarget; } object * captains_onboard() { object * asCaptains; int iCounter; object oTemp; asCaptains = ({}); for(iCounter = 0; iCounter < sizeof(masCaptains); iCounter++) { oTemp = is_onboard(masCaptains[iCounter]); if(oTemp) asCaptains += ({oTemp}); } return asCaptains; } //Needs to be revised /* void strike_color(string str) { if (member_array(str, COLORS) != -1) flag_color = str; set_long(SHIP_TYPES[type, LONG]+"The ship is flying a "+ flag_color + " flag.\n"); save_ship(); return; } string query_flag_color() { return(flag_color); } */ //Remove this when old vars are purged string query_type() { return (type); } //Added - Kanan 12/14/99 //Clean dest - moves all players to safe room and destroys all room //objects and the actual ship varargs void destroy_ship(int iSilently) { object * aoAllRooms; object * aoInventory; int iRoomCounter; int iInvCounter; if(!iSilently) tell_outside("\ The " + capitalize(msShipName) + " is battered to pieces by a tidal\n\ wave that seemed to come from nowhere.\n"); save_ship(); aoAllRooms = query_room_objects(); for(iRoomCounter = 0; iRoomCounter < sizeof(aoAllRooms); iRoomCounter++) { //Move players out of ship if(aoAllRooms[iRoomCounter]) aoInventory = all_inventory(aoAllRooms[iRoomCounter]); else aoInventory = ({ }); for(iInvCounter = 0; iInvCounter < sizeof(aoInventory); iInvCounter++) { if(interactive(aoInventory[iInvCounter])) { tell_object(aoInventory[iInvCounter],"The ship is breaking up!\n\ You are swept out into the ocean by a great wave!\n\ You wash ashore on a beach.\n"); move_object(aoInventory[iInvCounter], "/domains/darkwind/sea/beach"); } } //Destruct room object if(aoAllRooms[iRoomCounter]) destruct(aoAllRooms[iRoomCounter]); } destruct(this_object()); } //This will indicate whether the ship is being actively sailed or not //Right now it only indicates whether someone is on the bridge status query_ship_sailing() { object * aoInventory; int iCounter; if(!query_bridge()) return 0; aoInventory = all_inventory(query_bridge()); for(iCounter = 0; iCounter < sizeof(aoInventory); iCounter++ ) { if(interactive(aoInventory[iCounter])) return 1; } return 0; } string query_ship_name() { return msName; } string query_fleet_name() { return (msFleetName ? msFleetName : "unknown"); } string query_owner_name() { return msOwnerName; } void add_room_look(string sLookName, string sRoomName) { if(member(mmRoomLooks,sLookName)) { mmRoomLooks[sLookName] = sRoomName; return; } mmRoomLooks += ([sLookName:sRoomName]); } void add_extra_look(string sLookName, string sLookText) { if(member(mmExtraLooks,sLookName)) { mmExtraLooks[sLookName] = sLookText; return; } mmExtraLooks += ([sLookName: sLookText]); } //Code to allow extra looks in the room outside the ship status id(string sArg) { string sRoomName; string sShipName; if(!sArg) return 0; //Check for proper format if(sscanf(sArg,"%s of %s",sRoomName,sShipName) != 2) return ::id(sArg); sRoomName = lower_case(sRoomName); sShipName = lower_case(sShipName); //Check for the proper ship if(sShipName != msShipName) return 0; //Check for "extra look" if(member(mmExtraLooks,sRoomName)) return 1; //Check for visible room name if(member(mmRoomLooks,sRoomName)) return 1; return 0; } //Can't stricttype this because it inherits a void long() and it won't let me // override it unless I do this. long(sArg) { string sShipName; string sLookName; //Check for proper format if(sscanf(sArg,"%s of %s",sLookName,sShipName) != 2) { ::long(); return; } sLookName = lower_case(sLookName); sShipName = lower_case(sShipName); //Check for the proper ship if(sShipName != msShipName) { ::long(); return; } if(member(mmRoomLooks,sLookName)) { if(!find_room(mmRoomLooks[sLookName])) { write("That place seems to be missing!\n"); return; } find_room(mmRoomLooks[sLookName])->long(0); show_object_list(visible_inventory(find_room(mmRoomLooks[sLookName]), this_player()),this_player()); return; } if(!member(mmExtraLooks,sLookName)) return ::long(); write(mmExtraLooks[sLookName]); } //Ship Autoload code status add_ship_autoload(string sKey, string sPath, string sRoom, int ibType, mixed xArg) { object oTest; if(member(mmShipAutoLoads,sKey)) return 0; if(!mmShipAutoLoads) mmShipAutoLoads = ([ ]); if(catch(oTest = clone_object(sPath))) return 0; destruct(oTest); if(!find_room(sRoom)) return 0; mmShipAutoLoads += ([sKey:sPath;sRoom;ibType;xArg]); save_ship(); return 1; } void remove_ship_autoload(string sKey) { if(!member(mmShipAutoLoads,sKey)) return; mmShipAutoLoads = m_delete(mmShipAutoLoads,sKey); save_ship(); } string * query_autoload_keys() { return m_indices(mmShipAutoLoads); } mapping query_autoload_map() { return mmShipAutoLoads; } //End of Ship Autoload code object * query_ship_containers() { return maoContainers; } int query_no_destruct() { return 1; }