This commit is contained in:
Atermonera
2019-05-06 10:15:23 -08:00
committed by VirgoBot
parent 3ec181dace
commit 90ee680dd5
23 changed files with 837 additions and 3 deletions
+202
View File
@@ -0,0 +1,202 @@
/*
* Fishing! Contains normal fishing rods and nets.
*/
GLOBAL_LIST_INIT(generic_fishing_rare_list, list(
/mob/living/simple_mob/animal/passive/fish/solarfish = 1,
/mob/living/simple_mob/animal/passive/fish/icebass = 5,
/mob/living/simple_mob/animal/passive/fish/koi = 3
))
GLOBAL_LIST_INIT(generic_fishing_uncommon_list, list(
/mob/living/simple_mob/animal/passive/fish/salmon = 6,
/mob/living/simple_mob/animal/passive/fish/pike = 10,
/mob/living/simple_mob/animal/passive/fish/javelin = 3,
/mob/living/simple_mob/animal/passive/crab/sif = 1
))
GLOBAL_LIST_INIT(generic_fishing_common_list, list(
/mob/living/simple_mob/animal/passive/fish/bass = 10,
/mob/living/simple_mob/animal/passive/fish/trout = 8,
/mob/living/simple_mob/animal/passive/fish/perch = 6,
/mob/living/simple_mob/animal/passive/fish/murkin = 8,
/mob/living/simple_mob/animal/passive/fish/rockfish = 5,
/mob/living/simple_mob/animal/passive/crab = 1
))
GLOBAL_LIST_INIT(generic_fishing_junk_list, list(
/obj/item/clothing/shoes/boots/cowboy = 1,
/obj/random/fishing_junk = 10
))
GLOBAL_LIST_INIT(generic_fishing_pool_list, list(
/obj/item/weapon/bikehorn/rubberducky = 5,
/obj/item/toy/plushie/carp = 20,
/obj/random/junk = 80,
/obj/random/trash = 80,
/obj/item/weapon/spacecash/c1 = 10,
/obj/item/weapon/spacecash/c10 = 5,
/obj/item/weapon/spacecash/c100 = 1
))
#define FISHING_RARE "rare"
#define FISHING_UNCOMMON "uncommon"
#define FISHING_COMMON "common"
#define FISHING_JUNK "junk"
#define FISHING_NOTHING "nothing"
GLOBAL_LIST_INIT(generic_fishing_chance_list, list(FISHING_RARE = 5, FISHING_UNCOMMON = 15, FISHING_COMMON = 30, FISHING_JUNK = 30, FISHING_NOTHING = 40))
/turf/simulated/floor/water
var/has_fish = TRUE //If the water has fish or not.
var/list/rare_fish_list // Rare list.
var/list/uncommon_fish_list // Uncommon list.
var/list/common_fish_list // Common list.
var/list/junk_list // Junk item list.
var/list/fishing_loot // Chance list.
var/fishing_cooldown = 30 SECONDS
var/last_fished = 0
var/fish_type
var/min_fishing_time = 30 // Time in seconds.
var/max_fishing_time = 90
var/being_fished = FALSE
/turf/simulated/floor/water/proc/handle_fish() // Subtypes should over-ride this, and supply their own GLOB lists for maximum Mix and Match power.
if(has_fish)
rare_fish_list = GLOB.generic_fishing_rare_list
uncommon_fish_list = GLOB.generic_fishing_uncommon_list
common_fish_list = GLOB.generic_fishing_common_list
junk_list = GLOB.generic_fishing_junk_list
fishing_loot = GLOB.generic_fishing_chance_list
/turf/simulated/floor/water/pool
has_fish = FALSE
/turf/simulated/floor/water/deep/pool
has_fish = TRUE
/turf/simulated/floor/water/deep/pool/handle_fish()
if(has_fish)
rare_fish_list = GLOB.generic_fishing_pool_list
uncommon_fish_list = GLOB.generic_fishing_pool_list
common_fish_list = GLOB.generic_fishing_pool_list
junk_list = GLOB.generic_fishing_pool_list
fishing_loot = GLOB.generic_fishing_chance_list
/turf/simulated/floor/water/ex_act(severity) // Explosive fishing.
if(prob(5 * severity))
pick_fish()
if(fish_type)
var/fished = new fish_type(get_turf(src))
if(isliving(fished))
var/mob/living/L = fished
L.death()
has_fish = FALSE
..(severity)
/turf/simulated/floor/water/proc/pick_fish()
if(has_fish)
var/table = pickweight(fishing_loot)
if(table == FISHING_RARE && rare_fish_list.len)
fish_type = pickweight(rare_fish_list)
else if(table == FISHING_UNCOMMON && uncommon_fish_list.len)
fish_type = pickweight(uncommon_fish_list)
else if(table == FISHING_COMMON && common_fish_list.len)
fish_type = pickweight(common_fish_list)
else if(table == FISHING_JUNK && junk_list.len)
fish_type = pickweight(junk_list)
else
fish_type = null
else
fish_type = null
/turf/simulated/floor/water/attackby(obj/item/weapon/P as obj, mob/user as mob)
//If you use a fishing rod on an open body of water that var/has_fish enabled
if(istype(P, /obj/item/weapon/material/fishing_rod) && !being_fished)
var/obj/item/weapon/material/fishing_rod/R = P
if(!R.strung)
to_chat(user, "<span class='notice'>It is hard to go fishing without any line!</span>")
return
if(R.cast)
to_chat(user, "<span class='notice'>You can only cast one line at a time!</span>")
return
playsound(src, 'sound/effects/slosh.ogg', 5, 1, 5)
to_chat(user,"You cast \the [P.name] into \the [src].")
being_fished = TRUE
R.cast = TRUE
var/fishing_time = rand(min_fishing_time SECONDS,max_fishing_time SECONDS) * R.toolspeed
if(do_after(user,fishing_time,user))
playsound(src, 'sound/effects/slosh.ogg', 5, 1, 5)
to_chat(user,"<span class='notice'>You feel a tug and begin pulling!</span>")
if(world.time >= last_fished + fishing_cooldown)
pick_fish()
last_fished = world.time
else
fish_type = null
if(prob(3)) // No fish left here..
has_fish = FALSE
//List of possible outcomes.
if(!fish_type)
to_chat(user,"You caught... nothing. How sad.")
else
var/fished = new fish_type(get_turf(user))
if(isliving(fished))
R.consume_bait()
var/mob/living/L = fished
if(prob(rand(L.mob_size) + 10) && R.line_break)
R.strung = FALSE
R.update_icon()
user.visible_message("<span class='danger'>\The [R]'s string snaps!</span>")
if(prob(33)) // Dead on hook. Good for food, not so much for live catch.
L.death()
to_chat(user,"<span class='notice'>You fish out \the [fished] from the water with [P.name]!</span>")
R.cast = FALSE
being_fished = FALSE
else ..()
/obj/random/fishing_junk
name = "junk"
desc = "This is a random fishing junk item."
icon = 'icons/obj/storage.dmi'
icon_state = "red"
/obj/random/fishing_junk/item_to_spawn()
return pickweight(list(
/obj/random/toy = 60,
/obj/random/maintenance/engineering = 50,
/obj/random/maintenance/clean = 40,
/obj/random/maintenance/security = 40,
/obj/random/maintenance/research = 40,
/obj/structure/closet/crate/secure/loot = 30,
/obj/random/bomb_supply = 30,
/obj/random/powercell = 30,
/obj/random/tech_supply/component = 30,
/obj/random/unidentified_medicine/old_medicine = 30,
/obj/random/plushie = 30,
/obj/random/contraband = 20,
/obj/random/coin = 20,
/obj/random/medical = 15,
/obj/random/unidentified_medicine/fresh_medicine = 15,
/obj/random/action_figure = 15,
/obj/random/plushielarge = 15,
/obj/random/firstaid = 10,
/obj/random/tool/powermaint = 5,
/obj/random/unidentified_medicine/combat_medicine = 1,
/obj/random/tool/alien = 1,
/obj/random/handgun = 1,
/mob/living/simple_mob/animal/sif/hooligan_crab = 1
))
#undef FISHING_RARE
#undef FISHING_UNCOMMON
#undef FISHING_COMMON
#undef FISHING_JUNK
#undef FISHING_NOTHING
+109
View File
@@ -0,0 +1,109 @@
/obj/item/weapon/material/fishing_net
name = "fishing net"
desc = "A crude fishing net."
icon = 'icons/obj/items.dmi'
icon_state = "net"
item_state = "net"
description_info = "This object can be used to capture certain creatures easily, most commonly fish. \
It has a reach of two tiles, and can be emptied by activating it in-hand. \
This version will not keep creatures inside in stasis, and will be heavier if it contains a mob."
var/empty_state = "net"
var/contain_state = "net_full"
w_class = ITEMSIZE_SMALL
flags = NOBLUDGEON
slowdown = 0.25
reach = 2
default_material = "cloth"
var/list/accepted_mobs = list(/mob/living/simple_mob/animal/passive/fish)
/obj/item/weapon/material/fishing_net/Initialize()
..()
update_icon()
/obj/item/weapon/material/fishing_net/afterattack(var/atom/A, var/mob/user, var/proximity)
if(get_dist(get_turf(src), A) > reach)
return
if(istype(A, /turf))
var/mob/living/Target
for(var/type in accepted_mobs)
Target = locate(type) in A.contents
if(Target)
afterattack(Target, user, proximity)
break
if(istype(A, /mob))
var/accept = FALSE
for(var/D in accepted_mobs)
if(istype(A, D))
accept = TRUE
for(var/atom/At in src.contents)
if(isliving(At))
to_chat(user, "<span class='notice'>Your net is already holding something!</span>")
accept = FALSE
if(!accept)
to_chat(user, "[A] can't be trapped in \the [src].")
return
var/mob/L = A
user.visible_message("<span class='notice'>[user] snatches [L] with \the [src].</span>", "<span class='notice'>You snatch [L] with \the [src].</span>")
L.forceMove(src)
update_icon()
update_weight()
return
return ..()
/obj/item/weapon/material/fishing_net/attack_self(var/mob/user)
for(var/mob/M in src)
M.forceMove(get_turf(src))
user.visible_message("<span class='notice'>[user] releases [M] from \the [src].</span>", "<span class='notice'>You release [M] from \the [src].</span>")
for(var/obj/item/I in src)
I.forceMove(get_turf(src))
user.visible_message("<span class='notice'>[user] dumps \the [I] out of \the [src].</span>", "<span class='notice'>You dump \the [I] out of \the [src].</span>")
update_icon()
update_weight()
return
/obj/item/weapon/material/fishing_net/attackby(var/obj/item/W, var/mob/user)
if(contents)
for(var/mob/living/L in contents)
if(prob(25))
L.attackby(W, user)
..()
/obj/item/weapon/material/fishing_net/update_icon() // Also updates name and desc
underlays.Cut()
overlays.Cut()
..()
name = initial(name)
desc = initial(desc)
var/contains_mob = FALSE
for(var/mob/M in src)
var/image/victim = image(M.icon, M.icon_state)
underlays += victim
name = "filled net"
desc = "A net with [M] inside."
contains_mob = TRUE
if(contains_mob)
icon_state = contain_state
else
icon_state = empty_state
return
/obj/item/weapon/material/fishing_net/proc/update_weight()
if(icon_state == contain_state) // Let's not do a for loop just to see if a mob is in here.
slowdown = initial(slowdown) * 2
reach = 1
else
slowdown = initial(slowdown)
reach = initial(reach)
+124
View File
@@ -0,0 +1,124 @@
/obj/item/weapon/material/fishing_rod
name = "crude fishing rod"
desc = "A crude rod made for catching fish."
description_info = "A tool usable on water-tiles to attempt to catch fish by swiping it over them.\
You can add or remove cable by wirecutter or coil respectively to allow its use.\
Any food containing things like protein, sugar, or standard nutriment can be attached to the rod, allowing for faster fishing based on the amount.\
You can examine the rod to check if it has bait attached, and examine it automatically if so.\
\
Ctrl clicking the rod will remove any attached bait from the rod."
description_antag = "Some fishing rods can be utilized as long-range, sharp weapons, though their pseudo ranged ability comes at the cost of slow speed."
icon_state = "fishing_rod"
item_state = "fishing_rod"
force_divisor = 0.25
throwforce = 7
sharp = TRUE
attack_verb = list("whipped", "battered", "slapped", "fished", "hooked")
hitsound = 'sound/weapons/punchmiss.ogg'
applies_material_colour = TRUE
default_material = "wood"
can_dull = FALSE
var/strung = TRUE
var/line_break = TRUE
var/obj/item/weapon/reagent_containers/food/snacks/Bait
var/bait_type = /obj/item/weapon/reagent_containers/food/snacks
var/cast = FALSE
attackspeed = 3 SECONDS
/obj/item/weapon/material/fishing_rod/built
strung = FALSE
/obj/item/weapon/material/fishing_rod/examine(mob/M as mob)
..()
if(Bait)
to_chat(M, "<span class='notice'>\The [src] has \the [Bait] hanging on its hook.</span>")
Bait.examine(M)
/obj/item/weapon/material/fishing_rod/CtrlClick(mob/user)
if((src.loc == user || Adjacent(user)) && Bait)
Bait.forceMove(get_turf(user))
to_chat(user, "<span class='notice'>You remove the bait from \the [src].</span>")
Bait = null
else
..()
/obj/item/weapon/material/fishing_rod/Initialize()
..()
update_icon()
/obj/item/weapon/material/fishing_rod/attackby(obj/item/I as obj, mob/user as mob)
if(I.is_wirecutter() && strung)
strung = FALSE
to_chat(user, "<span class='notice'>You cut \the [src]'s string!</span>")
update_icon()
return
else if(istype(I, /obj/item/stack/cable_coil) && !strung)
var/obj/item/stack/cable_coil/C = I
if(C.amount < 5)
to_chat(user, "<span class='warning'>You do not have enough length in \the [C] to string this!</span>")
return
if(do_after(user, rand(10 SECONDS, 20 SECONDS)))
C.use(5)
strung = TRUE
to_chat(user, "<span class='notice'>You string \the [src]!</span>")
update_icon()
return
else if(istype(I, bait_type))
if(Bait)
Bait.forceMove(get_turf(user))
to_chat(user, "<span class='notice'>You swap \the [Bait] with \the [I].</span>")
Bait = I
user.drop_from_inventory(Bait)
Bait.forceMove(src)
update_bait()
return ..()
/obj/item/weapon/material/fishing_rod/update_icon()
overlays.Cut()
..()
if(strung)
overlays += image(icon, "[icon_state]_string")
/obj/item/weapon/material/fishing_rod/proc/update_bait()
if(istype(Bait, bait_type))
var/foodvolume
for(var/datum/reagent/re in Bait.reagents.reagent_list)
if(re.id == "nutriment" || re.id == "protein" || re.id == "glucose")
foodvolume += re.volume
toolspeed = initial(toolspeed) * min(0.75, (0.5 / max(0.5, (foodvolume / Bait.reagents.maximum_volume))))
else
toolspeed = initial(toolspeed)
/obj/item/weapon/material/fishing_rod/proc/consume_bait()
if(Bait)
qdel(Bait)
Bait = null
return TRUE
return FALSE
/obj/item/weapon/material/fishing_rod/attack(var/mob/M as mob, var/mob/user as mob, var/def_zone)
if(cast)
to_chat(user, "<span class='notice'>You cannot cast \the [src] when it is already in use!</span>")
return FALSE
update_bait()
return ..()
/obj/item/weapon/material/fishing_rod/modern
name = "fishing rod"
desc = "A refined rod for catching fish."
icon_state = "fishing_rod_modern"
item_state = "fishing_rod"
reach = 4
attackspeed = 2 SECONDS
default_material = "titanium"
toolspeed = 0.75
/obj/item/weapon/material/fishing_rod/modern/built
strung = FALSE