/** * Copyright (c)2000-2002 Sony Online Entertainment Inc. * All Rights Reserved * * Title: veteran_deprecated.scriptlib * Description: handles the veteran reward system * @author $Author:$ * @version $Revision:$ */ /***** INCLUDES ********************************************************/ include library.features; /***** CONSTANTS *******************************************************/ // !!!NOTE: all time values are in days const int UNENTITLED_TIME_LIMIT = 14; // time a player may be unentitled before losing veteran status const int MONTHS_PER_MILESTONE = 3; const int DAYS_PER_MONTH = 30; const int DAYS_PER_MILESTONE = MONTHS_PER_MILESTONE * DAYS_PER_MONTH; const int REWARD_FLAGS_SIZE = ((12 / MONTHS_PER_MILESTONE) * 10) / 32 + 1; // 10 years of rewards, 1 bit per milestone const int MAX_MILESTONE = REWARD_FLAGS_SIZE * 32; // base string table const string VETERAN_STRING_TABLE = "veteran"; // the rewards datatable data const string REWARDS_DATATABLE = "datatables/veteran/rewards.iff"; const string REWARDS_COLUMN_TEMPLATE = "template"; const string REWARDS_COLUMN_SCRIPT = "script"; const string REWARDS_COLUMN_MILESTONE = "milestone"; // this is base-1, we need to convert it to base-0 when we read it const string REWARDS_COLUMN_ONETIME = "oneTime"; const string REWARDS_COLUMN_NOTRADE = "noTrade"; const string REWARDS_COLUMN_NODELETE = "noDelete"; const string REWARDS_COLUMN_NOMOVE = "noMove"; const string REWARDS_COLUMN_REQUIREDGAMEFEATUREBITANY = "requiredGameFeatureBitAny"; const string REWARDS_COLUMN_REQUIREDGAMEFEATUREBITALL = "requiredGameFeatureBitAll"; const string REWARDS_COLUMN_REQUIREDSUBSCRIPTIONFEATUREBITANY = "requiredSubscriptionFeatureBitAny"; const string REWARDS_COLUMN_REQUIREDSUBSCRIPTIONFEATUREBITALL = "requiredSubscriptionFeatureBitAll"; // the emotes datatable data const string EMOTES_DATATABLE = "datatables/veteran/emotes.iff"; const string EMOTES_COLUMN_EMOTE = "emote"; const string EMOTES_COLUMN_GROUP = "group"; // callback when a player selects a reward const string HANDLER_SELECT_VETERAN_REWARD = "handleVeteranRewardSelected"; // callback when a player selects a milestone const string HANDLER_SELECT_VETERAN_MILESTONE = "handleVeteranMilestoneSelected"; // callback when a player responds to the cofirmation window when // the milestone of the selected reward doesn not match the milestone // that the player is claiming const string HANDLER_SELECT_VETERAN_REWARD_CONFIRM = "handleVeteranRewardConfirmed"; const string OBJVAR_TIME_ACTIVE = "veteran.timeActive"; const string OBJVAR_REWARDS_RECEIVED = "veteran.rewardsReceived"; const string OBJVAR_MILESTONES_NOTIFIED = "veteran.milestonesNotified"; const string OBJVAR_ONETIME_REWARDS_RECEIVED = "veteran.onetime"; const string OBJVAR_VETERAN_EMOTES = "veteran.emotes"; // one year anniversary rewards const string OBJVAR_ONE_YEAR_ANNIVERSARY = "anniversary.oneYear"; const string OBJVAR_ONE_YEAR_ANNIVERSARY_OVERRIDE = "anniversary.override"; const string TEMPLATE_ONE_YEAR_ANNIVERSARY = "object/tangible/veteran_reward/one_year_anniversary/painting_"; const string_id SID_ONE_YEAR_ANNIVERSARY = new string_id(VETERAN_STRING_TABLE, "one_year_anniversary"); const string_id SID_ONE_YEAR_ANNIVERSARY_SUBJECT = new string_id(VETERAN_STRING_TABLE, "one_year_anniversary_subject"); const string_id SID_ONE_YEAR_ANNIVERSARY_FROM = new string_id(VETERAN_STRING_TABLE, "one_year_anniversary_from"); const string_id SID_ONE_YEAR_ANNIVERSARY_INVENTORY_FULL = new string_id(VETERAN_STRING_TABLE, "one_year_inventory_full"); const string_id SID_ONE_YEAR_ANNIVERSARY_INVENTORY_FULL_SUBJECT = new string_id(VETERAN_STRING_TABLE, "one_year_inventory_full_subject"); const int ONE_YEAR_ANNIVERSARY_REWARD_COUNT = 9; const int MIN_ONE_YEAR_ANNIVERSARY_TIME = 30; // one (30 day) month // Flash speeder replacement cost const int FLASH_SPEEDER_COST = 20000; // return codes from canGetRewardAtIndex const int CAN_GET_REWARD_SUCCESS = 0; const int CAN_GET_REWARD_FAIL_INADEQUATE_MILESTONE = 1; const int CAN_GET_REWARD_FAIL_ALREADY_CLAIMED = 2; const int CAN_GET_REWARD_FAIL_INADEQUATE_SUBSCRIPTION = 3; // return codes from givePlayerReward const int GIVE_PLAYER_REWARD_SUCCESS = 0; const int GIVE_PLAYER_REWARD_FAILED = 1; const int GIVE_PLAYER_REWARD_MORE_PROCESSING_REQUIRED = 2; // objvars for testing the system. These are also in serverScript/ScriptMethodsPlayerAccount.cpp const string OBJVAR_FAKE_VETERAN = "_testVeteran"; const string OBJVAR_FAKE_VETERAN_TOTAL_TIME = OBJVAR_FAKE_VETERAN + ".total_time"; const string OBJVAR_FAKE_VETERAN_ENTITLED_TIME = OBJVAR_FAKE_VETERAN + ".entitled_time"; const string OBJVAR_FAKE_VETERAN_LOGIN_TIME = OBJVAR_FAKE_VETERAN + ".login_time"; const string OBJVAR_FAKE_VETERAN_ENTITLED_LOGIN_TIME = OBJVAR_FAKE_VETERAN + ".entitled_login_time"; const string SCRIPTVAR_VETERAN_LOGGED_IN = "veteran.loggedIn"; const string SCRIPTVAR_SELECTED_REWARD = "veteran.selectedReward"; const string SCRIPTVAR_SELECTED_MILESTONE = "veteran.selectedMilestone"; const string SCRIPTVAR_AVAILABLE_MILESTONES = "veteran.milestones"; const string_id SID_VETERAN_NEW_REWARD = new string_id(VETERAN_STRING_TABLE, "new_reward"); const string_id SID_VETERAN_NEW_REWARD_SUBJECT = new string_id(VETERAN_STRING_TABLE, "new_reward_subject"); const string_id SID_VETERAN_NEW_REWARD_FROM = new string_id(VETERAN_STRING_TABLE, "new_reward_from"); const string_id SID_VETERAN_NEW_REWARD_MSGBOX = new string_id(VETERAN_STRING_TABLE, "new_reward_msgbox"); const string_id SID_VETERAN_SELECT_MILESTONE_PROMPT = new string_id(VETERAN_STRING_TABLE, "select_milestone"); const string_id SID_VETERAN_SELECT_REWARD_PROMPT = new string_id(VETERAN_STRING_TABLE, "select_reward"); const string_id SID_VETERAN_SELECT_REWARD_CONFIRM = new string_id(VETERAN_STRING_TABLE, "select_reward_confirm"); const string_id SID_VETERAN_TIME_ACTIVE = new string_id(VETERAN_STRING_TABLE, "time_active"); const string_id SID_VETERAN_SELF_TIME_ACTIVE = new string_id(VETERAN_STRING_TABLE, "self_time_active"); const string_id SID_NOT_ELIGIBLE = new string_id(VETERAN_STRING_TABLE, "not_eligible"); const string_id SID_REWARD_GIVEN = new string_id(VETERAN_STRING_TABLE, "reward_given"); const string_id SID_REWARD_ERROR = new string_id(VETERAN_STRING_TABLE, "reward_error"); const string_id SID_SYSTEM_INACTIVE = new string_id(VETERAN_STRING_TABLE, "system_inactive"); const string_id SID_INVALID_TARGET = new string_id(VETERAN_STRING_TABLE, "invalid_target"); const string_id SID_MILESTONE_OUT_OF_RANGE = new string_id(VETERAN_STRING_TABLE, "milestone_out_of_range"); const string_id SID_HAS_MILESTONE = new string_id(VETERAN_STRING_TABLE, "has_milestone"); const string_id SID_HAS_NOT_MILESTONE = new string_id(VETERAN_STRING_TABLE, "has_not_milestone"); const string_id SID_OK = new string_id(VETERAN_STRING_TABLE, "ok"); const string_id SID_ACTIVE_MONTHS_CLEARED = new string_id(VETERAN_STRING_TABLE, "active_months_cleared"); const string_id SID_BAD_MILESTONE = new string_id(VETERAN_STRING_TABLE, "bad_milestone"); const string_id SID_BAD_REWARD = new string_id(VETERAN_STRING_TABLE, "bad_reward"); const string_id SID_DAYS = new string_id(VETERAN_STRING_TABLE, "days"); const string_id SID_RANK = new string_id(VETERAN_STRING_TABLE, "rank"); const string_id SID_UNAVAILABLE = new string_id(VETERAN_STRING_TABLE, "unavailable"); const string_id SID_UNAVAILABLE_CLAIMED = new string_id(VETERAN_STRING_TABLE, "unavailable_claimed"); const string_id SID_UNAVAILABLE_NEEDS_EXPANSION = new string_id(VETERAN_STRING_TABLE, "unavailable_needs_expansion"); const string_id SID_UNAVAILABLE_NOT_ENOUGH_MILESTONE= new string_id(VETERAN_STRING_TABLE, "unavailable_not_enough_milestone"); const string_id SID_UNKNOWN = new string_id(VETERAN_STRING_TABLE, "unknown"); /***** FUNCTIONS *******************************************************/ /** * Updates the amount of time a player has accumulated for their veteran reward(s). */ void updateVeteranTime(obj_id player) { if ( !isIdValid(player) ) return; if ( !"true".equals(getConfigSetting("GameServer", "enableVeteranRewards")) ) return; // make sure this function only gets run when the player actually logs in, not warps to another // planet, etc. if ( player.getScriptVars().hasKey(SCRIPTVAR_VETERAN_LOGGED_IN) ) return; player.getScriptVars().put(SCRIPTVAR_VETERAN_LOGGED_IN, true); // get the player's account info dictionary timeData = getAccountTimeData(player); if ( timeData == null ) { // this is OK, it means that the platform system currently does not // have access to the player's entitlement information (db may be down, // for example); we'll try again the next time the player logs in return; } int totalEntitledTime = timeData.getInt("total_entitled_time"); if ( !hasObjVar(player, OBJVAR_TIME_ACTIVE) ) { // initialize the player's time setObjVar(player, OBJVAR_TIME_ACTIVE, totalEntitledTime); setObjVar(player, OBJVAR_REWARDS_RECEIVED, new int[REWARD_FLAGS_SIZE]); setObjVar(player, OBJVAR_MILESTONES_NOTIFIED, new int[REWARD_FLAGS_SIZE]); } else { // update the player's time setObjVar(player, OBJVAR_TIME_ACTIVE, totalEntitledTime); } } /** * Tests if a player can get a veteran reward. */ boolean canGetReward(obj_id player) { // see if the player is qualified to receive any reward int[] milestones = getVeteranRewardMilestones(player); // nope, not qualified return ( (milestones != null) && (milestones.length >= 1) ); } /** * Sends a message to a player for what rewards (or milestones) they can choose and lets them choose one. */ boolean requestVeteranRewards(obj_id player) { if ( !isIdValid(player) ) return false; int[] milestones = getVeteranRewardMilestones(player); if ( (milestones == null) || (milestones.length < 1) ) { // tell the player no rewards are available return false; } // get all the possible milestone player has achieved int veteranTime = getIntObjVar(player, OBJVAR_TIME_ACTIVE); if ( veteranTime <= 0) { CustomerServiceLog("veteran", "requestVeteranRewards called for player %TU with no active time", player); return false; } int firstMilestone = veteranTime / DAYS_PER_MILESTONE; if ( firstMilestone < 1 ) return false; if ( firstMilestone > MAX_MILESTONE ) { CustomerServiceLog("veteran", "requestVeteranRewards called for player %TU who has a milestone " + firstMilestone + " which is greater than the maximum supported milestone " + MAX_MILESTONE, player); firstMilestone = MAX_MILESTONE; } // ask the player which milestone they would like to claim a reward from string daysText = getString(SID_DAYS); string alreadyClaimedText = getString(SID_UNAVAILABLE_CLAIMED); Vector milestonesText = new Vector(); for ( int i = 0; i < firstMilestone; ++i ) { // for now, only display the 180 days milestone if (i == 1) { if ( checkVeteranMilestone(player, (i + 1)) ) milestonesText.add(((i + 1) * DAYS_PER_MILESTONE) + daysText + " (" + alreadyClaimedText + ")"); else milestonesText.add(((i + 1) * DAYS_PER_MILESTONE) + daysText); } } int pid = sui.listbox(player, player, "@" + SID_VETERAN_SELECT_MILESTONE_PROMPT, sui.OK_CANCEL, sui.DEFAULT_TITLE, milestonesText, HANDLER_SELECT_VETERAN_MILESTONE, true); if ( pid < 0 ) { CustomerServiceLog("veteran", "Could not create sui reward list for player %TU, error = " + pid, player); return false; } player.getScriptVars().put(SCRIPTVAR_AVAILABLE_MILESTONES, milestones); return true; } /** * Sends a message to a player for what rewards they can choose and lets them choose one. */ boolean requestVeteranRewards(obj_id player, int milestone) { if ( !isIdValid(player) ) return false; // build a list of all the rewards, marking those that are not available // to be claimed with the appropriate text on the item string daysText = getString(SID_DAYS); string rankText = getString(SID_RANK); string unavailableText = getString(SID_UNAVAILABLE); string alreadyClaimedText = getString(SID_UNAVAILABLE_CLAIMED); string needsExpansionText = getString(SID_UNAVAILABLE_NEEDS_EXPANSION); string notEnoughMilestoneText = getString(SID_UNAVAILABLE_NOT_ENOUGH_MILESTONE); string unknownText = getString(SID_UNKNOWN); Vector availableRewards = new Vector(); int numRows = dataTableGetNumRows(REWARDS_DATATABLE); for ( int i = 0; i < numRows; ++i ) { string name = getRewardNameAtIndex(i); if ( name != null ) { boolean oneShot = dataTableGetInt(REWARDS_DATATABLE, i, REWARDS_COLUMN_ONETIME) != 0; if ( oneShot ) name += " *"; boolean noTrade = dataTableGetInt(REWARDS_DATATABLE, i, REWARDS_COLUMN_NOTRADE) != 0; if ( noTrade ) { if ( oneShot ) name += "#"; else name += " #"; } int rewardMilestone = dataTableGetInt(REWARDS_DATATABLE, i, REWARDS_COLUMN_MILESTONE); name += " ("; name += Integer.toString(rewardMilestone * DAYS_PER_MILESTONE); name += daysText; name += ", "; name += rankText; name += Integer.toString(rewardMilestone); name += ")"; int canGetRewardStatus = canGetRewardAtIndex(player, i, milestone); if ( canGetRewardStatus != CAN_GET_REWARD_SUCCESS ) { if ( canGetRewardStatus == CAN_GET_REWARD_FAIL_INADEQUATE_MILESTONE ) name = name + " (" + notEnoughMilestoneText + ")"; else if ( canGetRewardStatus == CAN_GET_REWARD_FAIL_ALREADY_CLAIMED ) name = name + " (" + alreadyClaimedText + ")"; else if ( canGetRewardStatus == CAN_GET_REWARD_FAIL_INADEQUATE_SUBSCRIPTION ) name = name + " (" + needsExpansionText + ")"; else name = name + " (" + unavailableText + ")"; } } else { availableRewards.add(unknownText); } availableRewards.add(name); } int pid = sui.listbox(player, player, "@" + SID_VETERAN_SELECT_REWARD_PROMPT, sui.OK_CANCEL, sui.DEFAULT_TITLE, availableRewards, HANDLER_SELECT_VETERAN_REWARD, true); if ( pid < 0 ) { CustomerServiceLog("veteran", "Could not create sui reward list for player %TU, error = " + pid, player); return false; } player.getScriptVars().put(SCRIPTVAR_SELECTED_MILESTONE, milestone); return true; } /** * Returns the milestones that a player can claim a reward from. */ int[] getVeteranRewardMilestones(obj_id player) { int veteranTime = getIntObjVar(player, OBJVAR_TIME_ACTIVE); if ( veteranTime <= 0) { CustomerServiceLog("veteran", "getVeteranRewardMilestones called for player %TU with no active time", player); return null; } int firstMilestone = veteranTime / DAYS_PER_MILESTONE; if ( firstMilestone < 1 ) return null; if ( firstMilestone > MAX_MILESTONE ) { CustomerServiceLog("veteran", "getVeteranRewardMilestones called for player %TU who has a milestone " + firstMilestone + " which is greater than the maximum supported milestone " + MAX_MILESTONE, player); firstMilestone = MAX_MILESTONE; } int[] veteranRewards = getIntArrayObjVar(player, OBJVAR_REWARDS_RECEIVED); if ( veteranRewards == null) { CustomerServiceLog("veteran", "getVeteranRewardMilestones called for player %TU with no rewards flags", player); veteranRewards = new int[REWARD_FLAGS_SIZE]; setObjVar(player, OBJVAR_REWARDS_RECEIVED, veteranRewards); } // get the index for every milestone not flagged Vector milestoneVector = new Vector(); for ( int i = 0; i < firstMilestone; ++i ) { // see if the player already gained a reward for the milestone int index = i / 32; int mask = 0x00000001 << (i - index * 32); if ( (veteranRewards[index] & mask) == 0 ) { // note we change from base-0 to base-1 here milestoneVector.add(new Integer(i + 1)); } } if ( milestoneVector.size() < 1 ) return null; // convert the milestone vector to an array int[] milestoneArray = new int[milestoneVector.size()]; for ( int i = 0; i < milestoneArray.length; ++i ) { milestoneArray[i] = ((Integer)(milestoneVector.elementAt(i))).intValue(); } return milestoneArray; } /** * Give the player the award they selected. */ int givePlayerReward(obj_id player, int rewardIndex, boolean checkMilestoneMismatch) { if ( !isIdValid(player) ) return GIVE_PLAYER_REWARD_FAILED; if ( !player.getScriptVars().hasKey(SCRIPTVAR_SELECTED_MILESTONE) ) { CustomerServiceLog("veteran", "givePlayerReward could not find SCRIPTVAR_SELECTED_MILESTONE for player %TU with reward index " + rewardIndex, player); return GIVE_PLAYER_REWARD_FAILED; } int milestone = player.getScriptVars().getInt(SCRIPTVAR_SELECTED_MILESTONE); // don't need to log anything here, it means player tried // to select a reward from the "read-only" rewards page; // we don't need to spam the log when this happens if ( milestone < 1 ) return GIVE_PLAYER_REWARD_FAILED; // possible hacker, passed an item index that's greater than the max index if ( rewardIndex >= dataTableGetNumRows(REWARDS_DATATABLE) ) { CustomerServiceLog("veteran", "givePlayerReward could not find reward for player %TU with reward index " + rewardIndex + " for milestone " + milestone, player); return GIVE_PLAYER_REWARD_FAILED; } // double check again to make sure that he is eligible for this // milestone, and he has not claimed a reward for this milestone int veteranTime = getIntObjVar(player, OBJVAR_TIME_ACTIVE); if ( veteranTime <= 0 ) { CustomerServiceLog("veteran", "givePlayerReward called for player %TU with no active time", player); return GIVE_PLAYER_REWARD_FAILED; } int firstMilestone = veteranTime / DAYS_PER_MILESTONE; if ( firstMilestone > MAX_MILESTONE ) { CustomerServiceLog("veteran", "givePlayerReward called for player %TU who has a milestone " + firstMilestone + " which is greater than the maximum supported milestone " + MAX_MILESTONE, player); firstMilestone = MAX_MILESTONE; } if ( milestone > firstMilestone ) { CustomerServiceLog("veteran", "givePlayerReward called for player %TU with requested milestone " + milestone + " which is greater than the actual milestone " + firstMilestone, player); return GIVE_PLAYER_REWARD_FAILED; } if ( checkVeteranMilestone(player, milestone) ) { CustomerServiceLog("veteran", "givePlayerReward called for player %TU who has already claimed the reward for milestone " + milestone, player); return GIVE_PLAYER_REWARD_FAILED; } // can the player get this reward? int canGetRewardStatus = canGetRewardAtIndex(player, rewardIndex, milestone); if ( canGetRewardStatus != CAN_GET_REWARD_SUCCESS ) { CustomerServiceLog("veteran", "givePlayerReward could not grant reward for player %TU with reward index " + rewardIndex + " for milestone " + milestone + ", error code " + canGetRewardStatus, player); return GIVE_PLAYER_REWARD_FAILED; } // get confirmation from the player if the milestone level for the reward // they have chosen does not match the reward milestone that they are using if ( checkMilestoneMismatch ) { int rewardMilestone = dataTableGetInt(REWARDS_DATATABLE, rewardIndex, REWARDS_COLUMN_MILESTONE); if ( rewardMilestone != milestone ) { int pid = sui.msgbox(player, player, "@" + SID_VETERAN_SELECT_REWARD_CONFIRM, sui.YES_NO, HANDLER_SELECT_VETERAN_REWARD_CONFIRM); if ( pid < 0 ) { CustomerServiceLog("veteran", "givePlayerReward could not create sui reward confirmation message box for player %TU, error = " + pid, player); return GIVE_PLAYER_REWARD_FAILED; } // save off the selected reward index, so that after // confirmation, we'll know which reward to give player.getScriptVars().put(SCRIPTVAR_SELECTED_REWARD, rewardIndex); return GIVE_PLAYER_REWARD_MORE_PROCESSING_REQUIRED; } } int templateCrc = dataTableGetInt(REWARDS_DATATABLE, rewardIndex, REWARDS_COLUMN_TEMPLATE); obj_id reward = createObjectInInventoryAllowOverload(templateCrc, player); if ( !isIdValid(reward) ) { CustomerServiceLog("veteran", "givePlayerReward could not create reward for reward index " + rewardIndex + ", template crc " + templateCrc + " for player %TU", player); return GIVE_PLAYER_REWARD_FAILED; } CustomerServiceLog("veteran", "givePlayerReward has given player %TU item " + getName(reward) + " (" + reward + ") for milestone " + milestone, player); // mark the reward as no trade, if necessary boolean noTrade = dataTableGetInt(REWARDS_DATATABLE, rewardIndex, REWARDS_COLUMN_NOTRADE) != 0; if ( noTrade ) setObjVar(reward, "noTrade", true); // mark the reward as no delete, if necessary boolean noDelete = dataTableGetInt(REWARDS_DATATABLE, rewardIndex, REWARDS_COLUMN_NODELETE) != 0; if ( noDelete ) attachScript(reward, "item.special.nodestroy"); // mark the reward as no move, if necessary boolean noMove = dataTableGetInt(REWARDS_DATATABLE, rewardIndex, REWARDS_COLUMN_NOMOVE) != 0; if ( noMove ) attachScript(reward, "item.special.nomove"); // update the player's rewards flag for the month of the first reward if ( !hasObjVar(player, OBJVAR_REWARDS_RECEIVED)) { CustomerServiceLog("veteran", "givePlayerReward called for player %TU with no rewards flags", player); } setVeteranMilestone(player, milestone); // if the reward is a one-time reward, flag the player as having received it boolean oneShot = dataTableGetInt(REWARDS_DATATABLE, rewardIndex, REWARDS_COLUMN_ONETIME) != 0; if ( oneShot ) { int[] onetimes = getIntArrayObjVar(player, OBJVAR_ONETIME_REWARDS_RECEIVED); int[] onetimesNew; if ( onetimes != null) { onetimesNew = new int[onetimes.length + 1]; for ( int i = 0; i < onetimes.length; ++i ) onetimesNew[i] = onetimes[i]; onetimesNew[onetimes.length] = templateCrc; } else { onetimesNew = new int[1]; onetimesNew[0] = templateCrc; } setObjVar(player, OBJVAR_ONETIME_REWARDS_RECEIVED, onetimesNew); } // attach the reward-specific script (if any) to the reward string script = dataTableGetString(REWARDS_DATATABLE, rewardIndex, REWARDS_COLUMN_SCRIPT); if ( script != null && script.length() > 0 ) { attachScript(reward, script); } cleanupPlayerData(player); return GIVE_PLAYER_REWARD_SUCCESS; } /** * Cleans up temporary data we've stored on a player. */ void cleanupPlayerData(obj_id player) { if ( !isIdValid(player) ) return; player.getScriptVars().remove(SCRIPTVAR_SELECTED_REWARD); player.getScriptVars().remove(SCRIPTVAR_SELECTED_MILESTONE); player.getScriptVars().remove(SCRIPTVAR_AVAILABLE_MILESTONES); } /** * Returns the reward name from the rewards datatable at a given index. */ string getRewardNameAtIndex(int index) { string name = null; int templateCrc = dataTableGetInt(REWARDS_DATATABLE, index, REWARDS_COLUMN_TEMPLATE); string_id nameId = getNameFromTemplate(templateCrc); if ( nameId != null) name = "@" + nameId; else CustomerServiceLog("veteran", "Could not find reward at index " + index); return name; } /** * Checks to see if a player can get the reward at a given index in the reward datatable. * * @param index the reward index to check * * @return int indicating success or failure */ int canGetRewardAtIndex(obj_id player, int index, int milestone) { // Note that the check is done in the order that we want to // communicate to the player as to why the reward is unavailable // if the reward is a one time reward, make sure the player hasn't received the award; int templateCrc = dataTableGetInt(REWARDS_DATATABLE, index, REWARDS_COLUMN_TEMPLATE); boolean oneShot = dataTableGetInt(REWARDS_DATATABLE, index, REWARDS_COLUMN_ONETIME) != 0; if ( oneShot ) { int[] onetimes = getIntArrayObjVar(player, OBJVAR_ONETIME_REWARDS_RECEIVED); if ( onetimes != null ) { for ( int i = 0; i < onetimes.length; ++i ) { if ( onetimes[i] == templateCrc ) return CAN_GET_REWARD_FAIL_ALREADY_CLAIMED; } } } // if the reward requires certain subscription bits, check for that int requiredBit = dataTableGetInt(REWARDS_DATATABLE, index, REWARDS_COLUMN_REQUIREDGAMEFEATUREBITANY); if (requiredBit > 0) { int game_bits = getGameFeatureBits(player); if ((game_bits & requiredBit) == 0) return CAN_GET_REWARD_FAIL_INADEQUATE_SUBSCRIPTION; } requiredBit = dataTableGetInt(REWARDS_DATATABLE, index, REWARDS_COLUMN_REQUIREDGAMEFEATUREBITALL); if (requiredBit > 0) { int game_bits = getGameFeatureBits(player); if ((game_bits & requiredBit) != requiredBit) return CAN_GET_REWARD_FAIL_INADEQUATE_SUBSCRIPTION; } requiredBit = dataTableGetInt(REWARDS_DATATABLE, index, REWARDS_COLUMN_REQUIREDSUBSCRIPTIONFEATUREBITANY); if (requiredBit > 0) { int sub_bits = getSubscriptionFeatureBits(player); if ((sub_bits & requiredBit) == 0) return CAN_GET_REWARD_FAIL_INADEQUATE_SUBSCRIPTION; } requiredBit = dataTableGetInt(REWARDS_DATATABLE, index, REWARDS_COLUMN_REQUIREDSUBSCRIPTIONFEATUREBITALL); if (requiredBit > 0) { int sub_bits = getSubscriptionFeatureBits(player); if ((sub_bits & requiredBit) != requiredBit) return CAN_GET_REWARD_FAIL_INADEQUATE_SUBSCRIPTION; } // the rewards's milestone cannot exceed the specified milestone int rewardMilestone = dataTableGetInt(REWARDS_DATATABLE, index, REWARDS_COLUMN_MILESTONE); if ( rewardMilestone > milestone ) return CAN_GET_REWARD_FAIL_INADEQUATE_MILESTONE; return CAN_GET_REWARD_SUCCESS; } /** * Returns if a veteran milestone is set on a player or not. * * @param player the player * @milestone the milestone to check. The milestone is expected to be base-1 * * @return true if the milestone is set, false if not */ boolean checkVeteranMilestone(obj_id player, int milestone) { if ( milestone < 1 || milestone > MAX_MILESTONE ) return false; int[] rewardsReceived = getIntArrayObjVar(player, OBJVAR_REWARDS_RECEIVED); if ( rewardsReceived == null) return false; // go from base-1 to base-0 --milestone; int index = milestone / 32; int mask = 0x00000001 << (milestone - index * 32); return (rewardsReceived[index] & mask) != 0; } /** * Returns if a notification for a veteran milestone achievement has been sent or not. * * @param player the player * @milestone the milestone to check. The milestone is expected to be base-1 * * @return true if the notification has been sent, false if not */ boolean checkMilestoneNotified(obj_id player, int milestone) { if ( milestone < 1 || milestone > MAX_MILESTONE ) return false; int[] milestonesNotified = getIntArrayObjVar(player, OBJVAR_MILESTONES_NOTIFIED); if ( milestonesNotified == null) return false; // go from base-1 to base-0 --milestone; int index = milestone / 32; int mask = 0x00000001 << (milestone - index * 32); return (milestonesNotified[index] & mask) != 0; } /** * Sets a milestone flag on a player. * * @param player the player * @milestone the milestone to set. The milestone is expected to be base-1 */ void setVeteranMilestone(obj_id player, int milestone) { if ( milestone < 1 || milestone > MAX_MILESTONE ) return; int[] rewardsReceived = getIntArrayObjVar(player, OBJVAR_REWARDS_RECEIVED); if ( rewardsReceived == null) rewardsReceived = new int[REWARD_FLAGS_SIZE]; // go from base-1 to base-0 --milestone; int index = milestone / 32; int mask = 0x00000001 << (milestone - index * 32); rewardsReceived[index] |= mask; setObjVar(player, OBJVAR_REWARDS_RECEIVED, rewardsReceived); } /** * Sets a flag indicating a notification for a veteran milestone achievement has been sent * * @param player the player * @milestone the milestone to set. The milestone is expected to be base-1 */ void setMilestoneNotified(obj_id player, int milestone) { if ( milestone < 1 || milestone > MAX_MILESTONE ) return; int[] milestonesNotified = getIntArrayObjVar(player, OBJVAR_MILESTONES_NOTIFIED); if ( milestonesNotified == null) milestonesNotified = new int[REWARD_FLAGS_SIZE]; // go from base-1 to base-0 --milestone; int index = milestone / 32; int mask = 0x00000001 << (milestone - index * 32); milestonesNotified[index] |= mask; setObjVar(player, OBJVAR_MILESTONES_NOTIFIED, milestonesNotified); } /** * Clears a milestone flag on a player. * * @param player the player * @milestone the milestone to clear. The milestone is expected to be base-1 */ void clearVeteranMilestone(obj_id player, int milestone) { if ( milestone < 1 || milestone > MAX_MILESTONE ) return; int[] rewardsReceived = getIntArrayObjVar(player, OBJVAR_REWARDS_RECEIVED); if ( rewardsReceived == null) rewardsReceived = new int[REWARD_FLAGS_SIZE]; // clear the flag indicating a notification has been sent for the milestone clearMilestoneNotified(player, milestone); // go from base-1 to base-0 --milestone; int index = milestone / 32; int mask = 0x00000001 << (milestone - index * 32); rewardsReceived[index] &= ~mask; setObjVar(player, OBJVAR_REWARDS_RECEIVED, rewardsReceived); } /** * Clears the flag indicating a notification for a veteran milestone achievement has been sent * * @param player the player * @milestone the milestone to clear. The milestone is expected to be base-1 */ void clearMilestoneNotified(obj_id player, int milestone) { if ( milestone < 1 || milestone > MAX_MILESTONE ) return; int[] milestonesNotified = getIntArrayObjVar(player, OBJVAR_MILESTONES_NOTIFIED); if ( milestonesNotified == null) milestonesNotified = new int[REWARD_FLAGS_SIZE]; // go from base-1 to base-0 --milestone; int index = milestone / 32; int mask = 0x00000001 << (milestone - index * 32); milestonesNotified[index] &= ~mask; setObjVar(player, OBJVAR_MILESTONES_NOTIFIED, milestonesNotified); } /** * Makes sure a target object is a veteran. */ boolean checkVeteranTarget(obj_id target) { if ( isIdValid(target) && isPlayer(target) ) { if ( hasObjVar(target, veteran_deprecated.OBJVAR_TIME_ACTIVE) ) { return true; } else sendSystemMessage(getSelf(), veteran_deprecated.SID_SYSTEM_INACTIVE); } else sendSystemMessage(getSelf(), veteran_deprecated.SID_INVALID_TARGET); return false; } /** * Gives a reward to players for the one year anniversary of the game. The player's * character must have been created at least a month ago. * * @param player the player to give the reward to */ void giveOneYearAnniversaryReward(obj_id player) { // make sure the system is enabled if (!"true".equals(getConfigSetting("GameServer", "enableOneYearAnniversary"))) return; if ( !isPlayer(player) ) return; // make sure the player hasn't already gotten the reward if ( hasObjVar(player, OBJVAR_ONE_YEAR_ANNIVERSARY ) ) return; // make sure the player has been around long enough int playerBorn = getPlayerBirthDate(player); int existTime = getCurrentBirthDate() - playerBorn; // check player time override if ( hasObjVar(player, OBJVAR_ONE_YEAR_ANNIVERSARY_OVERRIDE ) ) { existTime = getIntObjVar(player, OBJVAR_ONE_YEAR_ANNIVERSARY_OVERRIDE); CustomerServiceLog("one_year_anniversary", "Using override time of " + existTime + " for player %TU", player); } // debugServerConsoleMsg(null, "OneYearAnniversary: player date = " + playerBorn + ", current date = " + // getCurrentBirthDate() + ", exist time = " + existTime); if ( playerBorn < 0 || existTime < MIN_ONE_YEAR_ANNIVERSARY_TIME ) return; obj_id inventory = utils.getInventoryContainer(player); if ( !isIdValid(inventory) ) return; // make sure there is enough room in the player's inventory int free = getVolumeFree(inventory); if ( free == 0 ) { // tell the player to make room and reenter the game prose_package pp = new prose_package(); pp.stringId = SID_ONE_YEAR_ANNIVERSARY_INVENTORY_FULL; utils.sendMail( SID_ONE_YEAR_ANNIVERSARY_INVENTORY_FULL_SUBJECT, pp, player, "@" + SID_ONE_YEAR_ANNIVERSARY_FROM ); return; } int rewardNum = rand(1, ONE_YEAR_ANNIVERSARY_REWARD_COUNT); string rewardName = TEMPLATE_ONE_YEAR_ANNIVERSARY; if ( rewardNum < 10) rewardName += "0"; rewardName += rewardNum; obj_id reward = createObject(rewardName + ".iff", inventory, ""); if ( !isIdValid(reward) ) { CustomerServiceLog("one_year_anniversary", "WARNING: Error creating one year anniversary reward " + rewardName + ".iff for player %TU", player); return; } // set the one year objvar to so the player will only get one reward setObjVar(player, OBJVAR_ONE_YEAR_ANNIVERSARY, reward ); CustomerServiceLog("one_year_anniversary", "Gave player %TU one year anniversary reward " + reward, player); // let the player know they've gotten a reward prose_package pp = new prose_package(); pp.stringId = SID_ONE_YEAR_ANNIVERSARY; utils.sendMail( SID_ONE_YEAR_ANNIVERSARY_SUBJECT, pp, player, "@" + SID_ONE_YEAR_ANNIVERSARY_FROM ); } /** * Checks to see if the player is eligible for the Flash Speeder reward. * This is given for preordering JTL. * * @param player player to check * @return boolean true if a reward is granted. */ boolean checkFlashSpeederReward(obj_id player) { if (!isIdValid(player)) { LOG("flash_speeder", "veteran_deprecated.checkFlashSpeeder: Player is invalid."); return false; } if (!isPlayer(player)) { LOG("flash_speeder", "veteran_deprecated.checkFlashSpeeder: " + player + " is not a player."); return false; } if (isUsingAdminLogin(player)) { return false; } string config = getConfigSetting("GameServer", "flashSpeederReward"); //LOG("flash_speeder", "config ->" + config); if (config != null && config.equals("true")) { int sub_bits = getGameFeatureBits(player); if (hasObjVar(player, "flash_speeder.eligible")) sub_bits = getIntObjVar(player, "flash_speeder.eligible"); if ((features.isSpaceEdition(player) && utils.checkBit(sub_bits, 3)) || features.isJPCollectorEdition(player)) // 3 is the JtL pre-order bit. { if (!hasObjVar(player, "flash_speeder.granted")) { // Give the player a flash speeder deed and e-mail him about it. createObjectInInventoryAllowOverload("object/tangible/deed/vehicle_deed/speederbike_flash_deed.iff", player); CustomerServiceLog("flash_speeder", "%TU has received a JtL pre-order Flash Speeder.", player); string_id sub = new string_id(VETERAN_STRING_TABLE, "flash_speeder_granted_sub"); string_id body = new string_id(VETERAN_STRING_TABLE, "flash_speeder_granted_body"); utils.sendMail(sub, body, player, "System"); setObjVar(player, "flash_speeder.granted", 1); return true; } } } return false; }