mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-07-31 00:15:54 -04:00
2249 lines
74 KiB
Plaintext
2249 lines
74 KiB
Plaintext
include library.badge;
|
|
include library.factions;
|
|
include library.loot;
|
|
include library.money;
|
|
include library.prose;
|
|
include library.utils;
|
|
include library.weapons;
|
|
include library.xp;
|
|
include library.gcw;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
const string DISABLED_QUEST_TABLE = "datatables/quest/ground/disabled.iff";
|
|
const string DISABLED_QUEST_COLUMN = "disabled_quests";
|
|
|
|
const String questBaseObjVar = "quest";
|
|
const String questAllObjVar = "all";
|
|
const String questStaticEscortTargetObjVar = "staticEscortTarget";
|
|
const String dot = ".";
|
|
|
|
const String datatableColumnjournalEntryTitle = "JOURNAL_ENTRY_TITLE";
|
|
const String datatableColumnShowSystemMessages = "SHOW_SYSTEM_MESSAGES";
|
|
const String datatableColumnCategory = "CATEGORY";
|
|
const String dataTableColumnTaskName = "TASK_NAME";
|
|
const String dataTableColumnVisible = "IS_VISIBLE";
|
|
const String dataTableColumnActionName = "ACTION_NAME";
|
|
const String dataTableColumnQuestVisible = "VISIBLE";
|
|
|
|
const int maxTasksPerQuest = 16;
|
|
|
|
const string MUSIC_QUEST_ACTIVATED = "sound/ui_npe2_quest_received.snd";
|
|
const string MUSIC_QUEST_COMPLETED = "sound/ui_npe2_quest_completed.snd";
|
|
const string MUSIC_QUEST_RECEIVED_CREDITS = "sound/ui_npe2_quest_credits.snd";
|
|
const string MUSIC_QUEST_RECEIVED_ITEM = "sound/ui_npe2_quest_reward.snd";
|
|
const string MUSIC_QUEST_INCREMENT_COUNTER = "sound/ui_npe2_quest_step_completed.snd";
|
|
|
|
const string_id SID_TASK_COMPLETED = new string_id( "quest/ground/system_message", "quest_task_completed" );
|
|
const string_id SID_TASK_FAILED = new string_id( "quest/ground/system_message", "quest_task_failed" );
|
|
const string_id SID_QUEST_RECEIVED = new string_id( "quest/ground/system_message", "quest_received" );
|
|
const string_id SID_PLACED_IN_INVENTORY = new string_id( "quest/ground/system_message", "placed_in_inventory" );
|
|
const string_id SID_MORE_THAN_ONE_PLACED_IN_INVENTORY = new string_id( "quest/ground/system_message", "placed_in_inventory_number" );
|
|
const string_id SID_REMOVED_FROM_INVENTORY = new string_id( "quest/ground/system_message", "removed_from_inventory" );
|
|
const string_id SID_TIME_REMAINING_BEFORE_COMPLETION = new string_id("quest/ground/system_message", "time_remaining_before_completion");
|
|
const string_id SID_NO_XP_TRADER_ENTERTAINER = new string_id("quest/ground/system_message", "entertainer_trader_no_xp_combat");
|
|
|
|
const String objvarGoingHome = "quest.static_escort.goingHome";
|
|
const String objvarOnEscort = "quest.static_escort.onEscort";
|
|
|
|
const String objvarGuaranteedSuccess_Count = "guaranteedSuccess.count";
|
|
const String objvarGuaranteedSuccess_Target = "guaranteedSuccess.target";
|
|
|
|
const String JOURNAL_UPDATED_MUSIC = "sound/ui_journal_updated.snd";
|
|
|
|
const int INVALID_QUEST = 0;
|
|
|
|
const int PERFORM_ANY = 0;
|
|
const int PERFORM_DANCE = 1;
|
|
const int PERFORM_MUSIC = 2;
|
|
const int PERFORM_JUGGLE = 3;
|
|
|
|
const String PERFORM_TYPE = "performType";
|
|
|
|
const String QUEST_EXPERIENCE_TABLE = "datatables/quest/quest_experience.iff";
|
|
|
|
// variable name qualifiers
|
|
const String BASE_NAME = "quest.";
|
|
const String QUEST_CRC = BASE_NAME + "questCrc";
|
|
const String QUEST_NAME = BASE_NAME + "questName";
|
|
const String TASK_ID = BASE_NAME + "taskId";
|
|
const String TASK_NAME = BASE_NAME + "taskName";
|
|
|
|
const String dataTableColumnExperienceType = "EXPERIENCE_TYPE";
|
|
const String dataTableColumnExperienceAmount = "EXPERIENCE_AMOUNT";
|
|
const String dataTableColumnFactionName = "FACTION_NAME";
|
|
const String dataTableColumnFactionAmount = "FACTION_AMOUNT";
|
|
const String dataTableColumnGcwGrant = "GRANT_GCW";
|
|
const String dataTableColumnGcwOverwriteAmt = "QUEST_GCW_REWARD_OVERWRITE_AMOUNT";
|
|
const String dataTableColumnGcwOvrwrtSFMod = "QUEST_GCW_REWARD_OVERWRITE_SF_MODIFIER";
|
|
const String dataTableColumnGcwRebReward = "QUEST_GCW_REBEL_REWARD_LOOT_NAME";
|
|
const String dataTableColumnGcwRebRewardCnt = "QUEST_REWARD_REBEL_LOOT_COUNT";
|
|
const String dataTableColumnGcwImpReward = "QUEST_GCW_IMPERIAL_REWARD_LOOT_NAME";
|
|
const String dataTableColumnGcwImpRewardCnt = "QUEST_REWARD_IMPERIAL_LOOT_COUNT";
|
|
const String dataTableColumnGcwRewardMultip = "QUEST_GCW_REWARD_COUNT_SF_MULTIPLIER";
|
|
const String dataTableColumnBankCredits = "BANK_CREDITS";
|
|
const String dataTableColumnItem = "ITEM";
|
|
const String dataTableColumnCount = "COUNT";
|
|
const String dataTableColumnWeapon = "WEAPON";
|
|
const String dataTableColumnCountWeapon = "COUNT_WEAPON";
|
|
const String dataTableColumnSpeed = "SPEED";
|
|
const String dataTableColumnDamage = "DAMAGE";
|
|
const String dataTableColumnEfficiency = "EFFICIENCY";
|
|
const String dataTableColumnElementalValue = "ELEMENTAL_VALUE";
|
|
const String dataTableColumnArmor = "ARMOR";
|
|
const String dataTableColumnCountArmor = "COUNT_ARMOR";
|
|
const String dataTableColumnQuality = "QUALITY";
|
|
const String dataTableColumnLootName = "LOOT_NAME";
|
|
const String dataTableColumnLootCount = "LOOT_COUNT";
|
|
const String dataTableColumnLevel = "LEVEL";
|
|
const String dataTableColumnTier = "TIER";
|
|
|
|
const String dataTableColumnQuestRewardExperienceTeir1 = "TIER_1_EXPERIENCE";
|
|
const String dataTableColumnQuestRewardExperienceTeir2 = "TIER_2_EXPERIENCE";
|
|
const String dataTableColumnQuestRewardExperienceTeir3 = "TIER_3_EXPERIENCE";
|
|
const String dataTableColumnQuestRewardExperienceTeir4 = "TIER_4_EXPERIENCE";
|
|
const String dataTableColumnQuestRewardExperienceTeir5 = "TIER_5_EXPERIENCE";
|
|
const String dataTableColumnQuestRewardExperienceTeir6 = "TIER_6_EXPERIENCE";
|
|
const String dataTableColumnQuestRewardExperienceType = "QUEST_REWARD_EXPERIENCE_TYPE";
|
|
const String dataTableColumnQuestRewardExperienceAmount = "QUEST_REWARD_EXPERIENCE_AMOUNT";
|
|
const String dataTableColumnQuestRewardFactionName = "QUEST_REWARD_FACTION_NAME";
|
|
const String dataTableColumnQuestRewardFactionAmount = "QUEST_REWARD_FACTION_AMOUNT";
|
|
const String dataTableColumnQuestRewardBankCredits = "QUEST_REWARD_BANK_CREDITS";
|
|
const String dataTableColumnQuestRewardItem = "QUEST_REWARD_ITEM";
|
|
const String dataTableColumnQuestRewardCount = "QUEST_REWARD_COUNT";
|
|
const String dataTableColumnQuestRewardWeapon = "QUEST_REWARD_WEAPON";
|
|
const String dataTableColumnQuestRewardCountWeapon = "QUEST_REWARD_COUNT_WEAPON";
|
|
const String dataTableColumnQuestRewardSpeed = "QUEST_REWARD_SPEED";
|
|
const String dataTableColumnQuestRewardDamage = "QUEST_REWARD_DAMAGE";
|
|
const String dataTableColumnQuestRewardEfficiency = "QUEST_REWARD_EFFICIENCY";
|
|
const String dataTableColumnQuestRewardElementalValue = "QUEST_REWARD_ELEMENTAL_VALUE";
|
|
const String dataTableColumnQuestRewardArmor = "QUEST_REWARD_ARMOR";
|
|
const String dataTableColumnQuestRewardCountArmor = "QUEST_REWARD_COUNT_ARMOR";
|
|
const String dataTableColumnQuestRewardQuality = "QUEST_REWARD_QUALITY";
|
|
const String dataTableColumnQuestRewardLootName = "QUEST_REWARD_LOOT_NAME";
|
|
const String dataTableColumnQuestRewardLootCount = "QUEST_REWARD_LOOT_COUNT";
|
|
const String dataTableColumnQuestRewardLootName2 = "QUEST_REWARD_LOOT_NAME_2";
|
|
const String dataTableColumnQuestRewardLootCount2 = "QUEST_REWARD_LOOT_COUNT_2";
|
|
const String dataTableColumnQuestRewardLootName3 = "QUEST_REWARD_LOOT_NAME_3";
|
|
const String dataTableColumnQuestRewardLootCount3 = "QUEST_REWARD_LOOT_COUNT_3";
|
|
const String dataTableColumnQuestRewardExclusiveLootName = "QUEST_REWARD_EXCLUSIVE_LOOT_NAME";
|
|
const String dataTableColumnQuestRewardExclusiveLootCount = "QUEST_REWARD_EXCLUSIVE_LOOT_COUNT";
|
|
const String dataTableColumnQuestRewardExclusiveLootName2 = "QUEST_REWARD_EXCLUSIVE_LOOT_NAME_2";
|
|
const String dataTableColumnQuestRewardExclusiveLootCount2 = "QUEST_REWARD_EXCLUSIVE_LOOT_COUNT_2";
|
|
const String dataTableColumnQuestRewardExclusiveLootName3 = "QUEST_REWARD_EXCLUSIVE_LOOT_NAME_3";
|
|
const String dataTableColumnQuestRewardExclusiveLootCount3 = "QUEST_REWARD_EXCLUSIVE_LOOT_COUNT_3";
|
|
const String dataTableColumnQuestRewardExclusiveLootName4 = "QUEST_REWARD_EXCLUSIVE_LOOT_NAME_4";
|
|
const String dataTableColumnQuestRewardExclusiveLootCount4 = "QUEST_REWARD_EXCLUSIVE_LOOT_COUNT_4";
|
|
const String dataTableColumnQuestRewardExclusiveLootName5 = "QUEST_REWARD_EXCLUSIVE_LOOT_NAME_5";
|
|
const String dataTableColumnQuestRewardExclusiveLootCount5 = "QUEST_REWARD_EXCLUSIVE_LOOT_COUNT_5";
|
|
const String dataTableColumnQuestRewardExclusiveLootName6 = "QUEST_REWARD_EXCLUSIVE_LOOT_NAME_6";
|
|
const String dataTableColumnQuestRewardExclusiveLootCount6 = "QUEST_REWARD_EXCLUSIVE_LOOT_COUNT_6";
|
|
const String dataTableColumnQuestRewardExclusiveLootName7 = "QUEST_REWARD_EXCLUSIVE_LOOT_NAME_7";
|
|
const String dataTableColumnQuestRewardExclusiveLootCount7 = "QUEST_REWARD_EXCLUSIVE_LOOT_COUNT_7";
|
|
const String dataTableColumnQuestRewardExclusiveLootName8 = "QUEST_REWARD_EXCLUSIVE_LOOT_NAME_8";
|
|
const String dataTableColumnQuestRewardExclusiveLootCount8 = "QUEST_REWARD_EXCLUSIVE_LOOT_COUNT_8";
|
|
const String dataTableColumnQuestRewardExclusiveLootName9 = "QUEST_REWARD_EXCLUSIVE_LOOT_NAME_9";
|
|
const String dataTableColumnQuestRewardExclusiveLootCount9 = "QUEST_REWARD_EXCLUSIVE_LOOT_COUNT_9";
|
|
const String dataTableColumnQuestRewardExclusiveLootName10 = "QUEST_REWARD_EXCLUSIVE_LOOT_NAME_10";
|
|
const String dataTableColumnQuestRewardExclusiveLootCount10 = "QUEST_REWARD_EXCLUSIVE_LOOT_COUNT_10";
|
|
|
|
const String dataTableColumnQuestPenaltyFactionName = "QUEST_PENALTY_FACTION_NAME";
|
|
const String dataTableColumnQuestPenaltyFactionAmount = "QUEST_PENALTY_FACTION_AMOUNT";
|
|
|
|
const String dataTableColumnConditionQuestGrantQuest = "CONDITIONAL_QUEST_GRANT_QUEST";
|
|
const String dataTableColumnConditionQuestGrantListOfCompletedQuests = "CONDITIONAL_QUEST_GRANT_QUEST_LIST_OF_COMPLETED_QUESTS";
|
|
const String dataTableColumnBadge = "REWARD_BADGE";
|
|
|
|
const String dataTableColumnGuaranteedSuccessMin = "GUARANTEED_SUCCESS_MIN";
|
|
const String dataTableColumnGuaranteedSuccessMax = "GUARANTEED_SUCCESS_MAX";
|
|
|
|
const String dataTableColumnRemainingTime = "REMAINING_TIME";
|
|
|
|
//---------------------------------------------------------------------
|
|
// Quest Waypoints
|
|
|
|
const String dataTableColumnCreateWaypoint = "CREATE_WAYPOINT";
|
|
const String dataTableColumnPlanetName = "PLANET_NAME";
|
|
const String dataTableColumnLocationX = "LOCATION_X";
|
|
const String dataTableColumnLocationY = "LOCATION_Y";
|
|
const String dataTableColumnLocationZ = "LOCATION_Z";
|
|
const String dataTableColumnWaypointName = "WAYPOINT_NAME";
|
|
const String dataTableColumnInteriorWaypointAppearance = "INTERIOR_WAYPOINT_APPEARANCE";
|
|
const String dataTableColumnWaypointBuildingCellName = "WAYPOINT_BUILDING_CELL_NAME";
|
|
const String dataTableColumnEntranceCreateWaypoint = "CREATE_ENTRANCE_WAYPOINT";
|
|
const String dataTableColumnEntranceLocationX = "ENTRANCE_LOCATION_X";
|
|
const String dataTableColumnEntranceLocationY = "ENTRANCE_LOCATION_Y";
|
|
const String dataTableColumnEntranceLocationZ = "ENTRANCE_LOCATION_Z";
|
|
const String dataTableColumnEntranceWaypointName = "ENTRANCE_WAYPOINT_NAME";
|
|
const String taskType = "base_task";
|
|
const String objvarWaypoint = "waypoint";
|
|
const String objvarEntranceWaypoint = "entranceWaypoint";
|
|
const String objvarWaypointInActive = "waypointInactive";
|
|
const String timeObjVar = "playedTimeEnd";
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
String getStringDataEntry(String datatableName, int questId, int taskId, String columnName)
|
|
{
|
|
String result = null;
|
|
String questName = questGetQuestName(questId);
|
|
if ( questName == null || questName == "" )
|
|
{
|
|
string errText = "QUEST NAME IS NULL: datatableName: " + datatableName +
|
|
" - questId:" + questId +
|
|
" - taskId: " + taskId +
|
|
" - columnName: " + columnName;
|
|
|
|
logScriptDataError(errText);
|
|
}
|
|
else
|
|
{
|
|
String datatable = "datatables/" + datatableName + "/" + questName + ".iff";
|
|
if(isValidTaskId(taskId))
|
|
{
|
|
if(dataTableHasColumn(datatable, columnName))
|
|
result = dataTableGetString(datatable, taskId, columnName);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
int getIntDataEntry(String datatableName, int questId, int taskId, String columnName)
|
|
{
|
|
int result = -1;
|
|
String questName = questGetQuestName(questId);
|
|
String datatable = "datatables/" + datatableName + "/" + questName + ".iff";
|
|
if(isValidTaskId(taskId))
|
|
{
|
|
if(dataTableHasColumn(datatable, columnName))
|
|
result = dataTableGetInt(datatable, taskId, columnName);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
float getFloatDataEntry(String datatableName, int questId, int taskId, String columnName)
|
|
{
|
|
float result = 0.0f;
|
|
String questName = questGetQuestName(questId);
|
|
String datatable = "datatables/" + datatableName + "/" + questName + ".iff";
|
|
if(isValidTaskId(taskId))
|
|
{
|
|
if(dataTableHasColumn(datatable, columnName))
|
|
result = dataTableGetFloat(datatable, taskId, columnName);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
boolean getBoolDataEntry(String datatableName, int questId, int taskId, String columnName, boolean defaultValue)
|
|
{
|
|
int result = -1;
|
|
String questName = questGetQuestName(questId);
|
|
String datatable = "datatables/" + datatableName + "/" + questName + ".iff";
|
|
if(isValidTaskId(taskId))
|
|
{
|
|
if(dataTableHasColumn(datatable, columnName))
|
|
result = dataTableGetInt(datatable, taskId, columnName);
|
|
}
|
|
|
|
//-- if no column found, return default
|
|
if (result == -1)
|
|
return defaultValue;
|
|
|
|
return result != 0;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
String setBaseObjVar(obj_id player, String taskType, String questName, int taskId)
|
|
{
|
|
String objvar = questBaseObjVar + dot + taskType + dot + questName + dot + taskId;
|
|
setObjVar(player, objvar + dot + "inProgress", "true");
|
|
return objvar;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void clearBaseObjVar(obj_id player, String taskType, String questName, int taskId)
|
|
{
|
|
String objvarTask = questBaseObjVar + dot + taskType + dot + questName + dot + taskId;
|
|
removeObjVar(player, objvarTask);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
String getBaseObjVar(obj_id player, String taskType, String questName, int taskId)
|
|
{
|
|
return questBaseObjVar + dot + taskType + dot + questName + dot + taskId;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
String getTaskTypeObjVar(obj_id player, String taskType)
|
|
{
|
|
String objvar = questBaseObjVar + dot + taskType;
|
|
if(hasObjVar(player, objvar))
|
|
return objvar;
|
|
else
|
|
return null;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
String getTaskTypeObjVar(String taskType)
|
|
{
|
|
return questBaseObjVar + dot + taskType;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void questOutputDebugInfo(obj_id player, int questCrc, int taskId, String taskType, String method, String message)
|
|
{
|
|
if(isGod(player) && questGetDebugging())
|
|
debugSpeakMsg (player, "Quest: player[" + player + "], " + taskType + dot + method + ", " + questGetQuestName(questCrc) + ":task" + taskId + " - " + message);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void questOutputDebugInfo(obj_id player, String questName, int taskId, String taskType, String method, String message)
|
|
{
|
|
questOutputDebugInfo(player, questGetQuestId(questName), taskId, taskType, method, message);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void questOutputDebugInfo(obj_id player, String taskType, String method, String message)
|
|
{
|
|
if(isGod(player) && questGetDebugging())
|
|
debugSpeakMsg (player, "Quest: player[" + player + "], " + taskType + dot + method + " - " + message);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void questOutputDebugLog(String taskType, String method, String message)
|
|
{
|
|
if(questGetDebugging())
|
|
LOG("QUEST_DEBUG", taskType + dot + method + " - " + message);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void addDestroyNotification(obj_id target, obj_id player)
|
|
{
|
|
attachScript(target, "quest.utility.destroy_notification");
|
|
dictionary params = new dictionary();
|
|
params.put("target", player);
|
|
params.put("parameter", "");
|
|
messageTo(target, "addNotification", params, 0.0f, false);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void failAllActiveTasksOfType(obj_id player, String taskType)
|
|
{
|
|
dictionary tasks = getActiveTasksForTaskType(player, taskType);
|
|
if ((tasks != null) && !tasks.isEmpty())
|
|
{
|
|
java.util.Enumeration keys = tasks.keys();
|
|
while (keys.hasMoreElements())
|
|
{
|
|
String questCrcString = (string)keys.nextElement();
|
|
int questCrc = utils.stringToInt(questCrcString);
|
|
int[] tasksForCurrentQuest = tasks.getIntArray(questCrcString);
|
|
|
|
for(int i = 0; i < tasksForCurrentQuest.length; ++i)
|
|
{
|
|
int taskId = tasksForCurrentQuest[i];
|
|
|
|
//fail the task
|
|
if(isValidTaskId(taskId))
|
|
questFailTask(questCrc, taskId, player);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
String getTaskStringDataEntry(int questId, int taskId, String columnName)
|
|
{
|
|
return getStringDataEntry("questtask", questId, taskId, columnName);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
int getTaskIntDataEntry(int questId, int taskId, String columnName)
|
|
{
|
|
return getIntDataEntry("questtask", questId, taskId, columnName);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
float getTaskFloatDataEntry(int questId, int taskId, String columnName)
|
|
{
|
|
return getFloatDataEntry("questtask", questId, taskId, columnName);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
boolean getTaskBoolDataEntry(int questId, int taskId, String columnName, boolean defaultValue)
|
|
{
|
|
return getBoolDataEntry("questtask", questId, taskId, columnName, defaultValue);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
String getQuestStringDataEntry(int questId, String columnName)
|
|
{
|
|
return getStringDataEntry("questlist", questId, 0, columnName);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
int getQuestIntDataEntry(int questId, String columnName)
|
|
{
|
|
return getIntDataEntry("questlist", questId, 0, columnName);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
float getQuestFloatDataEntry(int questId, String columnName)
|
|
{
|
|
return getFloatDataEntry("questlist", questId, 0, columnName);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
boolean getQuestBoolDataEntry(int questId, String columnName, boolean defaultValue)
|
|
{
|
|
return getBoolDataEntry("questlist", questId, 0, columnName, defaultValue);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
boolean getShowSystemMessages(int questCrc, int taskId)
|
|
{
|
|
return getTaskIntDataEntry(questCrc, taskId, datatableColumnShowSystemMessages) > 0;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void sendGroundQuestSystemMessage(string_id message, int questCrc, int taskId, obj_id player)
|
|
{
|
|
string taskTitle = getTaskStringDataEntry(questCrc, taskId, datatableColumnjournalEntryTitle);
|
|
|
|
prose_package pp = prose.getPackage(message);
|
|
prose.setTO(pp, taskTitle);
|
|
sendQuestSystemMessage(player, pp);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void sendTaskCompletedSystemMessage(int questCrc, int taskId, obj_id player)
|
|
{
|
|
if (getShowSystemMessages(questCrc, taskId))
|
|
{
|
|
sendGroundQuestSystemMessage(SID_TASK_COMPLETED, questCrc, taskId, player);
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void sendTaskFailedSystemMessage(int questCrc, int taskId, obj_id player)
|
|
{
|
|
if (getShowSystemMessages(questCrc, taskId))
|
|
{
|
|
sendGroundQuestSystemMessage(SID_TASK_FAILED, questCrc, taskId, player);
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void requestGrantQuest(obj_id player, string questName)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
requestGrantQuest(questNum, player, player, true);
|
|
}
|
|
|
|
void requestGrantQuest(obj_id[] players, string questName)
|
|
{
|
|
if (players == null || players.length == 0)
|
|
return;
|
|
|
|
for (int i=0;i<players.length;i++)
|
|
{
|
|
if (!isIdValid(players[i]) || !exists(players[i]))
|
|
continue;
|
|
|
|
requestGrantQuest(players[i], questName);
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void requestGrantQuest(int questCrc, obj_id player, obj_id npc)
|
|
{
|
|
requestGrantQuest(questCrc, player, npc, false);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void requestGrantQuest(obj_id player, string questName, boolean showMessage)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
requestGrantQuest(questNum, player, player, showMessage);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void requestGrantQuest(int questCrc, obj_id player, obj_id npc, boolean showSystemMessage)
|
|
{
|
|
if(utils.isProfession(player, utils.TRADER) || utils.isProfession(player, utils.ENTERTAINER))
|
|
{
|
|
doTraderEntertainerXpWarning(questCrc, player);
|
|
}
|
|
requestActivateQuest(questCrc, player, npc);
|
|
return;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
/**
|
|
Deprecated, use requestGrantQuest instead
|
|
*/
|
|
int grantQuest(obj_id player, string questName)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
requestGrantQuest(questNum, player, player, true);
|
|
return 1;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
/**
|
|
Deprecated, use requestGrantQuest instead
|
|
*/
|
|
int grantQuest(int questCrc, obj_id player, obj_id npc)
|
|
{
|
|
requestGrantQuest(questCrc, player, npc, false);
|
|
return 1;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
/**
|
|
Deprecated, use requestGrantQuest instead
|
|
*/
|
|
int grantQuest(obj_id player, string questName, boolean showMessage)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
requestGrantQuest(questNum, player, player, showMessage);
|
|
return 1;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
/**
|
|
Deprecated, use requestGrantQuest instead
|
|
*/
|
|
int grantQuest(int questCrc, obj_id player, obj_id npc, boolean showSystemMessage)
|
|
{
|
|
if(utils.isProfession(player, utils.TRADER) || utils.isProfession(player, utils.ENTERTAINER))
|
|
{
|
|
doTraderEntertainerXpWarning(questCrc, player);
|
|
}
|
|
requestActivateQuest(questCrc, player, npc);
|
|
return 1;
|
|
}
|
|
|
|
|
|
void doTraderEntertainerXpWarning(int questCrc, obj_id player)
|
|
{
|
|
string xpType = "";
|
|
int xpAmount = -1;
|
|
|
|
xpType = getQuestStringDataEntry (questCrc, dataTableColumnQuestRewardExperienceType);
|
|
xpAmount = getQuestIntDataEntry (questCrc, dataTableColumnQuestRewardExperienceAmount);
|
|
|
|
if( xpType != null && !xpType.equals("") && xp.isCombatXpType(xpType) && xpAmount > 0 )
|
|
{
|
|
sendSystemMessage(player, SID_NO_XP_TRADER_ENTERTAINER);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
/**
|
|
THIS IS FOR INTERNAL QUEST SYSTEM USE ONLY!!! If you need to push a quest on a player, enter the quest name into
|
|
datatables/quest/force_accept_quests.tab
|
|
*/
|
|
int grantQuestNoAcceptUI(obj_id player, string questName, boolean showSystemMessage)
|
|
{
|
|
int questCrc = getQuestIdFromString(questName);
|
|
return questActivateQuest(questCrc, player, player);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
boolean isInNamedRegion(obj_id player, String requiredRegion)
|
|
{
|
|
if(requiredRegion == null || requiredRegion.length() == 0)
|
|
return true;
|
|
|
|
location here = getLocation (player);
|
|
region[] regions = getRegionsAtPoint(here);
|
|
if(regions != null)
|
|
{
|
|
for(int k = 0; k < regions.length; k++)
|
|
{
|
|
string regionWeAreIn = regions[k].getName();
|
|
|
|
if(regionWeAreIn.equals(requiredRegion))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
// ---------------------------------------------------------------------
|
|
|
|
/*** This function is used to emit a message to be caught by an active "Wait For Signal" task.*/
|
|
void sendSignal(obj_id player, String signalName)
|
|
{
|
|
dictionary params = new dictionary();
|
|
params.put("signal", signalName);
|
|
messageTo(player, "questSignal", params, 0, false);
|
|
}
|
|
|
|
void sendSignal(obj_id[] players, string signalName)
|
|
{
|
|
if (players == null || players.length == 0)
|
|
return;
|
|
|
|
for (int i=0;i<players.length;i++)
|
|
{
|
|
if (isIdValid(players[i]) && exists(players[i]))
|
|
{
|
|
sendSignal(players[i], signalName);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sendSignals(obj_id player, string[] signalNames)
|
|
{
|
|
if (signalNames == null || signalNames.length == 0 || !isIdValid(player))
|
|
return;
|
|
|
|
for (int i=0; i < signalNames.length; ++i)
|
|
{
|
|
if (signalNames[i] != null && signalNames[i].length() > 0)
|
|
{
|
|
sendSignal(player, signalNames[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
boolean isQuestDisabled (string questName)
|
|
{
|
|
if (questName.startsWith("quest/"))
|
|
{
|
|
questName = questName.substring(6);
|
|
}
|
|
|
|
int disabled = dataTableSearchColumnForString(questName, DISABLED_QUEST_COLUMN, DISABLED_QUEST_TABLE);
|
|
|
|
if (disabled >= 0)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int getQuestIdFromString(string questName)
|
|
{
|
|
|
|
if (questName.startsWith("quest/"))
|
|
return questGetQuestId(questName);
|
|
else
|
|
{
|
|
string fullPathQuestName = "quest/" + questName;
|
|
return questGetQuestId(fullPathQuestName);
|
|
}
|
|
}
|
|
|
|
|
|
boolean hasCompletedQuest(obj_id player, string questName)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
return questIsQuestComplete(questNum, player);
|
|
}
|
|
|
|
int canActivateQuest(obj_id player, string questName)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
return questCanActivateQuest(questNum, player);
|
|
}
|
|
|
|
void completeQuest(obj_id player, string questName)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
requestCompleteQuest(questNum, player);
|
|
}
|
|
|
|
void clearQuest(obj_id player, string questName)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
questClearQuest(questNum, player);
|
|
}
|
|
|
|
void clearQuest(obj_id[] players, string questName)
|
|
{
|
|
if ( players == null || players.length == 0 )
|
|
return;
|
|
|
|
for ( int i=0;i<players.length;i++ )
|
|
{
|
|
if ( !isIdValid(players[i]) || !exists(players[i]) )
|
|
continue;
|
|
|
|
if ( isQuestActiveOrComplete(players[i], questName) )
|
|
clearQuest(players[i], questName);
|
|
}
|
|
}
|
|
|
|
boolean isQuestActive(obj_id player, string questName)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
return questIsQuestActive(questNum, player);
|
|
}
|
|
|
|
boolean isQuestActiveOrComplete(obj_id player, string questName)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
return questIsQuestActive(questNum, player) || questIsQuestComplete(questNum, player);
|
|
}
|
|
|
|
boolean hasCompletedTask(obj_id player, string questName, int taskNum)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
return questIsTaskComplete(questNum, taskNum, player);
|
|
}
|
|
|
|
boolean isTaskActive(obj_id player, string questName, int taskNum)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
return questIsTaskActive(questNum, taskNum, player);
|
|
}
|
|
|
|
void activateTask(obj_id player, string questName, int taskNum)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
if(isValidQuestName(questName) && isValidTaskId(taskNum))
|
|
questActivateTask(questNum, taskNum, player);
|
|
}
|
|
|
|
void completeTask(obj_id player, string questName, int taskNum)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
if(isValidQuestName(questName) && isValidTaskId(taskNum))
|
|
questCompleteTask(questNum, taskNum, player);
|
|
}
|
|
|
|
void failTask(obj_id player, string questName, int taskNum)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
if(isValidQuestName(questName) && isValidTaskId(taskNum))
|
|
questFailTask(questNum, taskNum, player);
|
|
}
|
|
|
|
void clearTask(obj_id player, string questName, int taskNum)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
if(isValidQuestName(questName) && isValidTaskId(taskNum))
|
|
questClearQuestTask(questNum, taskNum, player);
|
|
}
|
|
//-------------------------------------
|
|
boolean hasCompletedTask(obj_id player, string questName, string taskName)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
int taskNum = getTaskId(questNum, taskName);
|
|
return questIsTaskComplete(questNum, taskNum, player);
|
|
}
|
|
|
|
boolean isTaskActive(obj_id player, string questName, string taskName)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
int taskNum = getTaskId(questNum, taskName);
|
|
return questIsTaskActive(questNum, taskNum, player);
|
|
}
|
|
|
|
void activateTask(obj_id player, string questName, string taskName)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
int taskNum = getTaskId(questNum, taskName);
|
|
if(isValidQuestName(questName) && isValidTaskId(taskNum))
|
|
questActivateTask(questNum, taskNum, player);
|
|
}
|
|
|
|
void completeTask(obj_id player, string questName, string taskName)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
int taskNum = getTaskId(questNum, taskName);
|
|
if(isValidQuestName(questName) && isValidTaskId(taskNum))
|
|
questCompleteTask(questNum, taskNum, player);
|
|
}
|
|
|
|
void failTask(obj_id player, string questName, string taskName)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
int taskNum = getTaskId(questNum, taskName);
|
|
if(isValidQuestName(questName) && isValidTaskId(taskNum))
|
|
questFailTask(questNum, taskNum, player);
|
|
}
|
|
|
|
void clearTask(obj_id player, string questName, string taskName)
|
|
{
|
|
int questNum = getQuestIdFromString(questName);
|
|
int taskNum = getTaskId(questNum, taskName);
|
|
if(isValidQuestName(questName) && isValidTaskId(taskNum))
|
|
questClearQuestTask(questNum, taskNum, player);
|
|
}
|
|
|
|
|
|
//-------------------------------------
|
|
|
|
int getTaskId(int questCrc, String taskName)
|
|
{
|
|
for(int i = 0; i < maxTasksPerQuest; ++i)
|
|
{
|
|
String name = getTaskStringDataEntry(questCrc, i, dataTableColumnTaskName);
|
|
if((name != null) && (name == taskName))
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
boolean isValidQuestName(String questName)
|
|
{
|
|
return getQuestIdFromString(questName) != INVALID_QUEST;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
dictionary getActiveTasksForTaskType(obj_id player, String taskType)
|
|
{
|
|
dictionary dict = new dictionary();
|
|
resizeable int[] tasks = new Vector(0);
|
|
|
|
//get the base objvar for the quest type, all data is under that
|
|
String taskObjVarName = getTaskTypeObjVar(player, taskType);
|
|
if(taskObjVarName != null)
|
|
{
|
|
//get the list of all active quests on the player
|
|
obj_var_list questList = getObjVarList(player, taskObjVarName);
|
|
if(questList != null)
|
|
{
|
|
int countQuests = questList.getNumItems();
|
|
for (int i = 0; i < countQuests; ++i)
|
|
{
|
|
obj_var ov = questList.getObjVar(i);
|
|
string questName = ov.getName();
|
|
int questCrc = questGetQuestId(questName);
|
|
|
|
String questObjVarName = taskObjVarName + dot + questName;
|
|
if(hasObjVar(player, questObjVarName))
|
|
{
|
|
//get the list of tasks for this quest that are of the appropriate type
|
|
obj_var_list taskList = getObjVarList(player, questObjVarName);
|
|
if(taskList != null)
|
|
{
|
|
tasks.clear();
|
|
|
|
int countTasks = taskList.getNumItems();
|
|
for (int j = 0; j < countTasks; ++j)
|
|
{
|
|
obj_var ov2 = taskList.getObjVar(j);
|
|
string taskName = ov2.getName();
|
|
int taskId = utils.stringToInt(taskName);
|
|
|
|
utils.addElement(tasks, taskId);
|
|
}
|
|
dict.put(Integer.toString(questCrc), tasks);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return dict;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
/** Given a player and two radaii, choose a new location in a ring around the player
|
|
that is on the terrain, or in the player's cell if in an interior. If the player
|
|
is in an interior, it will ensure that the location is a valid point in the cell.
|
|
It will test up to 4 points in an interior, before giving up and returning the
|
|
player's location.
|
|
*/
|
|
location getRandom2DLocationAroundPlayer(obj_id player, float minimumDistance, float maximumDistance)
|
|
{
|
|
location playerLocation = getLocation(player);
|
|
return getRandom2DLocationAroundLocation(player, 0, 0, minimumDistance, maximumDistance);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
location getRandom2DLocationAroundLocation(obj_id player, float relativeOffsetX, float relativeOffsetZ, float minimumDistance, float maximumDistance)
|
|
{
|
|
boolean onAFloor = isOnAFloor(player);
|
|
location playerLocation = getLocation(player);
|
|
boolean inACell = (playerLocation.cell != null) && (playerLocation.cell != obj_id.NULL_ID);
|
|
|
|
location newLocation = new location(playerLocation);
|
|
newLocation.x += relativeOffsetX;
|
|
newLocation.z += relativeOffsetZ;
|
|
|
|
//start off with the player location, including cell if there is one
|
|
newLocation = utils.getRandomLocationInRing(newLocation, minimumDistance, maximumDistance);
|
|
|
|
//make sure the point in the cell is valid
|
|
if(!isValidQuestSpawnPoint(player, newLocation, onAFloor, inACell))
|
|
{
|
|
float xDelta = (playerLocation.x - newLocation.x) * 2;
|
|
float zDelta = (playerLocation.z - newLocation.z) * 2;
|
|
|
|
//flip the x around the player, try again
|
|
if(newLocation.x < playerLocation.x)
|
|
newLocation.x += xDelta;
|
|
else
|
|
newLocation.x -= xDelta;
|
|
|
|
if(!isValidQuestSpawnPoint(player, newLocation, onAFloor, inACell))
|
|
{
|
|
//flip the z around the player, try once again
|
|
if(newLocation.z < playerLocation.z)
|
|
newLocation.z += zDelta;
|
|
else
|
|
newLocation.z -= zDelta;
|
|
|
|
if(!isValidQuestSpawnPoint(player, newLocation, onAFloor, inACell))
|
|
{
|
|
//put the x back (with the z still flipped), try one last time
|
|
if(newLocation.x < playerLocation.x)
|
|
newLocation.x += xDelta;
|
|
else
|
|
newLocation.x -= xDelta;
|
|
|
|
if(!isValidQuestSpawnPoint(player, newLocation, onAFloor, inACell))
|
|
{
|
|
//absolute failure to find a good point, use the original location
|
|
newLocation = (location)playerLocation.clone();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(onAFloor)
|
|
{
|
|
newLocation.y = getFloorHeightAtRelativePointOnSameFloorAsObject(player, newLocation.x - playerLocation.x, newLocation.z - playerLocation.z);
|
|
}
|
|
else
|
|
{
|
|
//check against terrain height
|
|
newLocation.y = getHeightAtLocation(newLocation.x, newLocation.z);
|
|
}
|
|
|
|
return newLocation;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
boolean isValidQuestSpawnPoint(obj_id player, location newLocation, boolean onAFloor, boolean inACell)
|
|
{
|
|
boolean validPoint = true;
|
|
location playerLocation = getLocation(player);
|
|
if(validPoint)
|
|
{
|
|
validPoint = !getCollidesWithObject(newLocation, 1.0f);
|
|
}
|
|
|
|
if(validPoint && onAFloor)
|
|
{
|
|
validPoint = isRelativePointOnSameFloorAsObject(player, newLocation.x - playerLocation.x, newLocation.z - playerLocation.z);
|
|
}
|
|
|
|
if(validPoint && inACell)
|
|
{
|
|
validPoint = isValidInteriorLocation(newLocation);
|
|
}
|
|
|
|
return validPoint;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
/** Given a location and two radaii, choose a new location in a ring around the players
|
|
that is on the terrain.
|
|
*/
|
|
location getRandom2DLocationInRing(location startLocation, float minimumRadius, float maximumRadius)
|
|
{
|
|
location newLocation = (location)startLocation.clone();
|
|
float deltaX = rand(minimumRadius, maximumRadius);
|
|
if(rand(1,2) == 2)
|
|
deltaX = -deltaX;
|
|
float deltaZ = rand(minimumRadius, maximumRadius);
|
|
if(rand(1,2) == 2)
|
|
deltaZ = -deltaZ;
|
|
newLocation.x += deltaX;
|
|
newLocation.z += deltaZ;
|
|
newLocation.y = getHeightAtLocation(newLocation.x, newLocation.z);
|
|
return newLocation;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
|
|
/** Set the target that a player will use for the next static_escort task that is activated.
|
|
* Use this in convos before BEFORE activating the static_escort task.
|
|
*/
|
|
void setPendingStaticEscortTarget(obj_id player, obj_id newEscortTarget)
|
|
{
|
|
setObjVar(player, questBaseObjVar + dot + questAllObjVar + dot + questStaticEscortTargetObjVar, newEscortTarget);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
/** See if the escort target is ready to be escorted.
|
|
* Use this function to make convos respond appropriately, i.e. "Sorry, I'm busy right now."
|
|
*/
|
|
boolean isEscortTargetReadyForStaticEscortTask(obj_id escortTarget)
|
|
{
|
|
//the target is busy if on an escort task already, or if going back home
|
|
if(hasObjVar(escortTarget, objvarOnEscort) || hasObjVar(escortTarget, objvarGoingHome))
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
/** Used by the quest system to get the escort target for a player when starting the task
|
|
*/
|
|
obj_id getPendingStaticEscortTarget(obj_id player)
|
|
{
|
|
return getObjIdObjVar(player, questBaseObjVar + dot + questAllObjVar + dot + questStaticEscortTargetObjVar);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
/** Remove the pending escort target objvar from the player
|
|
*/
|
|
void clearPendingStaticEscortTarget(obj_id player)
|
|
{
|
|
removeObjVar(player, questBaseObjVar + dot + questAllObjVar + dot + questStaticEscortTargetObjVar);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
/** See if a given task is visible
|
|
*/
|
|
boolean isTaskVisible(int questCrc, int taskId)
|
|
{
|
|
return groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnVisible) != 0;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
boolean isQuestVisible(int questCrc)
|
|
{
|
|
return getQuestBoolDataEntry(questCrc, dataTableColumnQuestVisible, true);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void playJournalUpdatedMusic(int questCrc, int taskId, obj_id player)
|
|
{
|
|
//only tell player things if task is visible
|
|
if(groundquests.isTaskVisible(questCrc, taskId))
|
|
{
|
|
play2dNonLoopingSound(player, JOURNAL_UPDATED_MUSIC);
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
/** Valid range is [0,maxTasksPerQuest)
|
|
*/
|
|
boolean isValidTaskId(int taskId)
|
|
{
|
|
return (taskId >= 0) && (taskId < maxTasksPerQuest);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void questStartPerforming(obj_id player, int performType)
|
|
{
|
|
dictionary params = new dictionary();
|
|
params.put(PERFORM_TYPE, performType);
|
|
messageTo(player, "startPerform", params, 1, false);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void questStopPerforming(obj_id player)
|
|
{
|
|
messageTo(player, "stopPerform", null, 1, false);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void questStartDance(obj_id player)
|
|
{
|
|
questStartPerforming(player, PERFORM_DANCE);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void questStartMusic(obj_id player)
|
|
{
|
|
questStartPerforming(player, PERFORM_MUSIC);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void questStartJuggle(obj_id player)
|
|
{
|
|
questStartPerforming(player, PERFORM_JUGGLE);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void sendPlacedMoreThanOneInInventorySystemMessage(obj_id player, obj_id objectPlaced, int count)
|
|
{
|
|
if(isValidId(objectPlaced))
|
|
{
|
|
string_id name = getNameStringId(objectPlaced);
|
|
prose_package pp = new prose_package();
|
|
pp = prose.setStringId(pp, SID_MORE_THAN_ONE_PLACED_IN_INVENTORY);
|
|
pp = prose.setDI(pp, count);
|
|
pp = prose.setTO(pp, name);
|
|
sendQuestSystemMessage(player, pp);
|
|
}
|
|
}
|
|
|
|
|
|
void sendPlacedInInventorySystemMessage(obj_id player, obj_id objectPlaced, String objectTemplate)
|
|
{
|
|
if (isValidId(objectPlaced))
|
|
{
|
|
prose_package pp = null;
|
|
string_id name = getNameStringId(objectPlaced);
|
|
|
|
pp = prose.getPackage(SID_PLACED_IN_INVENTORY, name);
|
|
sendQuestSystemMessage(player, pp);
|
|
}
|
|
else
|
|
{
|
|
if (objectTemplate != null && objectTemplate.length() > 0)
|
|
{
|
|
LOG("quest", "WARNING: Failed to place [" + objectTemplate + "] in player's inventory.");
|
|
}
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void sendPlacedInInventorySystemMessage(obj_id player, obj_id objectPlaced)
|
|
{
|
|
sendPlacedInInventorySystemMessage(player, objectPlaced, null);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void sendRemovedFromInventorySystemMessage(obj_id player, obj_id objectPlaced, String objectTemplate)
|
|
{
|
|
if (isValidId(objectPlaced))
|
|
{
|
|
prose_package pp = null;
|
|
string_id name = getNameStringId(objectPlaced);
|
|
|
|
pp = prose.getPackage(SID_REMOVED_FROM_INVENTORY, name);
|
|
sendQuestSystemMessage(player, pp);
|
|
}
|
|
else
|
|
{
|
|
if (objectTemplate != null && objectTemplate.length() > 0)
|
|
{
|
|
LOG("quest", "WARNING: Failed to remove [" + objectTemplate + "] from player's inventory.");
|
|
}
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void sendRemovedFromInventorySystemMessage(obj_id player, obj_id objectPlaced)
|
|
{
|
|
sendRemovedFromInventorySystemMessage(player, objectPlaced, null);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
boolean isActionAllowedForQuest(obj_id player, obj_id npc, string actionName)
|
|
{
|
|
//-- the NPC must have the correct object variables
|
|
if (!hasObjVar(npc, QUEST_NAME))
|
|
return false;
|
|
|
|
if (!hasObjVar(npc, TASK_NAME))
|
|
return false;
|
|
|
|
int questCrc = getQuestIdFromString(getStringObjVar(npc, QUEST_NAME));
|
|
int taskId = getTaskId(questCrc, getStringObjVar(npc, TASK_NAME));
|
|
|
|
//-- the player must have the NPC's quest/task active
|
|
if (!questIsTaskActive(questCrc, taskId, player))
|
|
return false;
|
|
|
|
//-- the action must correspond to the one required in the quest (or be a better version)
|
|
String questActionName = getTaskStringDataEntry(questCrc, taskId, dataTableColumnActionName);
|
|
|
|
//-- no action name associated with this quest
|
|
if (questActionName == null)
|
|
return false;
|
|
|
|
String baseQuest, baseAction;
|
|
int versionQuest, versionAction;
|
|
|
|
int indexQuest = questActionName.lastIndexOf('_');
|
|
int indexAction = actionName.lastIndexOf('_');
|
|
|
|
if (indexQuest < 0)
|
|
{
|
|
baseQuest = questActionName;
|
|
versionQuest = 0;
|
|
}
|
|
else
|
|
{
|
|
baseQuest = questActionName.substring(0, indexQuest);
|
|
versionQuest = utils.stringToInt(questActionName.substring(indexQuest+1));
|
|
}
|
|
|
|
if (indexAction < 0)
|
|
{
|
|
baseAction = actionName;
|
|
versionAction = 0;
|
|
}
|
|
else
|
|
{
|
|
baseAction = actionName.substring(0, indexAction);
|
|
versionAction = utils.stringToInt(actionName.substring(indexAction+1));
|
|
}
|
|
|
|
questOutputDebugInfo(player, "groundquests", "isActionAllowedForQuest",
|
|
questActionName + ": " + baseQuest + " - " + versionQuest + ", " + baseAction + " - " + versionAction);
|
|
|
|
boolean result = baseAction.equals(baseQuest) && versionAction >= versionQuest;
|
|
|
|
questOutputDebugInfo(player, "groundquests", "isActionAllowedForQuest",
|
|
"result = " + (result ? "true" : "false"));
|
|
|
|
return result;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
boolean questActionCompleted(obj_id player, obj_id npc, string actionName)
|
|
{
|
|
if (isActionAllowedForQuest(player, npc, actionName))
|
|
{
|
|
int questCrc = getQuestIdFromString(getStringObjVar(npc, QUEST_NAME));
|
|
int taskId = getTaskId(questCrc, getStringObjVar(npc, TASK_NAME));
|
|
|
|
dictionary params = new dictionary();
|
|
params.put(QUEST_CRC, questCrc);
|
|
params.put(TASK_ID, taskId);
|
|
|
|
questOutputDebugInfo(player, "groundquests", "questActionCompleted",
|
|
"sending questActionCompleted");
|
|
|
|
messageTo(player, "questActionCompleted", params, 0, false);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void applyQuestPenalty(obj_id player, String factionName, int factionAmount)
|
|
{
|
|
// apply faction penalty
|
|
if (factionName != null && factionName.length() > 0 && factionAmount > 0)
|
|
{
|
|
float currentFactionStanding = factions.getFactionStanding(player, factionName);
|
|
factions.setFactionStanding(player, factionName, currentFactionStanding - factionAmount);
|
|
prose_package pp = factions.getFactionProsePackage(factionName, -factionAmount);
|
|
sendQuestSystemMessage(player, pp);
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
void grantQuestReward(obj_id player, int questCrc, int questLevel, int questTier, String experienceType, int experienceAmount, String factionName, int factionAmount, boolean grantGcwReward, int bankCredits, String item, int itemCount, String weapon, int weaponCount, float weaponSpeed, float weaponDamage, float weaponEfficiency, float weaponElementalValue, String armor, int armorCount, int armorQuality, String[] inclusiveLootNames, int[] inclusiveLootCounts, String exclusiveLootChoiceName, int exclusiveLootChoiceCount, String badgeName, boolean useShowLootBox)
|
|
{
|
|
grantQuestReward(player, questCrc, questLevel, questTier, experienceType, experienceAmount, factionName, factionAmount, grantGcwReward, bankCredits, item, itemCount, weapon, weaponCount, weaponSpeed, weaponDamage, weaponEfficiency, weaponElementalValue, armor, armorCount, armorQuality, inclusiveLootNames, inclusiveLootCounts, exclusiveLootChoiceName, exclusiveLootChoiceCount, badgeName, useShowLootBox, 0, 0, null, 0, null, 0, 0);
|
|
}
|
|
|
|
|
|
|
|
void grantQuestReward(obj_id player, int questCrc, int questLevel, int questTier, String experienceType, int experienceAmount, String factionName, int factionAmount, boolean grantGcwReward, int bankCredits, String item, int itemCount, String weapon, int weaponCount, float weaponSpeed, float weaponDamage, float weaponEfficiency, float weaponElementalValue, String armor, int armorCount, int armorQuality, String[] inclusiveLootNames, int[] inclusiveLootCounts, String exclusiveLootChoiceName, int exclusiveLootChoiceCount, String badgeName, boolean useShowLootBox, int grantGcwOverwriteAmt, int grantGcwSFModifier, string grantGcwRebReward, int grantGcwRebRewardCount, string grantGcwImpReward, int grantGcwImpRewardCount, int grantGcwSFRewardMultip)
|
|
{
|
|
//default to 1 item to create
|
|
if(itemCount == -1)
|
|
itemCount = 1;
|
|
if(weaponCount == -1)
|
|
weaponCount = 1;
|
|
if(armorCount == -1)
|
|
armorCount = 1;
|
|
|
|
experienceAmount = getQuestExperienceReward(player, questLevel, questTier, experienceAmount);
|
|
obj_id playerInv = utils.getInventoryContainer(player);
|
|
resizeable obj_id[] lootItemsResizeable = new obj_id[0];
|
|
|
|
//give experience if appropriate
|
|
if((experienceType != null) && (experienceType.length() > 0) && (experienceAmount > 0))
|
|
{
|
|
if (xp.isCombatXpType(experienceType))
|
|
{
|
|
xp.grantCombatStyleXp(player, experienceType, experienceAmount);
|
|
}
|
|
else if (xp.isCraftingXpType(experienceType))
|
|
{
|
|
//we dont want to modify our crafting xp anymore.
|
|
xp.grantCraftingQuestXp(player, experienceAmount);
|
|
}
|
|
else if (xp.isSocialXpType(experienceType))
|
|
{
|
|
xp.grantSocialStyleXp(player, experienceType, experienceAmount);
|
|
}
|
|
else
|
|
{
|
|
xp.grantUnmodifiedExperience(player, experienceType, experienceAmount, false);
|
|
}
|
|
xp.displayXpFlyText(player, player, experienceAmount);//xp flies off your own head!
|
|
xp.displayXpMsg(player, experienceType, experienceAmount);
|
|
}
|
|
|
|
//give money if appropriate
|
|
if(bankCredits > 0)
|
|
{
|
|
money.bankTo(money.ACCT_NEW_PLAYER_QUESTS, player, bankCredits);
|
|
play2dNonLoopingSound(player, groundquests.MUSIC_QUEST_RECEIVED_CREDITS);
|
|
}
|
|
|
|
//give faction if appropriate
|
|
if((factionName != null) && (factionName.length() > 0) && (factionAmount != 0))
|
|
{
|
|
float currentFactionStanding = factions.getFactionStanding(player, factionName);
|
|
factions.setFactionStanding(player, factionName, currentFactionStanding + factionAmount);
|
|
prose_package pp = factions.getFactionProsePackage(factionName, factionAmount);
|
|
sendQuestSystemMessage(player, pp);
|
|
}
|
|
|
|
//give gcw points if appropriate
|
|
if (grantGcwReward)
|
|
{
|
|
int intFaction = pvpGetAlignedFaction(player);
|
|
if(intFaction == 0 && !factions.isRebelHelper(player) && !factions.isImperialHelper(player))
|
|
{
|
|
return; // no transition if you're really neutral
|
|
}
|
|
|
|
int playerPvpType = pvpGetType(player);
|
|
|
|
//Do not attempt to reward GCW to Helpers
|
|
if(!factions.isRebelHelper(player) && !factions.isImperialHelper(player))
|
|
{
|
|
if(grantGcwOverwriteAmt == 0)
|
|
{
|
|
int gcwGroundQuestValue = gcw.getGcwGroundQuestAward(player, questTier);
|
|
gcw._grantGcwPoints(null, player, gcwGroundQuestValue, false, gcw.GCW_POINT_TYPE_GROUND_QUEST, questGetQuestName(questCrc));
|
|
}
|
|
else if(grantGcwOverwriteAmt > 0)
|
|
{
|
|
if(playerPvpType == PVPTYPE_DECLARED && grantGcwSFModifier != 0)
|
|
{
|
|
grantGcwOverwriteAmt *= grantGcwSFModifier;
|
|
}
|
|
|
|
gcw._grantGcwPoints(null, player, grantGcwOverwriteAmt, false, gcw.GCW_POINT_TYPE_GROUND_QUEST, questGetQuestName(questCrc));
|
|
}
|
|
}
|
|
|
|
if(factions.isRebelorRebelHelper(player) && grantGcwRebReward != null && grantGcwRebReward.length() > 0 && grantGcwRebRewardCount != 0)
|
|
{
|
|
boolean declared = false;
|
|
if(playerPvpType == PVPTYPE_DECLARED)
|
|
{
|
|
declared = true;
|
|
}
|
|
else if(factions.isRebelHelper(player) && pvpNeutralIsMercenaryDeclared(player))
|
|
{
|
|
declared = true;
|
|
}
|
|
|
|
// Bonus tokens configuration
|
|
float multiplier = utils.stringToFloat(getConfigSetting("GameServer", "gcwTokenBonus"));
|
|
|
|
if(multiplier > 1)
|
|
{
|
|
grantGcwRebRewardCount *= multiplier; // Precision lost.
|
|
}
|
|
|
|
if(declared && grantGcwSFRewardMultip != 0)
|
|
{
|
|
grantGcwRebRewardCount *= grantGcwSFRewardMultip;
|
|
}
|
|
|
|
for(int i = 0; i < grantGcwRebRewardCount; i++)
|
|
{
|
|
obj_id lootItem = static_item.createNewItemFunction(grantGcwRebReward, playerInv);
|
|
|
|
if(i == 0)
|
|
{
|
|
utils.addElement(lootItemsResizeable, lootItem);
|
|
if(grantGcwRebRewardCount == 1)
|
|
{
|
|
sendPlacedInInventorySystemMessage(player, lootItem);
|
|
}
|
|
else if(grantGcwRebRewardCount > 1)
|
|
{
|
|
sendPlacedMoreThanOneInInventorySystemMessage(player, lootItem, grantGcwRebRewardCount);
|
|
}
|
|
}
|
|
|
|
CustomerServiceLog("QUEST_REWARD", player +" received reward "+ grantGcwRebReward + " ("+lootItem+")");
|
|
}
|
|
}
|
|
else if(factions.isImperialorImperialHelper(player) && grantGcwImpReward != null && grantGcwImpReward.length() > 0 & grantGcwImpRewardCount != 0)
|
|
{
|
|
boolean declared = false;
|
|
|
|
if(playerPvpType == PVPTYPE_DECLARED)
|
|
{
|
|
declared = true;
|
|
}
|
|
else if(factions.isImperialHelper(player) && pvpNeutralIsMercenaryDeclared(player))
|
|
{
|
|
declared = true;
|
|
}
|
|
|
|
// Bonus tokens configuration
|
|
float multiplier = utils.stringToFloat(getConfigSetting("GameServer", "gcwTokenBonus"));
|
|
|
|
if(multiplier > 1)
|
|
{
|
|
grantGcwImpRewardCount *= multiplier; // Precision lost.
|
|
}
|
|
|
|
if(declared && grantGcwSFRewardMultip != 0)
|
|
{
|
|
grantGcwImpRewardCount *= grantGcwSFRewardMultip;
|
|
}
|
|
|
|
for(int i = 0; i < grantGcwImpRewardCount; i++)
|
|
{
|
|
obj_id lootItem = static_item.createNewItemFunction(grantGcwImpReward, playerInv);
|
|
|
|
if(i == 0)
|
|
{
|
|
utils.addElement(lootItemsResizeable, lootItem);
|
|
if(grantGcwImpRewardCount == 1)
|
|
{
|
|
sendPlacedInInventorySystemMessage(player, lootItem);
|
|
}
|
|
else if(grantGcwImpRewardCount > 1)
|
|
{
|
|
sendPlacedMoreThanOneInInventorySystemMessage(player, lootItem, grantGcwImpRewardCount);
|
|
}
|
|
}
|
|
|
|
CustomerServiceLog("QUEST_REWARD", player +" received reward "+ grantGcwImpReward+ " ("+lootItem+")");
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((badgeName != null) && (badgeName != "") && (badgeName.length() > 0))
|
|
{
|
|
if (!badge.hasBadge (player, badgeName))
|
|
{
|
|
badge.grantBadge (player, badgeName);
|
|
}
|
|
}
|
|
|
|
//give item if appropriate
|
|
if ((item != null) && (item.length() > 0))
|
|
{
|
|
for(int i = 0; i < itemCount; ++i)
|
|
{
|
|
obj_id newItem = createObjectInInventoryAllowOverload(item, player);
|
|
sendPlacedInInventorySystemMessage(player, newItem, item);
|
|
CustomerServiceLog("QUEST_REWARD", player +" received reward "+ item +" ("+newItem+")");
|
|
}
|
|
play2dNonLoopingSound(player, groundquests.MUSIC_QUEST_RECEIVED_ITEM);
|
|
}
|
|
|
|
//give weapon if appropriate
|
|
if ((weapon != null) && (weapon.length() > 0))
|
|
{
|
|
for(int i = 0; i < weaponCount; ++i)
|
|
{
|
|
obj_id newWeapon = weapons.createWeaponOverloaded(weapon, playerInv, weaponSpeed, weaponDamage, weaponEfficiency, weaponElementalValue);
|
|
sendPlacedInInventorySystemMessage(player, newWeapon, weapon);
|
|
CustomerServiceLog("QUEST_REWARD", player +" received reward "+ weapon +" ("+newWeapon+")");
|
|
}
|
|
}
|
|
|
|
//give armor if appropriate
|
|
if ((armor != null) && (armor.length() > 0))
|
|
{
|
|
for(int i = 0; i < armorCount; ++i)
|
|
{
|
|
obj_id armorItem = createObjectInInventoryAllowOverload (armor, player);
|
|
loot.randomizeArmor(armorItem, armorQuality);
|
|
sendPlacedInInventorySystemMessage(player, armorItem, armor);
|
|
CustomerServiceLog("QUEST_REWARD", player +" received reward "+ armor +" ("+armorItem+")");
|
|
}
|
|
}
|
|
|
|
//give loot if appropriate
|
|
for(int j = 0; j < inclusiveLootNames.length; ++j)
|
|
{
|
|
if ((inclusiveLootNames[j] != null) && (inclusiveLootNames[j].length() > 0))
|
|
{
|
|
dictionary inclusiveItemData = static_item.getMasterItemDictionary(inclusiveLootNames[j]);
|
|
boolean giveInclusiveItemInventoryMessage = true;
|
|
if(inclusiveItemData != null)
|
|
{
|
|
for (int i = 0; i < inclusiveLootCounts[j]; ++i)
|
|
{
|
|
obj_id lootItem = static_item.createNewItemFunction(inclusiveLootNames[j], player);
|
|
|
|
if ( i == 0 )
|
|
{
|
|
utils.addElement(lootItemsResizeable, lootItem);
|
|
}
|
|
|
|
CustomerServiceLog("QUEST_REWARD", player +" received reward "+ inclusiveLootNames[j]+ " ("+lootItem+")");
|
|
|
|
if ( giveInclusiveItemInventoryMessage )
|
|
{
|
|
sendPlacedInInventorySystemMessage(player, lootItem, inclusiveLootNames[j]);
|
|
}
|
|
if ( inclusiveItemData.containsKey("scripts") )
|
|
{
|
|
string inclusiveItemScriptList = inclusiveItemData.getString("scripts");
|
|
if ( inclusiveItemScriptList != null && inclusiveItemScriptList.length() > 0 && inclusiveItemScriptList.indexOf("autostack") > -1 )
|
|
{
|
|
giveInclusiveItemInventoryMessage = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((exclusiveLootChoiceName != null) && (exclusiveLootChoiceName.length() > 0))
|
|
{
|
|
dictionary exclusiveItemData = static_item.getMasterItemDictionary(exclusiveLootChoiceName);
|
|
boolean giveExclusiveItemInventoryMessage = true;
|
|
if ( exclusiveItemData != null )
|
|
{
|
|
for (int i = 0; i < exclusiveLootChoiceCount; ++i)
|
|
{
|
|
obj_id lootItem = static_item.createNewItemFunction(exclusiveLootChoiceName, player);
|
|
|
|
if ( i == 0 )
|
|
{
|
|
utils.addElement(lootItemsResizeable, lootItem);
|
|
}
|
|
|
|
CustomerServiceLog("QUEST_REWARD", player +" received reward "+ exclusiveLootChoiceName+ " ("+lootItem+")");
|
|
|
|
if ( giveExclusiveItemInventoryMessage )
|
|
{
|
|
sendPlacedInInventorySystemMessage(player, lootItem, exclusiveLootChoiceName);
|
|
}
|
|
if ( exclusiveItemData.containsKey("scripts") )
|
|
{
|
|
string exclusiveItemScriptList = exclusiveItemData.getString("scripts");
|
|
if ( exclusiveItemScriptList != null && exclusiveItemScriptList.length() > 0 && exclusiveItemScriptList.indexOf("autostack") > -1 )
|
|
{
|
|
giveExclusiveItemInventoryMessage = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( useShowLootBox )
|
|
{
|
|
if(lootItemsResizeable.length > 0)
|
|
{
|
|
obj_id[] lootItems = lootItemsResizeable;
|
|
showLootBox(player, lootItems);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
// Shared Retrieve Item task functions
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
boolean playerNeedsToRetrieveThisItem(obj_id player, obj_id item)
|
|
{
|
|
// this handles pre-existing instances of this function being called with
|
|
// retrieve_item hard coded into it.
|
|
return playerNeedsToRetrieveThisItem(player, item, "retrieve_item");
|
|
}
|
|
|
|
boolean playerNeedsToRetrieveThisItem(obj_id player, obj_id item, string taskType)
|
|
{
|
|
if ( isMob(item) && isIncapacitated(item) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
boolean needed = false;
|
|
|
|
String itemTemplateName = getTemplateName(item);
|
|
|
|
dictionary tasks = groundquests.getActiveTasksForTaskType(player, taskType);
|
|
if ((tasks != null) && !tasks.isEmpty())
|
|
{
|
|
java.util.Enumeration keys = tasks.keys();
|
|
while (keys.hasMoreElements())
|
|
{
|
|
String questCrcString = (string)keys.nextElement();
|
|
int questCrc = utils.stringToInt(questCrcString);
|
|
int[] tasksForCurrentQuest = tasks.getIntArray(questCrcString);
|
|
|
|
for(int i = 0; i < tasksForCurrentQuest.length; ++i)
|
|
{
|
|
int taskId = tasksForCurrentQuest[i];
|
|
String baseObjVar = groundquests.getBaseObjVar(player, taskType, questGetQuestName(questCrc), taskId);
|
|
String retrieveTemplateName = groundquests.getTaskStringDataEntry(questCrc, taskId, "SERVER_TEMPLATE");
|
|
if( retrieveTemplateName != null && itemTemplateName == retrieveTemplateName )
|
|
{
|
|
needed = true;
|
|
|
|
String objvarRetrievedFull = baseObjVar + dot + "retrieved_items";
|
|
if (hasObjVar(player, objvarRetrievedFull))
|
|
{
|
|
obj_id[] itemsAlreadyRetrieved = getObjIdArrayObjVar(player, objvarRetrievedFull);
|
|
for (int j = 0; j < itemsAlreadyRetrieved.length; ++j)
|
|
{
|
|
obj_id itemAlredyRetrieved = itemsAlreadyRetrieved[j];
|
|
if(item == itemAlredyRetrieved)
|
|
{
|
|
needed = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return needed;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
String getRetrieveMenuText(obj_id player, obj_id item)
|
|
{
|
|
// this handles pre-existing instances of this function being called with
|
|
// retrieve_item hard coded into it.
|
|
return getRetrieveMenuText(player, item, "retrieve_item");
|
|
}
|
|
|
|
String getRetrieveMenuText(obj_id player, obj_id item, string taskType)
|
|
{
|
|
String menuText = null;
|
|
String itemTemplateName = getTemplateName(item);
|
|
boolean menuTextSet = false;
|
|
|
|
dictionary tasks = groundquests.getActiveTasksForTaskType(player, taskType);
|
|
if ((tasks != null) && !tasks.isEmpty())
|
|
{
|
|
java.util.Enumeration keys = tasks.keys();
|
|
while (keys.hasMoreElements())
|
|
{
|
|
String questCrcString = (string)keys.nextElement();
|
|
int questCrc = utils.stringToInt(questCrcString);
|
|
int[] tasksForCurrentQuest = tasks.getIntArray(questCrcString);
|
|
|
|
for(int i = 0; i < tasksForCurrentQuest.length; ++i)
|
|
{
|
|
int taskId = tasksForCurrentQuest[i];
|
|
String baseObjVar = groundquests.getBaseObjVar(player, taskType, questGetQuestName(questCrc), taskId);
|
|
String retrieveTemplateName = groundquests.getTaskStringDataEntry(questCrc, taskId, "SERVER_TEMPLATE");
|
|
|
|
if( retrieveTemplateName != null && itemTemplateName == retrieveTemplateName )
|
|
{
|
|
//-- read the optional localized menu text or use the default "ITEM_USE" string
|
|
string tempMenuText = groundquests.getTaskStringDataEntry(questCrc, taskId, "RETRIEVE_MENU_TEXT");
|
|
|
|
if ( tempMenuText != null && tempMenuText.length() > 0 )
|
|
{
|
|
if ( !menuTextSet )
|
|
{
|
|
menuText = tempMenuText;
|
|
groundquests.questOutputDebugInfo(player, questCrc, taskId, taskType, "getRetrieveMenuText",
|
|
"Menu text is [" + menuText + "]");
|
|
|
|
menuTextSet = true;
|
|
}
|
|
else
|
|
{
|
|
//-- if this happens more than once then the player is on 2 or more different quests that use the same object template
|
|
groundquests.questOutputDebugInfo(player, questCrc, taskId, taskType, "getRetrieveMenuText",
|
|
"Item used for multiple quests! Resetting menu to default. [" + itemTemplateName + "]");
|
|
|
|
menuText = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return menuText;
|
|
}
|
|
|
|
int getQuestCountdownTime(obj_id player, obj_id item)
|
|
{
|
|
// this handles pre-existing instances of this function being called with
|
|
// retrieve_item hard coded into it.
|
|
return getQuestCountdownTime(player, item, "retrieve_item");
|
|
}
|
|
|
|
int getQuestCountdownTime(obj_id player, obj_id item, string taskType)
|
|
{
|
|
int countdownTime = 0;
|
|
String itemTemplateName = getTemplateName(item);
|
|
|
|
dictionary tasks = groundquests.getActiveTasksForTaskType(player, taskType);
|
|
if ((tasks != null) && !tasks.isEmpty())
|
|
{
|
|
java.util.Enumeration keys = tasks.keys();
|
|
while (keys.hasMoreElements())
|
|
{
|
|
String questCrcString = (string)keys.nextElement();
|
|
int questCrc = utils.stringToInt(questCrcString);
|
|
int[] tasksForCurrentQuest = tasks.getIntArray(questCrcString);
|
|
|
|
for(int i = 0; i < tasksForCurrentQuest.length; ++i)
|
|
{
|
|
int taskId = tasksForCurrentQuest[i];
|
|
String baseObjVar = groundquests.getBaseObjVar(player, taskType, questGetQuestName(questCrc), taskId);
|
|
String retrieveTemplateName = groundquests.getTaskStringDataEntry(questCrc, taskId, "SERVER_TEMPLATE");
|
|
|
|
if ( retrieveTemplateName != null && itemTemplateName == retrieveTemplateName )
|
|
{
|
|
countdownTime = groundquests.getTaskIntDataEntry(questCrc, taskId, "COUNTDOWN_TIMER");
|
|
|
|
if (countdownTime < 0)
|
|
countdownTime = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return countdownTime;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
int getQuestExperienceReward(obj_id player, int questLevel, int questTier, int experienceAmount)
|
|
{
|
|
//-- NOTE: Any changes to this function must also be made to the client code used
|
|
//-- to calculate the reward experience displayed in the quest journal.
|
|
//-- See Quest::getExperienceRewardAmount in sharedGame.
|
|
|
|
if (questLevel < 1 || questTier < 0)
|
|
return experienceAmount;
|
|
|
|
if (questTier == 0)
|
|
return 0;
|
|
|
|
if (questTier > 6)
|
|
questTier = 6;
|
|
|
|
const string[] tierColumns = {
|
|
dataTableColumnQuestRewardExperienceTeir1,
|
|
dataTableColumnQuestRewardExperienceTeir2,
|
|
dataTableColumnQuestRewardExperienceTeir3,
|
|
dataTableColumnQuestRewardExperienceTeir4,
|
|
dataTableColumnQuestRewardExperienceTeir5,
|
|
dataTableColumnQuestRewardExperienceTeir6
|
|
};
|
|
|
|
int questXp = dataTableGetInt(QUEST_EXPERIENCE_TABLE, ""+questLevel, tierColumns[questTier-1]);
|
|
int xpCap = getQuestXpCap(player);
|
|
|
|
if (questXp > xpCap)
|
|
questXp = xpCap;
|
|
|
|
return questXp;
|
|
}
|
|
|
|
int getQuestXpCap(obj_id player)
|
|
{
|
|
int level = getLevel(player);
|
|
|
|
int xpCurrentLevel = dataTableGetInt("datatables/player/player_level.iff", level, "xp_required");
|
|
int xpPreviousLevel = dataTableGetInt("datatables/player/player_level.iff", level-1, "xp_required");
|
|
|
|
int xpRequired = xpCurrentLevel - xpPreviousLevel;
|
|
int xpCap = xpRequired / 2; // Max quest xp for single quest is half the xp for your current level
|
|
|
|
if (xpCap < 0) xpCap = 0; // Prevent the xp cap from going negative (side-effect of being at level cap)
|
|
|
|
return xpCap;
|
|
}
|
|
|
|
void createQuestWaypoints(int questCrc, int taskId, obj_id self)
|
|
{
|
|
boolean createWaypoint = groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnCreateWaypoint) > 0;
|
|
|
|
//check if entrance waypoint is to be created
|
|
boolean createEntranceWaypoint = groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnEntranceCreateWaypoint) > 0;
|
|
|
|
if (createWaypoint && createEntranceWaypoint)
|
|
{
|
|
String entranceWaypointName = groundquests.getTaskStringDataEntry(questCrc, taskId, dataTableColumnEntranceWaypointName);
|
|
float entranceWorldLocationX = utils.stringToFloat(groundquests.getTaskStringDataEntry(questCrc, taskId, dataTableColumnEntranceLocationX));
|
|
float entranceWorldLocationY = utils.stringToFloat(groundquests.getTaskStringDataEntry(questCrc, taskId, dataTableColumnEntranceLocationY));
|
|
float entranceWorldLocationZ = utils.stringToFloat(groundquests.getTaskStringDataEntry(questCrc, taskId, dataTableColumnEntranceLocationZ));
|
|
String planetName = groundquests.getTaskStringDataEntry(questCrc, taskId, dataTableColumnPlanetName);
|
|
|
|
location loc = new location(entranceWorldLocationX, entranceWorldLocationY, entranceWorldLocationZ, planetName);
|
|
|
|
obj_id entranceWaypoint = createWaypointInDatapad(self, loc);
|
|
|
|
setWaypointColor(entranceWaypoint, "entrance");
|
|
|
|
String baseObjVar = groundquests.getBaseObjVar(self, taskType, questGetQuestName(questCrc), taskId);
|
|
setObjVar(self, baseObjVar + dot + objvarEntranceWaypoint, entranceWaypoint);
|
|
|
|
setWaypointName(entranceWaypoint, entranceWaypointName);
|
|
//setWaypointActive(entranceWaypoint, true);
|
|
setQuestWaypointActive(entranceWaypoint, self, baseObjVar);
|
|
}
|
|
|
|
//maybe create waypoint
|
|
if (createWaypoint)
|
|
{
|
|
String planetName = groundquests.getTaskStringDataEntry(questCrc, taskId, dataTableColumnPlanetName);
|
|
String waypointName = groundquests.getTaskStringDataEntry(questCrc, taskId, dataTableColumnWaypointName);
|
|
float worldLocationX = utils.stringToFloat(groundquests.getTaskStringDataEntry(questCrc, taskId, dataTableColumnLocationX));
|
|
float worldLocationY = utils.stringToFloat(groundquests.getTaskStringDataEntry(questCrc, taskId, dataTableColumnLocationY));
|
|
float worldLocationZ = utils.stringToFloat(groundquests.getTaskStringDataEntry(questCrc, taskId, dataTableColumnLocationZ));
|
|
String interiorWaypointAppearance = groundquests.getTaskStringDataEntry(questCrc, taskId, dataTableColumnInteriorWaypointAppearance);
|
|
String waypointBuildingCellName = groundquests.getTaskStringDataEntry(questCrc, taskId, dataTableColumnWaypointBuildingCellName);
|
|
|
|
groundquests.questOutputDebugInfo(self, questCrc, taskId, taskType, "OnTaskActivated",
|
|
taskType + " creating waypoint: " + planetName + ": " + worldLocationX + ", " + worldLocationY + ", " + worldLocationZ);
|
|
|
|
location loc = new location(worldLocationX, worldLocationY, worldLocationZ, planetName);
|
|
obj_id waypoint = null;
|
|
|
|
if(interiorWaypointAppearance != null && waypointBuildingCellName != null && interiorWaypointAppearance.length() > 0 && waypointBuildingCellName.length() > 0)
|
|
waypoint = createWaypointInDatapadInternal(self, loc, interiorWaypointAppearance, waypointBuildingCellName);
|
|
else
|
|
waypoint = createWaypointInDatapad(self, loc);
|
|
|
|
if (createEntranceWaypoint)
|
|
setWaypointColor(waypoint, "small");
|
|
|
|
String baseObjVar = groundquests.getBaseObjVar(self, taskType, questGetQuestName(questCrc), taskId);
|
|
setObjVar(self, baseObjVar + dot + objvarWaypoint, waypoint);
|
|
|
|
setWaypointName(waypoint, waypointName);
|
|
//setWaypointActive(waypoint, true);
|
|
setQuestWaypointActive(waypoint, self, baseObjVar);
|
|
}
|
|
}
|
|
|
|
void setQuestWaypointActive(obj_id waypoint, obj_id player, string baseObjVar)
|
|
{
|
|
string objvarFullName = baseObjVar + dot + groundquests.objvarWaypointInActive;
|
|
|
|
if ( utils.waypointExists(player, waypoint) )
|
|
{
|
|
location waypointLoc = getWaypointLocation(waypoint);
|
|
string waypointPlanet = waypointLoc.area;
|
|
|
|
location playerLoc = getLocation(player);
|
|
string playerPlanet = playerLoc.area;
|
|
|
|
if ( waypointPlanet.equals(playerPlanet) )
|
|
{
|
|
if ( hasObjVar(player, objvarFullName) )
|
|
{
|
|
removeObjVar(player, objvarFullName);
|
|
}
|
|
|
|
setWaypointActive(waypoint, true);
|
|
}
|
|
else
|
|
{
|
|
if ( !hasObjVar(player, objvarFullName) )
|
|
{
|
|
setObjVar(player, objvarFullName, true);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( hasObjVar(player, objvarFullName) )
|
|
{
|
|
removeObjVar(player, objvarFullName);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
obj_id getObjIdForWaypoint(int questCrc, int taskId, obj_id self)
|
|
{
|
|
String baseObjVar = groundquests.getBaseObjVar(self, taskType, questGetQuestName(questCrc), taskId);
|
|
String baseWaypoint = baseObjVar + dot + objvarWaypoint;
|
|
return getObjIdObjVar(self, baseWaypoint);
|
|
}
|
|
|
|
obj_id getObjIdForEntranceWaypoint(int questCrc, int taskId, obj_id self)
|
|
{
|
|
String baseObjVar = groundquests.getBaseObjVar(self, taskType, questGetQuestName(questCrc), taskId);
|
|
String doorWaypoint = baseObjVar + dot + objvarEntranceWaypoint;
|
|
return getObjIdObjVar(self, doorWaypoint);
|
|
}
|
|
|
|
void deleteQuestWaypoints(int questCrc, int taskId, boolean isForCTS, obj_id self)
|
|
{
|
|
String baseObjVar = groundquests.getBaseObjVar(self, taskType, questGetQuestName(questCrc), taskId);
|
|
String baseWaypoint = baseObjVar + dot + objvarWaypoint;
|
|
String doorWaypoint = baseObjVar + dot + objvarEntranceWaypoint;
|
|
obj_id waypoint = getObjIdObjVar(self, baseWaypoint);
|
|
|
|
if (isIdValid(waypoint))
|
|
{
|
|
removeObjVar(self, baseWaypoint);
|
|
|
|
if (isForCTS == false)
|
|
destroyWaypointInDatapad(waypoint, self);
|
|
}
|
|
|
|
obj_id entranceWaypoint = getObjIdObjVar(self, doorWaypoint);
|
|
|
|
if (isIdValid(entranceWaypoint))
|
|
{
|
|
removeObjVar(self, doorWaypoint);
|
|
|
|
if (isForCTS == false)
|
|
destroyWaypointInDatapad(entranceWaypoint, self);
|
|
}
|
|
}
|
|
|
|
void reattachQuestScripts(obj_id self)
|
|
{
|
|
// iterate over quest.script objvar names.
|
|
obj_var_list scriptList = getObjVarList(self, questBaseObjVar + dot + "script");
|
|
|
|
if (scriptList != null)
|
|
{
|
|
string[] scriptNames = scriptList.getAllObjVarNames();
|
|
int numScripts = scriptNames.length;
|
|
for (int i = 0; i < numScripts; ++i)
|
|
{
|
|
// each objvar at this point represents the count of
|
|
// uses for a specific script. If the objvar is set to
|
|
// zero, the script is unused and does not need to be
|
|
// attached.
|
|
obj_var oneScript = scriptList.getObjVar(scriptNames[i]);
|
|
if(oneScript.getIntData() > 0)
|
|
{
|
|
|
|
if (!self.hasScript(scriptNames[i]))
|
|
{
|
|
attachScript(self, scriptNames[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void refreshQuestWaypoints(int questCrc, int taskId, boolean isForCTS, obj_id self)
|
|
{
|
|
deleteQuestWaypoints (questCrc, taskId, isForCTS, self);
|
|
|
|
createQuestWaypoints( questCrc, taskId, self);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
// Guaranteed Success
|
|
|
|
void setGuaranteedSuccessTarget(obj_id player, int questCrc, int taskId, string baseObjVar)
|
|
{
|
|
string guaranteedSuccessTargetObjVar = baseObjVar + dot + objvarGuaranteedSuccess_Target;
|
|
string guaranteedSuccessCountObjVar = baseObjVar + dot + objvarGuaranteedSuccess_Count;
|
|
|
|
// clean-up any previous guaranteed success objvars for this task
|
|
if ( hasObjVar(player, guaranteedSuccessTargetObjVar) )
|
|
{
|
|
removeObjVar(player, guaranteedSuccessTargetObjVar);
|
|
}
|
|
if ( hasObjVar(player, guaranteedSuccessCountObjVar) )
|
|
{
|
|
removeObjVar(player, guaranteedSuccessCountObjVar);
|
|
}
|
|
|
|
int minNumAttempts = groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnGuaranteedSuccessMin);
|
|
int maxNumAttempts = groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnGuaranteedSuccessMax);
|
|
|
|
// if the min or max number of attempts are 0, then do not use guaranteed success -
|
|
// otherwise, set a guaranteed success target
|
|
if ( minNumAttempts > 0 && maxNumAttempts > 0 )
|
|
{
|
|
int target = 0;
|
|
|
|
// if min and max are the same or if the max is smaller than the min,
|
|
// set the target as the min
|
|
if ( minNumAttempts >= maxNumAttempts )
|
|
{
|
|
target = minNumAttempts;
|
|
}
|
|
else
|
|
{
|
|
target = rand(minNumAttempts,maxNumAttempts);
|
|
}
|
|
|
|
if ( target > 0 )
|
|
{
|
|
setObjVar(player, guaranteedSuccessCountObjVar, 0);
|
|
setObjVar(player, guaranteedSuccessTargetObjVar, target);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
boolean checkForGuaranteedSuccess(obj_id player, string baseObjVar)
|
|
{
|
|
string guaranteedSuccessTargetObjVar = baseObjVar + dot + objvarGuaranteedSuccess_Target;
|
|
string guaranteedSuccessCountObjVar = baseObjVar + dot + objvarGuaranteedSuccess_Count;
|
|
|
|
boolean passed = false;
|
|
|
|
if ( hasObjVar(player, guaranteedSuccessTargetObjVar) )
|
|
{
|
|
int guaranteedSuccessTarget = getIntObjVar(player, guaranteedSuccessTargetObjVar);
|
|
|
|
// Increment the count to reflect that this is the player's next attempt.
|
|
//
|
|
// If the player succeeds, the count will be reset
|
|
// when the next guaranteed success target is set.
|
|
int guaranteedSuccessCount = 1;
|
|
if ( hasObjVar(player, guaranteedSuccessCountObjVar) )
|
|
{
|
|
guaranteedSuccessCount = getIntObjVar(player, guaranteedSuccessCountObjVar) + 1;
|
|
}
|
|
|
|
setObjVar(player, guaranteedSuccessCountObjVar, guaranteedSuccessCount);
|
|
|
|
// if the current attempt is equal to the target, then return true
|
|
if ( guaranteedSuccessCount >= guaranteedSuccessTarget )
|
|
{
|
|
passed = true;
|
|
}
|
|
}
|
|
|
|
return passed;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
boolean isDoingSmugglerMission(obj_id player)
|
|
{
|
|
if (isQuestActive (player, "smuggle_generic_1") || isQuestActive (player, "smuggle_generic_2")
|
|
|| isQuestActive (player, "smuggle_generic_3") || isQuestActive (player, "smuggle_generic_4")
|
|
|| isQuestActive (player, "smuggle_generic_5"))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (isQuestActive (player, "smuggle_illicit_1") || isQuestActive (player, "smuggle_illicit_2")
|
|
|| isQuestActive (player, "smuggle_illicit_3") || isQuestActive (player, "smuggle_illicit_4")
|
|
|| isQuestActive (player, "smuggle_illicit_5"))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (isQuestActive (player, "smuggle_pvp_4") || isQuestActive (player, "smuggle_pvp_5"))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
float getPlayerPlayedTimeWhenTimerEnds(obj_id player, int questCrc, int taskId)
|
|
{
|
|
String baseObjVar = groundquests.getBaseObjVar(player, "base_task", questGetQuestName(questCrc), taskId);
|
|
|
|
if (hasObjVar(player, baseObjVar + dot + timeObjVar))
|
|
return getFloatObjVar(player, baseObjVar + dot + timeObjVar);
|
|
|
|
return -1.f;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
boolean isTimeRemainingBeforeCompletion(obj_id player, int questCrc, int taskId)
|
|
{
|
|
const int remainingTime = getTaskIntDataEntry(questCrc, taskId, dataTableColumnRemainingTime);
|
|
|
|
if (remainingTime > 0)
|
|
{
|
|
const int endTime = (int)getPlayerPlayedTimeWhenTimerEnds(player, questCrc, taskId);
|
|
|
|
if (endTime > 0)
|
|
{
|
|
const int timeLeft = endTime - getPlayerPlayedTime(player) - remainingTime;
|
|
|
|
if (timeLeft > 0)
|
|
{
|
|
prose_package pp = prose.getPackage(SID_TIME_REMAINING_BEFORE_COMPLETION, player, player);
|
|
prose.setDI(pp, timeLeft);
|
|
sendSystemMessageProse(player, pp);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
boolean gcwActiveDutyCheck(obj_id self, obj_id player)
|
|
{
|
|
if ( hasObjVar(self, "questRequireActiveDuty") )
|
|
{
|
|
if ( factions.isOnLeave(player) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
boolean completeTaskForGroupMembersInRange(obj_id questObj, obj_id player, int questCrc, int taskId)
|
|
{
|
|
return completeTaskForGroupMembersInRange(questObj, player, questCrc, taskId, 200.0f);
|
|
}
|
|
|
|
boolean completeTaskForGroupMembersInRange(obj_id questObj, obj_id player, int questCrc, int taskId, float range)
|
|
{
|
|
boolean result = false;
|
|
|
|
if ( !isIdValid(player) || !exists(player) || !player.isLoaded() )
|
|
{
|
|
return result;
|
|
}
|
|
|
|
obj_id[] groupies = getGroupMembersInRange(questObj, player, range);
|
|
if ( groupies != null && groupies.length > 0 )
|
|
{
|
|
for ( int i = 0; i < groupies.length; i++ )
|
|
{
|
|
obj_id groupMember = groupies[i];
|
|
if ( isIdValid(groupMember) )
|
|
{
|
|
if ( questIsTaskActive(questCrc, taskId, groupMember) )
|
|
{
|
|
questCompleteTask(questCrc, taskId, groupMember);
|
|
result = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
obj_id[] getGroupMembersInRange(obj_id questObj, obj_id player)
|
|
{
|
|
return getGroupMembersInRange(questObj, player, 200.0f);
|
|
}
|
|
|
|
obj_id[] getGroupMembersInRange(obj_id questObj, obj_id player, float range)
|
|
{
|
|
resizeable obj_id[] groupMembersInRange = new obj_id[0];
|
|
|
|
obj_id gid = getGroupObject(player);
|
|
if ( !isIdValid(gid) )
|
|
{
|
|
return null;
|
|
}
|
|
|
|
obj_id[] groupies = getGroupMemberIds(gid);
|
|
if ( groupies != null && groupies.length > 0 )
|
|
{
|
|
location controllerLoc = getWorldLocation(questObj);
|
|
for ( int i = 0; i < groupies.length; i++ )
|
|
{
|
|
obj_id groupMember = groupies[i];
|
|
if ( isIdValid(groupMember) && groupMember.isLoaded() && isPlayer(groupMember) )
|
|
{
|
|
location groupieLoc = getWorldLocation(groupMember);
|
|
if ( getDistance(controllerLoc, groupieLoc) <= range )
|
|
{
|
|
utils.addElement(groupMembersInRange, groupMember);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
obj_id[] staticGroupMembersInRange = utils.toStaticObjIdArray(groupMembersInRange);
|
|
if ( staticGroupMembersInRange != null && staticGroupMembersInRange.length > 0 )
|
|
{
|
|
return staticGroupMembersInRange;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|