mirror of
https://bitbucket.org/seefoe/dsrc.git
synced 2026-07-31 01:15:55 -04:00
414 lines
11 KiB
Plaintext
414 lines
11 KiB
Plaintext
/**
|
|
* Title: meditation.scriptlib
|
|
* Description: scriptlib for meditation related functions
|
|
*/
|
|
|
|
/***** INCLUDES ********************************************************/
|
|
|
|
include library.dot;
|
|
include library.chat;
|
|
include library.utils;
|
|
include library.consumable;
|
|
include library.trial;
|
|
|
|
/***** CONSTANTS *******************************************************/
|
|
|
|
const float TIME_TICK = 5.0f;
|
|
const float DELAY_MIN = 3f;
|
|
const float DELAY_MAX = 7f;
|
|
|
|
const float RAND_MODIFIER = 0.33f;
|
|
|
|
const float POWERBOOST_RAMP = 60f;
|
|
|
|
const string MOD_MEDITATE = "meditate";
|
|
|
|
const string VAR_MEDITATION_BASE = "meditation";
|
|
|
|
const string VAR_POWERBOOST_ACTIVE = "meditation.powerBoost";
|
|
|
|
const string VAR_FORCE_OF_WILL_ACTIVE = "meditation.forceOfWill";
|
|
|
|
const string SCRIPT_MEDITATE = "player.skill.meditate";
|
|
|
|
const string HANDLER_MEDITATION_TICK = "handleMeditationTick";
|
|
|
|
const string HANDLER_POWERBOOST_WANE = "handlePowerBoostWane"; //in player.skill.cleanup
|
|
const string HANDLER_POWERBOOST_END = "handlePowerBoostEnd"; //in player.skill.cleanup
|
|
|
|
const string STF_TERASKASI = "teraskasi";
|
|
|
|
const string_id SID_MED_BEGIN = new string_id(STF_TERASKASI, "med_begin");
|
|
const string_id SID_MED_END = new string_id(STF_TERASKASI, "med_end");
|
|
const string_id SID_MED_FAIL = new string_id(STF_TERASKASI, "med_fail");
|
|
|
|
const string_id SID_POWERBOOST_BEGIN = new string_id(STF_TERASKASI, "powerboost_begin");
|
|
const string_id SID_POWERBOOST_WANE = new string_id(STF_TERASKASI, "powerboost_wane");
|
|
const string_id SID_POWERBOOST_END = new string_id(STF_TERASKASI, "powerboost_end");
|
|
const string_id SID_POWERBOOST_FAIL = new string_id(STF_TERASKASI, "powerboost_fail");
|
|
const string_id SID_POWERBOOST_ACTIVE = new string_id(STF_TERASKASI, "powerboost_active");
|
|
const string_id SID_POWERBOOST_MIND = new string_id(STF_TERASKASI, "powerboost_mind");
|
|
|
|
const string_id SID_FORCEOFWILL = new string_id(STF_TERASKASI, "forceofwill");
|
|
const string_id SID_FORCEOFWILL_UNSUCCESSFUL= new string_id(STF_TERASKASI, "forceofwill_unsuccessful");
|
|
const string_id SID_FORCEOFWILL_FAIL = new string_id(STF_TERASKASI, "forceofwill_fail");
|
|
const string_id SID_FORCEOFWILL_LOST = new string_id(STF_TERASKASI, "forceofwill_lost");
|
|
const string_id SID_FORCEOFWILL_UNAVAILABLE = new string_id(STF_TERASKASI, "forceofwill_unavailable");
|
|
|
|
const string_id SID_MUST_BE_MEDITATING = new string_id(STF_TERASKASI, "must_be_meditating");
|
|
const string_id SID_STATE_PREVENTS_POWERBOOST = new string_id(STF_TERASKASI, "state_prevent_powerboost");
|
|
const string_id SID_MIND_POOL_TOO_LOW = new string_id(STF_TERASKASI, "mind_pool_too_low");
|
|
|
|
const string_id PROSE_CUREWOUND = new string_id(STF_TERASKASI, "prose_curewound");
|
|
|
|
//meditate buffs
|
|
const string[] MEDITATE_BUFFS = {
|
|
"fs_meditate_1",
|
|
"fs_meditate_2",
|
|
"fs_meditate_3"
|
|
};
|
|
|
|
|
|
/***** FUNCTIONS ********************************************************/
|
|
int getMeditationSkillMod(obj_id player)
|
|
{
|
|
if ( !isIdValid(player) )
|
|
return -1;
|
|
|
|
int meditate = getEnhancedSkillStatisticModifierUncapped(player, MOD_MEDITATE);
|
|
return meditate;
|
|
}
|
|
|
|
/************************************************************************
|
|
* @brief begings meditation
|
|
*
|
|
* @param obj_id player
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean startMeditation(obj_id player)
|
|
{
|
|
if ( !isIdValid(player) )
|
|
return false;
|
|
|
|
setState(player, STATE_MEDITATE, true);
|
|
chat.setTempAnimationMood(player, "meditating");
|
|
messageTo(player, HANDLER_MEDITATION_TICK, trial.getSessionDict(player, meditation.HANDLER_MEDITATION_TICK), TIME_TICK, false);
|
|
|
|
sendSystemMessage(player, SID_MED_BEGIN);
|
|
|
|
return true;
|
|
}
|
|
|
|
/************************************************************************
|
|
* @brief terminates meditation
|
|
*
|
|
* @param obj_id player
|
|
*
|
|
* @return void
|
|
***********************************************************************/
|
|
void endMeditation(obj_id player, boolean verbose)
|
|
{
|
|
if ( !isIdValid(player) )
|
|
return;
|
|
|
|
setState(player, STATE_MEDITATE, false);
|
|
chat.resetTempAnimationMood(player);
|
|
utils.removeScriptVar(player, VAR_MEDITATION_BASE);
|
|
//fingerprinted messageto loop, we need to kill it
|
|
trial.bumpSession(player, meditation.HANDLER_MEDITATION_TICK);
|
|
|
|
if ( verbose )
|
|
sendSystemMessage(player, SID_MED_END);
|
|
}
|
|
|
|
void endMeditation(obj_id player)
|
|
{
|
|
endMeditation(player, true);
|
|
}
|
|
|
|
/************************************************************************
|
|
* @brief determines if a player is meditating
|
|
*
|
|
* @param obj_id player
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean isMeditating(obj_id player)
|
|
{
|
|
if ( !isIdValid(player) )
|
|
return false;
|
|
|
|
if (getState(player, STATE_MEDITATE) == 1)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/************************************************************************
|
|
* @brief handle what occurs during a meditation tick
|
|
*
|
|
* @param obj_id player
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
float trance(obj_id player)
|
|
{
|
|
if ( !isIdValid(player) )
|
|
return -1f;
|
|
|
|
int modval = getMeditationSkillMod(player);
|
|
if ( (modval < 1) || !isMeditating(player) )
|
|
return -1f;
|
|
|
|
float delay = 0f;
|
|
|
|
LOG("meditate","trance: slotDot -> DOT_BLEEDING");
|
|
delay = slowDOT(player, modval, dot.DOT_BLEEDING);
|
|
|
|
if ( modval > 20 && delay == 0f )
|
|
{
|
|
LOG("meditate","trance: slotDot -> DOT_POISON");
|
|
delay = slowDOT(player, modval, dot.DOT_POISON);
|
|
}
|
|
|
|
if ( modval > 40 && delay == 0f )
|
|
{
|
|
LOG("meditate","trance: slotDot -> DOT_DISEASE");
|
|
delay = slowDOT(player, modval, dot.DOT_DISEASE);
|
|
}
|
|
|
|
if ( modval > 60 && delay == 0f )
|
|
{
|
|
LOG("meditate","trance: cureWounds...");
|
|
delay = cureWounds(player, modval);
|
|
}
|
|
|
|
LOG("meditate","trance: pre-ret delay = " + delay);
|
|
|
|
if ( delay > 0f )
|
|
{
|
|
if ( delay < DELAY_MIN )
|
|
delay = DELAY_MIN;
|
|
|
|
if ( delay > DELAY_MAX )
|
|
delay = DELAY_MAX;
|
|
}
|
|
|
|
return delay;
|
|
}
|
|
|
|
/************************************************************************
|
|
* @brief handle what occurs during a meditation tick
|
|
*
|
|
* @param obj_id player
|
|
*
|
|
* @return float
|
|
***********************************************************************/
|
|
float slowDOT(obj_id player, int modval, string dotType)
|
|
{
|
|
if ( !isIdValid(player) )
|
|
return 0f;
|
|
|
|
int totalCured = 0;
|
|
int toCure = getDOTReductionAmount(player);
|
|
if ( toCure > 0 )
|
|
{
|
|
totalCured = dot.reduceDotTypeStrength(player, dotType, toCure);
|
|
}
|
|
|
|
if ( totalCured < 0f )
|
|
return 0f;
|
|
|
|
//return (float)(totalCured);
|
|
return 5f;
|
|
}
|
|
|
|
/************************************************************************
|
|
* @brief handle what occurs during a meditation tick
|
|
*
|
|
* @param obj_id player
|
|
*
|
|
* @return int
|
|
***********************************************************************/
|
|
int getDOTReductionAmount(obj_id player)
|
|
{
|
|
if ( !isIdValid(player) )
|
|
return -1;
|
|
|
|
int dotMod = getSkillStatMod(player, "private_med_dot");
|
|
|
|
float ret = (float)dotMod * (1f + rand(-RAND_MODIFIER, RAND_MODIFIER));
|
|
return Math.round(ret);
|
|
}
|
|
|
|
/************************************************************************
|
|
* @brief handle what occurs during a meditation tick
|
|
*
|
|
* @param obj_id player
|
|
*
|
|
* @return int
|
|
***********************************************************************/
|
|
int getWoundReductionAmount(obj_id player)
|
|
{
|
|
if ( !isIdValid(player) )
|
|
return -1;
|
|
|
|
int dotMod = getSkillStatMod(player, "private_med_wound");
|
|
|
|
float ret = (float)dotMod * (1f + rand(-RAND_MODIFIER, RAND_MODIFIER));
|
|
return Math.round(ret);
|
|
}
|
|
|
|
/************************************************************************
|
|
* @brief handle what occurs during a meditation tick
|
|
*
|
|
* @param obj_id player
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
float cureWounds(obj_id player, int modval)
|
|
{
|
|
if ( !isIdValid(player) )
|
|
return 0f;
|
|
|
|
dictionary toHeal = new dictionary();
|
|
if ( (toHeal == null) || (toHeal.isEmpty()) )
|
|
{
|
|
LOG("meditate","cureWounds: no wounds...");
|
|
return 0f;
|
|
}
|
|
|
|
//return (float)(totalCured);
|
|
return 5f;
|
|
}
|
|
|
|
/************************************************************************
|
|
* @brief attempts to bring the player back from incapacitation
|
|
*
|
|
* @param obj_id player
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean forceOfWill(obj_id player, int delta)
|
|
{
|
|
if ( !isIdValid(player) )
|
|
return false;
|
|
|
|
if ( delta < 0 )
|
|
delta = 0;
|
|
|
|
int modval = getMeditationSkillMod(player);
|
|
if ( (modval < 1) || getPosture(player) != POSTURE_INCAPACITATED )
|
|
return false;
|
|
|
|
if ( delta < 10 )
|
|
{
|
|
addShockWound(player, 100);
|
|
sendSystemMessage(player, new string_id(STF_TERASKASI, "forceofwill_crit_fail"));
|
|
}
|
|
else if ( delta < 40 )
|
|
{
|
|
for ( int i = 0; i < 3; i++ )
|
|
addAttribModifier(player, i*3, -200, 300, 0f, 0f);
|
|
|
|
addShockWound(player, 100);
|
|
sendSystemMessage(player, new string_id(STF_TERASKASI, "forceofwill_marginal"));
|
|
}
|
|
else if ( delta < 70 )
|
|
{
|
|
for ( int i = 0; i < 3; i++ )
|
|
addAttribModifier(player, i*3, -100, 300, 0f, 0f);
|
|
|
|
sendSystemMessage(player, new string_id(STF_TERASKASI, "forceofwill_normal"));
|
|
}
|
|
else
|
|
{
|
|
sendSystemMessage(player, new string_id(STF_TERASKASI, "forceofwill_exceptional"));
|
|
}
|
|
|
|
innate.equalizeEffect(player);
|
|
return true;
|
|
}
|
|
|
|
boolean forceOfWill(obj_id player)
|
|
{
|
|
if ( !isIdValid(player) )
|
|
return false;
|
|
|
|
return forceOfWill(player, rand(1,getMeditationSkillMod(player)));
|
|
}
|
|
|
|
/************************************************************************
|
|
* @brief attempts to bring the player back from incapacitation
|
|
*
|
|
* @param obj_id player
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean powerBoost(obj_id player)
|
|
{
|
|
if ( !isIdValid(player) )
|
|
return false;
|
|
|
|
int modval = getMeditationSkillMod(player);
|
|
if ( (modval < 1) )
|
|
return false;
|
|
|
|
if ( !isMeditating(player) )
|
|
{
|
|
sendSystemMessage(player, SID_MUST_BE_MEDITATING);
|
|
return false;
|
|
}
|
|
|
|
if ( hasObjVar(player, VAR_POWERBOOST_ACTIVE) )
|
|
{
|
|
sendSystemMessage(player, SID_POWERBOOST_ACTIVE);
|
|
return false;
|
|
}
|
|
|
|
int now = getGameTime();
|
|
float duration = 300f + (float)(modval) * 3 * rand(0.95f,1.05f);
|
|
|
|
//int maxMind = getWoundedMaxAttrib(player, MIND);
|
|
int maxMind = utils.getUnbuffedWoundedMaxAttrib(player, MIND);
|
|
if ( maxMind < 10 )
|
|
{
|
|
sendSystemMessage(player, SID_STATE_PREVENTS_POWERBOOST);
|
|
return false;
|
|
}
|
|
|
|
int boost = maxMind/2;
|
|
|
|
if ( getAttrib(player, MIND) <= boost )
|
|
{
|
|
sendSystemMessage(player, SID_MIND_POOL_TOO_LOW);
|
|
return false;
|
|
}
|
|
|
|
addAttribModifier(player, MIND, -boost, POWERBOOST_RAMP, 0f, 0f);
|
|
|
|
addAttribModifier(player, "meditation.powerboost.mind", MIND, boost, duration, POWERBOOST_RAMP, POWERBOOST_RAMP, false, false, true);
|
|
addAttribModifier(player, "meditation.powerboost.health", HEALTH, boost, duration, POWERBOOST_RAMP, POWERBOOST_RAMP, false, false, false);
|
|
addAttribModifier(player, "meditation.powerboost.action", ACTION, boost, duration, POWERBOOST_RAMP, POWERBOOST_RAMP, false, false, false);
|
|
|
|
int wane_time = (int)(duration + POWERBOOST_RAMP);
|
|
int expire_time = wane_time + (int)POWERBOOST_RAMP;
|
|
|
|
int expiration = now + expire_time;
|
|
setObjVar(player, VAR_POWERBOOST_ACTIVE, expiration);
|
|
|
|
dictionary d = new dictionary();
|
|
d.put("expiration", expiration);
|
|
|
|
messageTo(player, HANDLER_POWERBOOST_WANE, d, wane_time, false);
|
|
messageTo(player, HANDLER_POWERBOOST_END, d, expire_time, true);
|
|
|
|
// Log buff info
|
|
messageTo(player, "handlePowerBoostLog", null, POWERBOOST_RAMP*2, false);
|
|
|
|
sendSystemMessage(player, SID_POWERBOOST_BEGIN);
|
|
return true;
|
|
}
|