/// /// /// /// /// /// /// /// /// /// /// /// /// 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(){}