Files
dsrc/sku.0/sys.server/compiled/game/script/quest/task/ground/spawn.script
T
2013-09-10 23:17:15 -07:00

408 lines
14 KiB
Plaintext

// ================================================================================
//
// spawn.script
// copyright 2006, Sony Online Entertainment LLC
//
// ================================================================================
include ai.ai_combat;
include library.ai_lib;
include library.buff;
include library.create;
include library.groundquests;
include library.locations;
include library.utils;
include library.ship_ai;
include library.space_quest;
include library.space_utils;
include library.space_create;
include library.space_transition;
// --------------------------------------------------------------------------------
inherits quest.task.ground.base_task;
// --------------------------------------------------------------------------------
const String dataTableColumnCreatureType = "CREATURE_TYPE";
const String dataTableColumnMinCount = "MIN_COUNT";
const String dataTableColumnMaxCount = "MAX_COUNT";
const String dataTableColumnMinDistance = "MIN_DISTANCE";
const String dataTableColumnMaxDistance = "MAX_DISTANCE";
const String dataTableColumnMinLevelDifference = "MIN_LEVEL_DIFFERENCE";
const String dataTableColumnMaxLevelDifference = "MAX_LEVEL_DIFFERENCE";
const String dataTableColumnGroundStartCombat = "GROUND_START_COMBAT";
const String dataTableColumnDismountPlayer = "DISMOUNT_PLAYER";
const String dataTableColumnMountBlockDuration = "MOUNT_BLOCK_DURATION";
const String dataTableColumnBuffName = "BUFF_NAME";
const String dataTableColumnShipType = "SHIP_TYPE";
const String dataTableColumnShipMinCount = "SHIP_MIN_COUNT";
const String dataTableColumnShipMaxCount = "SHIP_MAX_COUNT";
const String dataTableColumnSpaceStartCombat = "SPACE_START_COMBAT";
const String dataTableColumnHyperspaceBlockDuration = "HYPERSPACE_BLOCK_DURATION";
const String dataTableColumnMinStartDelay = "MIN_START_DELAY";
const String dataTableColumnMaxStartDelay = "MAX_START_DELAY";
const String dataTableColumnChanceToSkip = "CHANCE_TO_SKIP";
const String objvarPlayedTimeEnd = "playedTimeEnd";
const String objvarOnCreatureOwner = "quest.owner";
const String objvarOnCreatureQuestCrc = "quest.questCrc";
const String objvarOnCreatureTaskId = "quest.taskId";
const String objvarOnCreatureCount = "quest.count";
const String taskType = "spawn";
const String dot = ".";
const float cleanupTime = 300.f;
const float cleanupRetryTime = 60.f;
const String scriptSpawnOnCreature = "quest.task.ground.spawn_on_creature";
const String scriptSpawnOnShip = "quest.task.ground.spawn_on_ship";
// --------------------------------------------------------------------------------
trigger OnTaskActivated(int questCrc, int taskId)
{
groundquests.questOutputDebugInfo(self, questCrc, taskId, taskType, "OnTaskActivated", taskType + " task activated.");
String baseObjVar = groundquests.setBaseObjVar(self, taskType, questGetQuestName(questCrc), taskId);
int minStartDelay = Math.max(0, groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnMinStartDelay));
int maxStartDelay = Math.max(minStartDelay, groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnMaxStartDelay));
int timeLeft = 0;
if (minStartDelay > 0 && maxStartDelay > 0)
timeLeft = rand(minStartDelay, maxStartDelay);
groundquests.questOutputDebugInfo(self, questCrc, taskId, taskType, "OnTaskActivated", "Spawn will start in " + timeLeft + " seconds.");
dictionary params = new dictionary();
params.put("questCrc", questCrc);
params.put("taskId", taskId);
float playerPlayedTimeWhenTimerEnds = (float)getPlayerPlayedTime(self) + timeLeft;
setObjVar(self, baseObjVar + "." + objvarPlayedTimeEnd, playerPlayedTimeWhenTimerEnds);
messageTo(self, "messageStartQuestSpawn", params, timeLeft, true);
return SCRIPT_CONTINUE;
}
// --------------------------------------------------------------------------------
messageHandler messageStartQuestSpawn()
{
int questCrc = params.getInt ("questCrc");
int taskId = params.getInt ("taskId");
if(questIsTaskActive(questCrc, taskId, self))
{
String baseObjVar = groundquests.getBaseObjVar(self, taskType, questGetQuestName(questCrc), taskId);
float playerPlayedTimeWhenTimerEnds = getFloatObjVar(self, baseObjVar + "." + objvarPlayedTimeEnd);
float timeLeft = playerPlayedTimeWhenTimerEnds - (float)getPlayerPlayedTime(self);
if(timeLeft > 1)
{
messageTo(self, "messageStartQuestSpawn", params, timeLeft, true);
return SCRIPT_CONTINUE;
}
int chanceToSkip = groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnChanceToSkip);
int chanceRoll = rand(0, 99);
if(chanceToSkip > chanceRoll)
{
questCompleteTask(questCrc, taskId, self);
return SCRIPT_CONTINUE;
}
if (isSpaceScene())
startSpaceQuestSpawn(self, questCrc, taskId);
else
startGroundQuestSpawn(self, questCrc, taskId);
}
return SCRIPT_CONTINUE;
}
// --------------------------------------------------------------------------------
void startGroundQuestSpawn(obj_id player, int questCrc, int taskId)
{
String creatureType = groundquests.getTaskStringDataEntry(questCrc, taskId, dataTableColumnCreatureType);
int minCount = groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnMinCount);
int maxCount = groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnMaxCount);
float minRadius = groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnMinDistance);
float maxRadius = groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnMaxDistance);
boolean shouldDismountPlayer = groundquests.getTaskBoolDataEntry(questCrc, taskId, dataTableColumnDismountPlayer, false);
int mountBlockDuration = groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnMountBlockDuration);
String buffName = groundquests.getTaskStringDataEntry(questCrc, taskId, dataTableColumnBuffName);
int minLevelDifference = Math.max(0, groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnMinLevelDifference));
int maxLevelDifference = Math.max(0, groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnMaxLevelDifference));
boolean doAutoLeveling = minLevelDifference > 0 || maxLevelDifference > 0;
location l = null;
location locTest = getLocation(player);
if(!isIdValid(locTest.cell))
{
location locA = locTest;
location locB = locTest;
locA.x -= 5;
locA.y -= 5;
locA.z -= 5;
locB.x += 5;
locB.y += 5;
locB.z += 5;
// getGoodLocation(float hintX, float hintZ, location searchRectLL, location searchRectUR, boolean dontCheckWater, boolean dontCheckSlope)
l = getGoodLocation(1, 1, locA, locB, false, true);
// Bad location found?
if(getDistance(l, locTest) < 0.0f || getDistance(l, locTest) > 10.0f)
{
questCompleteTask(questCrc, taskId, player);
return;
}
}
if (shouldDismountPlayer)
utils.dismountRiderJetpackCheck(player);
if (mountBlockDuration > 0)
utils.setScriptVar(player, "mountBlock", getPlayerPlayedTime(player) + mountBlockDuration);
if (buffName != null && buffName.length() > 0)
buff.applyBuff(player, buffName);
if (maxCount < minCount)
maxCount = minCount;
int count = rand(minCount, maxCount);
for (int i = 0; i < count; ++i)
{
l = null;
if(!isIdValid(locTest.cell))
{
l = groundquests.getRandom2DLocationAroundPlayer(player, minRadius, maxRadius);
}
else
{
// handle the case where the player is inside a building
string strCell = getCellName(locTest.cell);
obj_id objBuilding = getTopMostContainer(player);
l = getGoodLocation(objBuilding, strCell);
}
obj_id creature;
int creatureLevel = 0;
if (doAutoLeveling)
{
int minLevel = Math.max(1, getLevel(player) - minLevelDifference);
int maxLevel = Math.max(minLevel, getLevel(player) + maxLevelDifference);
creatureLevel = rand(minLevel, maxLevel);
if(creatureLevel > 90)
{
creatureLevel = 90;
}
else if(creatureLevel < 1)
{
creatureLevel = 1;
}
creature = create.createCreature(creatureType, l, creatureLevel, true);
}
else
{
creature = create.createCreature(creatureType, l, true);
}
setObjVar(creature, objvarOnCreatureOwner, player);
setObjVar(creature, objvarOnCreatureQuestCrc, questCrc);
setObjVar(creature, objvarOnCreatureTaskId, taskId);
setObjVar(creature, objvarOnCreatureCount, i);
attachScript(creature, scriptSpawnOnCreature);
// if we can be talked to, that probably means we shouldn't be attacking.
if (!hasCondition(creature, CONDITION_CONVERSABLE))
{
groundquests.questOutputDebugInfo(player, questCrc, taskId, taskType, "startGroundQuestSpawn",
"Spawned " + creature + "(" + creatureLevel + ") at [" + l.x + ", " + l.y + ", " + l.z + "] to attack " + player);
boolean shouldStartCombat = groundquests.getTaskBoolDataEntry(questCrc, taskId, dataTableColumnGroundStartCombat, false);
if (shouldStartCombat)
startCombat(creature, player);
}
}
questCompleteTask(questCrc, taskId, player);
return;
}
// --------------------------------------------------------------------------------
void startSpaceQuestSpawn(obj_id player, int questCrc, int taskId)
{
groundquests.questOutputDebugInfo(player, questCrc, taskId, taskType, "startSpaceQuestSpawn",
"Space spawn started!");
boolean shouldStartCombat = groundquests.getTaskBoolDataEntry(questCrc, taskId, dataTableColumnSpaceStartCombat, false);
if (shouldStartCombat && !space_utils.isPlayerShipAttackable(player))
{
groundquests.questOutputDebugInfo(player, questCrc, taskId, taskType, "startSpaceQuestSpawn",
"Spawn failed due to player's ship being unattackable.");
questFailTask(questCrc, taskId, player);
return;
}
String baseObjVar = groundquests.getBaseObjVar(player, taskType, questGetQuestName(questCrc), taskId);
String shipType = groundquests.getTaskStringDataEntry(questCrc, taskId, dataTableColumnShipType);
if (shipType == null || shipType.length() == 0)
{
groundquests.questOutputDebugInfo(player, questCrc, taskId, taskType, "startSpaceQuestSpawn",
"Spawn failed due to starting in space with no shipType defined.");
questFailTask(questCrc, taskId, player);
return;
}
int hyperspaceBlockDuration = groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnHyperspaceBlockDuration);
if (hyperspaceBlockDuration > 0)
space_utils.setHyperspaceBlock(player, hyperspaceBlockDuration, true);
int minCount = groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnShipMinCount);
int maxCount = groundquests.getTaskIntDataEntry(questCrc, taskId, dataTableColumnShipMaxCount);
if (maxCount < minCount)
maxCount = minCount;
int squad = ship_ai.squadCreateSquadId();
int count = rand(minCount, maxCount);
for (int i = 0; i < count; ++i)
{
transform gloc = getTransform_o2w(space_transition.getContainingShip(player));
// Move the starting spot out in front of us.
float dist = rand(700.f, 800.f);
vector n = gloc.getLocalFrameK_p().normalize().multiply(dist); // Project a point out in front of us.
gloc = gloc.move_p(n);
// Flip the starting spot around so its facing us.
gloc = gloc.yaw_l(3.14f);
// Find a spot on the IJ plane for deviation in a cone shape.
vector vi = gloc.getLocalFrameI_p().normalize().multiply(rand(-150.f, 150.f));
vector vj = gloc.getLocalFrameJ_p().normalize().multiply(rand(-150.f, 150.f));
vector vd = vi.add(vj);
gloc = gloc.move_p(vd);
obj_id newship = space_create.createShipHyperspace(shipType, gloc);
ship_ai.unitSetLeashDistance(newship, 16000);
if (count > 3)
ship_ai.unitSetSquadId(newship, squad);
attachScript(newship, scriptSpawnOnShip);
if (shouldStartCombat)
{
// This guy can only be harmed by the player or his group.
setObjVar(newship, "objMissionOwner", player);
ship_ai.unitAddExclusiveAggro(newship, player);
dictionary dict = new dictionary ();
dict.put("player", space_transition.getContainingShip(player));
messageTo(newship, "spawnAttackPlayerShip", dict, 4.0f, false);
}
}
// Set a formation.
if (count > 3)
ship_ai.squadSetFormationRandom(squad);
questCompleteTask(questCrc, taskId, player);
return;
}
// --------------------------------------------------------------------------------
trigger OnTaskCompleted(int questCrc, int taskId)
{
cleanup(self, questCrc, taskId);
groundquests.questOutputDebugInfo(self, questCrc, taskId, taskType, "OnTaskCompleted", taskType + " task completed.");
return SCRIPT_CONTINUE;
}
// --------------------------------------------------------------------------------
trigger OnTaskFailed(int questCrc, int taskId)
{
cleanup(self, questCrc, taskId);
groundquests.questOutputDebugInfo(self, questCrc, taskId, taskType, "OnTaskFailed", taskType + " task failed.");
return SCRIPT_CONTINUE;
}
// --------------------------------------------------------------------------------
trigger OnTaskCleared(int questCrc, int taskId)
{
cleanup(self, questCrc, taskId);
groundquests.questOutputDebugInfo(self, questCrc, taskId, taskType, "OnTaskCleared", taskType + " task cleared.");
return SCRIPT_CONTINUE;
}
// --------------------------------------------------------------------------------
void cleanup(obj_id player, int questCrc, int taskId)
{
groundquests.clearBaseObjVar(player, taskType, questGetQuestName(questCrc), taskId);
}
// --------------------------------------------------------------------------------
trigger OnDeath(obj_id killer, obj_id corpseId)
{
return SCRIPT_CONTINUE;
}
// --------------------------------------------------------------------------------
trigger OnLogout()
{
return SCRIPT_CONTINUE;
}
// --------------------------------------------------------------------------------
trigger OnDetach()
{
// make sure the base objvar is removed
removeObjVar(self, groundquests.getTaskTypeObjVar(self, taskType));
return SCRIPT_CONTINUE;
}
// --------------------------------------------------------------------------------
trigger OnInitialize()
{
return SCRIPT_CONTINUE;
}
// ================================================================================