/** * Copyright (c)2000-2002 Sony Online Entertainment Inc. * All Rights Reserved * * Title: player_collection.script * Description: required script for player collections * @author $Author:$ * @version $Revision:$ */ /***** INCLUDES ********************************************************/ include library.badge; include library.collection; include library.prose; include library.stealth; include library.sui; include library.utils; include library.trial; /***** CONSTANTS *******************************************************/ const string_id SID_SLOT_ADDED = new string_id("collection","player_slot_added"); const string_id SID_HIDDEN_SLOT = new string_id("collection","player_hidden_slot_added"); const string_id SID_COLLECTION_COMPLETE = new string_id("collection","player_collection_complete"); const string_id SID_SERVER_FIRST = new string_id("collection","player_server_first"); const string SERVER_FIRST_SLOT = "bdg_server_first_01"; const string VAR_ACCESS_DELAY = "delay.access_delay"; const string_id SID_REPORT_CONSUME_ITEM_FAIL = new string_id("collection", "report_consume_item_fail"); const string_id COUNTDOWN_TIMER = new string_id("collection", "click_countdown_timer"); const string_id SID_COUNTDOWN_LOCOMOTION = new string_id("quest/groundquests", "countdown_interrupted_locomotion"); const string_id SID_INTERRUPTED_INCAPACITATED = new string_id("quest/groundquests", "countdown_interrupted_incapacitated"); const string_id SID_INTERRUPTED_DAMAGED = new string_id("quest/groundquests", "countdown_interrupted_damaged"); const string_id SID_INVIS_COLLECTION_FAIL = new string_id("collection", "invis_collection_failed"); const int GCW_INSURGENT_LOCKOUT = 3600; //triggers trigger OnCollectionSlotModified(string bookName, string pageName, string collectionName, string slotName, boolean isCounterTypeSlot, int previousValue, int currentValue, int maxSlotValue, boolean slotCompleted) { //bail on badges, they do their own thing. if(bookName.equals(badge.BADGE_BOOK)) return SCRIPT_CONTINUE; //get all slots in the collection string[] collectionSlots = getAllCollectionSlotsInCollection(collectionName); //this shouldnt happen, but we will test just in case if(collectionSlots == null || collectionSlots.length <= 0) return SCRIPT_CONTINUE; //assume this is a new collection boolean newCollection = true; //bool - can clear collection boolean canResetCollection = false; //initialize our prose package prose_package pp = new prose_package(); //loop thru the collections slots for(int i = 0; i < collectionSlots.length; ++i) { //check if this slot is not the slot we just modified if(!collectionSlots[i].equals(slotName)) { //get the value of the slot long value = getCollectionSlotValue(self, collectionSlots[i]); //if the slots value is greater than 0, this is NOT a new collection if(value > 0) { newCollection = false; break; } } } int row = dataTableSearchColumnForString(slotName, "slotName", collection.COLLECTION_TABLE); if(row < 0) { //should never happen return SCRIPT_CONTINUE; } int isHidden = dataTableGetInt(collection.COLLECTION_TABLE, row, "hidden"); //if we are still a new collection check to see if this is the first time we have incremented this slot if((newCollection && currentValue == 1) && isHidden == 0) { //if all that passes, we send the message that they have activated a new collection prose.setStringId(pp, SID_HIDDEN_SLOT); prose.setTU(pp, new string_id("collection_n", slotName)); prose.setTO(pp, new string_id("collection_n", collectionName)); sendSystemMessageProse(self, pp); play2dNonLoopingSound(self, "sound/utinni.snd"); } //lets get all the catagories on the slot string[] catagories = getCollectionSlotCategoryInfo(slotName); //validate if(catagories != null && catagories.length > 0) { //loop thru them all for(int i = 0; i < catagories.length; ++i) { //check to see if this is a reward on update if(catagories[i].equals(collection.REWARD_ON_UPDATE_CATEGORY)) { collection.grantCollectionReward(self, slotName, false); } //check to see if this is a reward on update count if(catagories[i].startsWith(collection.CATEGORY_UPDATE_ON_COUNT)) { //if it is, find the count to update at string[] splitUpdateCount = split(catagories[i], ':'); if(splitUpdateCount != null && splitUpdateCount.length > 0) { int countToUpdateAt = utils.stringToInt(splitUpdateCount[1]); //if count to update at is equal to new value and we are a count type slot if((countToUpdateAt == currentValue) && isCounterTypeSlot) { //give appropriate reward for that count collection.grantCollectionReward(self, slotName + ":" + splitUpdateCount[1], false); } } } } } // don't do anything if didn't complete collection slot if (slotCompleted) { boolean giveMessage = true; if(catagories != null && catagories.length > 0) { for(int i = 0; i < catagories.length; ++i) { if(catagories[i].equals(collection.REWARD_ON_COMPLETE_CATEGORY)) { collection.grantCollectionReward(self, slotName, false); } if(catagories[i].equals(collection.NO_MESSAGE_CATEGORY)) { giveMessage = false; } if( bookName.equals("saga_relic_book") ) { giveMessage = false; } if(catagories[i].equals(collection.CLEAR_ON_COMPLETE) && hasCompletedCollection(self, collectionName)) { //This collection can be reset! canResetCollection = true; } } } if(isHidden > 0 && giveMessage) { prose.setStringId(pp, SID_HIDDEN_SLOT); prose.setTU(pp, new string_id("collection_n", slotName)); prose.setTO(pp, new string_id("collection_n", collectionName)); sendSystemMessageProse(self, pp); play2dNonLoopingSound(self, "sound/utinni.snd"); } else if (giveMessage) { prose.setStringId(pp, SID_SLOT_ADDED); prose.setTU(pp, new string_id("collection_n", slotName)); prose.setTO(pp, new string_id("collection_n", collectionName)); sendSystemMessageProse(self, pp); play2dNonLoopingSound(self, "sound/utinni.snd"); } if(hasCompletedCollection(self, collectionName)) { int rowNum = dataTableSearchColumnForString(collectionName, "collectionName", collection.COLLECTION_TABLE); //get dictionary for the Collection Row to see if we send a CompleteCollection Message dictionary dd = dataTableGetRow(collection.COLLECTION_TABLE, rowNum); //If the collection is hidden - we don't want to send a message. int giveCompletionMessage = dd.getInt("hidden"); //if giveMessage is true - give message. if(giveCompletionMessage == 0) { //they have finished the collection. We need to give them the reward prose.setTO(pp, new string_id("collection_n", collectionName)); prose.setStringId(pp, SID_COLLECTION_COMPLETE); sendSystemMessageProse(self, pp); collection.grantCollectionReward(self, collectionName, canResetCollection); } //otherwise get the reward. else { collection.grantCollectionReward(self, collectionName, canResetCollection); } } } return SCRIPT_CONTINUE; } trigger OnCollectionServerFirst(string bookName, string pageName, string collectionName) { prose_package pp = new prose_package(); prose.setStringId(pp, SID_SERVER_FIRST); prose.setTO(pp, new string_id("collection_n", collectionName)); prose.setTT(pp, getClusterName()); sendSystemMessageProse(self, pp); if(!badge.hasBadge(self, SERVER_FIRST_SLOT)) { badge.grantBadge(self, SERVER_FIRST_SLOT); } return SCRIPT_CONTINUE; } messageHandler modifySlot() { int pid = params.getInt("id"); int test_pid = getIntObjVar(self, sui.COUNTDOWNTIMER_SUI_VAR); if(pid != test_pid) { utils.removeScriptVarTree(self,"col"); sui.removePid(self, collection.CONSUME_PID_NAME); LOG("collection","Player PID Var wrong. Aborting. "); return SCRIPT_CONTINUE; } if(!sui.hasPid(self, collection.CONSUME_PID_NAME)) { //wrong pid utils.removeScriptVarTree(self,"col"); LOG("collection","Player PID Var wrong. Aborting. "); return SCRIPT_CONTINUE; } test_pid = sui.getPid(self, collection.CONSUME_PID_NAME); if(test_pid != pid) { //wrong pid utils.removeScriptVarTree(self,"col"); sui.removePid(self, collection.CONSUME_PID_NAME); LOG("collection","Player PID Var wrong. Aborting. "); return SCRIPT_CONTINUE; } if(!utils.hasScriptVarTree(self, "col")) { LOG("collection","Player is missing col scriptvar tree. we are now aborting"); sui.removePid(self, collection.CONSUME_PID_NAME); return SCRIPT_CONTINUE; } obj_id collectionItem = utils.getObjIdScriptVar(self, "col.collectionItem"); string slotName = utils.getStringScriptVar(self, "col.slotName"); int bp = sui.getIntButtonPressed(params); // Cancel button is sent when player manually closes the countdown window, // or when he/she moves out of range. if(bp == sui.BP_CANCEL) { utils.removeScriptVarTree(self,"col"); LOG("collection","Button Press Cancel - Player too far away. Aborting. "); sui.removePid(self, collection.CONSUME_PID_NAME); utils.setScriptVar(self, VAR_ACCESS_DELAY, getGameTime()); return SCRIPT_CONTINUE; } else if(bp == sui.BP_REVERT) { // Gets the reason why the timer was aborted int event = params.getInt("event"); // You can handle the situation differently depending on the reason if(event == sui.CD_EVENT_LOCOMOTION) { sendSystemMessage(self, SID_COUNTDOWN_LOCOMOTION); } else if(event == sui.CD_EVENT_INCAPACITATE) { sendSystemMessage(self, SID_INTERRUPTED_INCAPACITATED); } else if(event == sui.CD_EVENT_DAMAGED || event == sui.CD_EVENT_COMBAT) { sendSystemMessage(self, SID_INTERRUPTED_DAMAGED); } LOG("collection","Button Press Revert - Aborting. "); utils.removeScriptVarTree(self,"col"); utils.setScriptVar(self, VAR_ACCESS_DELAY, getGameTime()); sui.removePid(self, collection.CONSUME_PID_NAME); return SCRIPT_CONTINUE; } if(!hasObjVar(self, sui.COUNTDOWNTIMER_SUI_VAR)) { utils.removeScriptVarTree(self,"col"); sui.removePid(self, collection.CONSUME_PID_NAME); LOG("collection","Player has no COUNTDOWNTIMER_SUI_VAR. Aborting. "); return SCRIPT_CONTINUE; } LOG("collection","Button Press not cancel or revert. Player passed distance check."); if(stealth.hasInvisibleBuff(self)) { sendSystemMessage(self, SID_INVIS_COLLECTION_FAIL); forceCloseSUIPage(pid); utils.removeScriptVarTree(self,"col"); sui.removePid(self, collection.CONSUME_PID_NAME); LOG("collection","Player Invisible. Aborting. "); return SCRIPT_CONTINUE; } LOG("collection","Force Close the SUI."); forceCloseSUIPage(pid); //Update the player with the slot if(modifyCollectionSlotValue(self, slotName, 1)) { CustomerServiceLog("CollectionConsume: ", "collectionItem (" + collectionItem + ")"+ " was consumed into a collection, for player " + getFirstName(self) + "(" + self + ")."); if(utils.hasScriptVar(self, "col.isGCW")) { //1 hour lockout timer for GCW collection items (insurgency collection) utils.setScriptVar(collectionItem, "collection.gcw_lockout_time", "1"); messageTo(collectionItem, "removeGcwCollectionLockout", null, GCW_INSURGENT_LOCKOUT, false); } if (hasObjVar(collectionItem, "spawn_id")) { string collectedId = getStringObjVar(collectionItem, "spawn_id"); obj_id collectedParent = trial.getParent(collectionItem); dictionary dict = trial.getSessionDict(collectedParent); dict.put("triggerType", "triggerId"); dict.put("triggerName", collectedId+"_collected"); messageTo(collectedParent, "triggerFired", dict, 0.0f, false); } } else { //tell cs we failed CustomerServiceLog("CollectionConsume: ", "collectionItem (" + collectionItem + ")"+ " was NOT consumed into a collection, for player " + getFirstName(self) + "(" + self + ")."); //tell the player we failed sendSystemMessage(self, SID_REPORT_CONSUME_ITEM_FAIL); } utils.removeScriptVarTree(self,"col"); sui.removePid(self, collection.CONSUME_PID_NAME); return SCRIPT_CONTINUE; }