mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-07-31 00:15:54 -04:00
410 lines
12 KiB
Plaintext
410 lines
12 KiB
Plaintext
include ai.ai_combat;
|
|
include library.ai_lib;
|
|
include library.quests;
|
|
include library.create;
|
|
include library.groundquests;
|
|
include library.locations;
|
|
include library.prose;
|
|
include library.utils;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
inherits quest.task.ground.base_task;
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
const string OBJVAR_DEFENSE_TARGET = "defend_target";
|
|
const string DEFEND_TARGET = "defendTarget";
|
|
const string QUEST_CRC = "questCrc";
|
|
const string TASK_ID = "taskId";
|
|
const string PLAYER = "player";
|
|
const string OBJVAR_BEEN_WARNED_DISTANCE = "beenWarned";
|
|
const string TASK_TYPE = "defend";
|
|
const string DOT = ".";
|
|
|
|
const float DEFEND_DISTANCE_TIME_CHECK = 10;
|
|
const float MAX_ALLOWED_DISTANCE = 40;
|
|
const float CLEANUP_TIME = 120;
|
|
|
|
const boolean LOGGING_ON = false;
|
|
const string LOG_CAT = "defense_ground_task";
|
|
// ---------------------------------------------------------------------
|
|
|
|
//fires when this task is added to the player
|
|
trigger OnTaskActivated(int questCrc, int taskId)
|
|
{
|
|
blog("OnTaskActivated init");
|
|
groundquests.questOutputDebugInfo(self, questCrc, taskId, TASK_TYPE, "OnTaskActivated", TASK_TYPE + " task activated.");
|
|
string baseObjVar = groundquests.setBaseObjVar(self, TASK_TYPE, questGetQuestName(questCrc), taskId);
|
|
blog("baseObjVar: "+baseObjVar);
|
|
//check the player for the OID of the defense object
|
|
if(!hasObjVar(self, OBJVAR_DEFENSE_TARGET))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
blog("has var");
|
|
|
|
obj_id defendTarget = getObjIdObjVar(self, OBJVAR_DEFENSE_TARGET);
|
|
if(!isValidId(defendTarget) || !exists(defendTarget))
|
|
{
|
|
//fail quest
|
|
questFailTask(questCrc, taskId, self);
|
|
}
|
|
|
|
blog("defendTarget: "+defendTarget);
|
|
groundquests.addDestroyNotification(defendTarget, self);
|
|
setObjVar(self, baseObjVar + DOT + OBJVAR_DEFENSE_TARGET, defendTarget);
|
|
removeObjVar(self, OBJVAR_DEFENSE_TARGET);
|
|
//set up first distance check pulse
|
|
dictionary distanceCheckParams = new dictionary();
|
|
distanceCheckParams.put(PLAYER, self);
|
|
distanceCheckParams.put(DEFEND_TARGET, defendTarget);
|
|
distanceCheckParams.put(QUEST_CRC, questCrc);
|
|
distanceCheckParams.put(TASK_ID, taskId);
|
|
messageTo(self, "messageDefendCheckDistance", distanceCheckParams, DEFEND_DISTANCE_TIME_CHECK, false);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
messageHandler destroyNotification()
|
|
{
|
|
blog("destroyNotification init");
|
|
|
|
if(params == null)
|
|
{
|
|
blog("destroyNotification params null");
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
if(!params.containsKey("source"))
|
|
{
|
|
blog("destroyNotification params source NULL");
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
obj_id source = params.getObjId("source");
|
|
|
|
//blog("destroyNotification source: "+source);
|
|
|
|
//get the base objvar for quests, all data is under that
|
|
string taskObjVarName = groundquests.getTaskTypeObjVar(self, TASK_TYPE);
|
|
if(taskObjVarName == null || taskObjVarName.length() <= 0)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
blog("destroyNotification taskObjVarName: "+taskObjVarName);
|
|
|
|
//get the list of quests
|
|
obj_var_list questList = getObjVarList(self, taskObjVarName);
|
|
if(questList == null)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
blog("destroyNotification questList: "+questList);
|
|
|
|
int countQuests = questList.getNumItems();
|
|
blog("destroyNotification countQuests: "+countQuests);
|
|
|
|
//for each quest, check each task
|
|
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(self, questObjVarName))
|
|
{
|
|
//get the list of tasks for this quest that are of the right TASK_TYPE
|
|
obj_var_list taskList = getObjVarList(self, questObjVarName);
|
|
if(taskList != null)
|
|
{
|
|
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);
|
|
|
|
//check the data specific to this task type
|
|
string escortTargetObjVarName = questObjVarName + DOT + taskName + DOT + OBJVAR_DEFENSE_TARGET;
|
|
blog("destroyNotification escortTargetObjVarName: "+escortTargetObjVarName);
|
|
|
|
if(hasObjVar(self, escortTargetObjVarName))
|
|
{
|
|
obj_id escortTarget = getObjIdObjVar(self, escortTargetObjVarName);
|
|
if(source == escortTarget)
|
|
{
|
|
questFailTask(questCrc, taskId, self);
|
|
}
|
|
else if(!exists(source) && !exists(escortTarget))
|
|
{
|
|
questFailTask(questCrc, taskId, self);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
messageHandler messageDefendCheckDistance()
|
|
{
|
|
blog("messageDefendCheckDistance init");
|
|
if(params == null)
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
if(!params.containsKey(PLAYER))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
if(!params.containsKey(DEFEND_TARGET))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
if(!params.containsKey(QUEST_CRC))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
if(!params.containsKey(TASK_ID))
|
|
{
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
blog("messageDefendCheckDistance contains all keys needed");
|
|
obj_id player = params.getObjId(PLAYER);
|
|
obj_id defendTarget = params.getObjId(DEFEND_TARGET);
|
|
int questCrc = params.getInt (QUEST_CRC);
|
|
int taskId = params.getInt (TASK_ID);
|
|
|
|
if(questIsTaskActive(questCrc, taskId, player))
|
|
{
|
|
blog("messageDefendCheckDistance questIsTaskActive == true");
|
|
string baseObjVar = groundquests.getBaseObjVar(player, TASK_TYPE, questGetQuestName(questCrc), taskId);
|
|
blog("messageDefendCheckDistance baseObjVar: "+baseObjVar);
|
|
if(isDefenseObjectNearby(questCrc, taskId, player, defendTarget))
|
|
{
|
|
blog("messageDefendCheckDistance isDefenseObjectNearby == true");
|
|
|
|
if(hasObjVar(player, baseObjVar + OBJVAR_BEEN_WARNED_DISTANCE))
|
|
removeObjVar(player, baseObjVar + OBJVAR_BEEN_WARNED_DISTANCE);
|
|
}
|
|
else
|
|
{
|
|
blog("messageDefendCheckDistance isDefenseObjectNearby == FALSE");
|
|
|
|
if(hasObjVar(self, baseObjVar + DOT + OBJVAR_DEFENSE_TARGET))
|
|
{
|
|
obj_id defendTargetVar = getObjIdObjVar(self, baseObjVar + DOT + OBJVAR_DEFENSE_TARGET);
|
|
if(defendTargetVar != defendTarget)
|
|
{
|
|
//unneeded check on old object
|
|
blog("messageDefendCheckDistance defendTargetVar is NOT the correct object.");
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
blog("messageDefendCheckDistance defendTargetVar is the correct object.");
|
|
blog("messageDefendCheckDistance defendTargetVar: "+defendTargetVar);
|
|
}
|
|
|
|
failDefenseDistanceCheck(player, questCrc, taskId, defendTarget);
|
|
|
|
}
|
|
//send message for next pulse
|
|
//this is not an infinite loop because it checks distance each time, and fails the task if the distance check fails twice in a row
|
|
messageTo(self, "messageDefendCheckDistance", params, DEFEND_DISTANCE_TIME_CHECK, false);
|
|
}
|
|
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
boolean isDefenseObjectNearby(int questCrc, int taskId, obj_id player, obj_id defendTarget)
|
|
{
|
|
blog("isDefenseObjectNearby init");
|
|
|
|
boolean result = false;
|
|
if(isIdValid(player) && isIdValid(defendTarget))
|
|
{
|
|
blog("isDefenseObjectNearby player and defendTarget are VALID");
|
|
|
|
float distance = getDistance(player, defendTarget);
|
|
if(distance < 0.0f)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
result = distance <= MAX_ALLOWED_DISTANCE;
|
|
blog("isDefenseObjectNearby DISTANCE: "+getDistance(player, defendTarget));
|
|
}
|
|
blog("isDefenseObjectNearby result: "+result);
|
|
|
|
return result;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void failDefenseDistanceCheck(obj_id player, int questCrc, int taskId, obj_id defenseTarget)
|
|
{
|
|
blog("failDefenseDistanceCheck init");
|
|
|
|
String baseObjVar = groundquests.getBaseObjVar(player, TASK_TYPE, questGetQuestName(questCrc), taskId);
|
|
if(!hasObjVar(player, baseObjVar + OBJVAR_BEEN_WARNED_DISTANCE))
|
|
{
|
|
//set objvar and warn player
|
|
setObjVar(player, baseObjVar + OBJVAR_BEEN_WARNED_DISTANCE, "true");
|
|
|
|
string_id message = new string_id ("quest/groundquests", "static_defense_distance_warning");
|
|
prose_package pp = prose.getPackage(message, player, player, 0);
|
|
prose.setDF(pp, DEFEND_DISTANCE_TIME_CHECK);
|
|
sendSystemMessageProse(player, pp);
|
|
}
|
|
else
|
|
{
|
|
string_id message = new string_id ("quest/groundquests", "static_defense_failed_due_to_distance");
|
|
prose_package pp = prose.getPackage(message, player, player, 0);
|
|
sendSystemMessageProse(player, pp);
|
|
|
|
questFailTask(questCrc, taskId, player);
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
//fires when the task is completed
|
|
trigger OnTaskCompleted(int questCrc, int taskId)
|
|
{
|
|
blog("OnTaskCompleted init");
|
|
groundquests.questOutputDebugInfo(self, questCrc, taskId, TASK_TYPE, "OnTaskCompleted", TASK_TYPE + " task completed.");
|
|
|
|
String baseObjVar = groundquests.getBaseObjVar(self, TASK_TYPE, questGetQuestName(questCrc), taskId);
|
|
obj_id escort = getObjIdObjVar(self, baseObjVar + DOT + OBJVAR_DEFENSE_TARGET);
|
|
|
|
if(hasObjVar(escort, "questCallBack"))
|
|
{
|
|
dictionary webster = new dictionary();
|
|
webster.put("questComplete", true);
|
|
webster.put("player", self);
|
|
messageTo(escort, "handleQuestCallBack", webster, 0, false);
|
|
}
|
|
|
|
cleanup(self, questCrc, taskId);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
//fires when the task is failed
|
|
trigger OnTaskFailed(int questCrc, int taskId)
|
|
{
|
|
blog("OnTaskFailed init");
|
|
groundquests.questOutputDebugInfo(self, questCrc, taskId, TASK_TYPE, "OnTaskFailed", TASK_TYPE + " task failed.");
|
|
|
|
String baseObjVar = groundquests.getBaseObjVar(self, TASK_TYPE, questGetQuestName(questCrc), taskId);
|
|
obj_id escort = getObjIdObjVar(self, baseObjVar + DOT + OBJVAR_DEFENSE_TARGET);
|
|
|
|
if(hasObjVar(escort, "questCallBack"))
|
|
{
|
|
dictionary webster = new dictionary();
|
|
webster.put("questComplete", false);
|
|
webster.put("player", self);
|
|
messageTo(escort, "handleQuestCallBack", webster, 0, false);
|
|
}
|
|
|
|
cleanup(self, questCrc, taskId);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
//fires when the task is cleared
|
|
trigger OnTaskCleared(int questCrc, int taskId)
|
|
{
|
|
blog("OnTaskCleared init");
|
|
groundquests.questOutputDebugInfo(self, questCrc, taskId, TASK_TYPE, "OnTaskCleared", TASK_TYPE + " task cleared.");
|
|
|
|
String baseObjVar = groundquests.getBaseObjVar(self, TASK_TYPE, questGetQuestName(questCrc), taskId);
|
|
obj_id escort = getObjIdObjVar(self, baseObjVar + DOT + OBJVAR_DEFENSE_TARGET);
|
|
|
|
if(hasObjVar(escort, "questCallBack"))
|
|
{
|
|
dictionary webster = new dictionary();
|
|
webster.put("questComplete", false);
|
|
webster.put("player", self);
|
|
messageTo(escort, "handleQuestCallBack", webster, 0, false);
|
|
}
|
|
|
|
cleanup(self, questCrc, taskId);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
void cleanup(obj_id player, int questCrc, int taskId)
|
|
{
|
|
blog("cleanup init");
|
|
// destroy the escort target
|
|
String baseObjVar = groundquests.getBaseObjVar(player, TASK_TYPE, questGetQuestName(questCrc), taskId);
|
|
String escortTargetObjVarName = baseObjVar + DOT + OBJVAR_DEFENSE_TARGET;
|
|
|
|
obj_id escortTarget = getObjIdObjVar(player, escortTargetObjVarName);
|
|
|
|
if (escortTarget != null)
|
|
{
|
|
removeObjVar(player, escortTargetObjVarName);
|
|
if(!ai_lib.isAiDead(escortTarget))
|
|
{
|
|
//cleanup live escort targets after 2 minutes
|
|
dictionary params = new dictionary();
|
|
messageTo(escortTarget, "messageEscortCleanup", params, CLEANUP_TIME, false);
|
|
ai_lib.aiStopFollowing(escortTarget);
|
|
}
|
|
}
|
|
|
|
groundquests.clearBaseObjVar(player, TASK_TYPE, questGetQuestName(questCrc), taskId);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
trigger OnLogout()
|
|
{
|
|
blog("OnLogout init");
|
|
groundquests.failAllActiveTasksOfType(self, TASK_TYPE);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
trigger OnInitialize()
|
|
{
|
|
blog("OnInitialize init");
|
|
groundquests.failAllActiveTasksOfType(self, TASK_TYPE);
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
trigger OnDetach()
|
|
{
|
|
blog("OnDetach init");
|
|
//make sure the base objvar is removed
|
|
removeObjVar(self, groundquests.getTaskTypeObjVar(self, TASK_TYPE));
|
|
return SCRIPT_CONTINUE;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------
|
|
void blog(string text)
|
|
{
|
|
if(LOGGING_ON)
|
|
{
|
|
LOG(LOG_CAT, text);
|
|
}
|
|
}
|