diff --git a/code/modules/fishing/fishing.dm b/code/modules/fishing/fishing.dm new file mode 100644 index 0000000000..fb080138fb --- /dev/null +++ b/code/modules/fishing/fishing.dm @@ -0,0 +1,163 @@ +/* + * Fishing! Contains normal fishing rods and nets. + */ + +#define FISHING_RARE "rare" +#define FISHING_UNCOMMON "uncommon" +#define FISHING_COMMON "common" +#define FISHING_JUNK "junk" +#define FISHING_NOTHING "nothing" + +/turf/simulated/floor/water + var/has_fish = TRUE //If the water has fish or not. + + var/list/rare_fish_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 + ) + + var/list/uncommon_fish_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 + ) + + var/list/common_fish_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 + ) + + var/list/junk_list = list(/obj/item/clothing/shoes/boots/cowboy, /obj/random/fishing_junk) // 50-50 boots or junk. + + var/list/fishing_loot = list(FISHING_RARE = 5, FISHING_UNCOMMON = 15, FISHING_COMMON = 30, FISHING_JUNK = 30, FISHING_NOTHING = 40) + + 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/pool + has_fish = FALSE + +/turf/simulated/floor/water/deep/pool + has_fish = FALSE + +/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.len) + 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, "It is hard to go fishing without any line!") + return + if(R.cast) + to_chat(user, "You can only cast one line at a time!") + 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,"You feel a tug and begin pulling!") + 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("\The [R]'s string snaps!") + if(prob(33)) // Dead on hook. Good for food, not so much for live catch. + L.death() + to_chat(user,"You fish out \the [fished] from the water with [P.name]!") + 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 diff --git a/code/modules/fishing/fishing_net.dm b/code/modules/fishing/fishing_net.dm new file mode 100644 index 0000000000..136ed0c245 --- /dev/null +++ b/code/modules/fishing/fishing_net.dm @@ -0,0 +1,106 @@ +/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" + + 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, "Your net is already holding something!") + accept = FALSE + if(!accept) + to_chat(user, "[A] can't be trapped in \the [src].") + return + var/mob/L = A + user.visible_message("[user] natches [L] with \the [src].", "You snatch [L] with \the [src].") + 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("[user] releases [M] from \the [src].", "You release [M] from \the [src].") + for(var/obj/item/I in src) + I.forceMove(get_turf(src)) + user.visible_message("[user] dumps \the [I] out of \the [src].", "You dump \the [I] out of \the [src].") + 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) diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm new file mode 100644 index 0000000000..5b95a42740 --- /dev/null +++ b/code/modules/fishing/fishing_rod.dm @@ -0,0 +1,117 @@ + +/obj/item/weapon/material/fishing_rod + name = "crude fishing rod" + desc = "A crude rod made for catching fish." + 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, "\The [src] has \the [Bait] hanging on its hook.") + 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, "You remove the bait from \the [src].") + 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, "You cut \the [src]'s string!") + 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, "You do not have enough length in \the [C] to string this!") + return + if(do_after(user, rand(10 SECONDS, 20 SECONDS))) + C.use(5) + strung = TRUE + to_chat(user, "You re-string \the [src]!") + update_icon() + return + else if(istype(I, bait_type)) + if(Bait) + Bait.forceMove(get_turf(user)) + to_chat(user, "You swap \the [Bait] with \the [I].") + 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, "You cannot cast \the [src] when it is already in use!") + 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 diff --git a/code/modules/food/food/snacks.dm b/code/modules/food/food/snacks.dm index 294baee09b..66abd28a95 100644 --- a/code/modules/food/food/snacks.dm +++ b/code/modules/food/food/snacks.dm @@ -682,18 +682,36 @@ bitesize = 1 /obj/item/weapon/reagent_containers/food/snacks/carpmeat - name = "carp fillet" - desc = "A fillet of spess carp meat" + name = "fillet" + desc = "A fillet of carp meat" icon_state = "fishfillet" filling_color = "#FFDEFE" center_of_mass = list("x"=17, "y"=13) + var/toxin_type = "carpotoxin" + var/toxin_amount = 3 + /obj/item/weapon/reagent_containers/food/snacks/carpmeat/Initialize() . = ..() reagents.add_reagent("protein", 3) - reagents.add_reagent("carpotoxin", 3) + reagents.add_reagent(toxin_type, toxin_amount) src.bitesize = 6 +/obj/item/weapon/reagent_containers/food/snacks/carpmeat/sif + desc = "A fillet of sivian fish meat." + filling_color = "#2c2cff" + color = "#2c2cff" + toxin_type = "neurotoxic_protein" + toxin_amount = 2 + +/obj/item/weapon/reagent_containers/food/snacks/carpmeat/sif/murkfish + toxin_type = "murk_protein" + +/obj/item/weapon/reagent_containers/food/snacks/carpmeat/fish + desc = "A fillet of fish meat." + toxin_type = "neurotoxic_protein" + toxin_amount = 1 + /obj/item/weapon/reagent_containers/food/snacks/fishfingers name = "Fish Fingers" desc = "A finger of fish." diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm index f62356d83c..ef25ab2225 100644 --- a/code/modules/materials/material_recipes.dm +++ b/code/modules/materials/material_recipes.dm @@ -123,6 +123,7 @@ recipes += new/datum/stack_recipe("airtight plastic flaps", /obj/structure/plasticflaps/mining, 5, time = 25, one_per_turf = 1, on_floor = 1) recipes += new/datum/stack_recipe("water-cooler", /obj/structure/reagent_dispensers/water_cooler, 4, time = 10, one_per_turf = 1, on_floor = 1) recipes += new/datum/stack_recipe("lampshade", /obj/item/weapon/lampshade, 1, time = 1) + recipes += new/datum/stack_recipe("plastic net", /obj/item/weapon/material/fishing_net, 25, time = 1 MINUTE) /material/wood/generate_recipes() ..() @@ -142,6 +143,7 @@ recipes += new/datum/stack_recipe("noticeboard frame", /obj/item/frame/noticeboard, 4, time = 5, one_per_turf = 0, on_floor = 1) recipes += new/datum/stack_recipe("wooden bucket", /obj/item/weapon/reagent_containers/glass/bucket/wood, 2, time = 4, one_per_turf = 0, on_floor = 0) recipes += new/datum/stack_recipe("coilgun stock", /obj/item/weapon/coilgun_assembly, 5) + recipes += new/datum/stack_recipe("crude fishing rod", /obj/item/weapon/material/fishing_rod/built, 8, time = 10 SECONDS) /material/wood/log/generate_recipes() recipes = list() @@ -194,3 +196,20 @@ /material/supermatter/generate_recipes() recipes = list() recipes += new/datum/stack_recipe("supermatter shard", /obj/machinery/power/supermatter/shard, 30 , one_per_turf = 1, time = 600, on_floor = 1) + +/material/cloth/generate_recipes() + recipes = list() + recipes += new/datum/stack_recipe("woven net", /obj/item/weapon/material/fishing_net, 10, time = 30 SECONDS) + recipes += new/datum/stack_recipe("bedsheet", /obj/item/weapon/bedsheet, 10, time = 30 SECONDS) + recipes += new/datum/stack_recipe("uniform", /obj/item/clothing/under/color/white, 8, time = 15 SECONDS) + recipes += new/datum/stack_recipe("foot wraps", /obj/item/clothing/shoes/footwraps, 2, time = 5 SECONDS) + recipes += new/datum/stack_recipe("gloves", /obj/item/clothing/gloves/white, 2, time = 5 SECONDS) + recipes += new/datum/stack_recipe("wig", /obj/item/clothing/head/powdered_wig, 4, time = 10 SECONDS) + recipes += new/datum/stack_recipe("philosopher's wig", /obj/item/clothing/head/philosopher_wig, 50, time = 2 MINUTES) + recipes += new/datum/stack_recipe("taqiyah", /obj/item/clothing/head/taqiyah, 3, time = 6 SECONDS) + recipes += new/datum/stack_recipe("turban", /obj/item/clothing/head/turban, 3, time = 6 SECONDS) + recipes += new/datum/stack_recipe("hijab", /obj/item/clothing/head/hijab, 3, time = 6 SECONDS) + recipes += new/datum/stack_recipe("kippa", /obj/item/clothing/head/kippa, 3, time = 6 SECONDS) + recipes += new/datum/stack_recipe("scarf", /obj/item/clothing/accessory/scarf/white, 4, time = 5 SECONDS) + recipes += new/datum/stack_recipe("baggy pants", /obj/item/clothing/under/pants/baggy/white, 8, time = 10 SECONDS) + recipes += new/datum/stack_recipe("belt pouch", /obj/item/weapon/storage/belt/fannypack/white, 25, time = 1 MINUTE) diff --git a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm index 20d1b82aea..2362586051 100644 --- a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm +++ b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm @@ -32,6 +32,8 @@ // new /datum/data/mining_equipment("Industrial Hardsuit - Material Scanner", /obj/item/rig_module/vision/material, 500), // new /datum/data/mining_equipment("Industrial Hardsuit - Maneuvering Jets", /obj/item/rig_module/maneuvering_jets, 1250), // new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000), + new /datum/data/mining_equipment("Fishing Net", /obj/item/weapon/material/fishing_net, 500), + new /datum/data/mining_equipment("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 1000) ) /datum/data/mining_equipment diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index f48c4082b8..10d462d45d 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -104,6 +104,22 @@ var/list/holder_mob_icon_cache = list() /obj/item/weapon/holder/borer origin_tech = list(TECH_BIO = 6) +/obj/item/weapon/holder/fish + attack_verb = list("fished", "disrespected", "smacked", "smackereled") + hitsound = 'sound/effects/slime_squish.ogg' + slot_flags = SLOT_HOLSTER + origin_tech = list(TECH_BIO = 3) + +/obj/item/weapon/holder/fish/afterattack(var/atom/target, var/mob/living/user, proximity) + if(!target) + return + if(!proximity) + return + if(isliving(target)) + var/mob/living/L = target + if(prob(10)) + L.Stun(2) + /obj/item/weapon/holder/attackby(obj/item/weapon/W as obj, mob/user as mob) for(var/mob/M in src.contents) M.attackby(W,user) diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/crab.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/crab.dm index 3b40147794..06d4eb4caa 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/passive/crab.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/crab.dm @@ -16,6 +16,8 @@ response_harm = "stomps" friendly = "pinches" + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/crab + say_list_type = /datum/say_list/crab //COFFEE! SQUEEEEEEEEE! @@ -23,3 +25,33 @@ name = "Coffee" real_name = "Coffee" desc = "It's Coffee, the other pet!" + +// Sif! + +/datum/category_item/catalogue/fauna/sif_crab + name = "Sivian Fauna - Shelf Crab" + desc = "Classification: S Ocypode glacian\ +

\ + A small crustacean sometimes considered a pest to Sivian fisheries, \ + as the creatures often tend to ignore non-native fish species when feeding. This \ + results in an unfortunate advantage for invasive species. \ +
\ + Otherwise, these animals are enjoyed as a reliable source of high-grade meat." + value = CATALOGUER_REWARD_EASY + +/mob/living/simple_mob/animal/passive/crab/sif + icon = 'icons/mob/fish.dmi' + tt_desc = "S Ocypode glacian" + + catalogue_data = list(/datum/category_item/catalogue/fauna/sif_crab) + +/mob/living/simple_mob/animal/passive/crab/sif/Initialize() + ..() + adjust_scale(rand(5,15) / 10) + +// Meat! + +/obj/item/weapon/reagent_containers/food/snacks/meat/crab + name = "meat" + desc = "A chunk of meat." + icon_state = "crustacean-meat" diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/fish.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/fish.dm index bdf8853b4b..790681a3fc 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/passive/fish.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/fish.dm @@ -1,14 +1,27 @@ // Different types of fish! They are all subtypes of this tho +/datum/category_item/catalogue/fauna/invasive_fish + name = "Invasive Fauna - Fish" + desc = "This fish is considered an invasive species according \ + to Sivian wildlife regulations. Removal or relocation is advised." + value = CATALOGUER_REWARD_TRIVIAL + /mob/living/simple_mob/animal/passive/fish name = "fish" desc = "Its a fishy. No touchy fishy." icon = 'icons/mob/fish.dmi' + item_state = "fish" + + catalogue_data = list(/datum/category_item/catalogue/fauna/invasive_fish) mob_size = MOB_SMALL // So fish are actually underwater. plane = TURF_PLANE layer = UNDERWATER_LAYER + holder_type = /obj/item/weapon/holder/fish + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat/fish + // By default they can be in any water turf. Subtypes might restrict to deep/shallow etc var/global/list/suitable_turf_types = list( /turf/simulated/floor/beach/water, @@ -75,3 +88,212 @@ icon_living = "koi-swim" icon_dead = "koi-dead" +/datum/category_item/catalogue/fauna/javelin + name = "Sivian Fauna - Javelin Shark" + desc = "Classification: S Cetusan minimalix\ +

\ + A small breed of fatty shark native to the waters near the Ullran Expanse.\ + The creatures are not known to attack humans or larger animals, possibly \ + due to their size. It is speculated that they are actually scavengers, \ + as they are most commonly found near the gulf floor. \ +
\ + The Javelin's reproductive cycle only recurs between three and four \ + Sivian years. \ +
\ + These creatures are considered a protected species, and thus require an \ + up-to-date license to be hunted." + value = CATALOGUER_REWARD_EASY + +/mob/living/simple_mob/animal/passive/fish/javelin + name = "javelin" + tt_desc = "S Cetusan minimalix" + icon_state = "javelin-swim" + icon_living = "javelin-swim" + icon_dead = "javelin-dead" + + catalogue_data = list(/datum/category_item/catalogue/fauna/javelin) + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat/sif + +/datum/category_item/catalogue/fauna/icebass + name = "Sivian Fauna - Glitter Bass" + desc = "Classification: X Micropterus notius crotux\ +

\ + Initially a genetically engineered hybrid of the common Earth bass and \ + the Sivian Rock-Fish. These were designed to deal with the invasive \ + fish species, however to their creators' dismay, they instead \ + began to form their own passive niche. \ +
\ + Due to the brilliant reflective scales earning them their name, the \ + animals pose a specific issue for Sivian animals relying on \ + bioluminesence to aid in their hunt. \ +
\ + Despite their beauty, they are considered an invasive species." + value = CATALOGUER_REWARD_EASY + +/mob/living/simple_mob/animal/passive/fish/icebass + name = "glitter bass" + tt_desc = "X Micropterus notius crotux" + icon_state = "sifbass-swim" + icon_living = "sifbass-swim" + icon_dead = "sifbass-dead" + + catalogue_data = list(/datum/category_item/catalogue/fauna/icebass) + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat/sif + + var/max_red = 150 + var/min_red = 50 + + var/max_blue = 255 + var/min_blue = 50 + + var/max_green = 150 + var/min_green = 50 + + var/dorsal_color = "#FFFFFF" + var/belly_color = "#FFFFFF" + + var/image/dorsal_image + var/image/belly_image + +/mob/living/simple_mob/animal/passive/fish/icebass/Initialize() + ..() + dorsal_color = rgb(rand(min_red,max_red), rand(min_green,max_green), rand(min_blue,max_blue)) + belly_color = rgb(rand(min_red,max_red), rand(min_green,max_green), rand(min_blue,max_blue)) + update_icon() + +/mob/living/simple_mob/animal/passive/fish/icebass/update_icon() + overlays.Cut() + ..() + if(!dorsal_image) + dorsal_image = image(icon, "[icon_state]_mask-body") + if(!belly_image) + belly_image = image(icon, "[icon_state]_mask-belly") + + dorsal_image.color = dorsal_color + belly_image.color = belly_color + + overlays += dorsal_image + overlays += belly_image + +/datum/category_item/catalogue/fauna/rockfish + name = "Sivian Fauna - Rock Puffer" + desc = "Classification: S Tetraodontidae scopulix\ +

\ + A species strangely resembling the puffer-fish of Earth. These \ + creatures do not use toxic spines to protect themselves, instead \ + utilizing an incredibly durable exoskeleton that is molded by the \ + expansion of its ventral fluid bladders. \ +
\ + Rock Puffers or 'Rock-fish' are often host to smaller creatures which \ + maneuver their way into the gap between the fish's body and shell. \ +
\ + The species is also capable of pulling its vibrantly colored head into \ + the safer confines of its shell, the action being utilized in their \ + attempts to find a mate." + value = CATALOGUER_REWARD_EASY + +/mob/living/simple_mob/animal/passive/fish/rockfish + name = "rock-fish" + tt_desc = "S Tetraodontidae scopulix" + icon_state = "rockfish-swim" + icon_living = "rockfish-swim" + icon_dead = "rockfish-dead" + + catalogue_data = list(/datum/category_item/catalogue/fauna/rockfish) + + armor = list( + "melee" = 90, + "bullet" = 50, + "laser" = -15, + "energy" = 30, + "bomb" = 30, + "bio" = 100, + "rad" = 100) + + var/max_red = 255 + var/min_red = 50 + + var/max_blue = 255 + var/min_blue = 50 + + var/max_green = 255 + var/min_green = 50 + + var/head_color = "#FFFFFF" + + var/image/head_image + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat/sif + +/mob/living/simple_mob/animal/passive/fish/rockfish/Initialize() + ..() + head_color = rgb(rand(min_red,max_red), rand(min_green,max_green), rand(min_blue,max_blue)) + +/mob/living/simple_mob/animal/passive/fish/rockfish/update_icon() + overlays.Cut() + ..() + if(!head_image) + head_image = image(icon, "[icon_state]_mask") + + head_image.color = head_color + + overlays += head_image + +/datum/category_item/catalogue/fauna/solarfish + name = "Sivian Fauna - Solar Fin" + desc = "Classification: S Exocoetidae solarin\ +

\ + An incredibly rare species of Sivian fish.\ + The solar-fin missile fish is a specialized omnivore capable of \ + catching insects or small birds venturing too close to the water's \ + surface. \ +
\ + The glimmering fins of the solar-fin are actually biofluorescent, \ + 'charged' by the creature basking at the surface of the water, most \ + commonly by the edge of an ice-shelf, as a rapid means of cover. \ +
\ + These creatures are considered a protected species, and thus require an \ + up-to-date license to be hunted." + value = CATALOGUER_REWARD_HARD + +/mob/living/simple_mob/animal/passive/fish/solarfish + name = "sun-fin" + tt_desc = "S Exocoetidae solarin" + icon_state = "solarfin-swim" + icon_living = "solarfin-swim" + icon_dead = "solarfin-dead" + + catalogue_data = list(/datum/category_item/catalogue/fauna/solarfish) + + has_eye_glow = TRUE + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat/sif + +/datum/category_item/catalogue/fauna/murkin + name = "Sivian Fauna - Murkfish" + desc = "Classification: S Perca lutux\ +

\ + A small, Sivian fish most known for its bland-ness.\ +
\ + The species is incredibly close in appearance to the Earth \ + perch, aside from its incredibly tall dorsal fin. The animals use \ + the fin to assess the wind direction while near the surface. \ +
\ + The murkfish earns its name from the fact its dense meat tastes like mud \ + thanks to a specially formed protein, most likely an adaptation to \ + protect the species from predation." + value = CATALOGUER_REWARD_TRIVIAL + +/mob/living/simple_mob/animal/passive/fish/murkin + name = "murkin" + tt_desc = "S Perca lutux" + + icon_state = "murkin-swim" + icon_living = "murkin-swim" + icon_dead = "murkin-dead" + + catalogue_data = list(/datum/category_item/catalogue/fauna/murkin) + + meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat/sif/murkfish diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm index 35179e16a3..08547b9064 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -86,6 +86,12 @@ taste_description = "egg" color = "#FFFFAA" +/datum/reagent/nutriment/protein/murk + name = "murkfin protein" + id = "murk_protein" + taste_description = "mud" + color = "#664330" + /datum/reagent/nutriment/honey name = "Honey" id = "honey" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index 6595343169..93f005addb 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -49,6 +49,25 @@ color = "#003333" strength = 10 +/datum/reagent/toxin/neurotoxic_protein + name = "toxic protein" + id = "neurotoxic_protein" + description = "A weak neurotoxic chemical commonly found in Sivian fish meat." + taste_description = "fish" + reagent_state = LIQUID + color = "#005555" + strength = 8 + +/datum/reagent/toxin/neurotoxic_protein/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + ..() + if(alien != IS_DIONA) + if(M.canmove && !M.restrained() && istype(M.loc, /turf/space)) + step(M, pick(cardinal)) + if(prob(5)) + M.emote(pick("twitch", "drool", "moan")) + if(prob(20)) + M.adjustBrainLoss(0.1) + //R-UST port // Produced during deuterium synthesis. Super poisonous, SUPER flammable (doesn't need oxygen to burn). /datum/reagent/toxin/hydrophoron diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index 960df2fa75..8e4e84e3bf 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -2373,4 +2373,13 @@ id = "biomass" result = "biomass" required_reagents = list("protein" = 1, "sugar" = 1, "phoron" = 1) - result_amount = 1 // Roughly 20u per phoron sheet \ No newline at end of file + result_amount = 1 // Roughly 20u per phoron sheet + +// Neutralization. + +/datum/chemical_reaction/neutralize_neurotoxic_protein + name = "Neutralize Toxic Proteins" + id = "neurotoxic_protein_neutral" + result = "protein" + required_reagents = list("anti_toxin" = 1, "neurotoxic_protein" = 2) + result_amount = 2 diff --git a/icons/mob/fish.dmi b/icons/mob/fish.dmi index 81ba72c9fd..66dbf7278e 100644 Binary files a/icons/mob/fish.dmi and b/icons/mob/fish.dmi differ diff --git a/icons/mob/items/lefthand_holder.dmi b/icons/mob/items/lefthand_holder.dmi index 9f47a4743a..d629c657ce 100644 Binary files a/icons/mob/items/lefthand_holder.dmi and b/icons/mob/items/lefthand_holder.dmi differ diff --git a/icons/mob/items/lefthand_material.dmi b/icons/mob/items/lefthand_material.dmi index 767b25c77a..a2f035cd58 100644 Binary files a/icons/mob/items/lefthand_material.dmi and b/icons/mob/items/lefthand_material.dmi differ diff --git a/icons/mob/items/righthand_holder.dmi b/icons/mob/items/righthand_holder.dmi index 7ac02b7720..c1e0563ec4 100644 Binary files a/icons/mob/items/righthand_holder.dmi and b/icons/mob/items/righthand_holder.dmi differ diff --git a/icons/mob/items/righthand_material.dmi b/icons/mob/items/righthand_material.dmi index 28da6c5e55..6895183a5b 100644 Binary files a/icons/mob/items/righthand_material.dmi and b/icons/mob/items/righthand_material.dmi differ diff --git a/icons/obj/food.dmi b/icons/obj/food.dmi index d282fb3e6a..cef02f3564 100644 Binary files a/icons/obj/food.dmi and b/icons/obj/food.dmi differ diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi index c9cea71b82..d2d986c205 100644 Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi index 3abf08997f..da2754d04b 100644 Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ diff --git a/polaris.dme b/polaris.dme index 77024a848d..274d808b3f 100644 --- a/polaris.dme +++ b/polaris.dme @@ -1613,6 +1613,9 @@ #include "code\modules\examine\descriptions\weapons.dm" #include "code\modules\ext_scripts\irc.dm" #include "code\modules\ext_scripts\python.dm" +#include "code\modules\fishing\fishing.dm" +#include "code\modules\fishing\fishing_net.dm" +#include "code\modules\fishing\fishing_rod.dm" #include "code\modules\flufftext\Dreaming.dm" #include "code\modules\flufftext\Hallucination.dm" #include "code\modules\flufftext\look_up.dm"