/* Updated, ripped off and generally ruined by orch : I've change the way the script looks for the areas for successful or failed fishing. You now need to set 2 variables on the holes waypoint both strings, one called TsFishFailure and TsFishSuccess the vaule is the name of the waypoint for these areas. */ /* ts_fishing by Tseramed, aka Ken Demarest (c) 2003 - Free to use. Must give author credit. This script from the module 'Foreboding in Sylvani' This fishing uses bait, casts (with animated splash), makes the PC comment while waiting, and catches a variety of things. Also included are fishing rods, bait, and a 'fish splashing' script so that you know they're out there. Includes a variety of templates for useful fish and useless stuff you might accidentally catch. You can customize what gets caught very easily. The 'success' and 'failure' stuff is kept in 'holding areas', each about 10'x10' and isolated from the rest of the map. One holding area should have a waypoint called 'TsFishSuccess', and the other 'TsFishFailure' Just drop whatever items you want the player to catch, in whatever proportion you want the stuff caught, within 10' of each waypoint. You can put the holding areas in an area all their own, if you are worried about players seeing them on their maps. You can customize what gets caught in each area, or in different fishing holes in the same area. When the code searches for the TsFishSuccess and TsFishFailure waypoints, it looks for the nearest ones first, and uses them in preference to ones farther away. A big nod to Nouny for this. Even though I didn't use his script, I wouldn't have written this if it weren't for his efforts. */ //Added colors in messages... //Ba'al #include "gen_inc_color" #include "prc_inc_racial" int TS_CHANCE_TO_CATCH = 80; // % chance to catch something. float holeMaxDist = 15.0; float fRand( float max ) { int n = Random(10000); return IntToFloat(n) / 10000.0 * max; } // function for debugging void tell( string s ) { //SendMessageToPC( GetFirstPC(), s ); } int near( object thing1, object thing2, float maxDist ) { float dist = GetDistanceBetweenLocations( GetLocation(thing1), GetLocation(thing2) ); if( !GetIsObjectValid( thing1 ) ) return 0; if( !GetIsObjectValid( thing2 ) ) return 0; if( dist < 0.0 ) return 0; if( dist > maxDist ) return 0; return 1; } string getPronoun( string s ) { string firstLetter = GetStringLowerCase(GetStringLeft(s,1)); if( firstLetter == "a" || firstLetter == "e" || firstLetter == "i" || firstLetter == "o" || firstLetter == "u" ) return "an "+s; return "a "+s; } void setBusy() { SetLocalInt( OBJECT_SELF, "tsIsFishing", 1 ); } void clrBusy() { SetLocalInt( OBJECT_SELF, "tsIsFishing", 0 ); } int isBusy() { return GetLocalInt( OBJECT_SELF, "tsIsFishing" ); } object pickFromHoldingArea( string wpTag, int objectType ) { object wp = GetNearestObjectByTag( wpTag, OBJECT_SELF ); if( !GetIsObjectValid(wp) ) { wp = GetWaypointByTag( wpTag ); } if( !GetIsObjectValid(wp) ) { tell( "ERROR: A waypoint with the tag '"+wpTag+"' does not exist." ); return OBJECT_INVALID; } // Build the list of all combatants. if( !GetLocalInt( wp, "tsTemplateCount" ) ) { int done = 0; int count = 0; while( !done ) { object who = GetNearestObject( objectType, wp, count+1 ); if( GetIsObjectValid(who) && GetDistanceBetween( wp, who ) < 9.5 ) { SetLocalObject( wp, "tsTemplate"+IntToString(count), who ); int frequency = GetLocalInt( wp, "tsFrequency"+GetTag(who) ); ++frequency; SetLocalInt( wp, "tsFrequency"+GetTag(who), frequency ); ++count; } else done = 1; } SetLocalInt( wp, "tsTemplateCount", count ); } int index = Random( GetLocalInt( wp, "tsTemplateCount" ) ); return GetLocalObject( wp, "tsTemplate"+IntToString(index) ); } void flash() { effect e = EffectVisualEffect( 204 ); ApplyEffectToObject( DURATION_TYPE_TEMPORARY, e, OBJECT_SELF ); } void callBack( object who ) { tell( "Calling back to "+GetName(who) ); ExecuteScript( "ts_fishing", who ); } void incState() { int state = GetLocalInt( OBJECT_SELF, "tsFishingState" ); ++state; SetLocalInt( OBJECT_SELF, "tsFishingState", state ); } void clrState() { SetLocalInt( OBJECT_SELF, "tsFishingState", 0 ); SetLocalInt( OBJECT_SELF, "tsFishingReps", 0 ); } int isRod( object what ) { if( GetIsObjectValid(what) && ( GetTag(what)=="TsFishingRod" || GetTag(what)=="TsShortFishingRod" ) ) { return 1; } return 0; } object getRod( object pc ) { object rod = GetItemPossessedBy( pc, "TsFishingRod" ); if( ( MyPRCGetRacialType( pc ) == RACIAL_TYPE_HALFLING || MyPRCGetRacialType( pc ) == RACIAL_TYPE_GNOME ) || ( !GetIsObjectValid( rod ) ) ) { rod = GetItemPossessedBy( pc, "TsShortFishingRod" ); } return rod; } void pcUnequipRod( object pc ) { object inHand = GetItemInSlot( INVENTORY_SLOT_RIGHTHAND, pc ); if( isRod( inHand ) ) { AssignCommand( pc, ActionUnequipItem( inHand ) ); } } void pcEquipRod( object pc, object rod ) { object inHand = GetItemInSlot( INVENTORY_SLOT_RIGHTHAND, pc ); if( !isRod( inHand ) ) { AssignCommand( pc, ActionEquipItem( rod, INVENTORY_SLOT_RIGHTHAND ) ); } } void invisSplash( object pc, object rod ) { location loc = GetLocation( pc ); vector pos = GetPositionFromLocation( loc ); float facing = GetFacingFromLocation( loc )+(fRand(20.0)-10.0); float splashDistance = 3.0+fRand(5.0); // est of player vision distance pos.x += cos(facing) * splashDistance; pos.y += sin(facing) * splashDistance; loc = Location( GetAreaFromLocation(loc), pos, facing ); effect e = EffectVisualEffect( 93 ); ApplyEffectAtLocation( DURATION_TYPE_TEMPORARY, e, loc ); PlaySound( "as_na_splash2" ); DestroyObject( OBJECT_SELF, 2.0 ); } string getCastSpeech() { switch( Random(6) ) { case 0: return GetRGB(1,15,1) + "Nice cast..."; case 1: return GetRGB(1,15,1) + "Good cast."; case 2: return GetRGB(1,15,1) + "Cast could have been longer..."; case 3: return GetRGB(1,15,1) + "This cast was a bit left..."; case 4: return GetRGB(1,15,1) + "I made the cast."; case 5: return GetRGB(1,15,1) + "That cast was precise."; } return GetRGB(1,15,1) + "Nice cast..."; } string getWaitSpeech() { switch( Random(6) ) { case 0: return GetRGB(1,15,1) + "Hope I catch something."; case 1: return GetRGB(1,15,1) + "Hope I get a nice fish."; case 2: return GetRGB(1,15,1) + "I wonder if there are any eels here?"; case 3: return GetRGB(1,15,1) + "How long before I get a bite?"; case 4: return GetRGB(1,15,1) + "Was that a nibble?"; case 5: return GetRGB(1,15,1) + "Ho hum..."; } return GetRGB(1,15,1) + "Hope I catch something."; } void pcSplash( object pc, object rod ) { location loc = GetLocation( pc ); object invis = CreateObject( OBJECT_TYPE_PLACEABLE, "plc_invisobj", loc ); DelayCommand( 1.0, invisSplash( pc, rod ) ); DelayCommand( 4.0, AssignCommand( pc, SpeakString( getCastSpeech() ) ) ); DelayCommand( 11.0, AssignCommand( pc, SpeakString( getWaitSpeech() ) ) ); } void initFishing() { object pc = GetItemActivator(); if( !GetIsObjectValid( pc ) ) return; AssignCommand( pc, ClearAllActions() ); object rod = getRod( pc ); if( !GetIsObjectValid( rod ) ) { AssignCommand( pc, SpeakString( GetRGB(1,15,1) + "I need a fishing rod to fish." ) ); AssignCommand( pc, ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD , 1.0, 2.0) ); return; } int IsPCFishing = GetLocalInt(rod,"IsPCFishing"); if (IsPCFishing != 1) { //ok to start fishing SetLocalInt(rod,"IsPCFishing",1); } else { SetLocalInt(rod,"IsPCFishing",0); return; } object hole = GetNearestObjectByTag( "TsFishingHole", pc ); if( !near( pc, hole, holeMaxDist ) ) { AssignCommand( pc, SpeakString( GetRGB(1,15,1) + "There is no obvious place to fish." ) ); AssignCommand( pc, ActionPlayAnimation(ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD , 1.0, 2.0) ); AssignCommand( pc, ActionDoCommand( pcUnequipRod( pc ) ) ); return; } SetLocalObject( OBJECT_SELF, "tsPc", pc ); SetLocalObject( OBJECT_SELF, "tsRod", rod ); SetLocalObject( OBJECT_SELF, "tsHole", hole ); AssignCommand( pc, SpeakString( GetRGB(1,15,1) + "I think I'll drop a line..." ) ); setBusy(); incState(); callBack( OBJECT_SELF ); } void prepareToFish() { object pc = GetLocalObject( OBJECT_SELF, "tsPc" ); object hole = GetLocalObject( OBJECT_SELF, "tsHole" ); object rod = GetLocalObject( OBJECT_SELF, "tsRod" ); object bait = OBJECT_SELF; if( GetTag(bait) != "FishingBait" ) { tell( "Bait is "+GetName(bait) ); } incState(); AssignCommand( pc, ActionMoveToLocation( GetLocation( hole ), TRUE ) ); // CAST LINE AssignCommand( pc, ActionDoCommand( SetFacing( GetFacingFromLocation( GetLocation(hole) ) ) ) ); AssignCommand( pc, ActionDoCommand( pcEquipRod( pc, rod ) ) ); AssignCommand( pc, ActionWait( 2.0 ) ); AssignCommand( pc, ActionDoCommand( pcSplash( pc, rod ) ) ); AssignCommand( pc, ActionPlayAnimation( ANIMATION_LOOPING_LISTEN, 0.1, 6.0 ) ); AssignCommand( pc, ActionWait( 1.0 ) ); AssignCommand( pc, ActionDoCommand( callBack( bait ) ) ); } object catchResult( object makeThis, string sayThis ) { object pc = GetLocalObject( OBJECT_SELF, "tsPc" ); object thing = CopyObject( makeThis, GetLocation(pc) ); effect e = EffectVisualEffect( 284 ); ApplyEffectToObject( DURATION_TYPE_TEMPORARY, e, OBJECT_SELF ); AssignCommand( pc, SpeakString( sayThis ) ); if( GetObjectType(thing) == OBJECT_TYPE_ITEM ) { AssignCommand( pc, DelayCommand( 2.0, ActionPickUpItem( thing ) ) ); } return thing; } int testRodBreak() { object pc = GetLocalObject( OBJECT_SELF, "tsPc" ); object rod = GetLocalObject( OBJECT_SELF, "tsRod" ); if( d100() < 1 ) { AssignCommand( pc, SpeakString( GetRGB(1,15,1) + "Darn! I felt a tug, but my rod broke." ) ); DestroyObject( rod ); PlaySound( "as_na_branchsnp3" ); AssignCommand( pc, ActionPlayAnimation(ANIMATION_LOOPING_TALK_FORCEFUL , 1.0, 4.0 ) ); return 1; } return 0; } /*void goRotten( object what ) { if( GetIsObjectValid( what ) ) { object pc = GetItemPossessor( what ); if( GetIsObjectValid(pc) && GetIsPC(pc) ) { if( GetIsInCombat(pc) || GetIsResting(pc) || IsInConversation(pc) ) { DelayCommand( 6.0, goRotten(what) ); } AssignCommand( pc, SpeakString( "My "+GetName(what)+" just rotted away." ) ); } DestroyObject( what ); } } */ void fishingResult() { clrState(); clrBusy(); object pc = GetLocalObject( OBJECT_SELF, "tsPc" ); object hole = GetLocalObject( OBJECT_SELF, "tsHole" ); //int nDexMod = GetAbilityModifier( ABILITY_DEXTERITY, pc ); // int nWisMod = GetAbilityModifier( ABILITY_WISDOM, pc ); location lLoc = GetLocation( pc ); if( testRodBreak() ) { return; } if( d100() < 20 /*- (nDexMod+nWisMod)*3*/ ) { AssignCommand( pc, SpeakString( GetRGB(1,15,1) + "I did not catch anything." ) ); } else { string TsSuccess = GetLocalString( hole,"TsFishSuccess"); string TsFail = GetLocalString (hole , "TsFishFailure"); if (TsSuccess == "" || TsFail == "" ) { TsSuccess = "TsFishSuccess"; TsFail = "TsFishFailure"; } // Fish if( d100() < TS_CHANCE_TO_CATCH ) { object template = pickFromHoldingArea( TsSuccess, OBJECT_TYPE_ITEM ); object what = catchResult( template, GetRGB(1,15,1) + "I caught "+getPronoun(GetStringLowerCase(GetName(template))) ); //DelayCommand( 6.0 * 2.0/*10.0 * 5.0*/, goRotten( what ) ); } else { object template = pickFromHoldingArea( TsFail, OBJECT_TYPE_ITEM | OBJECT_TYPE_CREATURE ); catchResult( template, GetRGB(1,15,1) + "Oh crap! I caught "+getPronoun(GetStringLowerCase(GetName(template))) ); } } DestroyObject( OBJECT_SELF, 1.0 ); object rod = GetLocalObject( OBJECT_SELF, "tsRod" ); SetLocalInt(rod,"IsPCFishing",0); } int confirmState( int state ) { object pc = GetLocalObject( OBJECT_SELF, "tsPc" ); object hole = GetLocalObject( OBJECT_SELF, "tsHole" ); object rod = GetLocalObject( OBJECT_SELF, "tsRod" ); if( state > 0 ) { if( !GetIsObjectValid(pc) || !GetIsObjectValid(hole) || !GetIsObjectValid(rod) ) { tell( "reset state to 0" ); return 0; } } if( state > 0 ) { object rod = getRod( pc ); if( !GetIsObjectValid( rod ) ) { tell( "halted - no rod" ); return 99; } object hole = GetNearestObjectByTag( "TsFishingHole", pc ); if( !near( pc, hole, holeMaxDist ) ) { tell( "halted - no hole" ); return 99; } } if( state > 1 ) { // You must be near the hole. if( !near( pc, hole, holeMaxDist ) ) { tell( "restart - not near hole" ); object pc = GetLocalObject( OBJECT_SELF, "tsPc" ); AssignCommand( pc, ClearAllActions() ); clrState(); return 0; } // You don't get to catch fish if you're not holding the rod. object inHand = GetItemInSlot( INVENTORY_SLOT_RIGHTHAND, pc ); if( !isRod( inHand ) ) { tell( "halted - rod ! in hand" ); return 99; } } return state; } void main() { int state = GetLocalInt( OBJECT_SELF, "tsFishingState" ); tell( GetName(OBJECT_SELF)+" state="+IntToString(state) ); state = confirmState( state ); SetLocalInt( OBJECT_SELF, "tsFishingState", state ); switch( state ) { case 0: initFishing(); break; case 1: prepareToFish(); break; case 2: fishingResult(); break; case 99: { object pc = GetLocalObject( OBJECT_SELF, "tsPc" ); AssignCommand( pc, ClearAllActions() ); clrState(); break; } } }