mirror of
https://bitbucket.org/seefoe/dsrc.git
synced 2026-07-31 01:15:55 -04:00
1768 lines
43 KiB
Plaintext
1768 lines
43 KiB
Plaintext
/**
|
|
* Title: utils.scriptlib
|
|
* Description: A library containing public general utility functions.
|
|
*/
|
|
|
|
/***** INCLUDES ********************************************************/
|
|
|
|
include library.loot;
|
|
include library.utils;
|
|
include library.prose;
|
|
include library.colors;
|
|
include library.resource;
|
|
include library.session;
|
|
include library.static_item;
|
|
|
|
/***** CONSTANTS *******************************************************/
|
|
|
|
const string SCRIPT_FISHING_PLAYER = "fishing.player";
|
|
const string SCRIPT_FISHING_NPC = "fishing.npc";
|
|
const string SCRIPT_FISHING_POLE = "fishing.pole";
|
|
const int ROLL_FISH_OR_JUNK = 94;
|
|
|
|
const string VAR_FISH_BASE = "fish";
|
|
const string VAR_FISH_NAME = VAR_FISH_BASE + ".name";
|
|
const string VAR_FISH_LENGTH = VAR_FISH_BASE + ".length";
|
|
const string VAR_FISH_LOCATION = VAR_FISH_BASE + ".location";
|
|
const string VAR_FISH_STAMP = VAR_FISH_BASE + ".stamp";
|
|
const string VAR_FISH_TIME_STAMP = VAR_FISH_BASE + ".time";
|
|
const string VAR_FISH_CATCHER = VAR_FISH_BASE + ".catcher";
|
|
|
|
const float FISHING_TICK = 7f;
|
|
|
|
const float SPOOL_RANGE = 20f;
|
|
|
|
const string SPLASH_EFFECT = "object/tangible/fishing/splash.iff";
|
|
|
|
const string TBL_TEMPLATE = "datatables/fishing/fish/fish_template.iff";
|
|
const string COL_NAME = "name";
|
|
const string COL_TEMPLATE = "template";
|
|
const string COL_HUE1 = "hueColor1";
|
|
const string COL_HUE2 = "hueColor2";
|
|
const string COL_LENGTH_NORM = "lengthNorm";
|
|
const string COL_LENGTH_MIN = "lengthMin";
|
|
const string COL_LENGTH_MAX = "lengthMax";
|
|
const string COL_RESOURCE_TYPE = "resourceType";
|
|
const string COL_RESOURCE_NORM = "resourceNorm";
|
|
const string COL_RESOURCE_MIN = "resourceMin";
|
|
const string COL_RESOURCE_MAX = "resourceMax";
|
|
const string COL_CHUM_NORM = "chumNorm";
|
|
const string COL_TROPHY_TEMPLATE = "trophyTemplate";
|
|
|
|
//STRING FILE
|
|
const string STF_FISH = "fishing";
|
|
|
|
const string_id SID_START_FISHING = new string_id(STF_FISH, "start_fishing");
|
|
const string_id SID_STOP_FISHING = new string_id(STF_FISH, "stop_fishing");
|
|
|
|
const string_id SID_BAD_CAST = new string_id(STF_FISH, "bad_cast");
|
|
const string_id SID_LOCATION_UNFISHABLE = new string_id(STF_FISH, "loc_unfishable");
|
|
|
|
const string_id PROSE_TOSS_BAIT = new string_id(STF_FISH, "prose_toss_bait");
|
|
const string_id SID_TOSS_BAIT = new string_id(STF_FISH, "toss_bait");
|
|
|
|
const string_id SID_FS_NIBBLE = new string_id(STF_FISH, "fs_nibble");
|
|
const string_id SID_FS_BITE = new string_id(STF_FISH, "fs_bite");
|
|
const string_id SID_FS_CAUGHT = new string_id(STF_FISH, "fs_caught");
|
|
const string_id SID_FS_SNAG = new string_id(STF_FISH, "fs_snag");
|
|
const string_id SID_FS_LOOT = new string_id(STF_FISH, "fs_loot");
|
|
|
|
const string_id SID_LINE_FREE = new string_id(STF_FISH, "line_free");
|
|
const string_id SID_LINE_SNAP = new string_id(STF_FISH, "line_snap");
|
|
|
|
const string_id SID_HARD_NIBBLE = new string_id(STF_FISH, "hard_nibble");
|
|
const string_id SID_HARD_BITE = new string_id(STF_FISH, "hard_bite");
|
|
|
|
const string_id SID_LOST_BAIT = new string_id(STF_FISH, "lost_bait");
|
|
|
|
const string_id SID_LOST_CATCH = new string_id(STF_FISH, "lost_catch");
|
|
const string_id SID_REEL_IN = new string_id(STF_FISH, "reel_in");
|
|
const string_id SID_LINE_SPOOLED = new string_id(STF_FISH, "line_spooled");
|
|
|
|
const string_id SID_FISH_FIGHT_EASY = new string_id(STF_FISH, "fish_fight_easy");
|
|
const string_id SID_FISH_FIGHT_HARD = new string_id(STF_FISH, "fish_fight_hard");
|
|
|
|
const string_id SID_FISH_FIGHT_AWAY = new string_id(STF_FISH, "fish_fight_away");
|
|
const string_id SID_FISH_FIGHT_CLOSER = new string_id(STF_FISH, "fish_fight_closer");
|
|
|
|
const string_id SID_FISH_RUN = new string_id(STF_FISH, "fish_run");
|
|
const string_id SID_FISH_CHARGE = new string_id(STF_FISH, "fish_charge");
|
|
|
|
const string_id SID_LOOT_BEACHED = new string_id(STF_FISH, "loot_beached");
|
|
const string_id SID_REEL_LOOT = new string_id(STF_FISH, "reel_loot");
|
|
|
|
const string_id PROSE_NOTIFY_CATCH = new string_id(STF_FISH, "prose_notify_catch");
|
|
|
|
//FLY STRING IDS
|
|
const string_id FLY_NIBBLE = new string_id(STF_FISH, "fly_nibble");
|
|
const string_id FLY_BITE = new string_id(STF_FISH, "fly_bite");
|
|
const string_id FLY_CATCH = new string_id(STF_FISH, "fly_catch");
|
|
const string_id FLY_SNAG = new string_id(STF_FISH, "fly_snag");
|
|
|
|
//PLAYER DATA
|
|
const string SCRIPTVAR_OLD_MOOD = "fishing.oldMood";
|
|
|
|
const string SCRIPTVAR_STATUS = "fishing.status";
|
|
const string SCRIPTVAR_SUI = "fishing.sui";
|
|
|
|
const string SCRIPTVAR_POLE = "fishing.pole";
|
|
const string SCRIPTVAR_LOCATION = "fishing.location";
|
|
const string SCRIPTVAR_ACTION = "fishing.action";
|
|
const string SCRIPTVAR_BONUS = "fishing.bonus";
|
|
const string SCRIPTVAR_CAUGHT = "fishing.caught";
|
|
|
|
const string SCRIPTVAR_MARKER = "fishing.marker";
|
|
const string TEMPLATE_MARKER = "object/tangible/fishing/marker.iff";
|
|
|
|
//FISHING STATUS
|
|
const int FS_NONE = 0;
|
|
const int FS_CAST = 1;
|
|
const int FS_WAIT = 2;
|
|
const int FS_NIBBLE = 3;
|
|
const int FS_BITE = 4;
|
|
const int FS_CAUGHT = 5;
|
|
const int FS_SNAG = 6;
|
|
const int FS_LOOT = 7;
|
|
|
|
const string[] FISHING_STATUS = {
|
|
"None",
|
|
"Just Cast Line...",
|
|
"Waiting.....",
|
|
"Nibble...",
|
|
"BITE!",
|
|
"CAUGHT SOMETHING!",
|
|
"Line Snagged?",
|
|
"CAUGHT SOMETHING!"
|
|
};
|
|
|
|
//FISHING ACTIONS
|
|
const int FA_NONE = 0;
|
|
const int FA_TUG_UP = 1;
|
|
const int FA_TUG_RIGHT = 2;
|
|
const int FA_TUG_LEFT = 3;
|
|
const int FA_SMALL_REEL = 4;
|
|
const int FA_STOP_FISHING = 5;
|
|
|
|
const int FA_MAX = 5; //same as last number
|
|
|
|
const string[] FISHING_ACTIONS = {
|
|
"None",
|
|
"Tug Up",
|
|
"Tug Right",
|
|
"Tug Left",
|
|
"Small Reel",
|
|
"Stop Fishing"
|
|
};
|
|
|
|
const string[] ENCODED_FISHING_ACTIONS = {
|
|
//"@" + STF_FISH + ":fa_none",
|
|
"@" + STF_FISH + ":fa_tug_up",
|
|
"@" + STF_FISH + ":fa_tug_right",
|
|
"@" + STF_FISH + ":fa_tug_left",
|
|
"@" + STF_FISH + ":fa_small_reel",
|
|
"@" + STF_FISH + ":fa_stop"
|
|
};
|
|
|
|
//POLE DATA
|
|
const string SCRIPTVAR_IN_USE = "fishing.inUse";
|
|
|
|
const string VAR_FISHING_BAIT_BASE = "fishing.bait";
|
|
const string VAR_FISHING_BAIT_STATUS = VAR_FISHING_BAIT_BASE + ".status";
|
|
|
|
//BAIT STATUS
|
|
const int BS_NONE = 0;
|
|
const int BS_FRESH = 1;
|
|
const int BS_SOGGY = 2;
|
|
const int BS_MUSH = 3;
|
|
|
|
const string[] BAIT_STATUS = {
|
|
"None",
|
|
"Fresh",
|
|
"Soggy",
|
|
"Mush"
|
|
};
|
|
|
|
//PLAYER HANDLERS
|
|
const string HANDLER_FISHING_TICK = "handleFishingTick";
|
|
const string HANDLER_FISHING_SUI = "handleFishingSui";
|
|
|
|
const string HANDLER_PLAY_CAST_SPLASH = "handlePlayCastSplash";
|
|
|
|
const string HANDLER_REEL_IN = "handleReelIn";
|
|
const string HANDLER_CAUGHT_SOMETHING = "handleCaughtSomething";
|
|
|
|
//POLE HANDLERS
|
|
const string HANDLER_BAIT_SUI = "handleBaitSui";
|
|
|
|
/***** FISHING *******************************************************/
|
|
boolean startFishing(obj_id target)
|
|
{
|
|
LOG("fishing","************ startFishing: now = " + getGameTime() + " ****************");
|
|
LOG("fishing","startFishing: entered... target = " + target);
|
|
if ( !isIdValid(target) )
|
|
return false;
|
|
|
|
if ( isFishing(target) )
|
|
return false;
|
|
|
|
obj_id pole = getObjectInSlot(target, "hold_r");
|
|
if ( !isIdValid(pole) )
|
|
return false;
|
|
|
|
if ( !isFishingPole(pole) )
|
|
{
|
|
sendSystemMessage(target, new string_id(STF_FISH, "must_have_pole")); // To fish, you must first have a fishing pole equipped.
|
|
return false;
|
|
}
|
|
|
|
if ( !isFishingPoleBaited(pole) )
|
|
{
|
|
sendSystemMessage(target, new string_id(STF_FISH, "bait_your_pole")); // To fish, you must first bait your pole.
|
|
return false;
|
|
}
|
|
|
|
obj_id playerCurrentMount = getMountId (target);
|
|
boolean isMounted = isIdValid(playerCurrentMount);
|
|
boolean isOnYodaChair = false;
|
|
|
|
if(isMounted)
|
|
{
|
|
string template = getTemplateName(playerCurrentMount);
|
|
if(!template.equals("object/mobile/vehicle/hover_chair.iff"))
|
|
{
|
|
sendSystemMessage(target, new string_id(STF_FISH, "not_this_vehicle")); // To fish, you must first bait your pole.
|
|
return false;
|
|
}
|
|
else
|
|
isOnYodaChair = true;
|
|
}
|
|
|
|
if(getState(target, STATE_SWIMMING) == 1 && !isOnYodaChair)
|
|
{
|
|
sendSystemMessage(target, new string_id(STF_FISH, "no_fish_swim")); // To fish, you must first bait your pole.
|
|
return false;
|
|
}
|
|
|
|
location castLoc = getFishingCastLocation(target);
|
|
if ( castLoc == null )
|
|
return false;
|
|
|
|
if ( isPlayer(target) )
|
|
{
|
|
attachScript(target, SCRIPT_FISHING_PLAYER);
|
|
sendSystemMessage(target, new string_id(STF_FISH, "cast_line")); // You cast your line and begin fishing...
|
|
}
|
|
else
|
|
{
|
|
attachScript(target, SCRIPT_FISHING_NPC);
|
|
}
|
|
|
|
LOG("fishing","startFishing: casting line...");
|
|
|
|
float range = getDistance(getLocation(target), castLoc);
|
|
float castTime = getFishingCastTime(range);
|
|
LOG("fishing","startFishing: casting range = " + range + " time = " + castTime);
|
|
if ( castTime < 0f )
|
|
return false;
|
|
|
|
session.logActivity(target, session.ACTIVITY_FISHING);
|
|
|
|
utils.setScriptVar(pole, SCRIPTVAR_IN_USE, target);
|
|
|
|
chat.setTempAnimationMood(target, "fishing");
|
|
doAnimationAction(target, "fishing_cast");
|
|
|
|
LOG("fishing","startFishing: setting initial state to FS_CAST");
|
|
setFishingState(target, FS_CAST);
|
|
|
|
//store cast data...
|
|
LOG("fishing","startFishing: storing initial data...");
|
|
initializeFishingData(target, pole, castLoc);
|
|
|
|
dictionary params = new dictionary();
|
|
params.put("pole", pole);
|
|
params.put("castLoc", castLoc);
|
|
|
|
LOG("fishing","startFishing: messaging HANDLER_PLAY_CAST_SPLASH...");
|
|
messageTo(target, HANDLER_PLAY_CAST_SPLASH, params, castTime, false);
|
|
return true;
|
|
}
|
|
|
|
void stopFishing(obj_id target, boolean animate)
|
|
{
|
|
LOG("fishing","************ stopFishing: now = " + getGameTime() + " ****************");
|
|
LOG("fishing","stopFishing: entered... target = " + target);
|
|
|
|
if ( !isIdValid(target) )
|
|
return;
|
|
|
|
//debug
|
|
if ( utils.hasScriptVar(target, SCRIPTVAR_MARKER) )
|
|
{
|
|
obj_id marker = utils.getObjIdScriptVar(target, SCRIPTVAR_MARKER);
|
|
if ( isIdValid(marker) )
|
|
destroyObject(marker);
|
|
|
|
utils.removeScriptVar(target, SCRIPTVAR_MARKER);
|
|
}
|
|
//end debug
|
|
|
|
if ( isPlayer(target) )
|
|
{
|
|
if ( !animate )
|
|
utils.setScriptVar(target, "noAnimate", true);
|
|
|
|
detachScript(target, SCRIPT_FISHING_PLAYER);
|
|
sendSystemMessage(target, new string_id(STF_FISH, "stop_fishing")); // You reel-in your line and stop fishing...
|
|
}
|
|
else
|
|
{
|
|
detachScript(target, SCRIPT_FISHING_NPC);
|
|
}
|
|
}
|
|
|
|
void stopFishing(obj_id target)
|
|
{
|
|
stopFishing(target, true);
|
|
}
|
|
|
|
boolean isPoleInUse(obj_id pole)
|
|
{
|
|
if ( !isIdValid(pole) )
|
|
return false;
|
|
|
|
return utils.hasScriptVar(pole, SCRIPTVAR_IN_USE);
|
|
}
|
|
|
|
void playCastSplash(obj_id target, dictionary params)
|
|
{
|
|
if ( !isIdValid(target) || (params == null) || (params.isEmpty()) )
|
|
return;
|
|
|
|
location castLoc = params.getLocation("castLoc");
|
|
if ( castLoc == null )
|
|
return;
|
|
|
|
//This is never getting cleaned up - changing it to a particle effect
|
|
/*
|
|
obj_id splash = createObject(SPLASH_EFFECT, castLoc);
|
|
if ( isIdValid(splash) )
|
|
{
|
|
dictionary cleanup = new dictionary();
|
|
cleanup.put("id", splash);
|
|
messageTo(target, "handleSplashCleanup", cleanup, 5, false);
|
|
}
|
|
*/
|
|
playClientEffectLoc(getPlayerCreaturesInRange(castLoc, 100.0f), "appearance/pt_splash.prt", castLoc, 0.0f);
|
|
|
|
// Clean up the old marker.
|
|
if ( utils.hasScriptVar(target, SCRIPTVAR_MARKER) )
|
|
{
|
|
obj_id marker = utils.getObjIdScriptVar(target, SCRIPTVAR_MARKER);
|
|
if ( isIdValid(marker) )
|
|
destroyObject(marker);
|
|
|
|
utils.removeScriptVar(target, SCRIPTVAR_MARKER);
|
|
}
|
|
|
|
obj_id marker = createObject(TEMPLATE_MARKER, castLoc);
|
|
if ( isIdValid(marker) )
|
|
{
|
|
setLocation(marker, castLoc);
|
|
faceTo(marker, target);
|
|
utils.setScriptVar(target, SCRIPTVAR_MARKER, marker);
|
|
}
|
|
}
|
|
|
|
void initializeFishingData(obj_id target, obj_id pole, location castLoc)
|
|
{
|
|
if ( !isIdValid(target) || !isIdValid(pole) || (castLoc == null) )
|
|
return;
|
|
|
|
LOG("fishing","initializeFishingData: setting initial fishing scriptvars on target...");
|
|
utils.setScriptVar(target, SCRIPTVAR_STATUS, FS_CAST);
|
|
utils.setScriptVar(target, SCRIPTVAR_POLE, pole);
|
|
utils.setScriptVar(target, SCRIPTVAR_LOCATION, castLoc);
|
|
|
|
obj_id bait = getBait(pole);
|
|
LOG("fishing","initializeFishingData: bait = " + bait);
|
|
if ( !isIdValid(bait) )
|
|
return;
|
|
|
|
if ( !hasObjVar(bait, VAR_FISHING_BAIT_STATUS) )
|
|
{
|
|
LOG("fishing","initializeFishingData: bait lacks objvar VAR_FISHING_BAIT_STATUS. initializing...");
|
|
setObjVar(bait, VAR_FISHING_BAIT_STATUS, BS_FRESH);
|
|
}
|
|
}
|
|
|
|
void cleanupFishing(obj_id target) //must be called by target!!
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return;
|
|
|
|
obj_id pole = utils.getObjIdScriptVar(target, SCRIPTVAR_POLE);
|
|
if ( isIdValid(pole) )
|
|
{
|
|
cleanupBait(target, pole);
|
|
utils.removeScriptVar(pole, SCRIPTVAR_IN_USE);
|
|
}
|
|
|
|
if ( !utils.hasScriptVar(target, "noAnimate") )
|
|
{
|
|
doAnimationAction(target, "fishing_reel");
|
|
}
|
|
else
|
|
{
|
|
utils.removeScriptVar(target, "noAnimate");
|
|
}
|
|
|
|
if ( utils.hasScriptVar(target, SCRIPTVAR_MARKER) )
|
|
{
|
|
obj_id marker = utils.getObjIdScriptVar(target, SCRIPTVAR_MARKER);
|
|
if ( isIdValid(marker) )
|
|
destroyObject(marker);
|
|
}
|
|
|
|
utils.removeScriptVar(target, SCRIPTVAR_STATUS);
|
|
utils.removeScriptVar(target, SCRIPTVAR_POLE);
|
|
utils.removeScriptVar(target, SCRIPTVAR_LOCATION);
|
|
utils.removeScriptVar(target, SCRIPTVAR_ACTION);
|
|
utils.removeScriptVar(target, SCRIPTVAR_BONUS);
|
|
utils.removeScriptVar(target, SCRIPTVAR_CAUGHT);
|
|
utils.removeScriptVar(target, SCRIPTVAR_MARKER);
|
|
utils.removeScriptVar(target, SCRIPTVAR_OLD_MOOD);
|
|
|
|
closeFishingSui(target);
|
|
|
|
chat.resetTempAnimationMood(target);
|
|
}
|
|
|
|
boolean isFishing(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return false;
|
|
|
|
return hasScript(target, SCRIPT_FISHING_PLAYER) || hasScript(target, SCRIPT_FISHING_NPC);
|
|
}
|
|
|
|
boolean isFishingPole(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return false;
|
|
|
|
/*if ( getGameObjectType(target) != GOT_misc_fishing_pole )
|
|
return false;*/
|
|
|
|
if ( !hasScript(target, SCRIPT_FISHING_POLE) )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void updateBaitStatus(obj_id target)
|
|
{
|
|
LOG("fishing","updateBaitStatus: entering...");
|
|
if ( !isIdValid(target) )
|
|
return;
|
|
|
|
if ( !isFishing(target) )
|
|
return;
|
|
|
|
LOG("fishing","updateBaitStatus: getting target's (" + target + ") fishing pole");
|
|
obj_id pole = utils.getObjIdScriptVar(target, SCRIPTVAR_POLE);
|
|
if ( !isIdValid(pole) )
|
|
return;
|
|
|
|
if ( !isFishingPole(pole) )
|
|
return;
|
|
|
|
LOG("fishing","updateBaitStatus: target = " + target);
|
|
obj_id bait = getBait(pole);
|
|
if ( !isIdValid(bait) )
|
|
return;
|
|
|
|
LOG("fishing","updateBaitStatus: bait = " + bait);
|
|
|
|
if ( !hasObjVar(bait, VAR_FISHING_BAIT_STATUS) )
|
|
return;
|
|
|
|
int status = getIntObjVar(bait, VAR_FISHING_BAIT_STATUS);
|
|
LOG("fishing","updateBaitStatus: bait status = " + status);
|
|
|
|
int roll = rand(0,100);
|
|
if(isGod(target))
|
|
{
|
|
roll = 100;
|
|
debugSpeakMsg(target, "God Mode is keeping your bait fresh!");
|
|
}
|
|
LOG("fishing","updateBaitStatus: roll = " + roll);
|
|
if ( roll < 20 )
|
|
status++;
|
|
|
|
if ( status > BS_MUSH )
|
|
{
|
|
LOG("fishing","updateBaitStatus: bait just went from mush to nothing...");
|
|
lostBait(target);
|
|
}
|
|
else
|
|
{
|
|
setObjVar(bait, VAR_FISHING_BAIT_STATUS, status);
|
|
}
|
|
}
|
|
|
|
void cleanupBait(obj_id target, obj_id pole)
|
|
{
|
|
if ( !isIdValid(target) || !isIdValid(pole) )
|
|
return;
|
|
|
|
if ( !isFishingPole(pole) )
|
|
return;
|
|
|
|
obj_id bait = getBait(pole);
|
|
if ( !isIdValid(bait) )
|
|
return;
|
|
|
|
int baitStatus = getIntObjVar(pole, VAR_FISHING_BAIT_STATUS);
|
|
if ( baitStatus > BS_FRESH )
|
|
{
|
|
incrementCount(bait, -1);
|
|
|
|
string stringStatus = getEncodedBaitStatus(baitStatus);
|
|
if ( stringStatus != null )
|
|
{
|
|
prose_package ppTossBait = prose.getPackage(PROSE_TOSS_BAIT, bait, stringStatus);
|
|
sendSystemMessageProse(target, ppTossBait);
|
|
}
|
|
else
|
|
{
|
|
sendSystemMessage(target, SID_TOSS_BAIT);
|
|
}
|
|
|
|
if ( getCount(bait) < 1 )
|
|
{
|
|
sendSystemMessage(target, new string_id(STF_FISH, "out_of_bait")); // You have run out of bait in your tackle...
|
|
destroyObject(bait);
|
|
}
|
|
}
|
|
else if ( baitStatus == BS_NONE )
|
|
{
|
|
removeObjVar(bait, VAR_FISHING_BAIT_STATUS);
|
|
}
|
|
}
|
|
|
|
boolean isFishingPoleBaited(obj_id pole)
|
|
{
|
|
if ( !isIdValid(pole) )
|
|
return false;
|
|
|
|
obj_id bait = getBait(pole);
|
|
if ( isIdValid(bait) )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
obj_id getBait(obj_id pole)
|
|
{
|
|
if ( !isIdValid(pole) )
|
|
return null;
|
|
|
|
obj_id[] contents = getContents(pole);
|
|
if ( contents != null && contents.length == 1 )
|
|
{
|
|
return contents[0];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
int getBaitStatus(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return -1;
|
|
|
|
if ( !isFishing(target) )
|
|
return -1;
|
|
|
|
obj_id pole = utils.getObjIdScriptVar(target, SCRIPTVAR_POLE);
|
|
if ( !isIdValid(pole) )
|
|
return -1;
|
|
|
|
if ( !isFishingPole(pole) )
|
|
return -1;
|
|
|
|
obj_id bait = getBait(pole);
|
|
if ( !isIdValid(bait) )
|
|
return -1;
|
|
|
|
if ( !hasObjVar(bait, VAR_FISHING_BAIT_STATUS) )
|
|
return -1;
|
|
|
|
return getIntObjVar(bait, VAR_FISHING_BAIT_STATUS);
|
|
}
|
|
|
|
string getEncodedBaitStatus(int status)
|
|
{
|
|
if ( status < 0 || status > BAIT_STATUS.length - 1 )
|
|
return null;
|
|
|
|
string baitStatus = BAIT_STATUS[status];
|
|
string_id sidStatus = new string_id(STF_FISH, baitStatus);
|
|
return utils.packStringId(sidStatus);
|
|
}
|
|
|
|
location getFishingCastLocation(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return null;
|
|
|
|
location here = getLocation(target);
|
|
float yaw = getYaw(target);
|
|
|
|
float min = Float.POSITIVE_INFINITY;
|
|
float max = Float.NEGATIVE_INFINITY;
|
|
for ( int i = 2; i < 10; i++ )
|
|
{
|
|
float range = i + 0.5f;
|
|
location testLoc = utils.rotatePointXZ(here, range, yaw);
|
|
testLoc.y = getHeightAtLocation(testLoc.x, testLoc.z);
|
|
if ( isLocationFishable(testLoc) )
|
|
{
|
|
if ( range < min )
|
|
min = range;
|
|
|
|
if ( range > max )
|
|
max = range;
|
|
}
|
|
else
|
|
{
|
|
if ( i == 2 )
|
|
{
|
|
sendSystemMessage(target, new string_id(STF_FISH, "too_far")); // You must be within 2 meters of fishable water and facing it to start fishing.
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( min == Float.POSITIVE_INFINITY )
|
|
{
|
|
sendSystemMessage(target, new string_id(STF_FISH, "invalid_location")); // Unable to determine valid fishing location ahead of you.
|
|
return null;
|
|
}
|
|
|
|
LOG("fishing","getFishingCastLocation: range min = " + min + " max = " + max);
|
|
|
|
float castRange = rand(min, max);
|
|
LOG("fishing","getFishingCastLocation: randomized cast range = " + castRange);
|
|
location there = utils.rotatePointXZ(here, castRange, yaw);
|
|
LOG("fishing","getFishingCastLocation: straight cast loc = " + there);
|
|
|
|
|
|
location castLoc = utils.getRandomLocationInRing(there, 0f, 0.5f);
|
|
LOG("fishing","getFishingCastLocation: ringed cast loc = " + castLoc);
|
|
if ( !isLocationFishable(castLoc) )
|
|
{
|
|
sendSystemMessage(target, SID_BAD_CAST);
|
|
return null;
|
|
}
|
|
|
|
castLoc.y = getWaterTableHeight(castLoc);
|
|
return castLoc;
|
|
}
|
|
|
|
float getFishingCastTime(float range)
|
|
{
|
|
if ( range < 0f )
|
|
return -1f;
|
|
|
|
return 3f;
|
|
}
|
|
|
|
boolean isLocationFishable(location loc)
|
|
{
|
|
if ( loc != null )
|
|
{
|
|
location testLoc = (location)loc.clone();
|
|
testLoc.y = getHeightAtLocation(loc.x, loc.z);
|
|
return isBelowWater(testLoc); //temp hack
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int showFishingSui(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) || !isPlayer(target) || !isFishing(target) )
|
|
return -1;
|
|
|
|
closeFishingSui(target);
|
|
|
|
int status = utils.getIntScriptVar(target, SCRIPTVAR_STATUS);
|
|
|
|
obj_id pole = utils.getObjIdScriptVar(target, SCRIPTVAR_POLE);
|
|
obj_id marker = utils.getObjIdScriptVar(target, SCRIPTVAR_MARKER);
|
|
if ( !isIdValid(pole) || !isIdValid(marker) )
|
|
{
|
|
cleanupFishing(target);
|
|
return -1;
|
|
}
|
|
|
|
location loc = getLocation(marker);
|
|
if ( loc == null )
|
|
{
|
|
cleanupFishing(target);
|
|
return -1;
|
|
}
|
|
|
|
float lineRange = getDistance(getLocation(target), loc);
|
|
|
|
obj_id bait = getBait(pole);
|
|
if ( !isIdValid(bait) || !hasObjVar(bait, VAR_FISHING_BAIT_STATUS) )
|
|
{
|
|
LOG("fishing","showFishingSui: bad bait data... stop fishing!");
|
|
LOG("fishing","showFishingSui: - bait = " + bait);
|
|
stopFishing(target);
|
|
return -1;
|
|
}
|
|
|
|
int baitStatus = getIntObjVar(bait, VAR_FISHING_BAIT_STATUS);
|
|
|
|
int action = utils.getIntScriptVar(target, SCRIPTVAR_ACTION);
|
|
|
|
string title = "@" + STF_FISH + ":sui_title";
|
|
|
|
string prompt = "";
|
|
prompt += "STATUS : " + FISHING_STATUS[status] + "\n";
|
|
prompt += "BAIT STATUS : " + BAIT_STATUS[baitStatus] + "\n";
|
|
|
|
if ( lineRange >= 10f )
|
|
prompt += "LINE RANGE : " + (String.valueOf(lineRange)).substring(0,5) + " \n";
|
|
else
|
|
prompt += "LINE RANGE : " + (String.valueOf(lineRange)).substring(0,4) + " \n";
|
|
|
|
|
|
prompt += "FISH DENSITY: " + getStars(getFishEfficiency(loc)) + "\n";
|
|
//prompt += "FISH DENSITY: " + getFishEfficiency(loc) + "\n";
|
|
|
|
prompt += "VEGETATION : " + getStars(getVegetationSnagFactor(loc)) + "\n";
|
|
//prompt += "VEGETATION : " + getVegetationSnagFactor(loc) + "\n";
|
|
|
|
//prompt += "BONUS : " + utils.getFloatScriptVar(target, SCRIPTVAR_BONUS) + "\n";
|
|
|
|
prompt += "NEXT ACTION : " + FISHING_ACTIONS[action] + "\n";
|
|
|
|
int pid = sui.listbox(target, prompt, title, ENCODED_FISHING_ACTIONS, HANDLER_FISHING_SUI);
|
|
if ( pid > -1 )
|
|
{
|
|
utils.setScriptVar(target, SCRIPTVAR_SUI, pid);
|
|
}
|
|
|
|
return pid;
|
|
}
|
|
|
|
string getStars(float eff)
|
|
{
|
|
if ( eff < 0.16f )
|
|
return "";
|
|
else if ( eff < 0.32f )
|
|
return "*";
|
|
else if ( eff < 0.48f )
|
|
return "**";
|
|
else if ( eff < 0.64f )
|
|
return "***";
|
|
else if ( eff < 0.80f )
|
|
return "****";
|
|
|
|
return "*****";
|
|
}
|
|
|
|
void closeFishingSui(obj_id target)
|
|
{
|
|
if ( utils.hasScriptVar(target, SCRIPTVAR_SUI) )
|
|
{
|
|
int pid = utils.getIntScriptVar(target, SCRIPTVAR_SUI);
|
|
forceCloseSUIPage(pid);
|
|
utils.removeScriptVar(target, SCRIPTVAR_SUI);
|
|
}
|
|
}
|
|
|
|
void defaultFishingUpdate(obj_id target, int action)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return;
|
|
|
|
int status = utils.getIntScriptVar(target, SCRIPTVAR_STATUS);
|
|
|
|
boolean setWait = true;
|
|
switch ( action )
|
|
{
|
|
case FA_TUG_UP:
|
|
case FA_TUG_RIGHT:
|
|
case FA_TUG_LEFT:
|
|
if ( status == FS_NIBBLE )
|
|
{
|
|
if ( checkForBite(target, -0.25f) )
|
|
setWait = false;
|
|
}
|
|
else if ( status == FS_BITE )
|
|
{
|
|
if ( checkForCatch(target, -0.25f) )
|
|
setWait = false;
|
|
}
|
|
|
|
case FA_SMALL_REEL:
|
|
updateFishingLocation(target, action);
|
|
break;
|
|
|
|
case FA_NONE:
|
|
default:
|
|
updateFishingWaitState(target);
|
|
break;
|
|
}
|
|
|
|
if ( setWait )
|
|
utils.setScriptVar(target, SCRIPTVAR_STATUS, FS_WAIT);
|
|
}
|
|
|
|
void updateFishingLocation(obj_id target, int action, boolean caught)
|
|
{
|
|
LOG("fishing","updateFishingLocation: entered...");
|
|
if ( !isIdValid(target) )
|
|
return;
|
|
|
|
location here = getLocation(target);
|
|
|
|
obj_id marker = utils.getObjIdScriptVar(target, SCRIPTVAR_MARKER);
|
|
if ( !isIdValid(marker) )
|
|
{
|
|
stopFishing(target);
|
|
return;
|
|
}
|
|
|
|
location there = getLocation(marker);
|
|
if ( there == null )
|
|
{
|
|
stopFishing(target);
|
|
return;
|
|
}
|
|
|
|
float currentDistance = getDistance(here, there);
|
|
LOG("fishing","updateFishingLocation: here = " + here.toString());
|
|
LOG("fishing","updateFishingLocation: there = " + there.toString());
|
|
LOG("fishing","updateFishingLocation: pre-update distance = " + currentDistance);
|
|
|
|
float dist = 0f;
|
|
switch ( action )
|
|
{
|
|
case FA_TUG_UP:
|
|
case FA_TUG_RIGHT:
|
|
case FA_TUG_LEFT:
|
|
dist = 0.25f;
|
|
break;
|
|
|
|
case FA_SMALL_REEL:
|
|
default:
|
|
dist = 0.75f;
|
|
break;
|
|
}
|
|
|
|
switch ( action )
|
|
{
|
|
case FA_TUG_UP:
|
|
doAnimationAction(target, "fishing_tug_back");
|
|
break;
|
|
|
|
case FA_TUG_RIGHT:
|
|
doAnimationAction(target, "fishing_tug_right");
|
|
break;
|
|
|
|
case FA_TUG_LEFT:
|
|
doAnimationAction(target, "fishing_tug_left");
|
|
break;
|
|
|
|
case FA_SMALL_REEL:
|
|
doAnimationAction(target, "fishing_reel");
|
|
break;
|
|
}
|
|
|
|
LOG("fishing","updateFishingLocation: action distance = " + dist);
|
|
if ( currentDistance < dist && !caught )
|
|
{
|
|
LOG("fishing","updateFishingLocation: current distance > action distance & caught = false... stop fishing!");
|
|
stopFishing(target);
|
|
return;
|
|
}
|
|
|
|
//float theta = utils.getHeadingToLocation(there, here); //degree measure
|
|
float theta = getYaw(marker);
|
|
|
|
float dTheta = 0f;
|
|
switch ( action )
|
|
{
|
|
case FA_TUG_RIGHT:
|
|
dTheta = rand(-45f, -15f);
|
|
break;
|
|
|
|
case FA_TUG_LEFT:
|
|
dTheta = rand(15f, 45f);
|
|
break;
|
|
|
|
case FA_TUG_UP:
|
|
case FA_SMALL_REEL:
|
|
default:
|
|
dTheta = rand(-5f, 5f);
|
|
break;
|
|
}
|
|
|
|
LOG("fishing","updateFishingLocation: heading to player = " + theta);
|
|
LOG("fishing","updateFishingLocation: action heading delta = " + dTheta);
|
|
|
|
theta += dTheta;
|
|
LOG("fishing","updateFishingLocation: revised heading = " + theta);
|
|
|
|
location loc = utils.rotatePointXZ(there, dist, theta);
|
|
if ( loc == null )
|
|
{
|
|
LOG("fishing","updateFishingLocation: revised location = null");
|
|
stopFishing(target);
|
|
return;
|
|
}
|
|
|
|
loc.y = getWaterTableHeight(loc);
|
|
|
|
LOG("fishing","updateFishingLocation: revised location = " + loc.toString());
|
|
|
|
if ( !isLocationFishable(loc) )
|
|
{
|
|
LOG("fishing","updateFishingLocation: revised location not fishable.. stop fishing...");
|
|
sendSystemMessage(target, SID_LOCATION_UNFISHABLE);
|
|
stopFishing(target);
|
|
return;
|
|
}
|
|
|
|
LOG("fishing","updateFishingLocation: updating scriptvar location ...");
|
|
setLocation(marker, loc);
|
|
faceTo(marker, target);
|
|
|
|
checkForSnag(target, loc);
|
|
}
|
|
|
|
void updateFishingLocation(obj_id target, int action)
|
|
{
|
|
updateFishingLocation(target, action, false);
|
|
}
|
|
|
|
void setFishingState(obj_id target, int state)
|
|
{
|
|
LOG("fishing","setFishingState: entered... target = " + target + " state = " + state);
|
|
if ( !isIdValid(target) )
|
|
return;
|
|
|
|
utils.setScriptVar(target, SCRIPTVAR_STATUS, state);
|
|
|
|
switch ( state )
|
|
{
|
|
case FS_WAIT:
|
|
//utils.removeScriptVar(target, SCRIPTVAR_BONUS);
|
|
break;
|
|
|
|
case FS_NIBBLE:
|
|
markerFlyText(target, FLY_NIBBLE, colors.GREEN);
|
|
sendSystemMessage(target, SID_FS_NIBBLE);
|
|
break;
|
|
|
|
case FS_BITE:
|
|
markerFlyText(target, FLY_BITE, colors.SALMON);
|
|
sendSystemMessage(target, SID_FS_BITE);
|
|
break;
|
|
|
|
case FS_CAUGHT:
|
|
markerFlyText(target, FLY_CATCH, colors.GOLDYELLOW);
|
|
sendSystemMessage(target, SID_FS_CAUGHT);
|
|
break;
|
|
|
|
case FS_SNAG:
|
|
markerFlyText(target, FLY_SNAG, colors.ORANGERED);
|
|
sendSystemMessage(target, SID_FS_SNAG);
|
|
break;
|
|
|
|
case FS_LOOT:
|
|
markerFlyText(target, FLY_CATCH, colors.GOLDYELLOW);
|
|
sendSystemMessage(target, SID_FS_LOOT);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if ( state == FS_LOOT || state == FS_CAUGHT )
|
|
utils.setScriptVar(target, SCRIPTVAR_CAUGHT, true);
|
|
}
|
|
|
|
void updateFishingWaitState(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return;
|
|
|
|
float bonus = 0f;
|
|
if ( utils.hasScriptVar(target, SCRIPTVAR_BONUS) )
|
|
bonus = utils.getFloatScriptVar(target, SCRIPTVAR_BONUS);
|
|
|
|
bonus += rand(0f, 0.05f);
|
|
utils.setScriptVar(target, SCRIPTVAR_BONUS, bonus);
|
|
}
|
|
|
|
boolean checkForNibble(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return false;
|
|
|
|
int baitStatus = getBaitStatus(target);
|
|
if ( baitStatus <= BS_NONE )
|
|
return false;
|
|
|
|
//TO DO: check for nibble and update state is necessary
|
|
float bonus = 0f;
|
|
if ( utils.hasScriptVar(target, SCRIPTVAR_BONUS) )
|
|
bonus = utils.getFloatScriptVar(target, SCRIPTVAR_BONUS);
|
|
|
|
obj_id marker = utils.getObjIdScriptVar(target, SCRIPTVAR_MARKER);
|
|
if ( !isIdValid(marker) )
|
|
{
|
|
stopFishing(target);
|
|
return false;
|
|
}
|
|
|
|
location there = getLocation(marker);
|
|
if ( there == null )
|
|
{
|
|
stopFishing(target);
|
|
return false;
|
|
}
|
|
|
|
float eff = getFishEfficiency(there);
|
|
|
|
float chance = eff + bonus;
|
|
float roll = rand(0f, 1f);
|
|
|
|
if ( roll == 0f )
|
|
{
|
|
bonus += rand(0.1f, 0.2f);
|
|
utils.setScriptVar(target, SCRIPTVAR_BONUS, bonus);
|
|
|
|
if ( !checkForBite(target, 0.3f) )
|
|
{
|
|
sendSystemMessage(target, SID_HARD_NIBBLE);
|
|
utils.setScriptVar(target, SCRIPTVAR_STATUS, FS_NIBBLE);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
if ( roll < chance )
|
|
{
|
|
bonus += rand(0.05f, 0.1f);
|
|
utils.setScriptVar(target, SCRIPTVAR_BONUS, bonus);
|
|
|
|
setFishingState(target, FS_NIBBLE);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
boolean checkForBite(obj_id target, float superBonus)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return false;
|
|
|
|
int baitStatus = getBaitStatus(target);
|
|
if ( baitStatus <= BS_NONE )
|
|
return false;
|
|
|
|
//TO DO: check for nibble and update state is necessary
|
|
float bonus = 0f;
|
|
if ( utils.hasScriptVar(target, SCRIPTVAR_BONUS) )
|
|
bonus = utils.getFloatScriptVar(target, SCRIPTVAR_BONUS);
|
|
|
|
obj_id marker = utils.getObjIdScriptVar(target, SCRIPTVAR_MARKER);
|
|
if ( !isIdValid(marker) )
|
|
{
|
|
stopFishing(target);
|
|
return false;
|
|
}
|
|
|
|
location there = getLocation(marker);
|
|
if ( there == null )
|
|
{
|
|
stopFishing(target);
|
|
return false;
|
|
}
|
|
|
|
float eff = getFishEfficiency(there);
|
|
|
|
float poleBonus = getPoleBonus(target);
|
|
|
|
float chance = eff + bonus + superBonus + poleBonus;
|
|
float roll = rand(0f, 1f);
|
|
|
|
if ( roll < 0.05f )
|
|
{
|
|
sendSystemMessage(target, SID_HARD_BITE);
|
|
|
|
//set bonus to POSTITIVE_INFINITY so cant fail catch
|
|
utils.setScriptVar(target, SCRIPTVAR_BONUS, Float.POSITIVE_INFINITY);
|
|
utils.setScriptVar(target, SCRIPTVAR_STATUS, FS_BITE);
|
|
return true;
|
|
}
|
|
|
|
if ( roll < chance )
|
|
{
|
|
bonus += rand(0.05f, 0.1f);
|
|
utils.setScriptVar(target, SCRIPTVAR_BONUS, bonus);
|
|
setFishingState(target, FS_BITE);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
boolean checkForBite(obj_id target)
|
|
{
|
|
return checkForBite(target, 0f);
|
|
}
|
|
|
|
boolean checkForCatch(obj_id target, float superBonus)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return false;
|
|
|
|
int baitStatus = getBaitStatus(target);
|
|
if ( baitStatus <= BS_NONE )
|
|
return false;
|
|
|
|
//TO DO: check for nibble and update state is necessary
|
|
float bonus = 0f;
|
|
if ( utils.hasScriptVar(target, SCRIPTVAR_BONUS) )
|
|
bonus = utils.getFloatScriptVar(target, SCRIPTVAR_BONUS);
|
|
|
|
boolean caughtFish = false;
|
|
if ( bonus == Float.POSITIVE_INFINITY )
|
|
{
|
|
caughtFish = true;
|
|
}
|
|
else
|
|
{
|
|
float poleBonus = getPoleBonus(target);
|
|
|
|
float chance = 0.25f + bonus + superBonus + poleBonus;
|
|
float roll = rand(0f, 1f);
|
|
if ( roll < chance )
|
|
{
|
|
caughtFish = true;
|
|
}
|
|
}
|
|
|
|
if ( caughtFish )
|
|
{
|
|
setFishingState(target, FS_CAUGHT);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
boolean checkForCatch(obj_id target)
|
|
{
|
|
return checkForCatch(target, 0f);
|
|
}
|
|
|
|
boolean checkForSnag(obj_id target, location loc)
|
|
{
|
|
if ( !isIdValid(target) || loc == null )
|
|
return false;
|
|
|
|
float eff = getVegetationSnagFactor(loc);
|
|
if ( eff > rand(0.3f, 1f) )
|
|
{
|
|
setFishingState(target, FS_SNAG);
|
|
utils.setScriptVar(target, SCRIPTVAR_BONUS, eff);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
float getFishEfficiency(location loc)
|
|
{
|
|
if ( loc == null )
|
|
return -1f;
|
|
|
|
//string rType = "seafood_fish";
|
|
string rType = "seafood_fish_" + loc.area;
|
|
LOG("fishing","getFishEfficiency: rType = " + rType);
|
|
obj_id resourceId = pickRandomNonDepeletedResource(rType);
|
|
if ( (resourceId == null) || (resourceId == obj_id.NULL_ID) )
|
|
{
|
|
return -1f;
|
|
}
|
|
|
|
return getResourceEfficiency( resourceId, loc );
|
|
}
|
|
|
|
float getVegetationSnagFactor(location loc)
|
|
{
|
|
if ( loc == null )
|
|
return -1f;
|
|
|
|
obj_id resourceId = pickRandomNonDepeletedResource("vegetable_greens");
|
|
if ( (resourceId == null) || (resourceId == obj_id.NULL_ID) )
|
|
{
|
|
return -1f;
|
|
}
|
|
|
|
return getResourceEfficiency( resourceId, loc );
|
|
}
|
|
|
|
void freeSnaggedLine(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return;
|
|
|
|
sendSystemMessage(target, SID_LINE_FREE);
|
|
setFishingState(target, FS_WAIT);
|
|
utils.removeScriptVar(target, SCRIPTVAR_BONUS);
|
|
}
|
|
|
|
void snapFishingLine(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return;
|
|
|
|
sendSystemMessage(target, SID_LINE_SNAP);
|
|
decrementBait(target);
|
|
stopFishing(target);
|
|
}
|
|
|
|
void spoolFishingLine(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return;
|
|
|
|
sendSystemMessage(target, SID_LINE_SPOOLED);
|
|
decrementBait(target);
|
|
stopFishing(target);
|
|
}
|
|
|
|
void caughtLoot(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return;
|
|
|
|
setFishingState(target, FS_LOOT);
|
|
utils.removeScriptVar(target, SCRIPTVAR_BONUS);
|
|
}
|
|
|
|
void lostBait(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return;
|
|
|
|
if ( !isFishing(target) )
|
|
return;
|
|
|
|
decrementBait(target);
|
|
|
|
sendSystemMessage(target, SID_LOST_BAIT);
|
|
stopFishing(target);
|
|
}
|
|
|
|
void decrementBait(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return;
|
|
|
|
if ( !isFishing(target) )
|
|
return;
|
|
|
|
obj_id pole = utils.getObjIdScriptVar(target, SCRIPTVAR_POLE);
|
|
if ( !isIdValid(pole) )
|
|
return;
|
|
|
|
if ( !isFishingPole(pole) )
|
|
return;
|
|
|
|
obj_id bait = getBait(pole);
|
|
if ( !isIdValid(bait) )
|
|
return;
|
|
|
|
if ( !hasObjVar(bait, VAR_FISHING_BAIT_STATUS) )
|
|
return;
|
|
|
|
int baitStatus = getIntObjVar(bait, VAR_FISHING_BAIT_STATUS);
|
|
if ( baitStatus != BS_NONE )
|
|
{
|
|
setObjVar(bait, VAR_FISHING_BAIT_STATUS, BS_NONE);
|
|
incrementCount(bait, -1);
|
|
|
|
if ( getCount(bait) < 1 )
|
|
{
|
|
sendSystemMessage(target, new string_id(STF_FISH, "out_of_bait")); // You have run out of bait in your tackle...
|
|
destroyObject(bait);
|
|
}
|
|
}
|
|
}
|
|
|
|
int[] getGoodActions()
|
|
{
|
|
int numActions = rand(1, 2);
|
|
int[] ret = new int[numActions];
|
|
for ( int i = 0; i < numActions; i++ )
|
|
{
|
|
ret[i] = rand(FA_TUG_UP, FA_TUG_LEFT);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void confirmReelIn(obj_id target, location castLoc)
|
|
{
|
|
if ( !isIdValid(target) || (castLoc == null) )
|
|
return;
|
|
|
|
if ( !isFishing(target) )
|
|
return;
|
|
|
|
int status = utils.getIntScriptVar(target, SCRIPTVAR_STATUS);
|
|
if ( status != FS_CAUGHT && status != FS_LOOT )
|
|
return;
|
|
|
|
int base_chance = 40;
|
|
float bonus = utils.getFloatScriptVar(target, SCRIPTVAR_BONUS);
|
|
int chance = base_chance + (int)(bonus*100);
|
|
|
|
boolean lostCatch = false;
|
|
int roll = rand(0,100);
|
|
|
|
if(isGod(target))
|
|
{
|
|
roll = 1;
|
|
debugSpeakMsg(target, "Bypassing -minigame.loseCatch- due to God Mode!");
|
|
}
|
|
|
|
if ( roll > 98 ) //standard % lose catch chance
|
|
{
|
|
lostCatch = true;
|
|
}
|
|
|
|
if ( lostCatch )
|
|
{
|
|
//lost catch!
|
|
loseCatch(target);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
//do caught something stuff here
|
|
sendSystemMessage(target, SID_REEL_IN);
|
|
float delay = rand(1.5f, 5f);
|
|
|
|
dictionary params = new dictionary();
|
|
params.put("castLoc", castLoc);
|
|
|
|
messageTo(target, HANDLER_REEL_IN, params, delay, false);
|
|
}
|
|
}
|
|
|
|
void loseCatch(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return;
|
|
|
|
sendSystemMessage(target, SID_LOST_CATCH);
|
|
lostBait(target);
|
|
}
|
|
|
|
void markerFlyText(obj_id target, string_id sid, color textColor)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return;
|
|
|
|
if ( sid == null )
|
|
return;
|
|
|
|
if ( textColor == null )
|
|
return;
|
|
|
|
obj_id marker = utils.getObjIdScriptVar(target, SCRIPTVAR_MARKER);
|
|
if ( !isIdValid(marker) )
|
|
return;
|
|
|
|
showFlyText(marker, sid, 1.0f, textColor);
|
|
}
|
|
|
|
float getPoleBonus(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return 0f;
|
|
|
|
obj_id pole = utils.getObjIdScriptVar(target, SCRIPTVAR_POLE);
|
|
if ( !isIdValid(pole) )
|
|
return 0f;
|
|
|
|
if ( !isFishingPole(pole) )
|
|
return 0f;
|
|
|
|
int useModifier = getIntObjVar(pole, "useModifier");
|
|
|
|
float bonus = useModifier/500f;
|
|
return bonus;
|
|
}
|
|
|
|
obj_id spawnFishingFish(obj_id target, location castLoc)
|
|
{
|
|
LOG("fishingLog", "target = " + target);
|
|
|
|
if(!isIdValid(target) || castLoc == null)
|
|
return null;
|
|
|
|
obj_id inv = utils.getInventoryContainer(target);
|
|
if (!isIdValid(inv))
|
|
return null;
|
|
|
|
int volFree = getVolumeFree(inv);
|
|
if(volFree < 1)
|
|
{
|
|
sendSystemMessage(target, new string_id(STF_FISH, "inventory_full")); // Since your inventory is full, you toss the fish back...
|
|
return null;
|
|
}
|
|
|
|
//queueCommand(target, ##"kneel", null, "", COMMAND_PRIORITY_DEFAULT);
|
|
|
|
dictionary row = getFishData(target, castLoc);
|
|
|
|
if(row == null || row.isEmpty())
|
|
{
|
|
//debugSpeakMsg(target, "getFishData() returned null...");
|
|
createVegetation(target, inv, castLoc);
|
|
return null;
|
|
}
|
|
|
|
obj_id fish = obj_id.NULL_ID;
|
|
string fishName = row.getString("generic");
|
|
LOG("fishingLog", "fishName = " + fishName);
|
|
if(static_item.isStaticItem(fishName))
|
|
{
|
|
|
|
//debugSpeakMsg(target, "static item creation");
|
|
fish = static_item.createNewItemFunction(fishName, inv); // failed somehow
|
|
LOG("fishingLog", "Static Fish= " + fish);
|
|
}
|
|
else
|
|
{
|
|
// get template name from datatables/fishing/fish/fish_template.iff
|
|
dictionary templateRow = dataTableGetRow(TBL_TEMPLATE, fishName);
|
|
string templateFish = templateRow.getString("template");
|
|
LOG("fishingLog", "this is the templateFish - non-static -= "+templateFish);
|
|
//string template = row.getString(COL_TEMPLATE);
|
|
if(templateFish == null || templateFish.equals(""))
|
|
{
|
|
createVegetation(target, inv, castLoc);
|
|
return null;
|
|
}
|
|
fish = createObject(templateFish, inv, "");
|
|
|
|
LOG("fishingLog", "this is the fish created - "+ fish);
|
|
}
|
|
|
|
|
|
//string path = "object/tangible/fishing/fish/" + template; //
|
|
//obj_id fish = createObject(path, inv, "");
|
|
if(!isIdValid(fish))
|
|
{
|
|
//debugSpeakMsg(target, "unable to create fish from template: ");
|
|
sendSystemMessage(target, new string_id(STF_FISH, "size_matters")); // The fish was too small, so you toss it back...
|
|
return null;
|
|
}
|
|
|
|
row = dataTableGetRow(TBL_TEMPLATE, fishName);
|
|
if(row == null)
|
|
{
|
|
LOG("fishingLog", "row is null...wtf");
|
|
}
|
|
LOG("fishingLog", "datatable ROW - " + row);
|
|
|
|
setFishData(fish, row, target, castLoc);
|
|
// Award Wilderness Survival xp for this catch.
|
|
//int fish_xp = utils.getIntScriptVar( fish, "fish_xp" );
|
|
//xp.grant( target, xp.SCOUT, fish_xp, true );
|
|
|
|
//queueCommand(target, ##"stand", null, "", COMMAND_PRIORITY_DEFAULT);
|
|
return fish;
|
|
}
|
|
|
|
dictionary getFishData(obj_id target, location castLoc)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if ( castLoc == null )
|
|
{
|
|
return null;
|
|
}
|
|
|
|
int tableChance = rand(1,100); // roll for which table to loot from
|
|
string fishLootTable = "";
|
|
|
|
if(tableChance <= ROLL_FISH_OR_JUNK) // loot from fish table
|
|
{
|
|
string planetName = getCurrentSceneName();
|
|
fishLootTable = "datatables/fishing/fish/" + planetName + ".iff";
|
|
}
|
|
else // loot from generic table (fish tank parts and treasure maps)
|
|
{
|
|
fishLootTable = "datatables/fishing/loot/generic.iff";
|
|
}
|
|
|
|
string[] names = dataTableGetStringColumnNoDefaults(fishLootTable, "generic");
|
|
|
|
string name = "";
|
|
if ( names == null || names.length == 0 )
|
|
{
|
|
name = "fish_generic";
|
|
return null;
|
|
}
|
|
|
|
int idx = rand(0, names.length - 1);
|
|
name = names[idx];
|
|
|
|
if ( name == null || name.equals("") )
|
|
name = "fish_generic";
|
|
|
|
return dataTableGetRow(fishLootTable, name);
|
|
}
|
|
|
|
boolean setFishData(obj_id fish, dictionary params, obj_id player, location castLoc)
|
|
{
|
|
LOG("fishingLog", "static fish - after passing to SetFishData - " + fish);
|
|
LOG("fishingLog", "params? - " + params);
|
|
|
|
if ( !isIdValid(fish) || !isIdValid(player) )
|
|
return false;
|
|
|
|
if ( params == null || params.isEmpty() )
|
|
return false;
|
|
|
|
if ( castLoc == null )
|
|
castLoc = getLocation(player);
|
|
|
|
string name = params.getString(COL_NAME);
|
|
if ( name == null || name.equals("") )
|
|
return false;
|
|
|
|
string_id sid_name = new string_id("fish_n",name);
|
|
if ( getString(sid_name) != null )
|
|
setName(fish, sid_name);
|
|
|
|
int timeCaught = getCalendarTime();
|
|
|
|
if(timeCaught > 0)
|
|
{
|
|
setObjVar(fish, VAR_FISH_TIME_STAMP, timeCaught);
|
|
}
|
|
|
|
string playerName = getPlayerFullName(player);
|
|
|
|
if(playerName != null || playerName != "")
|
|
{
|
|
setObjVar(fish, VAR_FISH_CATCHER, playerName);
|
|
}
|
|
|
|
setObjVar(fish, VAR_FISH_NAME, name);
|
|
|
|
setObjVar(fish, VAR_FISH_LOCATION, castLoc);
|
|
|
|
setObjVar(fish, VAR_FISH_STAMP, getGameTime());
|
|
|
|
float lengthMin = params.getFloat(COL_LENGTH_MIN);
|
|
float lengthNorm = params.getFloat(COL_LENGTH_NORM);
|
|
float absoluteLengthMax = params.getFloat(COL_LENGTH_MAX);
|
|
|
|
float dLength = lengthNorm - lengthMin;
|
|
float lengthMax = lengthNorm + dLength;
|
|
|
|
float length = rand(lengthMin, lengthMax);
|
|
float lengthPercentile = 1.0f;
|
|
if ( lengthMin != lengthMax )
|
|
{
|
|
lengthPercentile = (length - lengthMin)/(lengthMax - lengthMin);
|
|
if ( lengthPercentile > 0.95f )
|
|
{
|
|
float dPercentile = 0f;
|
|
do
|
|
{
|
|
float toAdd = rand(0f, dLength);
|
|
length += toAdd;
|
|
|
|
dPercentile = toAdd/dLength;
|
|
} while ( dPercentile > 0.95f && length < absoluteLengthMax );
|
|
}
|
|
}
|
|
|
|
if ( length > absoluteLengthMax )
|
|
length = absoluteLengthMax;
|
|
|
|
setObjVar(fish, VAR_FISH_LENGTH, length);
|
|
|
|
// Assign an xp value based on the fish length.
|
|
int xp = (int) (90.f * (length / lengthNorm));
|
|
utils.setScriptVar( fish, "fish_xp", xp );
|
|
|
|
int resourceMin = params.getInt(COL_RESOURCE_MIN);
|
|
int resourceNorm = params.getInt(COL_RESOURCE_NORM);
|
|
int absoluteResourceMax = params.getInt(COL_RESOURCE_MAX);
|
|
|
|
int dResource = resourceNorm - resourceMin;
|
|
int resourceMax = resourceNorm + dResource;
|
|
|
|
int resourceAmt = rand(resourceMin, resourceMax);
|
|
float resourcePercentile = 1.0f;
|
|
if ( resourceMin != resourceMax )
|
|
{
|
|
resourcePercentile = (resourceAmt - resourceMin)/(resourceMax - resourceMin);
|
|
if ( resourcePercentile > 0.95f )
|
|
{
|
|
float dPercentile = 0f;
|
|
do
|
|
{
|
|
int toAdd = rand(0, dResource);
|
|
resourceAmt += toAdd;
|
|
|
|
dPercentile = toAdd/dResource;
|
|
} while ( dPercentile > 0.95f && resourceAmt < absoluteResourceMax );
|
|
}
|
|
}
|
|
|
|
if ( resourceAmt > absoluteResourceMax )
|
|
resourceAmt = absoluteResourceMax;
|
|
|
|
if ( resourceAmt > 0 )
|
|
{
|
|
string resourceType = params.getString(COL_RESOURCE_TYPE);
|
|
if ( resourceType != null && !resourceType.equals("") )
|
|
{
|
|
resource.createRandom(resourceType, resourceAmt, castLoc, fish, player, 1);
|
|
}
|
|
}
|
|
|
|
int chumNorm = params.getInt(COL_CHUM_NORM);
|
|
|
|
int chumAmt = chumNorm;
|
|
if ( resourceMax != resourceMin)
|
|
{
|
|
float percentile = (resourceAmt - resourceMin)/(resourceMax - resourceMin);
|
|
chumAmt = chumNorm + (int)rand(-percentile, percentile);
|
|
}
|
|
|
|
if ( chumAmt > 0 )
|
|
{
|
|
obj_id chum = createObject("object/tangible/fishing/bait/bait_chum.iff", fish, "");
|
|
if ( isIdValid(chum) )
|
|
setCount(chum, chumAmt);
|
|
}
|
|
|
|
int hue1 = params.getInt(COL_HUE1);
|
|
if ( hue1 > -1 )
|
|
hue.setColor(fish, 1, hue1);
|
|
|
|
int hue2 = params.getInt(COL_HUE2);
|
|
if ( hue2 > -1 )
|
|
hue.setColor(fish, 2, hue2);
|
|
|
|
return true;
|
|
}
|
|
|
|
boolean filetFish(obj_id target, obj_id fish)
|
|
{
|
|
if ( !isIdValid(target) || !isIdValid(fish) )
|
|
return false;
|
|
|
|
obj_id[] contents = getContents(fish);
|
|
if ( contents == null || contents.length == 0 )
|
|
{
|
|
sendSystemMessage(target, new string_id(STF_FISH, "already_fileted")); // But this fish has already been fileted.
|
|
return false;
|
|
}
|
|
|
|
obj_id inv = utils.getInventoryContainer(target);
|
|
if ( !isIdValid(inv) )
|
|
return false;
|
|
|
|
int volFree = getVolumeFree(inv);
|
|
if ( volFree < contents.length )
|
|
{
|
|
sendSystemMessageProse(target, prose.getPackage(new string_id (STF_FISH, "units_inventory"), contents.length)); // You require %DI units of available space in your inventory to filet this fish.
|
|
return false;
|
|
}
|
|
|
|
int cec = moveContents(fish, inv);
|
|
if ( cec == CEC_SUCCESS || cec == CEC_ADD_SELF )
|
|
sendSystemMessage(target, new string_id(STF_FISH, "good_filet")); // You successfully filet the fish.
|
|
else
|
|
{
|
|
//debugSpeakMsg(target, "CEC = " + cec);
|
|
sendSystemMessage(target, new string_id(STF_FISH, "no_resource")); // There was no salvagable resource to harvest.
|
|
}
|
|
|
|
return trophyFish(target, fish);
|
|
}
|
|
|
|
boolean trophyFish(obj_id target, obj_id fish)
|
|
{
|
|
if ( !isIdValid(target) || !isIdValid(fish) )
|
|
return false;
|
|
|
|
//sendSystemMessageTestingOnly(target, "Make Trophy functionality not implemented... yet!");
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
void createVegetation(obj_id target, obj_id inv, location castLoc)
|
|
{
|
|
if ( !isIdValid(target) || !isIdValid(inv) || castLoc == null )
|
|
return;
|
|
|
|
sendSystemMessage(target, new string_id(STF_FISH, "shucks_veggies")); // Shucks... It was really just a handful of vegetation.
|
|
resource.createRandom("vegetable_greens", 2, castLoc, inv, target, 1);
|
|
}
|
|
|
|
obj_id[] spawnFishingLoot(obj_id target, location castLoc)
|
|
{
|
|
if ( !isIdValid(target) || castLoc == null )
|
|
return null;
|
|
|
|
obj_id inv = utils.getInventoryContainer(target);
|
|
if ( !isIdValid(inv) )
|
|
return null;
|
|
|
|
int volFree = getVolumeFree(inv);
|
|
if ( volFree < 1 )
|
|
{
|
|
sendSystemMessage(target, new string_id(STF_FISH, "toss_trash")); // Since your inventory is full, you toss the trash back in the water...
|
|
return null;
|
|
}
|
|
|
|
int lvl = rand(1,10);
|
|
while ( lvl % 10 == 0 )
|
|
{
|
|
lvl += rand(1,10);
|
|
}
|
|
return null;
|
|
}
|