259 lines
9.2 KiB
Plaintext
259 lines
9.2 KiB
Plaintext
/// /// /// /// /// /// /// /// /// /// /// ///
|
|
/// lib_witchgrass
|
|
/// This is an include file.
|
|
/// TimeStamps are accurate for checking one unit (ie. one hour or one day).
|
|
/// I plan to write a compare function for timestamps, that would be accurate
|
|
/// for any unit.
|
|
/// The other functions are used by the various witchgrass scripts.
|
|
///
|
|
/// Created by Gilgon Avalrock
|
|
/// /// /// /// /// /// /// /// /// /// /// ///
|
|
|
|
#include "prc_inc_racial"
|
|
|
|
int ONE_MONTH = 100000000;
|
|
int ONE_DAY = 1000000;
|
|
int ONE_HOUR = 10000;
|
|
int ONE_MINUTE = 100;
|
|
|
|
//used to store all time info as one integer
|
|
//doesn't take year into account
|
|
int GetTimeStamp(){
|
|
int month = GetCalendarMonth();
|
|
int day = GetCalendarDay();
|
|
int hour = GetTimeHour();
|
|
int minute = GetTimeMinute();
|
|
int second = GetTimeSecond();
|
|
|
|
int timestamp = (month*ONE_MONTH)+(day*ONE_DAY)+(hour*ONE_HOUR)+(minute*ONE_MINUTE)+(second);
|
|
return timestamp;
|
|
}
|
|
|
|
//called whenever a creature inhales witchgrass smoke
|
|
int GetHigh(object oSmoker){
|
|
int time = GetTimeStamp();
|
|
int lastsmoke = GetLocalInt(oSmoker,"nMyLastToke");
|
|
float duration = HoursToSeconds(1);//effects last 1 game hour
|
|
string comment;
|
|
|
|
//check to see how long since my last smoke
|
|
if(lastsmoke==0 || (time-lastsmoke) > ONE_HOUR){
|
|
//apply effects
|
|
ApplyEffectToObject( DURATION_TYPE_TEMPORARY, EffectMovementSpeedDecrease(10), oSmoker, duration);
|
|
ApplyEffectToObject( DURATION_TYPE_TEMPORARY, EffectSkillIncrease(SKILL_SPOT,5), oSmoker, duration);
|
|
ApplyEffectToObject( DURATION_TYPE_TEMPORARY, EffectSkillIncrease(SKILL_LISTEN,5), oSmoker, duration);
|
|
ApplyEffectToObject( DURATION_TYPE_TEMPORARY, EffectAbilityIncrease(ABILITY_WISDOM,1), oSmoker, duration);
|
|
ApplyEffectToObject( DURATION_TYPE_TEMPORARY, EffectAbilityDecrease(ABILITY_INTELLIGENCE,1), oSmoker, duration);
|
|
//I had problems with this visual effect if had been fired off previously...
|
|
if(lastsmoke!=0)
|
|
RemoveEffect( oSmoker, EffectVisualEffect(VFX_DUR_MIND_AFFECTING_DISABLED));
|
|
DelayCommand(2.f,ApplyEffectToObject( DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_MIND_AFFECTING_DISABLED), oSmoker, duration));
|
|
|
|
SetLocalInt(oSmoker,"nMyLastToke",time);
|
|
//random emotes and side effects
|
|
switch(d6()){
|
|
case 1:
|
|
comment="*cough, cough*";
|
|
break;
|
|
case 2:
|
|
comment="Oh, yeah. This is the good stuff.";
|
|
DelayCommand(3.f,AssignCommand(oSmoker,ActionPlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING,1.0f,3.0f)));
|
|
break;
|
|
case 3:
|
|
comment="Woah. Heh, heh. I feel like I'm floating.";
|
|
DelayCommand(3.f,AssignCommand(oSmoker,ActionPlayAnimation(ANIMATION_LOOPING_TALK_LAUGHING,1.0f,3.0f)));
|
|
break;
|
|
case 4:
|
|
comment="Um, where was I going?";
|
|
DelayCommand(3.f,ApplyEffectToObject( DURATION_TYPE_TEMPORARY, EffectConfused(), oSmoker, RoundsToSeconds(d4())));
|
|
break;
|
|
//case 5,6 do nothing
|
|
}
|
|
DelayCommand(2.f,AssignCommand(oSmoker,ActionSpeakString(comment)));
|
|
return 1;
|
|
}else{//it hasn't been long enough, so just slow the smoker down some more.
|
|
ApplyEffectToObject( DURATION_TYPE_TEMPORARY, EffectMovementSpeedDecrease(10), oSmoker, duration);
|
|
RemoveEffect( oSmoker, EffectVisualEffect(VFX_DUR_MIND_AFFECTING_DISABLED));
|
|
DelayCommand(2.f,ApplyEffectToObject( DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_MIND_AFFECTING_DISABLED), oSmoker, duration-2.0f));
|
|
SetLocalInt(oSmoker,"nMyLastToke",time);
|
|
//random emotes and side effects
|
|
switch(d4()){
|
|
case 1:
|
|
comment="I shouldn't smoke so often.";
|
|
break;
|
|
case 2:
|
|
comment="Man, now I just feel tired.";
|
|
DelayCommand(3.f,AssignCommand(oSmoker,ActionPlayAnimation( ANIMATION_LOOPING_SIT_CROSS, 1.0f, 3.f)));
|
|
DelayCommand(4.f,ApplyEffectToObject( DURATION_TYPE_TEMPORARY, EffectSleep(), oSmoker, RoundsToSeconds(d2())));
|
|
break;
|
|
case 3:
|
|
comment="Too much of a good thing, eh?";
|
|
break;
|
|
case 4:
|
|
comment="I could use a nap.";
|
|
break;
|
|
}
|
|
DelayCommand(2.f,AssignCommand(oSmoker,ActionSpeakString(comment)));
|
|
return 0;
|
|
}
|
|
}
|
|
//used when the whole plant is burned
|
|
int DestroyInventory( object oObject, float fDelay=0.0f ){
|
|
int count = 0;
|
|
if(GetHasInventory(oObject)){
|
|
object oItem = GetFirstItemInInventory(oObject);
|
|
while(oItem != OBJECT_INVALID){
|
|
count++;
|
|
DestroyObject( oItem, fDelay );
|
|
oItem = GetNextItemInInventory(oObject);
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
//set plant on fire
|
|
void SetOnFire( object oObject ) {
|
|
location lBurnLocation = GetLocation( oObject );
|
|
//burns for 5-7 seconds
|
|
float fBurnDuration = IntToFloat( 8 - d3() );
|
|
string sFireResRef = "plc_flamesmall";
|
|
|
|
//destroy inventory and plant
|
|
DestroyInventory(oObject);
|
|
DestroyObject( oObject, fBurnDuration / 2 );
|
|
|
|
//create fire effect
|
|
object oFire = CreateObject( OBJECT_TYPE_PLACEABLE, sFireResRef, lBurnLocation );
|
|
DestroyObject( oFire, fBurnDuration );
|
|
}
|
|
|
|
//used when planting a new witchgrass plant
|
|
void CreateNewPlant( object oPlanter ){
|
|
AssignCommand(oPlanter,ClearAllActions());
|
|
AssignCommand(oPlanter,ActionPlayAnimation(ANIMATION_LOOPING_GET_LOW,1.0f,2.0f));
|
|
location lLoc = GetLocation(oPlanter);
|
|
vector vPos = GetPositionFromLocation(lLoc);
|
|
vPos = vPos + AngleToVector(GetFacing(oPlanter));
|
|
lLoc = Location(GetAreaFromLocation(lLoc),vPos,GetFacingFromLocation(lLoc));
|
|
object oPlant = CreateObject(OBJECT_TYPE_PLACEABLE, "witchgrass", lLoc, TRUE);
|
|
//random emote
|
|
switch(d6()){
|
|
case 1:
|
|
DelayCommand(3.0f, AssignCommand(oPlanter,ActionSpeakString("That's what I call 'miricle grow'.")));
|
|
break;
|
|
case 2:
|
|
DelayCommand(3.0f, AssignCommand(oPlanter,ActionSpeakString("Grows like a weed.")));
|
|
break;
|
|
case 3:
|
|
DelayCommand(3.0f, AssignCommand(oPlanter,ActionSpeakString("Truly the plant of the gods.")));
|
|
break;
|
|
case 4:
|
|
DelayCommand(3.0f, AssignCommand(oPlanter,ActionSpeakString("Must be magic seeds...")));
|
|
break;
|
|
//case 5,6 do nothing
|
|
}
|
|
}
|
|
|
|
//The following two functions were taken from Jason Robinson from his smokable pipe item.
|
|
//The first of which was optimized, and the second of which was trimmed down to just the racial data.
|
|
location GetLocationAboveAndInFrontOf(object oTarget, float fDist, float fHeight)
|
|
{
|
|
object oArea = GetArea(oTarget);
|
|
vector vPosition = GetPosition(oTarget);
|
|
float fOrientation = GetFacing(oTarget);
|
|
vector vNewPos = AngleToVector(fOrientation);
|
|
float vZ = vPosition.z + fHeight;
|
|
float vX = vPosition.x + fDist * vNewPos.x;
|
|
float vY = vPosition.y + fDist * vNewPos.y;
|
|
vNewPos = Vector(vX, vY, vZ);
|
|
return Location(oArea, vNewPos, fOrientation);
|
|
}
|
|
|
|
location GetSmokeLocation(object oSmoker)
|
|
{
|
|
float fHeight = 1.7;
|
|
float fDistance = 0.1;
|
|
// Set height based on race and gender
|
|
if (GetGender(oSmoker) == GENDER_MALE)
|
|
{
|
|
switch (MyPRCGetRacialType(oSmoker))
|
|
{
|
|
case RACIAL_TYPE_HUMAN:
|
|
case RACIAL_TYPE_HALFELF:
|
|
fHeight = 1.7;
|
|
fDistance = 0.12;
|
|
break;
|
|
|
|
case RACIAL_TYPE_ELF:
|
|
fHeight = 1.55;
|
|
fDistance = 0.08;
|
|
break;
|
|
|
|
case RACIAL_TYPE_GNOME:
|
|
case RACIAL_TYPE_HALFLING:
|
|
fHeight = 1.15;
|
|
fDistance = 0.12;
|
|
break;
|
|
|
|
case RACIAL_TYPE_DWARF:
|
|
fHeight = 1.2;
|
|
fDistance = 0.12;
|
|
break;
|
|
|
|
case RACIAL_TYPE_HALFORC:
|
|
fHeight = 1.9;
|
|
fDistance = 0.2;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// FEMALES
|
|
switch (MyPRCGetRacialType(oSmoker))
|
|
{
|
|
case RACIAL_TYPE_HUMAN:
|
|
case RACIAL_TYPE_HALFELF:
|
|
fHeight = 1.6;
|
|
fDistance = 0.12;
|
|
break;
|
|
|
|
case RACIAL_TYPE_ELF:
|
|
fHeight = 1.45;
|
|
fDistance = 0.12;
|
|
break;
|
|
|
|
case RACIAL_TYPE_GNOME:
|
|
case RACIAL_TYPE_HALFLING:
|
|
fHeight = 1.1;
|
|
fDistance = 0.075;
|
|
break;
|
|
|
|
case RACIAL_TYPE_DWARF:
|
|
fHeight = 1.2;
|
|
fDistance = 0.1;
|
|
break;
|
|
|
|
case RACIAL_TYPE_HALFORC:
|
|
fHeight = 1.8;
|
|
fDistance = 0.13;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return GetLocationAboveAndInFrontOf(oSmoker, fDistance, fHeight);
|
|
}
|
|
|
|
//uses the above two functions to create smoke by a player's face, or out of an object.
|
|
void GenerateSmoke(object oSmoker, int bPlayer = FALSE){
|
|
location lLoc;
|
|
if(bPlayer){
|
|
//find the location in front of the players mouth...
|
|
lLoc = GetSmokeLocation(oSmoker);
|
|
}else{
|
|
//object...just use its location
|
|
lLoc = GetLocation(oSmoker);
|
|
}
|
|
//generate smoke
|
|
ApplyEffectAtLocation(DURATION_TYPE_INSTANT,EffectVisualEffect(VFX_FNF_SMOKE_PUFF),lLoc);
|
|
}
|
|
|
|
//::void main(){} |