diff options
Diffstat (limited to 'npc/functions/fishing.txt')
-rw-r--r-- | npc/functions/fishing.txt | 401 |
1 files changed, 401 insertions, 0 deletions
diff --git a/npc/functions/fishing.txt b/npc/functions/fishing.txt new file mode 100644 index 00000000..4dcb4882 --- /dev/null +++ b/npc/functions/fishing.txt @@ -0,0 +1,401 @@ +// Evol functions. +// Authors: +// gumi +// omatt +// Travolta +// Reid +// Jesusalva +// Description: +// Fishing functions. +// Variable +// .dir +// DOWN Never try or pulled too late +// UP Bait dropped +// LEFT Fish bite bait +// +// player log on .dir is DOWN, start by choose bait menu +// player chooses bait, script addtimer in npc .dir is UP +// if player pulls before signal npc, bait is lost, set .bait to DOWN goto choose bait +// if player pulls after pull delay max, bait is lost, set .bait to DOWN goto choose bait +// npc signal .dir is LEFT +// player pulls between npc signal and pulls delay max, got the fish, set .dir to DOWN goto choose bait + +function script fishing_cleanup { + .@npc$ = getarg(0, ""); + if (.@npc$ == "") end; + + set getvariableofnpc(.char_id, .@npc$), 0; // clean acc id + set getvariableofnpc(.account_id, .@npc$), 0; // clean char id + set getvariableofnpc(.last_used, .@npc$), gettimetick(2); // set last used time + setnpcdir .@npc$, DOWN; // reset direction + return; +} + +- script global fishing handler 32767,{ + end; + +OnBite: + if (getnpcdir(@fishing_spot$) != UP) + end; + + setnpcdir @fishing_spot$, LEFT; + @fishing_tick = gettimetick(0); + specialeffect(getvariableofnpc(.bite_fx, @fishing_spot$), SELF, playerattached()); + end; + +OnCleanUp: + dispbottom l("You waited too long and lost the bait..."); + specialeffect(getvariableofnpc(.failure_fx, @fishing_spot$), SELF, playerattached()); // event fail + fishing_cleanup(@fishing_spot$); + @fishing_spot$ = ""; // unbind fishing npc + end; +} + +function script fishing { + +/////////////////////////////////////////// +// Var initialization + + .@npc$ = strnpcinfo(0); // the full name of the fishing spot + + .@account_id = getvariableofnpc(.account_id, .@npc$); // the account id of the player using the fishing spot + .@char_id = getvariableofnpc(.char_id, .@npc$); // the char id of the player using the fishing spot + .@dir = getnpcdir(.@npc$); // direction of the fishing spot + .@last_used = getvariableofnpc(.last_used, .@npc$); // when this fishing spot was last used + .@baits = getvariableofnpc(.baits, .@npc$); // bait count + + .@rod = getvariableofnpc(.fishing_rod, .@npc$); // the fishing rod required for this spot + .@rod = (.@rod ? .@rod : FishingRod); + + .@regen_time = getvariableofnpc(.cooldown, .@npc$); // cooldown for the fishing spot + .@regen_time = (.@regen_time ? .@regen_time : 20); + + .@success_fx = getvariableofnpc(.success_fx, .@npc$); // effect to show on success + .@success_fx = (.@success_fx ? .@success_fx : 27); + + .@failure_fx = getvariableofnpc(.failure_fx, .@npc$); // effect to show on failure + if (.@failure_fx < 1) + { + .@failure_fx = 28; + set getvariableofnpc(.failure_fx, .@npc$), .@failure_fx; // needed by global handler + } + + .@initial_fx = getvariableofnpc(.initial_fx, .@npc$); // effect to show when throwing the bait + .@initial_fx = (.@initial_fx ? .@initial_fx : 29); + + .@bite_fx = getvariableofnpc(.bite_fx, .@npc$); // effect to show when something bites + if (.@bite_fx < 1) + { + .@bite_fx = 30; + set getvariableofnpc(.bite_fx, .@npc$), .@bite_fx; // needed by global handler + } + + .@wait_time_min = getvariableofnpc(.wait_time_min, .@npc$); // min amount of time to wait for the line to sink + .@wait_time_min = (.@wait_time_min ? .@wait_time_min : 4000); + + .@wait_time_max = getvariableofnpc(.wait_time_max, .@npc$); // max amount of time to wait for the line to sink + .@wait_time_max = (.@wait_time_max ? .@wait_time_max : 18000); + + .@catch_time = getvariableofnpc(.catch_time, .@npc$); // the player must catch the fish within X ms after the line sinks + .@catch_time = (.@catch_time ? .@catch_time : 5000); + + .@pull_rand_max = getvariableofnpc(.pull_rand_max, .@npc$); + .@pull_rand_max = (.@pull_rand_max ? .@pull_rand_max : 800); + + + if (getvariableofnpc(.bait_ids[1], .@npc$) < 1) + { + // default baits (bait, chance booster) + // TODO: we should have some fish prefer certain baits while other + // prefer other bait. currently all fish prefer the same baits + setarray getvariableofnpc(.bait_ids[1], .@npc$), + SmallTentacles, 0, + Bread, 0, + Aquada, 1, + UrchinMeat, 0, + TortugaTongue, 2, + Tentacles, 0; + } + + if (getvariableofnpc(.fish_ids[1], .@npc$) < 1) + { + // default fish: <array: 0, {[fish, probability]..}> + setarray getvariableofnpc(.fish_ids[1], .@npc$), + CommonCarp, 25, + GrassCarp, 1; + } + + if (.@baits < 1) + { + // only count it once + .@baits = getarraysize(getvariableofnpc(.bait_ids[0], .@npc$)); + set getvariableofnpc(.baits, .@npc$), .@baits; + } + + +/////////////////////////////////////////// +// Logic below + + if (countitem(.@rod) < 1) + { + dispbottom l("You don't have any @@.", getitemlink(.@rod)); + return -1; + } + + if (.@account_id > 0 && !isloggedin(.@account_id, .@char_id)) + { + fishing_cleanup .@npc$; // reset + .@dir = DOWN; + } + + if (.@char_id != getcharid(CHAR_ID_CHAR) && .@dir != DOWN) + { + dispbottom l("This fishing spot is already being used!"); + return -2; + } + + + // pull too soon + if (.@dir == UP) + { + deltimer "global fishing handler::OnCleanUp"; // cancel auto cleanup + deltimer "global fishing handler::OnBite"; + specialeffect(.@failure_fx, SELF, playerattached()); // event fail + fishing_cleanup .@npc$; // do it manually instead + dispbottom l("You pulled too soon and lost the bait."); + return -3; + } + + // pull maybe on time + else if (.@dir == LEFT) + { + deltimer "global fishing handler::OnCleanUp"; // cancel auto cleanup + fishing_cleanup .@npc$; // do it manually instead + + getmapxy .@mapbis$, .@xbis, .@ybis, UNITTYPE_PC; // get current char location + + // Leave spot, lost the bait + if (.@mapbis$ != @fishing_loc$[0] || .@xbis != @fishing_loc[0] || .@ybis != @fishing_loc[1] || @fishing_spot$ != .@npc$) + { + dispbottom l("You left your fishing spot!"); + return -4; + } + + .@fish_id = relative_array_random(getvariableofnpc(.fish_ids[0], .@npc$)); + + // RNG to obtain a fish + if (rand(gettimetick(0) - @fishing_tick) <= .@pull_rand_max + (100 * @FISHING_BOOSTER[getnpcid()])) + { + specialeffect(.@success_fx, SELF, playerattached()); // event success + + if(!checkweight(.@fish_id, 1)) + { + dispbottom l("You caught a @@ but had no room in your inventory to carry it.", getitemlink(.@fish_id)); + makeitem .@fish_id, 1, .@mapbis$, .@xbis, .@ybis; // drop on the ground + return 0; + } + + //dispbottom l("You caught a @@!", getitemlink(.@fish_id)); <= already shows "you picked up [...]" + getitem .@fish_id, 1; + } + else + { + dispbottom l("You pulled too late and lost the bait..."); + specialeffect(.@failure_fx, SELF, playerattached()); // event fail + .@fish_id = 0; + } + + return .@fish_id; + } + + + + if (gettimetick(2) - .@last_used < .@regen_time) + { + dispbottom l("This fishing spot has just been used, give it a rest."); + return -5; + } + + + // begin fishing + narrator S_LAST_NEXT, + l("You see some fish reflecting the sun on the surface of the water."), + l("What will be the bait for the fish?"); + + mes "##B" + l("Drag and drop an item from your inventory.") + "##b"; + + .@bait = requestitem(); + .@bait_c = false; + + if (.@bait < 1) + { + narrator S_FIRST_BLANK_LINE, + l("You take your fishing rod and leave."); + + return -6; + } + + if (countitem(.@bait) < 1) + { + return -6; + } + + for (.@i = 1; .@i < .@baits; .@i += 2) + { + if (getvariableofnpc(.bait_ids[.@i], .@npc$) == .@bait) + { + .@bait_c = true; + @FISHING_BOOSTER[getnpcid()] = getvariableofnpc(.bait_ids[.@i + 1], .@npc$); + break; + } + } + + if (.@bait_c != true) + { + narrator S_FIRST_BLANK_LINE, + l("This item cannot be used as bait here."); + + return -6; + } + + if (getvariableofnpc(.char_id, .@npc$) > 0) + { + narrator S_FIRST_BLANK_LINE, + l("Somebody took your place on this spot!"), + l("You take your fishing rod and leave."); + return -8; + } + + @fishing_spot$ = .@npc$; // bind player to fishing spot + set getvariableofnpc(.account_id, .@npc$), getcharid(CHAR_ID_ACCOUNT); // record account id + set getvariableofnpc(.char_id, .@npc$), getcharid(CHAR_ID_CHAR); // record char id + set getvariableofnpc(.last_used, .@npc$), gettimetick(2); + getmapxy(@fishing_loc$[0], @fishing_loc[0], @fishing_loc[1], 0); // record char pos + delitem .@bait, 1; + + // The player uses this spot, his bait is ready, he just has to wait for the signal. + closeclientdialog; + + specialeffect(.@initial_fx, SELF); // throw the bait + sleep2 800; // wait 0.8s for synchronize the sound of "plop" in water with the npc dir UP. + setnpcdir .@npc$, UP; + + dispbottom l("Wait for the bait to sink underwater."); + + .@delay = rand(.@wait_time_min, .@wait_time_max); + + addtimer .@delay, "global fishing handler::OnBite"; // bite logic + addtimer (.@delay + .@catch_time), "global fishing handler::OnCleanUp"; // auto clean up + + return 0; +} + + +//////////////////// +// Fishing Templates + +// #fish_basic - has only carps (freshwater) +- script #fish_basic NPC_WATER_SPLASH,{ + + fishing(); // begin or continue fishing + close; + +OnInit: + .distance = 5; + setarray .fish_ids, 0, + CommonCarp, 25, + GrassCarp, 1; + .fishing_rod = FishingRod; // Equipment to fish here + .catch_time = 5000; // must catch the fish within X ms after the line sinks + .wait_time_min = 4000; // min amount of time to wait for the line to sink + .wait_time_max = 18000; // max amount of time to wait for the line to sink + end; +} + + +// #fish_seawater - has only tuna +- script #fish_seawater NPC_WATER_SPLASH,{ + + fishing(); // begin or continue fishing + close; + +OnInit: + .distance = 5; + setarray .fish_ids, 0, + Tuna, 15, + Salmon, 1; + .fishing_rod = FishingRod; // Equipment to fish here + .catch_time = 4000; // must catch the fish within X ms after the line sinks + .wait_time_min = 8000; // min amount of time to wait for the line to sink + .wait_time_max = 18000; // max amount of time to wait for the line to sink + end; +} + + + +// #fish_river - A balanced fishing spot for Woodlands (Trout) +- script #fish_river NPC_WATER_SPLASH,{ + + fishing(); // begin or continue fishing + close; + +OnInit: + .distance = 5; + setarray .fish_ids, 0, + CommonCarp, 25, + Trout, 20, + GrassCarp, 5, + Salmon, 1; + .fishing_rod = FishingRod; // Equipment to fish here + .catch_time = 5500; // must catch the fish within X ms after the line sinks + .wait_time_min = 5000; // min amount of time to wait for the line to sink + .wait_time_max = 16000; // max amount of time to wait for the line to sink + end; +} + + + + +// #fish_river2 - A balanced fishing spot for Candor (Salmon) +- script #fish_river2 NPC_WATER_SPLASH,{ + + fishing(); // begin or continue fishing + close; + +OnInit: + .distance = 5; + setarray .fish_ids, 0, + CommonCarp, 25, + Salmon, 20, + GrassCarp, 5, + Trout, 1; + .fishing_rod = FishingRod; // Equipment to fish here + .catch_time = 5500; // must catch the fish within X ms after the line sinks + .wait_time_min = 5000; // min amount of time to wait for the line to sink + .wait_time_max = 16000; // max amount of time to wait for the line to sink + end; +} + + + + +// #fish_frozen - A fishing spot with cold waters (for Nivalis) +- script #fish_frozen NPC_WATER_SPLASH,{ + + fishing(); // begin or continue fishing + close; + +OnInit: + .distance = 5; + setarray .fish_ids, 0, + CommonCarp, 25, + Codfish, 20, + GrassCarp, 5, + Salmon, 1; + .fishing_rod = FishingRod; // Equipment to fish here + .catch_time = 5500; // must catch the fish within X ms after the line sinks + .wait_time_min = 5000; // min amount of time to wait for the line to sink + .wait_time_max = 16000; // max amount of time to wait for the line to sink + end; +} + |