REO-EE/_module/nss/rhs_include.nss
Jaysyn904 f82740bbbd Initial commit
Initial commit
2024-02-22 13:22:03 -05:00

1231 lines
49 KiB
Plaintext

//////////////////////////////////////////////////////
// Resident Evil Online Housing System Include File //
// Created by Zunath //
//////////////////////////////////////////////////////
#include "inc_system_const"
#include "inc_mysql_tables"
#include "inc_helper_funcs"
#include "colors_inc"
#include "rwt_include"
#include "nwnx_areas"
//////////////////////////
// SYSTEM CONFIGURATION //
//////////////////////////
// Linux has the ability to create and destroy copies of areas on the fly.
// Windows version uses simulated area instances.
// Set this to TRUE if your server is hosted on Linux
// Set this to FALSE if your server is hosted on Windows
const int RHS_USING_LINUX = TRUE;
// The amount of time to add to a player's rent payment. Number is in terms of days.
// Default: 7 (1 Week)
const int RHS_RENT_LENGTH = 7;
// The maximum number of furniture objects that a player can place in a single area
// Default: 100
const int RHS_MAX_FURNITURE = 100;
// The maximum character length a house's name can be. You shouldn't set this higher than 32.
// Default: 32
const int RHS_MAX_HOUSE_NAME_LENGTH = 32;
// The minimum character length a house's name can be. You shouldn't set this lower than 3.
// Default: 3
const int RHS_MIN_HOUSE_NAME_LENGTH = 3;
// The maximum distance in meters furniture objects will be picked up from. The higher you set this, the more
// furniture objects will display in the furniture menu.
// Default: 2.5
const float RHS_FURNITURE_DISTANCE = 2.5;
// Percentage of money received when a piece of furniture is sold.
// The player will receve this fraction of the full price when furniture is sold.
// Do not set this higher than 1.00!
// Default: 0.50 (50%)
const float RHS_FURNITURE_SELL_BACK_PERCENTAGE = 0.50;
// The amount of time a preview of a furniture object will exist. After this time,
// the furniture will be destroyed.
// Default: 6.0 (6 seconds)
const float RHS_FURNITURE_PREVIEW_LENGTH = 6.0;
// The capitialized version of the term used for houses
// Default: House
const string RHS_HOUSE_TERM_PROPER = "Room";
// The lower case version of the term used for houses
// Default: house
const string RHS_HOUSE_TERM_LOWER = "room";
// The capitalized, plural version of the term used for houses
// Default: Houses
const string RHS_HOUSE_TERM_PROPER_PLURAL = "Rooms";
// The lower case, plural version of the term used for houses
// Default: houses
const string RHS_HOUSE_TERM_LOWER_PLURAL = "rooms";
// The name of the schema used by the database for this system
// Default: rhs_housing
const string RHS_SCHEMA = "reo_housing";
///////////////////////////////
// SYSTEM CONSTANTS - MODULE //
///////////////////////////////
// Prefix of the specific area instance arrays. Followed by the area's resref
const string RHS_HOUSE_INSTANCE_PREFIX = "RHS_INSTANCE_";
///////////////////////////////
// SYSTEM CONSTANTS - HOUSES //
///////////////////////////////
// House publicity ID types
const int RHS_HOUSE_PUBLICITY_TYPE_PRIVATE = 1; // Only the owner can visit the house
const int RHS_HOUSE_PUBLICITY_TYPE_FRIENDS = 2; // Only specified friends can visit the house
const int RHS_HOUSE_PUBLICITY_TYPE_PUBLIC = 3; // Everyone can visit the house
const int RHS_HOUSE_PUBLICITY_TYPE_TRUSTEES = 4; // Only specified trustees can visit the house
// Friend access ID types
const int RHS_HOUSE_FRIEND_TYPE_FRIEND = 1; // The default setting: Friends can visit the house but can't modify furniture
const int RHS_HOUSE_FRIEND_TYPE_TRUSTEE = 2; // Trustees can modify furniture
// Name of the location variable which tracks the entry point in an instanced house.
const string RHS_HOUSE_ENTRY_WAYPOINT = "RHS_HOUSE_ENTRY_WAYPOINT";
// Name of the tag and resref of the waypoint which is used as the warp-in spot for players entering an instanced house.
const string RHS_HOUSE_WAYPOINT_RESREF = "rhs_house_wp";
// Name of the integer variable which tracks the ID number of the player who owns the area instance. For later use with furniture manipulation.
const string RHS_HOUSE_OWNER_ID_NUMBER = "RHS_HOUSE_OWNER_ID_NUMBER";
// Name of the conversation script which fires when a PC uses a "House Door" (I.E: The entry door)
const string RHS_HOUSE_ENTRY_CONVERSATION = "rhs_house_menu";
// Name of the integer variable which tracks what owner ID is CURRENTLY being used by the house instance
const string RHS_IN_USE_ID = "RHS_IN_USE_ID";
// Name of the boolean variable which tracks whether or not an area is a house interior
// Stored on the house area
const string RHS_HOUSE_MARKER = "RHS_HOUSE";
////////////////////////////////
// SYSTEM CONSTANTS - PLAYERS //
////////////////////////////////
// Name of the boolean variable which tracks whether or not a player currently has a house rented
// Whether or not that rent is paid doesn't matter - this only tracks whether there's specific data
// in the database for this player
const string RHS_PLAYER_HOUSE_RENTED = "RHS_PLAYER_HOUSE_RENTED";
// Name of the string variable which tracks a player's original position (I.E: The position they were at before entering a house instance)
const string RHS_PLAYER_ORIGINAL_POSITION = "RHS_PLAYER_ORIGINAL_POSITION";
// Tracks whether or not the system is listening for text input by the player - used for inputting the house's name
const string RHS_PAGE_TEMP_LISTENING = "RHS_PAGE_TEMP_LISTENING";
// Tracks the text input by player when naming his or her house
const string RHS_PAGE_TEMP_NEW_HOUSE_NAME = "RHS_PAGE_TEMP_NEW_HOUSE_NAME";
// House permissions settings for friends
const int RHS_FRIEND_TYPE_INVALID = 0; // Not a friend
const int RHS_FRIEND_TYPE_FRIEND = 1; // Friend level permissions
const int RHS_FRIEND_TYPE_TRUSTEE = 2; // Trustee level permissions
//////////////////////////////////
// SYSTEM CONSTANTS - FURNITURE //
//////////////////////////////////
// Tracks a particular furniture object's ID number
const string RHS_FURNITURE_ID_NUMBER = "RHS_FURNITURE_ID_NUMBER";
// Tag and resref of the tool used to manipulate furniture
const string RHS_FURNITURE_TOOL_RESREF = "rhs_furn_tool";
// Name of the string variable which tracks the location targeted using the furniture tool
// Stored on the PC that used the furniture tool
const string RHS_FURNITURE_TOOL_TARGET_LOCATION = "RHS_FURNITURE_TOOL_TARGET_LOCATION";
// Name of the dialogue script used for furniture manipulation
const string RHS_FURNITURE_MENU = "rhs_furn_menu";
// Name of the boolean variable which tracks whether or not a furniture object should be moved the next time
// a player uses his or her furniture tool
const string RHS_FURNITURE_MOVING_OBJECT = "RHS_FURNITURE_MOVING_OBJECT";
// Name of the object variable which tracks the object oPC is moving to a new location
const string RHS_FURNITURE_MOVING_OBJECT_REFERENCE = "RHS_FURNITURE_MOVING_OBJECT_REFERENCE";
//////////////////////////////////
// SYSTEM CONSTANTS - LANDLORDS //
//////////////////////////////////
// Array of integers which tracks what houses are rented out by a particular landlord NPC
const string RHS_LANDLORD_HOUSES_AVAILABLE_ARRAY = "RHS_LANDLORD_HOUSES";
////////////////
// PROTOTYPES //
////////////////
// Replaces a player's house information with this new information.
// This essentially start's a player's house from scratch by removing all information about it. Make sure you
// warn the player in advance before calling this function.
// ***NOTE: Friends list and furniture will be completely deleted. Make SURE you know what you're doing when you call this!
// oPC = The player whose house we're setting
// iHouseType = The house ID number listed in the RHS_TABLE_HOUSE_TYPES table
// iPublicity = RHS_HOUSE_PUBLICITY_TYPE_*
void RHS_SetPlayerHouse(object oPC, int iHouseType, int iPublicity = RHS_HOUSE_PUBLICITY_TYPE_PRIVATE);
// Deletes all information about oPC's house from the database.
// Be careful about calling this function - once the house is deleted, it's irreversible.
// If there are any players inside the house instance, they will all be ported back outside.
// * Removes the following:
// * House specific information (in RHS_TABLE_HOUSES)
// * Furniture (in RHS_TABLE_FURNITURE_#)
// * Friends (in RHS_TABLE_FRIENDS_#)
// oPC = The player object
// iGold = If this is set greater than zero, this amount of gold will be given to oPC. Useful for returning money from sold furniture.
void RHS_RemovePlayerHouse(object oPC, int iGold = 0);
// Marks a player's house to a specified publicity level.
// oPC = The player whose house we're changing
// iPublicity = The new publicity level
void RHS_SetHousePublicity(object oPC, int iPublicity = RHS_HOUSE_PUBLICITY_TYPE_PRIVATE);
// Changes the name of oPC's house to sNewName.
// oPC = The player object
// sNewName = The new name to set the house to. If this is left blank the name willl default to "Name's House" where Name is the name of oPC
void RHS_SetHouseName(object oPC, string sNewName = "");
// Adds a specified number of days to a player's rent. They will lose access to their house on this date until they pay the rent.
// oPC = The player whose house's rent we're extending
// iDays = The number of days we're adding on to their rent payment date
// iPCID = If set greater than 0, the function will use this PC ID instead of the one assigned for oPC. This is useful if oPC cannot be obtained (I.E: They're offline)
void RHS_ExtendHouseRent(object oPC, int iDays, int iPCID = -1);
// Adds a particular furniture object to oPC's house's furniture table
// oPC = The player object
// oFurniture = The furniture you want to add
// iPCID = If set, the function will use this specific ID number instead of oPC's
void RHS_AddFurniture(object oPC, object oFurniture, int iPCID = -1);
// Removes a particular furniture object from oPC's house's furniture table
// oPC = The player object
// oFurniture = The furniture you want to remove.
// iPCID = If set, the function will use this specific ID number instead of oPC's
// ***NOTE: Make sure you call this before you physically destroy the furniture object with DestroyObject
void RHS_RemoveFurniture(object oPC, object oFurniture, int iPCID = -1);
// Sells all of the furniture in a player's household.
// Money is given to oPC and all of the furniture is removed from the table.
// oPC = The player whose furniture we're selling.
// ***NOTE: This also destroys all of the furniture objects inside the house instance, if the house instance exists.
void RHS_SellAllFurniture(object oPC);
// Adds a friend to oPC's list of friends. This makes it so that the friend can enter the house if permissions are set to "friends only"
// oPC = The player object
// iFriendID = If set, the function will use this specific ID number
// oFriend = If set, the function will get the friend ID from this friend object
// iSetting = The level of permission the friend has for oPC's house. Uses RHS_HOUSE_FRIEND_TYPE_* constants
void RHS_AddFriend(object oPC, int iFriendID = -1, object oFriend = OBJECT_INVALID, int iSetting = RHS_HOUSE_FRIEND_TYPE_FRIEND);
// Deletes a friend from oPC's list of friends. This makes it so that the friend can't enter the house unless permissions are set to "public"
// oPC = The player object
// iFriendID = If set, the function will use this specific ID number
// oFriend = If set, the function will get the friend ID from this friend object
// If iFriendID is less than 1 and oFriend is invalid, this function will do nothing
void RHS_RemoveFriend(object oPC, int iFriendID = -1, object oFriend = OBJECT_INVALID);
// Creates a furniture table for oPC's house, based off the template already in the database
// oPC = The player object
void RHS_CreateFurnitureTable(object oPC);
// Creates a friends table for oPC's house, based off the template already in the database
// oPC = The player object
void RHS_CreateFriendsTable(object oPC);
// Spawns all of a player's furniture into the instance of their house.
// oPC = The owner of the house. Set this to OBJECT_INVALID if you want to use iPCID instead
// oAreaInstance = The area instance in which to spawn the furniture
// iPCID = If greater than 0, the function will use this PC ID instead of the one assigned for oPC. This is useful if oPC cannot be obtained (I.E: They're offline)
void RHS_LoadHouseFurniture(object oPC, object oAreaInstance, int iPCID = -1);
// Creates a new area from the house template oPC is currently renting and returns the area instance
// oPC = The player object
// iPCID = If set greater than 0, the function will use this PC ID instead of the one assigned for oPC. This is useful if oPC cannot be obtained (I.E: They're offline)
// sHouseName = If set, the house name will be set to this value
// bPreviewArray = If TRUE, the previewing array will be used to track this instance as opposed to the standard instance array
// iHouseType = Used for previews - will force a specific house type to be created.
// Returns OBJECT_INVALID on error
object RHS_CreateHouseInstance(object oPC, int iPCID = -1, string sHouseName = "", int bPreviewArray = FALSE, int iHouseType = -1);
// Creates a house preview for oPC. No one but that player can enter it.
// oPC = The player previewing the house
// iHouseType = The database ID of a house type (Located in table RHS_TABLE_HOUSE_TYPES)
// sHouseName = If this is set, the house name will be set to it. Otherwise a generic "(PREVIEW) House Name" will be used as the area's name
void RHS_PreviewHouse(object oPC, int iHouseType, string sHouseName = "");
// Forces oPC to enter the house of oOwner.
// An instanced copy of the owner's house will be created and oPC will be teleported inside. All furniture will be spawned.
// If the instanced copy already exists, oPC will simply be sent to that copy instead of creating another.
// oPC = The player entering the house
// oOwner = The owner of the house, set this to OBJECT_INVALID if you're using iOwnerID instead
// iOwnerID = If set greater than 0, the function will use this Owner ID instead of the one assigned for oOwner. This is useful if oOwner cannot be obtained (I.E: They're offline)
// sHouseName = If set, the area's name will be set to this value. Useful for when PCs preview houses
// ***NOTE: oPC and oOwner can be the same object
void RHS_EnterHouse(object oPC, object oOwner = OBJECT_INVALID, int iOwnerID = -1, string sHouseName = "");
// Call this on the module's OnChat event.
// When a player has the necessary temporary variables, this will mark the next thing that player says
// for later use in the house renaming menu.
void RHS_OnPlayerChat();
// Call this on your module's OnEnter event.
// If a player doesn't have a furniture tool item, they will be given one.
// This tool should be undroppable.
void RHS_OnModuleEnter();
// Returns RHS_FRIEND_TYPE_INVALID if oFriend is not listed as a friend of oOwner's house.
// Returns RHS_FRIEND_TYPE_FRIEND if oFriend IS listed as a friend of oOwner's house.
// Returns RHS_FRIEND_TYPE_TRUSTEE if oFriend is a trustee of oOwner's house.
// oFriend = The friend we're checking
// oOwner = The owner of the house
// iFriendID = If this is greater than zero, this ID number will be used instead of the one listed on oFriend
// iOwnerID = If this is greater than zero, this ID number will be used instead of the one listed on oOwner
int RHS_IsPlayerFriend(object oFriend, object oOwner, int iFriendID = -1, int iOwnerID = -1);
// Returns TRUE if the rent is paid for oOwner's house
// Returns FALSE if the rent is due for oOwner's house
// Returns -1 on error
// oOwner = The house owner object
// iOwnerID = If this is greater than zero, this ID number will be used instead of the one listed on oOwner. Useful if oOwner is offline.
int RHS_IsRentPaid(object oOwner, int iOwnerID = -1);
// Calculates and returns the total worth of oOwner's furniture after the sell back penalty is applied.
// oOwner = The owner of the house
// iOwnerID = If this is greater than zero, this ID number will be used instead of the one listed on oOwner. Useful if oOwner is offline.
// Returns -1 on error.
int RHS_CalculateTotalFurnitureValue(object oOwner, int iOwnerID = -1);
// Call this on the door that's used to exit your house areas.
// It will teleport the user back to his or her stored location (I.E: The location they were at before entering the house)
// If there are no more players in the area, the area instance will be destroyed.
void RHS_OnDoorAreaTransitionClick();
// Returns the area object instance currently in use based on the owner's ID number
// iOwnerID = The ID number of the house's owner
// sAreaResref = The resref of the area instance
// Returns OBJECT_INVALID on error.
object RHS_GetAreaInstance(int iOwnerID, string sAreaResref);
// Destroys all of the items inside the inventory of a placeable or other object with inventory
void RHS_ClearInventory(object oObject);
///////////////
// FUNCTIONS //
///////////////
void RHS_SetPlayerHouse(object oPC, int iHouseType, int iPublicity = RHS_HOUSE_PUBLICITY_TYPE_PRIVATE)
{
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
int iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
string sPCID = IntToString(iPCID);
string sCharName = SQLEncodeSpecialChars(GetName(oPC));
string sAccessibleUntil = RWT_GetTimestampFromUnix(RWT_CreateCooldown(RHS_RENT_LENGTH * RWT_NUMBER_OF_SECONDS_IN_DAY));
string sHouseName = SQLEncodeSpecialChars(sCharName + "'s " + RHS_HOUSE_TERM_PROPER);
string sPublicityCode;
if(iPublicity == RHS_HOUSE_PUBLICITY_TYPE_PRIVATE)
sPublicityCode = "O";
else if(iPublicity == RHS_HOUSE_PUBLICITY_TYPE_FRIENDS)
sPublicityCode = "F";
else if(iPublicity == RHS_HOUSE_PUBLICITY_TYPE_PUBLIC)
sPublicityCode = "P";
else if(iPublicity == RHS_HOUSE_PUBLICITY_TYPE_TRUSTEES)
sPublicityCode = "T";
// Remove any existing data about the player's house
string sSQL = "DELETE FROM " + RHS_SCHEMA + "." + RHS_TABLE_HOUSES + " WHERE Player_ID=" + sPCID + "; ";
SQLExecDirect(sSQL);
sSQL = "DROP TABLE " + RHS_SCHEMA + "." + RHS_TABLE_FURNITURE + sPCID + "; ";
SQLExecDirect(sSQL);
sSQL = "DROP TABLE " + RHS_SCHEMA + "." + RHS_TABLE_FRIENDS + sPCID + "; ";
SQLExecDirect(sSQL);
// Add the new row's information
sSQL = "INSERT INTO " + RHS_SCHEMA + "." + RHS_TABLE_HOUSES + " (Player_ID, House_Name, Character_Name, House_Type, Publicity, Accessible_Until) VALUES (";
sSQL += sPCID + ", '" + sHouseName + "', '" + sCharName + "', " + IntToString(iHouseType) + ", '" + sPublicityCode + "', '" + sAccessibleUntil + "');";
SQLExecDirect(sSQL);
// Create the house's furniture and friends tables
RHS_CreateFurnitureTable(oPC);
RHS_CreateFriendsTable(oPC);
// Mark player as having a house
SetLocalInt(oDatabase, RHS_PLAYER_HOUSE_RENTED, TRUE);
}
object RHS_GetAreaInstance(int iOwnerID, string sAreaResref)
{
object oArea;
object oModule = GetModule();
string sArray = RHS_HOUSE_INSTANCE_PREFIX + sAreaResref;
int iCurArea = 1;
do
{
oArea = GetLocalArrayObject(oModule, sArray, iCurArea);
// Found it - return the area
if(GetLocalInt(oArea, RHS_IN_USE_ID) == iOwnerID)
{
return oArea;
}
iCurArea++;
}while(GetIsObjectValid(oArea));
// Didn't find the area - return OBJECT_INVALID
return OBJECT_INVALID;
}
void RHS_RemovePlayerHouse(object oPC, int iGold = 0)
{
object oModule = GetModule();
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
int iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
int iHouseType = StringToInt(GetMySQLData(RHS_TABLE_HOUSES, "House_Type", iPCID, "Player_ID", RHS_SCHEMA));
string sPCID = IntToString(iPCID);
string sAreaResref = GetMySQLData(RHS_TABLE_HOUSE_TYPES, "Resref", iHouseType, "ID", RHS_SCHEMA);
// Grab the area currently used by the instance
object oArea = RHS_GetAreaInstance(iPCID, sAreaResref);
// If the area is valid, kick everyone inside out and make the house vacant
if(GetIsObjectValid(oArea))
{
//SendMessageToPC(oPC, "House instance is valid"); // DEBUG
// Make the house vacant
DeleteLocalInt(oArea, RHS_IN_USE_ID);
// Find all players in the instance area and kick them out
object oPlayerInInstance = GetFirstPC();
while(GetIsObjectValid(oPlayerInInstance))
{
// If the player's area matches the instance area boot the player out of the house
if(GetArea(oPlayerInInstance) == oArea && !GetIsDM(oPC))
{
object oPlayerInInstanceDatabase = GetItemPossessedBy(oPlayerInInstance, PC_DATABASE);
string sPlayerInInstanceOriginalLocation = GetLocalString(oPlayerInInstanceDatabase, RHS_PLAYER_ORIGINAL_POSITION);
location lPlayerInInstanceOriginalLocation = APSStringToLocation(sPlayerInInstanceOriginalLocation);
FloatingTextStringOnCreature(ColorTokenRed() + "The owner of this " + RHS_HOUSE_TERM_LOWER + " has moved out. You have been kicked out." + ColorTokenEnd(), oPlayerInInstance, FALSE);
AssignCommand(oPlayerInInstance, ActionJumpToLocation(lPlayerInInstanceOriginalLocation));
}
oPlayerInInstance = GetNextPC();
}
}
// Remove from global houses table
string sSQL = "DELETE FROM " + RHS_SCHEMA + "." + RHS_TABLE_HOUSES + " WHERE Player_ID=" + sPCID + ";";
SQLExecDirect(sSQL);
// Remove house's specific tables
sSQL = "DROP TABLE " + RHS_SCHEMA + "." + RHS_TABLE_FURNITURE + sPCID + ";";
SQLExecDirect(sSQL);
sSQL = "DROP TABLE " + RHS_SCHEMA + "." + RHS_TABLE_FRIENDS + sPCID + ";";
SQLExecDirect(sSQL);
// Remove information from oPC
DeleteLocalInt(oDatabase, RHS_PLAYER_HOUSE_RENTED);
// If gold was passed through, give oPC that money
AssignCommand(oPC, GiveGoldToCreature(oPC, iGold));
}
void RHS_SellAllFurniture(object oPC)
{
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
int iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
// Safety check - ensure that iPCID is greater than 0. Otherwise, bail out
if(iPCID <= 0) return;
string sPCID = IntToString(iPCID);
string sTable = RHS_TABLE_FURNITURE + sPCID;
// Calculate and give the gold value to oPC
int iGold = RHS_CalculateTotalFurnitureValue(OBJECT_INVALID, iPCID);
AssignCommand(oPC, GiveGoldToCreature(oPC, iGold));
// Check if there's a house instance created for oPC's house
object oModule = GetModule();
// Look for the area instance
int iHouseType = StringToInt(GetMySQLData(RHS_TABLE_HOUSES, "House_Type", iPCID, "Player_ID", RHS_SCHEMA));
string sAreaResref = GetMySQLData(RHS_TABLE_HOUSE_TYPES, "Resref", iHouseType, "ID", RHS_SCHEMA);
object oArea = RHS_GetAreaInstance(iPCID, sAreaResref);
// Area was found - destroy all of the furniture in that area
if(GetIsObjectValid(oArea))
{
object oFurniture = GetFirstObjectInArea(oArea);
while(GetIsObjectValid(oFurniture))
{
// Don't destroy anything that isn't a furniture object
// We use the furniture's unique ID number to confirm this
if(GetLocalInt(oFurniture, RHS_FURNITURE_ID_NUMBER) > 0)
{
DestroyObject(oFurniture);
}
oFurniture = GetNextObjectInArea(oArea);
}
}
// Now delete all the furniture information from the table
string sSQL = "DELETE FROM " + RHS_SCHEMA + "." + sTable + ";";
SQLExecDirect(sSQL);
}
void RHS_SetHousePublicity(object oPC, int iPublicity = RHS_HOUSE_PUBLICITY_TYPE_PRIVATE)
{
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
int iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
string sPCID = IntToString(iPCID);
// Convert publicity to the correct code
string sPublicity = "O";
if(iPublicity == RHS_HOUSE_PUBLICITY_TYPE_FRIENDS)
{
sPublicity = "F";
}
else if(iPublicity == RHS_HOUSE_PUBLICITY_TYPE_PUBLIC)
{
sPublicity = "P";
}
else if(iPublicity == RHS_HOUSE_PUBLICITY_TYPE_TRUSTEES)
{
sPublicity = "T";
}
string sSQL = "UPDATE " + RHS_SCHEMA + "." + RHS_TABLE_HOUSES + " SET Publicity='" + sPublicity + "' WHERE Player_ID=" + sPCID + ";";
SQLExecDirect(sSQL);
}
void RHS_SetHouseName(object oPC, string sNewName = "")
{
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
int iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
string sPCID = IntToString(iPCID);
// If blank, default to "oPC's House"
if(sNewName == "")
sNewName = GetName(oPC) + "'s " + RHS_HOUSE_TERM_PROPER;
sNewName = SQLEncodeSpecialChars(sNewName);
string sSQL = "UPDATE " + RHS_SCHEMA + "." + RHS_TABLE_HOUSES + " SET House_Name='" + sNewName + "' WHERE Player_ID=" + sPCID + ";";
SQLExecDirect(sSQL);
}
void RHS_ExtendHouseRent(object oPC, int iDays, int iPCID = -1)
{
// Can't pass anything less than 1 as an extension
if(iDays <= 0) return;
// If oPC is valid and iPCID wasn't passed as a parameter, get the PC ID from oPC
if(GetIsObjectValid(oPC) && iPCID <= 0)
{
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
}
// Safety check - ensure that iPCID is greater than 0. Otherwise, bail out
if(iPCID <= 0) return;
string sPCID = IntToString(iPCID);
// I'm sure there's a better way to do this but I don't know SQL that well
int iUnixTime;
int iCurrentUnixTime;
string sSQL = "SELECT UNIX_TIMESTAMP(Accessible_Until), UNIX_TIMESTAMP() FROM " + RHS_SCHEMA + "." + RHS_TABLE_HOUSES + " WHERE Player_ID=" + sPCID;
SQLExecDirect(sSQL);
while(SQLFetch() == SQL_SUCCESS)
{
iUnixTime = StringToInt(SQLGetData(1));
iCurrentUnixTime = StringToInt(SQLGetData(2));
}
// Add time on to the current extension date
if(iCurrentUnixTime < iUnixTime)
{
// Add the number of days to the accessible_until date
iUnixTime += iDays * RWT_NUMBER_OF_SECONDS_IN_DAY;
}
// Rent payment has expired - new payments update time to now plus the number of days extended
else
{
iUnixTime = iCurrentUnixTime + (iDays * RWT_NUMBER_OF_SECONDS_IN_DAY);
}
// Update it in the table
sSQL = "UPDATE " + RHS_SCHEMA + "." + RHS_TABLE_HOUSES + " SET Accessible_Until=FROM_UNIXTIME(" + IntToString(iUnixTime) + ") WHERE Player_ID=" + IntToString(iPCID) + ";";
SQLExecDirect(sSQL);
}
void RHS_AddFurniture(object oPC, object oFurniture, int iPCID = -1)
{
if(iPCID <= 0)
{
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
}
// Check friend ID number again - if it's less than or equal to zero at this point bail out.
if(iPCID <= 0) return;
vector vPosition = GetPosition(oFurniture);
string sPCID = IntToString(iPCID);
string sTable = RHS_TABLE_FURNITURE + sPCID;
string sName = SQLEncodeSpecialChars(GetName(oFurniture));
string sTag = SQLEncodeSpecialChars(GetTag(oFurniture));
string sResref = SQLEncodeSpecialChars(GetResRef(oFurniture));
string sPositionX = FloatToString(vPosition.x);
string sPositionY = FloatToString(vPosition.y);
string sPositionZ = FloatToString(vPosition.z);
string sFacing = FloatToString(GetFacing(oFurniture));
string sSQL = "INSERT INTO " + RHS_SCHEMA + "." + sTable + " (Name, Tag, Resref, Position_X, Position_Y, Position_Z, Facing, Timestamp) VALUES ('";
sSQL += sName + "', '" + sTag + "', '" + sResref + "', '" + sPositionX + "', '" + sPositionY + "', '" + sPositionZ + "', '" + sFacing + "', CURRENT_TIMESTAMP);";
SQLExecDirect(sSQL);
sSQL = "SELECT LAST_INSERT_ID();";
SQLExecDirect(sSQL);
// Mark the furniture's ID number
if(SQLFetch() == SQL_SUCCESS)
{
SetLocalInt(oFurniture, RHS_FURNITURE_ID_NUMBER, StringToInt(SQLGetData(1)));
}
// Always make the furniture plot (I.E: Unable to be destroyed)
SetPlotFlag(oFurniture, TRUE);
// If the object is listed as "useable" in the furniture types table, make sure this object is marked as useable too
int bUseable = StringToInt(GetMySQLDataKeyString(RHS_TABLE_FURNITURE_TYPES, "Useable", sResref, "Resref", RHS_SCHEMA));
if(bUseable)
{
SetUseableFlag(oFurniture, TRUE);
}
else
{
SetUseableFlag(oFurniture, FALSE);
}
}
void RHS_RemoveFurniture(object oPC, object oFurniture, int iPCID = -1)
{
if(iPCID <= 0)
{
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
}
// Check friend ID number again - if it's less than or equal to zero at this point bail out.
if(iPCID <= 0) return;
int iFurnitureID = GetLocalInt(oFurniture, RHS_FURNITURE_ID_NUMBER);
string sPCID = IntToString(iPCID);
string sFurnitureID = IntToString(iFurnitureID);
string sTable = RHS_TABLE_FURNITURE + sPCID;
string sSQL = "DELETE FROM " + RHS_SCHEMA + "." + sTable + " WHERE ID=" + sFurnitureID;
SQLExecDirect(sSQL);
}
void RHS_AddFriend(object oPC, int iFriendID = -1, object oFriend = OBJECT_INVALID, int iSetting = RHS_HOUSE_FRIEND_TYPE_FRIEND)
{
// Invalid parameters were passed, can't continue so bail out
if(iFriendID <= 0 && oFriend == OBJECT_INVALID) return;
if(iFriendID <= 0)
{
object oFriendDatabase = GetItemPossessedBy(oFriend, PC_DATABASE);
iFriendID = GetLocalInt(oFriendDatabase, PC_ID_NUMBER);
}
// Check friend ID number again - if it's less than or equal to zero at this point bail out.
if(iFriendID <= 0) return;
// By this point we've got the friend's ID number. We can go ahead and input it into the friends table
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
int iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
string sPCID = IntToString(iPCID);
string sFriendID = IntToString(iFriendID);
string sTable = RHS_TABLE_FRIENDS + sPCID;
string sSetting;
// Convert friend types
if(iSetting == RHS_HOUSE_FRIEND_TYPE_TRUSTEE)
sSetting = "T";
else
sSetting = "F";
// ****************************************************************************************
// NOTE: Add the 'Name' field after you figure out how to refer to info in another table **
// ****************************************************************************************
string sSQL = "DELETE FROM " + RHS_SCHEMA + "." + sTable + " WHERE ID=" + sFriendID + ";";
SQLExecDirect(sSQL);
sSQL = "INSERT INTO " + RHS_SCHEMA + "." + sTable + " (ID, Setting) VALUES (" + sFriendID + ", '" + sSetting + "');";
SQLExecDirect(sSQL);
}
void RHS_RemoveFriend(object oPC, int iFriendID = -1, object oFriend = OBJECT_INVALID)
{
// Invalid parameters were passed, can't continue so bail out
if(iFriendID <= 0 && oFriend == OBJECT_INVALID) return;
if(iFriendID <= 0)
{
object oFriendDatabase = GetItemPossessedBy(oFriend, PC_DATABASE);
iFriendID = GetLocalInt(oFriendDatabase, PC_ID_NUMBER);
}
// Check friend ID number again - if it's less than or equal to zero at this point bail out.
if(iFriendID <= 0) return;
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
int iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
string sPCID = IntToString(iPCID);
string sFriendID = IntToString(iFriendID);
string sTable = RHS_TABLE_FRIENDS + sPCID;
string sSQL = "DELETE FROM " + RHS_SCHEMA + "." + sTable + " WHERE ID=" + sFriendID;
SQLExecDirect(sSQL);
}
void RHS_CreateFurnitureTable(object oPC)
{
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
int iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
string sPCID = IntToString(iPCID);
string sSQL = "CREATE TABLE " + RHS_SCHEMA + "." + RHS_TABLE_FURNITURE + sPCID + " LIKE " + RHS_SCHEMA + "." + RHS_TABLE_FURNITURE_TEMPLATE;
SQLExecDirect(sSQL);
}
void RHS_CreateFriendsTable(object oPC)
{
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
int iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
string sPCID = IntToString(iPCID);
string sSQL = "CREATE TABLE " + RHS_SCHEMA + "." + RHS_TABLE_FRIENDS + sPCID + " LIKE " + RHS_SCHEMA + "." + RHS_TABLE_FRIENDS_TEMPLATE;
SQLExecDirect(sSQL);
}
void RHS_LoadHouseFurniture(object oPC, object oAreaInstance, int iPCID = -1)
{
// If oPC is valid and iPCID wasn't passed as a parameter, get the PC ID from oPC
if(GetIsObjectValid(oPC) && iPCID <= 0)
{
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
}
// Safety check - ensure that iPCID is greater than 0. Otherwise, bail out
if(iPCID <= 0) return;
string sPCID = IntToString(iPCID);
// Spawn furniture
string sSQL = "SELECT ID, Resref, Position_X, Position_Y, Position_Z, Facing FROM " + RHS_SCHEMA + "." + RHS_TABLE_FURNITURE + sPCID;
SQLExecDirect(sSQL);
while(SQLFetch() == SQL_SUCCESS)
{
int iFurnitureID = StringToInt(SQLGetData(1));
string sResref = SQLGetData(2);
vector vPosition = Vector(StringToFloat(SQLGetData(3)), StringToFloat(SQLGetData(4)), StringToFloat(SQLGetData(5)));
location lLocation = Location(oAreaInstance, vPosition, StringToFloat(SQLGetData(6)));
object oFurniture = CreateObject(OBJECT_TYPE_PLACEABLE, sResref, lLocation);
SetLocalInt(oFurniture, RHS_FURNITURE_ID_NUMBER, iFurnitureID);
// Make unusable - temporary until I set up usability options
SetUseableFlag(oFurniture, FALSE);
// Make the furniture not able to be destroyed by normal means
SetPlotFlag(oFurniture, TRUE);
}
}
object RHS_CreateHouseInstance(object oPC, int iPCID = -1, string sHouseName = "", int bPreviewArray = FALSE, int iHouseType = -1)
{
object oModule = GetModule();
object oArea = OBJECT_INVALID;
string sHouseResref;
string sSQL;
// If oPC is valid and iPCID wasn't passed as a parameter, get the PC ID from oPC
if(GetIsObjectValid(oPC) && iPCID <= 0)
{
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
}
// Safety check - ensure that iPCID is greater than 0. Otherwise, bail out
if(iPCID <= 0) return oArea;
string sPCID = IntToString(iPCID);
if(iHouseType <= 0)
{
sSQL = "SELECT House_Name, House_Type FROM " + RHS_SCHEMA + "." + RHS_TABLE_HOUSES + " WHERE Player_ID=" + sPCID + ";";
SQLExecDirect(sSQL);
while(SQLFetch() == SQL_SUCCESS)
{
// Only use the one in the database if a house name wasn't passed for this function
if(sHouseName == "")
sHouseName = SQLDecodeSpecialChars(SQLGetData(1));
iHouseType = StringToInt(SQLGetData(2));
}
// Safety check - ensure house ID is at least 1
if(iHouseType <= 0) return oArea;
}
sSQL = "SELECT Resref FROM " + RHS_SCHEMA + "." + RHS_TABLE_HOUSE_TYPES + " WHERE ID=" + IntToString(iHouseType) + ";";
SQLExecDirect(sSQL);
while(SQLFetch() == SQL_SUCCESS)
{
sHouseResref = SQLDecodeSpecialChars(SQLGetData(1));
}
// Safety check - ensure house resref is not null
if(sHouseResref == "") return oArea;
// We've got the necessary data - create the area instance
oArea = CreateArea(sHouseResref);
// Set the area's name
SetAreaName(oArea, sHouseName);
// Find an open index number for the array for this house
int iIndex = 0;
object oArrayArea;
do
{
iIndex++;
oArrayArea = GetLocalArrayObject(oModule, RHS_HOUSE_INSTANCE_PREFIX + sHouseResref, iIndex);
}while(GetIsObjectValid(oArrayArea));
//SendMessageToPC(oPC, "DEBUG: iIndex = " + IntToString(iIndex)); // DEBUG
// Add instance to array of instances
SetLocalArrayObject(oModule, RHS_HOUSE_INSTANCE_PREFIX + sHouseResref, iIndex, oArea);
// Mark owner's ID number on the instanced area - previews do not get this set
if(!bPreviewArray)
SetLocalInt(oArea, RHS_HOUSE_OWNER_ID_NUMBER, iPCID);
// Mark the entry waypoint on the area
object oEntry = GetFirstObjectInArea(oArea);
while(GetIsObjectValid(oEntry))
{
// oEntry matches the entry waypoint - store the location of the waypoint on the area
// and break out of the loop.
if(GetResRef(oEntry) == RHS_HOUSE_WAYPOINT_RESREF)
{
location lEntryLocation = GetLocation(oEntry);
SetLocalLocation(oArea, RHS_HOUSE_ENTRY_WAYPOINT, lEntryLocation);
break;
}
oEntry = GetNextObjectInArea(oArea);
}
return oArea;
}
void RHS_PreviewHouse(object oPC, int iHouseType, string sHouseName = "")
{
object oModule = GetModule();
string sResref;
string sSQL = "SELECT Name, Resref FROM " + RHS_SCHEMA + "." + RHS_TABLE_HOUSE_TYPES + " WHERE ID=" + IntToString(iHouseType) + ";";
SQLExecDirect(sSQL);
if(SQLFetch() == SQL_SUCCESS)
{
// Add (PREVIEW) to beginning of area's name, if no name was passed through
if(sHouseName == "")
{
sHouseName = "(PREVIEW) " + SQLDecodeSpecialChars(SQLGetData(1));
}
sResref = SQLGetData(2);
}
// Something messed up - inform player
else
{
SendMessageToPC(oPC, ColorTokenRed() + "ERROR: Resref and name of area instance could not be found. Ensure MySQL is running correctly." + ColorTokenEnd());
return;
}
// Look for a vacant area instance and use it, if it exists
object oArea;
int iIndex = 1;
int bFoundArea = FALSE;
do
{
oArea = GetLocalArrayObject(oModule, RHS_HOUSE_INSTANCE_PREFIX + sResref, iIndex);
//SendMessageToPC(oPC, "Index = " + IntToString(iIndex) + ", In Use ID = " + IntToString(GetLocalInt(oArea, RHS_IN_USE_ID))); // DEBUG
if(GetLocalInt(oArea, RHS_IN_USE_ID) == 0)
{
int bFoundArea = TRUE;
break;
}
iIndex++;
}while(GetIsObjectValid(oArea) && !bFoundArea);
// No instances are vacant - create a new one
if(!GetIsObjectValid(oArea))
{
//SendMessageToPC(oPC, "Firing RHS_CreateHouseInstance dude"); // DEBUG
oArea = RHS_CreateHouseInstance(oPC, -1, sHouseName, TRUE, iHouseType);
}
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
int iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
location lLocation = GetLocalLocation(oArea, RHS_HOUSE_ENTRY_WAYPOINT);
AssignCommand(oPC, ActionJumpToLocation(lLocation));
SetLocalInt(oArea, RHS_HOUSE_OWNER_ID_NUMBER, iPCID);
SetLocalInt(oArea, RHS_IN_USE_ID, iPCID);
// Store the player's original location - for later use when they leave the instance area
location lOriginalLocation = GetLocation(oPC);
string sOriginalLocation = APSLocationToString(lOriginalLocation);
SetLocalString(oDatabase, RHS_PLAYER_ORIGINAL_POSITION, sOriginalLocation);
}
void RHS_EnterHouse(object oPC, object oOwner = OBJECT_INVALID, int iOwnerID = -1, string sHouseName = "")
{
// If oPC is valid and iPCID wasn't passed as a parameter, get the PC ID from oPC
if(GetIsObjectValid(oOwner) && iOwnerID <= 0)
{
object oDatabase = GetItemPossessedBy(oOwner, PC_DATABASE);
iOwnerID = GetLocalInt(oDatabase, PC_ID_NUMBER);
}
// Safety check - ensure that iOwnerID is greater than 0. Otherwise, bail out
if(iOwnerID <= 0) return;
string sOwnerID = IntToString(iOwnerID);
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
int iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
string sPublicitySetting;
int iHouseType;
// Fire SQL to get Publicity level and area Resref
string sSQL = "SELECT Publicity, House_Type FROM " + RHS_SCHEMA + "." + RHS_TABLE_HOUSES + " WHERE Player_ID=" + sOwnerID + ";";
SQLExecDirect(sSQL);
if(SQLFetch() == SQL_SUCCESS)
{
sPublicitySetting = SQLGetData(1);
iHouseType = StringToInt(SQLGetData(2));
}
int iFriendLevel = RHS_IsPlayerFriend(OBJECT_INVALID, OBJECT_INVALID, iPCID, iOwnerID);
// Owner only setting
if(sPublicitySetting == "O" && oPC != oOwner)
{
FloatingTextStringOnCreature(ColorTokenRed() + "The owner of that " + RHS_HOUSE_TERM_LOWER + " has set his or her privacy setting to 'Owner Only'. You cannot enter." + ColorTokenEnd(), oPC, FALSE);
return;
}
// Friends only setting
else if(sPublicitySetting == "F" && oPC != oOwner)
{
// Check if oPC is on the list of friends
if(iFriendLevel == RHS_FRIEND_TYPE_INVALID)
{
FloatingTextStringOnCreature(ColorTokenRed() + "The owner of that " + RHS_HOUSE_TERM_LOWER + " has set his or her privacy setting to 'Friends Only'. You cannot enter because you are not set as a friend." + ColorTokenEnd(), oPC, FALSE);
return;
}
}
// Trustees only setting
else if(sPublicitySetting == "T" && oPC != oOwner)
{
// Check if oPC is on the list of friends AND is a trustee
if(iFriendLevel != RHS_FRIEND_TYPE_TRUSTEE)
{
FloatingTextStringOnCreature(ColorTokenRed() + "The owner of that " + RHS_HOUSE_TERM_LOWER + " has set his or her privacy setting to 'Trustees Only'. You cannot enter because you are not set as a trustee." + ColorTokenEnd(), oPC, FALSE);
return;
}
}
object oModule = GetModule();
string sAreaResref = GetMySQLData(RHS_TABLE_HOUSE_TYPES, "Resref", iHouseType, "ID", RHS_SCHEMA);
// Look for the current house instance in use
int iCurArea = 1;
object oArea;
do
{
oArea = GetLocalArrayObject(oModule, RHS_HOUSE_INSTANCE_PREFIX + sAreaResref, iCurArea);
// The house we found is currently in use. Send the PC to this area
if(GetLocalInt(oArea, RHS_IN_USE_ID) == iOwnerID)
{
break;
}
iCurArea++;
}while(GetIsObjectValid(oArea));
// No house instance was found to be in use. Find the first open area
if(!GetIsObjectValid(oArea))
{
do
{
oArea = GetLocalArrayObject(oModule, RHS_HOUSE_INSTANCE_PREFIX + sAreaResref, iCurArea);
if(GetLocalInt(oArea, RHS_IN_USE_ID) == 0)
{
break;
}
iCurArea++;
}while(GetIsObjectValid(oArea));
}
// No house instances are open - create a new instance
if(!GetIsObjectValid(oArea))
{
// Create instance and mark the entry location
oArea = RHS_CreateHouseInstance(OBJECT_INVALID, iOwnerID, sHouseName);
// Safety check - don't want to create non-existant areas
if(GetIsObjectValid(oArea))
{
// Spawn the owner's furniture in the house
RHS_LoadHouseFurniture(OBJECT_INVALID, oArea, iOwnerID);
}
}
// Otherwise rename the area
else
{
SetAreaName(oArea, sHouseName);
}
// Mark the owner ID who is currently using this area
SetLocalInt(oArea, RHS_IN_USE_ID, iOwnerID);
SetLocalInt(oArea, RHS_HOUSE_OWNER_ID_NUMBER, iOwnerID);
// By this point we know which area to send the player to. Store the PC's current location and
// then go ahead and send him or her inside
// Store the player's original location - for later use when they leave the instance area
location lOriginalLocation = GetLocation(oPC);
string sOriginalLocation = APSLocationToString(lOriginalLocation);
SetLocalString(oDatabase, RHS_PLAYER_ORIGINAL_POSITION, sOriginalLocation);
// Send the player into the instanced house
AssignCommand(oPC, ActionJumpToLocation(GetLocalLocation(oArea, RHS_HOUSE_ENTRY_WAYPOINT)));
}
void RHS_OnPlayerChat()
{
object oPC = GetPCChatSpeaker();
string sMessage = GetPCChatMessage();
int bListening = GetLocalInt(oPC, RHS_PAGE_TEMP_LISTENING);
// Remove temporary variables and inform player they need to hit the next button on the conversation menu
if(bListening)
{
SetLocalString(oPC, RHS_PAGE_TEMP_NEW_HOUSE_NAME, sMessage);
DeleteLocalInt(oPC, RHS_PAGE_TEMP_LISTENING);
SetPCChatMessage("");
FloatingTextStringOnCreature(ColorTokenGreen() + "New name set! Press 'Finish Entering New " + RHS_HOUSE_TERM_PROPER + " Name' to continue." + ColorTokenEnd(), oPC, FALSE);
}
}
int RHS_IsPlayerFriend(object oFriend, object oOwner, int iFriendID = -1, int iOwnerID = -1)
{
// If oFriend is valid and iFriendID wasn't passed as a parameter, get the Friend ID from oFriend
if(GetIsObjectValid(oFriend) && iFriendID <= 0)
{
object oDatabase = GetItemPossessedBy(oFriend, PC_DATABASE);
iFriendID = GetLocalInt(oDatabase, PC_ID_NUMBER);
}
if(iFriendID <= 0) return RHS_FRIEND_TYPE_INVALID;
// Do the same for the owner
if(GetIsObjectValid(oOwner) && iOwnerID <= 0)
{
object oDatabase = GetItemPossessedBy(oOwner, PC_DATABASE);
iOwnerID = GetLocalInt(oDatabase, PC_ID_NUMBER);
}
if(iOwnerID <= 0) return RHS_FRIEND_TYPE_INVALID;
string sFriendID = IntToString(iFriendID);
string sOwnerID = IntToString(iOwnerID);
string sSQL = "SELECT Setting FROM " + RHS_SCHEMA + "." + RHS_TABLE_FRIENDS + sOwnerID + " WHERE ID=" + sFriendID + ";";
SQLExecDirect(sSQL);
while(SQLFetch() == SQL_SUCCESS)
{
return StringToInt(SQLGetData(1));
}
// If we make it to this point, they're either not listed or something went wrong. Default to RHS_FRIEND_TYPE_INVALID
return RHS_FRIEND_TYPE_INVALID;
}
void RHS_OnDoorAreaTransitionClick()
{
object oPC = GetClickingObject();
if(GetIsDM(oPC)) return;
object oDoor = OBJECT_SELF;
object oModule = GetModule();
object oArea = GetArea(oDoor);
object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
string sLocation = GetLocalString(oDatabase, RHS_PLAYER_ORIGINAL_POSITION);
location lLocation = APSStringToLocation(sLocation);
int bDestroyArea = TRUE;
//int iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER);
int iOwnerID = GetLocalInt(oArea, RHS_HOUSE_OWNER_ID_NUMBER);
AssignCommand(oPC, ActionJumpToLocation(lLocation));
object oCurPlayer = GetFirstPC();
while(GetIsObjectValid(oCurPlayer))
{
// Just in case the PC leaving the area is picked up
// Or a DM was picked up
if(oCurPlayer != oPC && !GetIsDM(oPC))
{
// If the current player is in the instance area, we don't want to destroy it
if(GetArea(oCurPlayer) == oArea)
{
bDestroyArea = FALSE;
break;
}
}
oCurPlayer = GetNextPC();
}
// No one in the instance - mark this area as vacant, ready for the next person's use
// Also destroy all furniture
if(bDestroyArea)
{
object oCurFurniture = GetFirstObjectInArea(oArea);
while(GetIsObjectValid(oCurFurniture))
{
if(GetLocalInt(oCurFurniture, RHS_FURNITURE_ID_NUMBER) > 0)
{
RHS_ClearInventory(oCurFurniture);
DestroyObject(oCurFurniture);
}
oCurFurniture = GetNextObjectInArea(oArea);
}
if(GetIsObjectValid(oArea))
{
//SendMessageToPC(oPC, "Destroying area instance"); // DEBUG
//DestroyArea(oArea); // Removed because the server seg-faults if an area is destroyed
}
DeleteLocalInt(oArea, RHS_IN_USE_ID);
DeleteLocalInt(oArea, RHS_HOUSE_OWNER_ID_NUMBER);
}
}
int RHS_IsRentPaid(object oOwner, int iOwnerID = -1)
{
int bRentPaid = FALSE;
// If oOwner is valid and iOwnerID wasn't passed as a parameter, get the Owner ID from oOwner
if(GetIsObjectValid(oOwner) && iOwnerID <= 0)
{
object oDatabase = GetItemPossessedBy(oOwner, PC_DATABASE);
iOwnerID = GetLocalInt(oDatabase, PC_ID_NUMBER);
}
if(iOwnerID <= 0) return -1;
string sOwnerID = IntToString(iOwnerID);
string sSQL = "SELECT UNIX_TIMESTAMP(), UNIX_TIMESTAMP(Accessible_Until) FROM " + RHS_SCHEMA + "." + RHS_TABLE_HOUSES + " WHERE Player_ID=" + sOwnerID + ";";
SQLExecDirect(sSQL);
while(SQLFetch() == SQL_SUCCESS)
{
int iUnixTime = StringToInt(SQLGetData(1));
int iAccessibleUnix = StringToInt(SQLGetData(2));
if(iUnixTime >= iAccessibleUnix)
bRentPaid = FALSE;
else
bRentPaid = TRUE;
}
return bRentPaid;
}
int RHS_CalculateTotalFurnitureValue(object oOwner, int iOwnerID = -1)
{
// If oOwner is valid and iOwnerID wasn't passed as a parameter, get the Owner ID from oOwner
if(GetIsObjectValid(oOwner) && iOwnerID <= 0)
{
object oDatabase = GetItemPossessedBy(oOwner, PC_DATABASE);
iOwnerID = GetLocalInt(oDatabase, PC_ID_NUMBER);
}
if(iOwnerID <= 0) return -1;
string sOwnerID = IntToString(iOwnerID);
int iGold;
string sTable = RHS_SCHEMA + "." + RHS_TABLE_FURNITURE + sOwnerID;
string sSQL = "SELECT SUM(Gold_Cost) FROM " + RHS_SCHEMA + "." + RHS_TABLE_FURNITURE_TYPES + ", " + sTable + " WHERE ";
sSQL += RHS_TABLE_FURNITURE_TYPES + ".Resref = " + sTable + ".Resref;";
SQLExecDirect(sSQL);
while(SQLFetch() == SQL_SUCCESS)
{
iGold = StringToInt(SQLGetData(1));
iGold = FloatToInt(iGold * RHS_FURNITURE_SELL_BACK_PERCENTAGE);
}
return iGold;
}
void RHS_OnModuleEnter()
{
object oPC = GetEnteringObject();
if(!GetIsPC(oPC) || GetIsDM(oPC)) return;
if(!GetIsObjectValid(GetItemPossessedBy(oPC, RHS_FURNITURE_TOOL_RESREF)))
{
CreateItemOnObject(RHS_FURNITURE_TOOL_RESREF, oPC, 1);
}
}
void RHS_ClearInventory(object oObject)
{
object oInventory = GetFirstItemInInventory(oObject);
while(GetIsObjectValid(oInventory))
{
DestroyObject(oInventory);
oInventory = GetNextItemInInventory(oObject);
}
}
// Error checking
void main(){}