NWScript :
//:/
//:: Update Lylver 2005-12-12
//:: evt 550 : regenere les effets du aux custom items apres repos
//:/
//:: Update Lylver 2005-12-11
//:: correction erreur maladie
//:/
//:: Update Lylver 2005-10-15
//:: changement : ameliore critere bRepas
//:: manger = guerison complete
//:: maladie isolee
//:: rayon de la zone de tente augmente 7.0 au lieu de 5.0
//:/
//:: Update Lylver 2005-09-29
//:: variables pour les zones
//:: int REPOS :
//
// 1 - feu requis
// 2 - tente/abri requis
// 3 = 2 & 1 : les deux requis
//:: int MIASME : (positif) malus au jet de vigueur
//:: string REPOS1, message specifique de zone remplacant "Il fait froid"
//:: string REPOS2, message specifique de zone remplacant "Il fait humide"
//:/
//:: Update Lylver 2005-09-17
//:: repos non bloquant => maladie a la place
//:/
//:: Update Lylver 2005-09-16
//:: adaptation TN Bouchon 2
//://///////////////////////////////////
// Update Lylver 2005-08-01 : mise en fonction de la reputation
// Note : reste encore des pbs de repos intempestif (rares)
//::
// mod_onrest
// by dluan on sep 2003,
// updated Lylver 2004-04-17
// Update Lylver 2004-12-15 pour SoW 3h<>540s
// Update Lylver 2004-12-17 pour SoW materiel de camping.
// remplace x2_mod_def_rest a etudier
// Update Lylver 2005-06-03 : correction repos intempestif
// enlevant les sorts de facon aggressive
//://///////////////////////////////////
#include "nw_i0_plot"
#include "ly_lib_time"
#include "ly_lib_death"
#include "x0_i0_position"
void main()
{
object oPC = GetLastPCRested() ;
object oArea = GetArea(oPC);
object oMod = GetModule() ;
// code TN Bouchon specifique
object oFood ;
if(GetTag(oArea)=="Zone002")
{
SendMessageToPC(oPC,LocationToString(GetAheadLocation(oPC)));
return;
}
// code TN Bouchon specifique
int iHostileRange = 30;
int nDisease = 0 ;
int bRepas = FALSE ;
int nCirc = 0 ;
string sDisease = "";
// set a stack size
int i = 10;
// set an object equal to the provisions on the player. This will be
// OBJECT_INVALID if the player doesn't have any
object oProvisions = GetItemPossessedBy(oPC, "PROVISIONS");
int nSetting = GetLocalInt(oArea, "REPOS");
int nSetDis = GetLocalInt(oArea, "MIASME");
string sMessage1 = GetLocalString(oArea, "REPOS1");
string sMessage2 = GetLocalString(oArea, "REPOS2");
int nModif = GetAbilityModifier(ABILITY_CONSTITUTION,oPC); //... corrige 2005-03-28
int iCDay = ly_day() ;
int iCTime = ly_time() ;
int iRestDelay ;
int iRestDay ;
int iRestSecond ;
/* int RESTDELAY = 540 ; // Real Time 3min <=> 1h Game Play
// Repos toutes les 3 heures */
int RESTDELAY = 120 ; // Real Time 5min <=> 1h Game Play
// Repos toutes les 2 minutes irl
int curHP = GetCurrentHitPoints(oPC);
int maxHP = GetMaxHitPoints(oPC);
// debut du repos
if (GetLastRestEventType() == REST_EVENTTYPE_REST_STARTED) {
// code TN Bouchon partie 1/2
// Aliments pour manger, necessaire avant de se reposer.
SendMessageToPC(oPC,"Vous essayez de vous reposer....");
if( HasItem(oPC,"alimentderepos1") &&
HasItem(oPC,"alimentderepos2") &&
HasItem(oPC,"alimentderepos3") ){
WriteTimestampedLogEntry("Repos de "+GetName(oPC));
bRepas = TRUE ;
} else {
SendMessageToPC(oPC,"Vous n'avez pas ce qu'il faut pour vous nourrir avant de vous reposer");
SendMessageToPC(oPC,"Vous ressentirez la faim à votre réveil");
if( oProvisions == OBJECT_INVALID ){
bRepas = FALSE ;
} else {
bRepas = TRUE ;
}
// AssignCommand(oPC, ClearAllActions());
}
// code TN Bouchon partie 1/2
iRestDay = GetLocalInt(oPC, "PC_LastDayRest");
iRestSecond = GetLocalInt(oPC, "PC_LastRest") ;
iRestDelay = iCTime - iRestSecond + FloatToInt(HoursToSeconds((iCDay - iRestDay) * 24));
SetLocalInt(oPC, "PC_HPRest", curHP);
SetLocalInt(oPC, "PC_CNRest", nModif);
// si on a des provisions (pass-DM) : Repos Immediat
if (oProvisions != OBJECT_INVALID) { iRestDelay = RESTDELAY ; DestroyObject(oProvisions) ; } ;
/* Checking the Resting Delay */
if (iRestDelay < RESTDELAY) {
AssignCommand(oPC, ClearAllActions());
if (RESTDELAY-iRestDelay <= 60) SendMessageToPC(oPC, "Vous devez attendre moins d'une minute pour vous reposez");
else SendMessageToPC(oPC, "Vous devez attendre " + IntToString(FloatToInt(IntToFloat((RESTDELAY-iRestDelay))/60)) + " minute(s) avant de vous reposer a nouveau.");
SetLocalInt(oPC, "PC_WARest", TRUE);
return;
}
// code TN Bouchon partie 2/2
// Aliments pour manger, necessaire avant de se reposer.
if( bRepas ){
SendMessageToPC(oPC,"Vous mangez un peu... et faites une sieste réparatrice");
oFood = GetItemPossessedBy(oPC, "alimentderepos1");
DestroyObject(oFood);
oFood = GetItemPossessedBy(oPC, "alimentderepos2");
DestroyObject(oFood);
oFood = GetItemPossessedBy(oPC, "alimentderepos3");
DestroyObject(oFood);
}
// code TN Bouchon partie 2/2
/* Blindness Effect */
effect eBlind = EffectBlindness();
effect eDeaf = EffectDeaf();
effect eVis = EffectVisualEffect(VFX_IMP_SLEEP);
eBlind = ExtraordinaryEffect(eBlind);
eDeaf = ExtraordinaryEffect(eDeaf);
// get nearest creature check proximity hostility etc.
object oCreature = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
if (iHostileRange == 0 || (iHostileRange != 0 && GetDistanceToObject(oCreature) <= IntToFloat(iHostileRange))) {
// Initiate Resting, make a Gangus bedroll
object oRestbedroll = CreateObject (OBJECT_TYPE_PLACEABLE, "sow_bedrolls", GetLocation (oPC), FALSE);
// Autodestruction c'est mieux.
SetPlotFlag(oRestbedroll, TRUE) ;
DestroyObject(oRestbedroll, 120.0) ;
SetLocalInt(oRestbedroll,"DC_FIND",d20(1));
SetLocalInt(oRestbedroll,"PJ_RACE",GetRacialType(oPC));
SetLocalInt(oRestbedroll,"PJ_SEXE",GetGender(oPC));
SetLocalInt(oRestbedroll,"PJ_POIDS",GetWeight(oPC));
SetLocalString(oRestbedroll,"PJ_NAME",GetName(oPC));
// repos complet ?
if( bRepas ) nCirc = 4 ; else nCirc = 0 ;
nCirc += 3 ;
SetLocalInt(oPC, "PC_FullRest", nCirc); // par defaut
int iAuSec = TRUE ; // par defaut
int iAuChaud = TRUE ; // par defaut
if( nSetting != 0 ){ // exemple desert de jour...
// mettre a la variable "REPOS"
// 1 - feu requis
// 2 - tente/abri requis
// 3 = 2 & 1 : les deux requis
switch( nSetting ){
case 1: iAuChaud = FALSE ; break ;
case 2: iAuSec = FALSE ; break ;
case 3: iAuChaud = FALSE ; iAuSec = FALSE ; break ;
default: break;
}
}
// preselection des zones hostiles
// Au Sec ?
if( (GetWeather(oArea) == WEATHER_RAIN) ||
(GetWeather(oArea) == WEATHER_SNOW) ){
iAuSec = FALSE ;
object oTente = GetFirstObjectInShape(SHAPE_SPHERE, 7.0, GetLocation (oPC), TRUE, OBJECT_TYPE_PLACEABLE) ;
while (oTente != OBJECT_INVALID) {
if ((GetTag(oTente)=="SOW_PLC_TENTE") ||
(GetTag(oTente)=="SOW_PLC_TENTEB") ){
iAuSec = TRUE ; break ; } ;
oTente = GetNextObjectInShape(SHAPE_SPHERE, 7.0, GetLocation (oPC), TRUE, OBJECT_TYPE_PLACEABLE) ;
}
}
// Au Chaud ?
if( GetWeather(oArea) == WEATHER_SNOW ){ iAuChaud = FALSE ; }
if( GetIsAreaNatural(oArea) && GetIsNight() ){ iAuChaud = FALSE ; }
if( GetIsAreaNatural(oArea) && (GetIsAreaAboveGround(oArea) == AREA_UNDERGROUND) ){
iAuChaud = FALSE ;
}
// Eviter de faire des loops inutiles...
if( !iAuChaud ){
object oFeuCamp = GetFirstObjectInShape(SHAPE_SPHERE, 5.0, GetLocation (oPC), TRUE, OBJECT_TYPE_PLACEABLE) ;
while (oFeuCamp != OBJECT_INVALID) {
if( (GetTag(oFeuCamp)=="SOW_FEU_CAMP") ||
(GetTag(oFeuCamp)=="SOW_FEU_CUIS") ||
(GetTag(oFeuCamp)=="SOW_FEU_BROC") ||
(GetLevelByClass(CLASS_TYPE_SHADOWDANCER,oPC)>0) ){
iAuChaud = TRUE ; break ;
}
oFeuCamp = GetNextObjectInShape(SHAPE_SPHERE, 5.0, GetLocation (oPC), TRUE, OBJECT_TYPE_PLACEABLE) ;
}
}
//
if( bRepas ) nCirc = 4 ; else nCirc = 0 ;
if( iAuSec ) nCirc +=2 ;
if( iAuChaud ) nCirc++ ;
// nCirc = 4*bRepas + 2*iAuSec + iAuChaud ;
// SendMessageToPC(oPC, "Faim/Sec/Chaud : "+IntToString(nCirc));
SetLocalInt(oPC, "PC_FullRest", nCirc);
if( !iAuChaud ){
if( sMessage1 == "" ) SendMessageToPC(oPC, "Il fait froid") ;
else SendMessageToPC(oPC, sMessage1) ;
}
if( !iAuSec ){
if( sMessage2 == "" ) SendMessageToPC(oPC, "Il fait humide") ;
else SendMessageToPC(oPC, sMessage2) ;
}
if( !(iAuSec && iAuChaud) ){
SendMessageToPC(oPC, "Vous dormez mal") ;
}
AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlind, oPC, 26.0));
AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDeaf, oPC, 26.0));
AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oPC, 26.0));
}
else { // Enemy too close for resting
AssignCommand (oPC, ClearAllActions());
SendMessageToPC(oPC, "Des monstres sont proches, vous ne pouvez pas vous reposer");
}
}
// Annulation du repos
if (GetLastRestEventType() == REST_EVENTTYPE_REST_CANCELLED) {
/* cancel blindness and eventually damage PC */
DeleteLocalInt(oPC, "PC_CNRest");
effect eBad = GetFirstEffect(oPC);
while (GetIsEffectValid(eBad)) {
if (GetEffectType(eBad) == EFFECT_TYPE_BLINDNESS &&
GetEffectCreator(eBad) == oPC) {
RemoveEffect(oPC, eBad);
}
eBad = GetNextEffect(oPC);
}
/* cancel deaf and eventually damage PC */
eBad = GetFirstEffect(oPC);
while (GetIsEffectValid(eBad)) {
if (GetEffectType(eBad) == EFFECT_TYPE_DEAF &&
GetEffectCreator(eBad) == oPC) {
RemoveEffect(oPC, eBad);
}
eBad = GetNextEffect(oPC);
}
/* cancel effects created by PCs */
effect eGood = GetFirstEffect(oPC);
int iPC_No_Wait = !GetLocalInt(oPC, "PC_WARest");
DeleteLocalInt(oPC, "PC_WARest"); // correction repos intempestif
while (GetIsEffectValid(eGood) && iPC_No_Wait) { // enlevant les sorts de facon aggressive
if (GetIsFriend(oPC, GetEffectCreator(eGood))) {
RemoveEffect(oPC, eGood);
}
eGood = GetNextEffect(oPC);
}
iRestDelay = GetLocalInt(oPC, "PC_LastRest");
if (iCTime < iRestDelay + 5) {
// don't let players to cheat
talent tFeat, tSpell;
int nIndex, i, nTalentID;
for (nIndex=1; nIndex<1000; nIndex++) {
tFeat = TalentFeat (nIndex);
tSpell = TalentSpell(nIndex);
if (GetIsTalentValid(tFeat)) {
nTalentID = GetIdFromTalent(tFeat);
for (i=1; i<40; i++) {
DecrementRemainingFeatUses(oPC, nTalentID);
if (!GetHasFeat(nTalentID, oPC)) i = 40;
}
}
if (GetIsTalentValid(tSpell)) {
nTalentID = GetIdFromTalent(tSpell);
for (i=1; i<40; i++) {
DecrementRemainingSpellUses(oPC, nTalentID);
if (!GetHasSpell(nTalentID, oPC)) i = 40;
}
}
}
// end cheating section
}
curHP = GetLocalInt(oPC, "PC_HPRest");
maxHP = GetCurrentHitPoints(oPC);
if (curHP >= maxHP) return;
effect eDamage = EffectDamage(maxHP-curHP, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_FIVE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oPC);
// regeneration d'effets enleves par le repos
// Gestion des objets a effets sur le PJ
// => Les Bracelets d'AC ici
SetLocalObject(oMod,"PJ_ITEFF",oPC) ;
DeleteLocalObject(oMod,"OBJ_ITEFF") ; // rend invalide : le sc va chercher tout
SignalEvent(oMod, EventUserDefined(550)) ;
//
}
// Repos effectif
if (GetLastRestEventType() == REST_EVENTTYPE_REST_FINISHED) {
SetLocalInt(oPC, "PC_LastRest", iCTime);
SetLocalInt(oPC, "PC_LastDayRest", iCDay);
nModif = GetLocalInt(oPC, "PC_CNRest") + 3*GetHasFeat(FEAT_TOUGHNESS, oPC); // Constitution de debut de repos
nModif += ( (GetLevelByClass(CLASS_TYPE_BARBARIAN, oPC)>0) ||
(GetLevelByClass(CLASS_TYPE_DRUID, oPC)>0) ||
(GetLevelByClass(CLASS_TYPE_HARPER, oPC)>0) ||
(GetLevelByClass(CLASS_TYPE_RANGER, oPC)>0) ) ? 2 : 0 ;
// metamorphe forcement druide
DeleteLocalInt(oPC, "PC_CNRest");
CleanDeathCard(oPC) ;
CleanAgoCard(oPC) ;
/* eventually damage PC */
curHP = GetLocalInt(oPC, "PC_HPRest");
maxHP = GetMaxHitPoints(oPC);
int nLevel = GetHitDice(oPC);
int nHeal = 0;
if( curHP > maxHP ) curHP = maxHP ;
int nDamage = maxHP-curHP ;
// natural heal or damage
nHeal += (maxHP * (2 + nModif))/20 ;
if( nDamage > nHeal) { nDamage = nDamage - nHeal ; nHeal=0; }
else { nHeal = nHeal - nDamage ; nDamage = 0 ;}
effect eDamage, eHeal ;
if( nDamage > 0 ) eDamage = EffectDamage(nDamage, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_FIVE);
// si on est dans de bonnes conditions : Full repos
nCirc = GetLocalInt(oPC, "PC_FullRest") ;
// SendMessageToPC(oPC, "Faim/Sec/Chaud : "+IntToString(nCirc));
if (nCirc >= 4) { // cf bRepas
nHeal = maxHP-curHP ;
} else if( nDamage >0 ) DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oPC));
if (nHeal > 0) {
eHeal = EffectHeal(nHeal);
DelayCommand(1.0,ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oPC));
}
if( nCirc >= 4 ) nCirc -= 4 ; // bRepas gere, on passe a chaud/froid, sec/humide
// SendMessageToPC(oPC, "Faim/Sec/Chaud : "+IntToString(nCirc));
if( nCirc < 3 ) {
if (nCirc == 0) nDisease = Random(5) ; else nDisease = 5 + Random(5) ;
DeleteLocalInt(oPC,"PC_FullRest");
switch (nDisease) {
case 0:
sDisease = "La Croupissure tente de s'insinuer en vous" ;
break;
case 1:
sDisease = "Les miasmes de la Fièvre Gloussante accompagne votre sommeil" ;
break;
case 2:
sDisease = "Une Folie Parasitaire vous guette" ; nDisease = 16 ;
break;
case 3:
sDisease = "Le froid et l'humidité amène la Tremblote du Soldat" ; nDisease = 15 ;
break;
case 4:
sDisease = "Le Mal Rouge agrémente votre réveil" ; nDisease = 7 ;
break;
case 5:
sDisease = "La Bouille-Crâne accompagne votre fin de nuit" ;
break;
case 6:
sDisease = "Les miasmes environnant déclenche des Pustules Effroyables" ; nDisease = 13 ;
break;
case 7:
sDisease = "La Fièvre des Marais est le risque du voyageur"; nDisease = 4 ;
break;
case 8:
sDisease = "Auriez-vous attrapé la Tremblote ?" ;
break;
case 9:
sDisease = "La Mort Vaseuse est une croupissure des plus communes" ;
break;
default:
sDisease = "La Fièvre des Marais est le risque du voyageur"; nDisease = 4 ;
break;
}
effect eBadSleep = EffectDisease(nDisease) ;
effect eWanderer = SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_FORT, 2, SAVING_THROW_TYPE_DISEASE)) ;
SendMessageToPC(oPC, sDisease);
if( (GetLevelByClass(CLASS_TYPE_HARPER, oPC) +
GetLevelByClass(CLASS_TYPE_BARBARIAN, oPC) +
GetLevelByClass(CLASS_TYPE_RANGER, oPC)) > 0 ) {
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eWanderer, oPC, 3.0) ;
}
if( nSetDis !=0 ){ // malus de zone
eWanderer = SupernaturalEffect(EffectSavingThrowDecrease(SAVING_THROW_FORT, nSetDis, SAVING_THROW_TYPE_DISEASE)) ;
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eWanderer, oPC, 3.0) ;
}
ApplyEffectToObject(DURATION_TYPE_INSTANT, eBadSleep, oPC) ;
}
//
SendMessageToPC(oPC, "Vous restaurez "+IntToString(nHeal)+" points de vie.");
// regeneration d'effets enleves par le repos
// Gestion des objets a effets sur le PJ
// => Les Bracelets d'AC ici
SetLocalObject(oMod,"PJ_ITEFF",oPC) ;
DeleteLocalObject(oMod,"OBJ_ITEFF") ; // rend invalide : le sc va chercher tout
SignalEvent(oMod, EventUserDefined(550)) ;
//
}
}
Le code a colorer syntaxiquement est trop long (plus de 10240 caractères) et risque de ne pas s'afficher du tout. Vous pouvez le voir en version colorée ici.//:: Update Lylver 2005-12-12
//:: evt 550 : regenere les effets du aux custom items apres repos
//:/
//:: Update Lylver 2005-12-11
//:: correction erreur maladie
//:/
//:: Update Lylver 2005-10-15
//:: changement : ameliore critere bRepas
//:: manger = guerison complete
//:: maladie isolee
//:: rayon de la zone de tente augmente 7.0 au lieu de 5.0
//:/
//:: Update Lylver 2005-09-29
//:: variables pour les zones
//:: int REPOS :
//
// 1 - feu requis
// 2 - tente/abri requis
// 3 = 2 & 1 : les deux requis
//:: int MIASME : (positif) malus au jet de vigueur
//:: string REPOS1, message specifique de zone remplacant "Il fait froid"
//:: string REPOS2, message specifique de zone remplacant "Il fait humide"
//:/
//:: Update Lylver 2005-09-17
//:: repos non bloquant => maladie a la place
//:/
//:: Update Lylver 2005-09-16
//:: adaptation TN Bouchon 2
//://///////////////////////////////////
// Update Lylver 2005-08-01 : mise en fonction de la reputation
// Note : reste encore des pbs de repos intempestif (rares)
//::
// mod_onrest
// by dluan on sep 2003,
// updated Lylver 2004-04-17
// Update Lylver 2004-12-15 pour SoW 3h<>540s
// Update Lylver 2004-12-17 pour SoW materiel de camping.
// remplace x2_mod_def_rest a etudier
// Update Lylver 2005-06-03 : correction repos intempestif
// enlevant les sorts de facon aggressive
//://///////////////////////////////////
#include "nw_i0_plot"
#include "ly_lib_time"
#include "ly_lib_death"
#include "x0_i0_position"
void main()
{
object oPC = GetLastPCRested() ;
object oArea = GetArea(oPC);
object oMod = GetModule() ;
// code TN Bouchon specifique
object oFood ;
if(GetTag(oArea)=="Zone002")
{
SendMessageToPC(oPC,LocationToString(GetAheadLocation(oPC)));
return;
}
// code TN Bouchon specifique
int iHostileRange = 30;
int nDisease = 0 ;
int bRepas = FALSE ;
int nCirc = 0 ;
string sDisease = "";
// set a stack size
int i = 10;
// set an object equal to the provisions on the player. This will be
// OBJECT_INVALID if the player doesn't have any
object oProvisions = GetItemPossessedBy(oPC, "PROVISIONS");
int nSetting = GetLocalInt(oArea, "REPOS");
int nSetDis = GetLocalInt(oArea, "MIASME");
string sMessage1 = GetLocalString(oArea, "REPOS1");
string sMessage2 = GetLocalString(oArea, "REPOS2");
int nModif = GetAbilityModifier(ABILITY_CONSTITUTION,oPC); //... corrige 2005-03-28
int iCDay = ly_day() ;
int iCTime = ly_time() ;
int iRestDelay ;
int iRestDay ;
int iRestSecond ;
/* int RESTDELAY = 540 ; // Real Time 3min <=> 1h Game Play
// Repos toutes les 3 heures */
int RESTDELAY = 120 ; // Real Time 5min <=> 1h Game Play
// Repos toutes les 2 minutes irl
int curHP = GetCurrentHitPoints(oPC);
int maxHP = GetMaxHitPoints(oPC);
// debut du repos
if (GetLastRestEventType() == REST_EVENTTYPE_REST_STARTED) {
// code TN Bouchon partie 1/2
// Aliments pour manger, necessaire avant de se reposer.
SendMessageToPC(oPC,"Vous essayez de vous reposer....");
if( HasItem(oPC,"alimentderepos1") &&
HasItem(oPC,"alimentderepos2") &&
HasItem(oPC,"alimentderepos3") ){
WriteTimestampedLogEntry("Repos de "+GetName(oPC));
bRepas = TRUE ;
} else {
SendMessageToPC(oPC,"Vous n'avez pas ce qu'il faut pour vous nourrir avant de vous reposer");
SendMessageToPC(oPC,"Vous ressentirez la faim à votre réveil");
if( oProvisions == OBJECT_INVALID ){
bRepas = FALSE ;
} else {
bRepas = TRUE ;
}
// AssignCommand(oPC, ClearAllActions());
}
// code TN Bouchon partie 1/2
iRestDay = GetLocalInt(oPC, "PC_LastDayRest");
iRestSecond = GetLocalInt(oPC, "PC_LastRest") ;
iRestDelay = iCTime - iRestSecond + FloatToInt(HoursToSeconds((iCDay - iRestDay) * 24));
SetLocalInt(oPC, "PC_HPRest", curHP);
SetLocalInt(oPC, "PC_CNRest", nModif);
// si on a des provisions (pass-DM) : Repos Immediat
if (oProvisions != OBJECT_INVALID) { iRestDelay = RESTDELAY ; DestroyObject(oProvisions) ; } ;
/* Checking the Resting Delay */
if (iRestDelay < RESTDELAY) {
AssignCommand(oPC, ClearAllActions());
if (RESTDELAY-iRestDelay <= 60) SendMessageToPC(oPC, "Vous devez attendre moins d'une minute pour vous reposez");
else SendMessageToPC(oPC, "Vous devez attendre " + IntToString(FloatToInt(IntToFloat((RESTDELAY-iRestDelay))/60)) + " minute(s) avant de vous reposer a nouveau.");
SetLocalInt(oPC, "PC_WARest", TRUE);
return;
}
// code TN Bouchon partie 2/2
// Aliments pour manger, necessaire avant de se reposer.
if( bRepas ){
SendMessageToPC(oPC,"Vous mangez un peu... et faites une sieste réparatrice");
oFood = GetItemPossessedBy(oPC, "alimentderepos1");
DestroyObject(oFood);
oFood = GetItemPossessedBy(oPC, "alimentderepos2");
DestroyObject(oFood);
oFood = GetItemPossessedBy(oPC, "alimentderepos3");
DestroyObject(oFood);
}
// code TN Bouchon partie 2/2
/* Blindness Effect */
effect eBlind = EffectBlindness();
effect eDeaf = EffectDeaf();
effect eVis = EffectVisualEffect(VFX_IMP_SLEEP);
eBlind = ExtraordinaryEffect(eBlind);
eDeaf = ExtraordinaryEffect(eDeaf);
// get nearest creature check proximity hostility etc.
object oCreature = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
if (iHostileRange == 0 || (iHostileRange != 0 && GetDistanceToObject(oCreature) <= IntToFloat(iHostileRange))) {
// Initiate Resting, make a Gangus bedroll
object oRestbedroll = CreateObject (OBJECT_TYPE_PLACEABLE, "sow_bedrolls", GetLocation (oPC), FALSE);
// Autodestruction c'est mieux.
SetPlotFlag(oRestbedroll, TRUE) ;
DestroyObject(oRestbedroll, 120.0) ;
SetLocalInt(oRestbedroll,"DC_FIND",d20(1));
SetLocalInt(oRestbedroll,"PJ_RACE",GetRacialType(oPC));
SetLocalInt(oRestbedroll,"PJ_SEXE",GetGender(oPC));
SetLocalInt(oRestbedroll,"PJ_POIDS",GetWeight(oPC));
SetLocalString(oRestbedroll,"PJ_NAME",GetName(oPC));
// repos complet ?
if( bRepas ) nCirc = 4 ; else nCirc = 0 ;
nCirc += 3 ;
SetLocalInt(oPC, "PC_FullRest", nCirc); // par defaut
int iAuSec = TRUE ; // par defaut
int iAuChaud = TRUE ; // par defaut
if( nSetting != 0 ){ // exemple desert de jour...
// mettre a la variable "REPOS"
// 1 - feu requis
// 2 - tente/abri requis
// 3 = 2 & 1 : les deux requis
switch( nSetting ){
case 1: iAuChaud = FALSE ; break ;
case 2: iAuSec = FALSE ; break ;
case 3: iAuChaud = FALSE ; iAuSec = FALSE ; break ;
default: break;
}
}
// preselection des zones hostiles
// Au Sec ?
if( (GetWeather(oArea) == WEATHER_RAIN) ||
(GetWeather(oArea) == WEATHER_SNOW) ){
iAuSec = FALSE ;
object oTente = GetFirstObjectInShape(SHAPE_SPHERE, 7.0, GetLocation (oPC), TRUE, OBJECT_TYPE_PLACEABLE) ;
while (oTente != OBJECT_INVALID) {
if ((GetTag(oTente)=="SOW_PLC_TENTE") ||
(GetTag(oTente)=="SOW_PLC_TENTEB") ){
iAuSec = TRUE ; break ; } ;
oTente = GetNextObjectInShape(SHAPE_SPHERE, 7.0, GetLocation (oPC), TRUE, OBJECT_TYPE_PLACEABLE) ;
}
}
// Au Chaud ?
if( GetWeather(oArea) == WEATHER_SNOW ){ iAuChaud = FALSE ; }
if( GetIsAreaNatural(oArea) && GetIsNight() ){ iAuChaud = FALSE ; }
if( GetIsAreaNatural(oArea) && (GetIsAreaAboveGround(oArea) == AREA_UNDERGROUND) ){
iAuChaud = FALSE ;
}
// Eviter de faire des loops inutiles...
if( !iAuChaud ){
object oFeuCamp = GetFirstObjectInShape(SHAPE_SPHERE, 5.0, GetLocation (oPC), TRUE, OBJECT_TYPE_PLACEABLE) ;
while (oFeuCamp != OBJECT_INVALID) {
if( (GetTag(oFeuCamp)=="SOW_FEU_CAMP") ||
(GetTag(oFeuCamp)=="SOW_FEU_CUIS") ||
(GetTag(oFeuCamp)=="SOW_FEU_BROC") ||
(GetLevelByClass(CLASS_TYPE_SHADOWDANCER,oPC)>0) ){
iAuChaud = TRUE ; break ;
}
oFeuCamp = GetNextObjectInShape(SHAPE_SPHERE, 5.0, GetLocation (oPC), TRUE, OBJECT_TYPE_PLACEABLE) ;
}
}
//
if( bRepas ) nCirc = 4 ; else nCirc = 0 ;
if( iAuSec ) nCirc +=2 ;
if( iAuChaud ) nCirc++ ;
// nCirc = 4*bRepas + 2*iAuSec + iAuChaud ;
// SendMessageToPC(oPC, "Faim/Sec/Chaud : "+IntToString(nCirc));
SetLocalInt(oPC, "PC_FullRest", nCirc);
if( !iAuChaud ){
if( sMessage1 == "" ) SendMessageToPC(oPC, "Il fait froid") ;
else SendMessageToPC(oPC, sMessage1) ;
}
if( !iAuSec ){
if( sMessage2 == "" ) SendMessageToPC(oPC, "Il fait humide") ;
else SendMessageToPC(oPC, sMessage2) ;
}
if( !(iAuSec && iAuChaud) ){
SendMessageToPC(oPC, "Vous dormez mal") ;
}
AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBlind, oPC, 26.0));
AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDeaf, oPC, 26.0));
AssignCommand(oPC, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oPC, 26.0));
}
else { // Enemy too close for resting
AssignCommand (oPC, ClearAllActions());
SendMessageToPC(oPC, "Des monstres sont proches, vous ne pouvez pas vous reposer");
}
}
// Annulation du repos
if (GetLastRestEventType() == REST_EVENTTYPE_REST_CANCELLED) {
/* cancel blindness and eventually damage PC */
DeleteLocalInt(oPC, "PC_CNRest");
effect eBad = GetFirstEffect(oPC);
while (GetIsEffectValid(eBad)) {
if (GetEffectType(eBad) == EFFECT_TYPE_BLINDNESS &&
GetEffectCreator(eBad) == oPC) {
RemoveEffect(oPC, eBad);
}
eBad = GetNextEffect(oPC);
}
/* cancel deaf and eventually damage PC */
eBad = GetFirstEffect(oPC);
while (GetIsEffectValid(eBad)) {
if (GetEffectType(eBad) == EFFECT_TYPE_DEAF &&
GetEffectCreator(eBad) == oPC) {
RemoveEffect(oPC, eBad);
}
eBad = GetNextEffect(oPC);
}
/* cancel effects created by PCs */
effect eGood = GetFirstEffect(oPC);
int iPC_No_Wait = !GetLocalInt(oPC, "PC_WARest");
DeleteLocalInt(oPC, "PC_WARest"); // correction repos intempestif
while (GetIsEffectValid(eGood) && iPC_No_Wait) { // enlevant les sorts de facon aggressive
if (GetIsFriend(oPC, GetEffectCreator(eGood))) {
RemoveEffect(oPC, eGood);
}
eGood = GetNextEffect(oPC);
}
iRestDelay = GetLocalInt(oPC, "PC_LastRest");
if (iCTime < iRestDelay + 5) {
// don't let players to cheat
talent tFeat, tSpell;
int nIndex, i, nTalentID;
for (nIndex=1; nIndex<1000; nIndex++) {
tFeat = TalentFeat (nIndex);
tSpell = TalentSpell(nIndex);
if (GetIsTalentValid(tFeat)) {
nTalentID = GetIdFromTalent(tFeat);
for (i=1; i<40; i++) {
DecrementRemainingFeatUses(oPC, nTalentID);
if (!GetHasFeat(nTalentID, oPC)) i = 40;
}
}
if (GetIsTalentValid(tSpell)) {
nTalentID = GetIdFromTalent(tSpell);
for (i=1; i<40; i++) {
DecrementRemainingSpellUses(oPC, nTalentID);
if (!GetHasSpell(nTalentID, oPC)) i = 40;
}
}
}
// end cheating section
}
curHP = GetLocalInt(oPC, "PC_HPRest");
maxHP = GetCurrentHitPoints(oPC);
if (curHP >= maxHP) return;
effect eDamage = EffectDamage(maxHP-curHP, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_FIVE);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oPC);
// regeneration d'effets enleves par le repos
// Gestion des objets a effets sur le PJ
// => Les Bracelets d'AC ici
SetLocalObject(oMod,"PJ_ITEFF",oPC) ;
DeleteLocalObject(oMod,"OBJ_ITEFF") ; // rend invalide : le sc va chercher tout
SignalEvent(oMod, EventUserDefined(550)) ;
//
}
// Repos effectif
if (GetLastRestEventType() == REST_EVENTTYPE_REST_FINISHED) {
SetLocalInt(oPC, "PC_LastRest", iCTime);
SetLocalInt(oPC, "PC_LastDayRest", iCDay);
nModif = GetLocalInt(oPC, "PC_CNRest") + 3*GetHasFeat(FEAT_TOUGHNESS, oPC); // Constitution de debut de repos
nModif += ( (GetLevelByClass(CLASS_TYPE_BARBARIAN, oPC)>0) ||
(GetLevelByClass(CLASS_TYPE_DRUID, oPC)>0) ||
(GetLevelByClass(CLASS_TYPE_HARPER, oPC)>0) ||
(GetLevelByClass(CLASS_TYPE_RANGER, oPC)>0) ) ? 2 : 0 ;
// metamorphe forcement druide
DeleteLocalInt(oPC, "PC_CNRest");
CleanDeathCard(oPC) ;
CleanAgoCard(oPC) ;
/* eventually damage PC */
curHP = GetLocalInt(oPC, "PC_HPRest");
maxHP = GetMaxHitPoints(oPC);
int nLevel = GetHitDice(oPC);
int nHeal = 0;
if( curHP > maxHP ) curHP = maxHP ;
int nDamage = maxHP-curHP ;
// natural heal or damage
nHeal += (maxHP * (2 + nModif))/20 ;
if( nDamage > nHeal) { nDamage = nDamage - nHeal ; nHeal=0; }
else { nHeal = nHeal - nDamage ; nDamage = 0 ;}
effect eDamage, eHeal ;
if( nDamage > 0 ) eDamage = EffectDamage(nDamage, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_PLUS_FIVE);
// si on est dans de bonnes conditions : Full repos
nCirc = GetLocalInt(oPC, "PC_FullRest") ;
// SendMessageToPC(oPC, "Faim/Sec/Chaud : "+IntToString(nCirc));
if (nCirc >= 4) { // cf bRepas
nHeal = maxHP-curHP ;
} else if( nDamage >0 ) DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oPC));
if (nHeal > 0) {
eHeal = EffectHeal(nHeal);
DelayCommand(1.0,ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oPC));
}
if( nCirc >= 4 ) nCirc -= 4 ; // bRepas gere, on passe a chaud/froid, sec/humide
// SendMessageToPC(oPC, "Faim/Sec/Chaud : "+IntToString(nCirc));
if( nCirc < 3 ) {
if (nCirc == 0) nDisease = Random(5) ; else nDisease = 5 + Random(5) ;
DeleteLocalInt(oPC,"PC_FullRest");
switch (nDisease) {
case 0:
sDisease = "La Croupissure tente de s'insinuer en vous" ;
break;
case 1:
sDisease = "Les miasmes de la Fièvre Gloussante accompagne votre sommeil" ;
break;
case 2:
sDisease = "Une Folie Parasitaire vous guette" ; nDisease = 16 ;
break;
case 3:
sDisease = "Le froid et l'humidité amène la Tremblote du Soldat" ; nDisease = 15 ;
break;
case 4:
sDisease = "Le Mal Rouge agrémente votre réveil" ; nDisease = 7 ;
break;
case 5:
sDisease = "La Bouille-Crâne accompagne votre fin de nuit" ;
break;
case 6:
sDisease = "Les miasmes environnant déclenche des Pustules Effroyables" ; nDisease = 13 ;
break;
case 7:
sDisease = "La Fièvre des Marais est le risque du voyageur"; nDisease = 4 ;
break;
case 8:
sDisease = "Auriez-vous attrapé la Tremblote ?" ;
break;
case 9:
sDisease = "La Mort Vaseuse est une croupissure des plus communes" ;
break;
default:
sDisease = "La Fièvre des Marais est le risque du voyageur"; nDisease = 4 ;
break;
}
effect eBadSleep = EffectDisease(nDisease) ;
effect eWanderer = SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_FORT, 2, SAVING_THROW_TYPE_DISEASE)) ;
SendMessageToPC(oPC, sDisease);
if( (GetLevelByClass(CLASS_TYPE_HARPER, oPC) +
GetLevelByClass(CLASS_TYPE_BARBARIAN, oPC) +
GetLevelByClass(CLASS_TYPE_RANGER, oPC)) > 0 ) {
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eWanderer, oPC, 3.0) ;
}
if( nSetDis !=0 ){ // malus de zone
eWanderer = SupernaturalEffect(EffectSavingThrowDecrease(SAVING_THROW_FORT, nSetDis, SAVING_THROW_TYPE_DISEASE)) ;
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eWanderer, oPC, 3.0) ;
}
ApplyEffectToObject(DURATION_TYPE_INSTANT, eBadSleep, oPC) ;
}
//
SendMessageToPC(oPC, "Vous restaurez "+IntToString(nHeal)+" points de vie.");
// regeneration d'effets enleves par le repos
// Gestion des objets a effets sur le PJ
// => Les Bracelets d'AC ici
SetLocalObject(oMod,"PJ_ITEFF",oPC) ;
DeleteLocalObject(oMod,"OBJ_ITEFF") ; // rend invalide : le sc va chercher tout
SignalEvent(oMod, EventUserDefined(550)) ;
//
}
}