mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-12 11:13:16 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -248,7 +248,7 @@
|
|||||||
icon_state = "television"
|
icon_state = "television"
|
||||||
icon_keyboard = null
|
icon_keyboard = null
|
||||||
icon_screen = "detective_tv"
|
icon_screen = "detective_tv"
|
||||||
circuit = null
|
circuit = /obj/item/weapon/circuitboard/security/tv
|
||||||
light_color = "#3848B3"
|
light_color = "#3848B3"
|
||||||
light_power_on = 0.5
|
light_power_on = 0.5
|
||||||
|
|
||||||
|
|||||||
@@ -553,4 +553,5 @@
|
|||||||
icon_state = "laptop"
|
icon_state = "laptop"
|
||||||
icon_keyboard = "laptop_key"
|
icon_keyboard = "laptop_key"
|
||||||
icon_screen = "medlaptop"
|
icon_screen = "medlaptop"
|
||||||
|
circuit = /obj/item/weapon/circuitboard/med_data/laptop
|
||||||
density = 0
|
density = 0
|
||||||
@@ -121,7 +121,7 @@
|
|||||||
if(card)
|
if(card)
|
||||||
if(checkFace())
|
if(checkFace())
|
||||||
if(checkCardCooldown())
|
if(checkCardCooldown())
|
||||||
makeOffDuty()
|
makeOnDuty(href_list["switch-to-onduty"])
|
||||||
usr.put_in_hands(card)
|
usr.put_in_hands(card)
|
||||||
card = null
|
card = null
|
||||||
update_icon()
|
update_icon()
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ obj/machinery/recharger
|
|||||||
use_power = 1
|
use_power = 1
|
||||||
idle_power_usage = 4
|
idle_power_usage = 4
|
||||||
active_power_usage = 40000 //40 kW
|
active_power_usage = 40000 //40 kW
|
||||||
|
var/efficiency = 40000 //will provide the modified power rate when upgraded
|
||||||
var/obj/item/charging = null
|
var/obj/item/charging = null
|
||||||
var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/modular_computer, /obj/item/weapon/computer_hardware/battery_module, /obj/item/weapon/cell, /obj/item/device/flashlight, /obj/item/device/electronic_assembly, /obj/item/weapon/weldingtool/electric, /obj/item/ammo_magazine/smart, /obj/item/device/flash, /obj/item/ammo_casing/nsfw_batt) //VOREStation Add - NSFW Batteries
|
var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/modular_computer, /obj/item/weapon/computer_hardware/battery_module, /obj/item/weapon/cell, /obj/item/device/flashlight, /obj/item/device/electronic_assembly, /obj/item/weapon/weldingtool/electric, /obj/item/ammo_magazine/smart, /obj/item/device/flash, /obj/item/ammo_casing/nsfw_batt) //VOREStation Add - NSFW Batteries
|
||||||
var/icon_state_charged = "recharger2"
|
var/icon_state_charged = "recharger2"
|
||||||
@@ -68,6 +69,8 @@ obj/machinery/recharger
|
|||||||
return
|
return
|
||||||
else if(default_deconstruction_crowbar(user, G))
|
else if(default_deconstruction_crowbar(user, G))
|
||||||
return
|
return
|
||||||
|
else if(default_part_replacement(user, G))
|
||||||
|
return
|
||||||
|
|
||||||
/obj/machinery/recharger/attack_hand(mob/user as mob)
|
/obj/machinery/recharger/attack_hand(mob/user as mob)
|
||||||
if(istype(user,/mob/living/silicon))
|
if(istype(user,/mob/living/silicon))
|
||||||
@@ -95,7 +98,7 @@ obj/machinery/recharger
|
|||||||
var/obj/item/modular_computer/C = charging
|
var/obj/item/modular_computer/C = charging
|
||||||
if(!C.battery_module.battery.fully_charged())
|
if(!C.battery_module.battery.fully_charged())
|
||||||
icon_state = icon_state_charging
|
icon_state = icon_state_charging
|
||||||
C.battery_module.battery.give(active_power_usage*CELLRATE)
|
C.battery_module.battery.give(CELLRATE*efficiency)
|
||||||
update_use_power(2)
|
update_use_power(2)
|
||||||
else
|
else
|
||||||
icon_state = icon_state_charged
|
icon_state = icon_state_charged
|
||||||
@@ -105,7 +108,7 @@ obj/machinery/recharger
|
|||||||
var/obj/item/weapon/computer_hardware/battery_module/BM = charging
|
var/obj/item/weapon/computer_hardware/battery_module/BM = charging
|
||||||
if(!BM.battery.fully_charged())
|
if(!BM.battery.fully_charged())
|
||||||
icon_state = icon_state_charging
|
icon_state = icon_state_charging
|
||||||
BM.battery.give(active_power_usage*CELLRATE)
|
BM.battery.give(CELLRATE*efficiency)
|
||||||
update_use_power(2)
|
update_use_power(2)
|
||||||
else
|
else
|
||||||
icon_state = icon_state_charged
|
icon_state = icon_state_charged
|
||||||
@@ -116,7 +119,7 @@ obj/machinery/recharger
|
|||||||
if(istype(C))
|
if(istype(C))
|
||||||
if(!C.fully_charged())
|
if(!C.fully_charged())
|
||||||
icon_state = icon_state_charging
|
icon_state = icon_state_charging
|
||||||
C.give(active_power_usage*CELLRATE)
|
C.give(CELLRATE*efficiency)
|
||||||
update_use_power(2)
|
update_use_power(2)
|
||||||
else
|
else
|
||||||
icon_state = icon_state_charged
|
icon_state = icon_state_charged
|
||||||
@@ -153,13 +156,20 @@ obj/machinery/recharger
|
|||||||
else
|
else
|
||||||
icon_state = icon_state_idle
|
icon_state = icon_state_idle
|
||||||
|
|
||||||
|
/obj/machinery/recharger/RefreshParts()
|
||||||
|
var/E = 0
|
||||||
|
for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts)
|
||||||
|
E += C.rating
|
||||||
|
efficiency = active_power_usage * (1+ (E - 1)*0.5)
|
||||||
|
|
||||||
/obj/machinery/recharger/wallcharger
|
/obj/machinery/recharger/wallcharger
|
||||||
name = "wall recharger"
|
name = "wall recharger"
|
||||||
icon = 'icons/obj/stationobjs.dmi'
|
icon = 'icons/obj/stationobjs.dmi'
|
||||||
icon_state = "wrecharger0"
|
icon_state = "wrecharger0"
|
||||||
plane = TURF_PLANE
|
plane = TURF_PLANE
|
||||||
layer = ABOVE_TURF_LAYER
|
layer = ABOVE_TURF_LAYER
|
||||||
active_power_usage = 25000 //25 kW , It's more specialized than the standalone recharger (guns, batons, and flashlights only) so make it more powerful
|
active_power_usage = 60000 //60 kW , It's more specialized than the standalone recharger (guns, batons, and flashlights only) so make it more powerful
|
||||||
|
efficiency = 60000
|
||||||
allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/gun/magnetic, /obj/item/weapon/melee/baton, /obj/item/device/flashlight, /obj/item/weapon/cell/device)
|
allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/gun/magnetic, /obj/item/weapon/melee/baton, /obj/item/device/flashlight, /obj/item/weapon/cell/device)
|
||||||
icon_state_charged = "wrecharger2"
|
icon_state_charged = "wrecharger2"
|
||||||
icon_state_charging = "wrecharger1"
|
icon_state_charging = "wrecharger1"
|
||||||
|
|||||||
@@ -515,6 +515,7 @@
|
|||||||
if(M)
|
if(M)
|
||||||
S.icon_state = initial(S.icon_state)
|
S.icon_state = initial(S.icon_state)
|
||||||
S.icon = initial(S.icon)
|
S.icon = initial(S.icon)
|
||||||
|
if(M.can_inject())
|
||||||
S.reagents.trans_to_mob(M, S.reagents.total_volume, CHEM_BLOOD)
|
S.reagents.trans_to_mob(M, S.reagents.total_volume, CHEM_BLOOD)
|
||||||
M.take_organ_damage(2)
|
M.take_organ_damage(2)
|
||||||
S.visible_message("<span class=\"attack\"> [M] was hit by the syringe!</span>")
|
S.visible_message("<span class=\"attack\"> [M] was hit by the syringe!</span>")
|
||||||
@@ -661,6 +662,7 @@
|
|||||||
occupant_message("<span class=\"alert\">No reagent info gained from [A].</span>")
|
occupant_message("<span class=\"alert\">No reagent info gained from [A].</span>")
|
||||||
return 0
|
return 0
|
||||||
occupant_message("Analyzing reagents...")
|
occupant_message("Analyzing reagents...")
|
||||||
|
//VOREStation Block Edit - Start
|
||||||
for(var/datum/reagent/R in A.reagents.reagent_list)
|
for(var/datum/reagent/R in A.reagents.reagent_list)
|
||||||
if(R.id in known_reagents)
|
if(R.id in known_reagents)
|
||||||
occupant_message("Reagent \"[R.name]\" already present in database, skipping.")
|
occupant_message("Reagent \"[R.name]\" already present in database, skipping.")
|
||||||
@@ -669,7 +671,8 @@
|
|||||||
send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form())
|
send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form())
|
||||||
else
|
else
|
||||||
occupant_message("Reagent \"[R.name]\" unable to be scanned, skipping.")
|
occupant_message("Reagent \"[R.name]\" unable to be scanned, skipping.")
|
||||||
occupant_message("Analyzis complete.")
|
//VOREstation Block Edit - End
|
||||||
|
occupant_message("Analysis complete.")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/add_known_reagent(r_id,r_name)
|
/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/add_known_reagent(r_id,r_name)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
w_class = ITEMSIZE_SMALL
|
w_class = ITEMSIZE_SMALL
|
||||||
matter = list("glass" = 200)
|
matter = list("glass" = 200)
|
||||||
flags = NOBLUDGEON
|
flags = NOBLUDGEON
|
||||||
var/list/accept_mobs = list(/mob/living/simple_mob/animal/passive/lizard, /mob/living/simple_mob/animal/passive/mouse)
|
var/list/accept_mobs = list(/mob/living/simple_mob/animal/passive/lizard, /mob/living/simple_mob/animal/passive/mouse, /mob/living/simple_mob/animal/sif/leech, /mob/living/simple_mob/animal/sif/frostfly, /mob/living/simple_mob/animal/sif/glitterfly)
|
||||||
var/contains = 0 // 0 = nothing, 1 = money, 2 = animal, 3 = spiderling
|
var/contains = 0 // 0 = nothing, 1 = money, 2 = animal, 3 = spiderling
|
||||||
|
|
||||||
/obj/item/glass_jar/New()
|
/obj/item/glass_jar/New()
|
||||||
@@ -96,6 +96,12 @@
|
|||||||
for(var/mob/M in src)
|
for(var/mob/M in src)
|
||||||
var/image/victim = image(M.icon, M.icon_state)
|
var/image/victim = image(M.icon, M.icon_state)
|
||||||
victim.pixel_y = 6
|
victim.pixel_y = 6
|
||||||
|
victim.color = M.color
|
||||||
|
if(M.plane == PLANE_LIGHTING_ABOVE) // This will only show up on the ground sprite, due to the HuD being over it, so we need both images.
|
||||||
|
var/image/victim_glow = image(M.icon, M.icon_state)
|
||||||
|
victim_glow.pixel_y = 6
|
||||||
|
victim_glow.color = M.color
|
||||||
|
underlays += victim_glow
|
||||||
underlays += victim
|
underlays += victim
|
||||||
name = "glass jar with [M]"
|
name = "glass jar with [M]"
|
||||||
desc = "A small jar with [M] inside."
|
desc = "A small jar with [M] inside."
|
||||||
|
|||||||
@@ -14,6 +14,10 @@
|
|||||||
..()
|
..()
|
||||||
network = using_map.station_networks
|
network = using_map.station_networks
|
||||||
|
|
||||||
|
/obj/item/weapon/circuitboard/security/tv
|
||||||
|
name = T_BOARD("security camera monitor - television")
|
||||||
|
build_path = /obj/machinery/computer/security/wooden_tv
|
||||||
|
|
||||||
/obj/item/weapon/circuitboard/security/engineering
|
/obj/item/weapon/circuitboard/security/engineering
|
||||||
name = T_BOARD("engineering camera monitor")
|
name = T_BOARD("engineering camera monitor")
|
||||||
build_path = /obj/machinery/computer/security/engineering
|
build_path = /obj/machinery/computer/security/engineering
|
||||||
|
|||||||
@@ -21,6 +21,10 @@
|
|||||||
name = T_BOARD("medical records console")
|
name = T_BOARD("medical records console")
|
||||||
build_path = /obj/machinery/computer/med_data
|
build_path = /obj/machinery/computer/med_data
|
||||||
|
|
||||||
|
/obj/item/weapon/circuitboard/med_data/laptop
|
||||||
|
name = T_BOARD("medical records laptop")
|
||||||
|
build_path = /obj/machinery/computer/med_data/laptop
|
||||||
|
|
||||||
/obj/item/weapon/circuitboard/scan_consolenew
|
/obj/item/weapon/circuitboard/scan_consolenew
|
||||||
name = T_BOARD("DNA machine")
|
name = T_BOARD("DNA machine")
|
||||||
build_path = /obj/machinery/computer/scan_consolenew
|
build_path = /obj/machinery/computer/scan_consolenew
|
||||||
|
|||||||
@@ -177,7 +177,8 @@
|
|||||||
/obj/item/weapon/gun/projectile/sec,
|
/obj/item/weapon/gun/projectile/sec,
|
||||||
/obj/item/weapon/gun/projectile/p92x,
|
/obj/item/weapon/gun/projectile/p92x,
|
||||||
/obj/item/taperoll,
|
/obj/item/taperoll,
|
||||||
/obj/item/weapon/gun/projectile/colt/detective
|
/obj/item/weapon/gun/projectile/colt/detective,
|
||||||
|
/obj/item/device/holowarrant
|
||||||
)
|
)
|
||||||
|
|
||||||
/obj/item/weapon/storage/belt/detective
|
/obj/item/weapon/storage/belt/detective
|
||||||
@@ -219,7 +220,8 @@
|
|||||||
/obj/item/weapon/flame/lighter,
|
/obj/item/weapon/flame/lighter,
|
||||||
/obj/item/weapon/reagent_containers/food/snacks/donut/,
|
/obj/item/weapon/reagent_containers/food/snacks/donut/,
|
||||||
/obj/item/ammo_magazine,
|
/obj/item/ammo_magazine,
|
||||||
/obj/item/weapon/gun/projectile/colt/detective
|
/obj/item/weapon/gun/projectile/colt/detective,
|
||||||
|
/obj/item/device/holowarrant
|
||||||
)
|
)
|
||||||
|
|
||||||
/obj/item/weapon/storage/belt/soulstone
|
/obj/item/weapon/storage/belt/soulstone
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
// Step 1, find out what we can see.
|
// Step 1, find out what we can see.
|
||||||
/datum/ai_holder/proc/list_targets()
|
/datum/ai_holder/proc/list_targets()
|
||||||
. = hearers(vision_range, holder) - src // Remove ourselves to prevent suicidal decisions.
|
. = hearers(vision_range, holder) - holder // Remove ourselves to prevent suicidal decisions. ~ SRC is the ai_holder.
|
||||||
|
|
||||||
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha))
|
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha))
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
gas_transfer_coefficient = 0.01
|
gas_transfer_coefficient = 0.01
|
||||||
permeability_coefficient = 0.02
|
permeability_coefficient = 0.02
|
||||||
item_flags = 0
|
item_flags = 0
|
||||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS
|
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
|
||||||
allowed = list(/obj/item/weapon/tank/emergency/oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_magazine, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs)
|
allowed = list(/obj/item/weapon/tank/emergency/oxygen, /obj/item/device/flashlight,/obj/item/weapon/gun/energy, /obj/item/weapon/gun/projectile, /obj/item/ammo_magazine, /obj/item/ammo_casing, /obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs)
|
||||||
slowdown = 1.5
|
slowdown = 1.5
|
||||||
armor = list(melee = 65, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50)
|
armor = list(melee = 65, bullet = 50, laser = 50, energy = 25, bomb = 50, bio = 100, rad = 50)
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
switch(suit_style)
|
switch(suit_style)
|
||||||
if("Engineer")
|
if("Engineer")
|
||||||
name = "\improper Engineer's Guild Shroud"
|
name = "\improper Engineer's Guild Shroud"
|
||||||
|
base_name = "\improper Engineer's Guild Shroud"
|
||||||
desc = "This rugged Shroud was created by the Xozi Engineering Guild."
|
desc = "This rugged Shroud was created by the Xozi Engineering Guild."
|
||||||
icon_state = "zaddat_engie"
|
icon_state = "zaddat_engie"
|
||||||
item_state = "zaddat_engie"
|
item_state = "zaddat_engie"
|
||||||
@@ -52,6 +53,7 @@
|
|||||||
helmet.item_state = "zaddat_engie"
|
helmet.item_state = "zaddat_engie"
|
||||||
if("Spacer")
|
if("Spacer")
|
||||||
name = "\improper Spacer's Guild Shroud"
|
name = "\improper Spacer's Guild Shroud"
|
||||||
|
base_name = "\improper Spacer's Guild Shroud"
|
||||||
desc = "The blue plastic Shroud worn by members of the Zaddat Spacer's Guild."
|
desc = "The blue plastic Shroud worn by members of the Zaddat Spacer's Guild."
|
||||||
icon_state = "zaddat_spacer"
|
icon_state = "zaddat_spacer"
|
||||||
item_state = "zaddat_spacer"
|
item_state = "zaddat_spacer"
|
||||||
@@ -62,6 +64,7 @@
|
|||||||
helmet.item_state = "zaddat_spacer"
|
helmet.item_state = "zaddat_spacer"
|
||||||
if("Knight")
|
if("Knight")
|
||||||
name = "\improper Knight's Shroud"
|
name = "\improper Knight's Shroud"
|
||||||
|
base_name = "\improper Knight's Shroud"
|
||||||
desc = "This distinctive steel-plated Shroud was popularized by the Noble Guild."
|
desc = "This distinctive steel-plated Shroud was popularized by the Noble Guild."
|
||||||
icon_state = "zaddat_knight"
|
icon_state = "zaddat_knight"
|
||||||
item_state = "zaddat_knight"
|
item_state = "zaddat_knight"
|
||||||
@@ -72,6 +75,7 @@
|
|||||||
helmet.item_state = "zaddat_knight"
|
helmet.item_state = "zaddat_knight"
|
||||||
if("Fashion")
|
if("Fashion")
|
||||||
name = "\improper Avazi House Shroud"
|
name = "\improper Avazi House Shroud"
|
||||||
|
base_name = "\improper Avazi House Shroud"
|
||||||
desc = "The designers of the Avazi Fashion House are among the most renowned in Zaddat society, and their Shroud designs second to none."
|
desc = "The designers of the Avazi Fashion House are among the most renowned in Zaddat society, and their Shroud designs second to none."
|
||||||
icon_state = "zaddat_fashion"
|
icon_state = "zaddat_fashion"
|
||||||
item_state = "zaddat_fashion"
|
item_state = "zaddat_fashion"
|
||||||
@@ -82,6 +86,7 @@
|
|||||||
helmet.item_state = "zaddat_fashion"
|
helmet.item_state = "zaddat_fashion"
|
||||||
if("Bishop")
|
if("Bishop")
|
||||||
name = "\improper Bishop-patterned Shroud"
|
name = "\improper Bishop-patterned Shroud"
|
||||||
|
base_name = "\improper Bishop-patterned Shroud"
|
||||||
desc = "The bold designers of the Dzaz Fashion House chose to make this Bishop-themed Shroud design as a commentary on the symbiotic nature of Vanax and human culture. Allegedly."
|
desc = "The bold designers of the Dzaz Fashion House chose to make this Bishop-themed Shroud design as a commentary on the symbiotic nature of Vanax and human culture. Allegedly."
|
||||||
icon_state = "zaddat_bishop"
|
icon_state = "zaddat_bishop"
|
||||||
item_state = "zaddat_bishop"
|
item_state = "zaddat_bishop"
|
||||||
@@ -92,6 +97,7 @@
|
|||||||
helmet.item_state = "zaddat_bishop"
|
helmet.item_state = "zaddat_bishop"
|
||||||
if("Rugged")
|
if("Rugged")
|
||||||
name = "rugged Shroud"
|
name = "rugged Shroud"
|
||||||
|
base_name = "rugged Shroud"
|
||||||
desc = "This Shroud was patterned after from First Contact era human voidsuits."
|
desc = "This Shroud was patterned after from First Contact era human voidsuits."
|
||||||
icon_state = "zaddat_rugged"
|
icon_state = "zaddat_rugged"
|
||||||
item_state = "zaddat_rugged"
|
item_state = "zaddat_rugged"
|
||||||
|
|||||||
@@ -269,6 +269,20 @@ the artifact triggers the rage.
|
|||||||
return FALSE
|
return FALSE
|
||||||
return TRUE
|
return TRUE
|
||||||
|
|
||||||
|
/datum/modifier/poisoned/paralysis
|
||||||
|
desc = "You have poison inside of you. It will cause harm over a long span of time if not cured, and may cause temporary paralysis."
|
||||||
|
on_created_text = "<span class='warning'>You feel incredibly weak...</span>"
|
||||||
|
damage_per_tick = 0.75
|
||||||
|
|
||||||
|
/datum/modifier/poisoned/paralysis/tick()
|
||||||
|
..()
|
||||||
|
if(prob(5))
|
||||||
|
holder.Paralyse(3)
|
||||||
|
|
||||||
|
/datum/modifier/poisoned/paralysis/on_applied()
|
||||||
|
..()
|
||||||
|
holder.Paralyse(4)
|
||||||
|
|
||||||
// Pulse modifier.
|
// Pulse modifier.
|
||||||
/datum/modifier/false_pulse
|
/datum/modifier/false_pulse
|
||||||
name = "false pulse"
|
name = "false pulse"
|
||||||
|
|||||||
@@ -104,6 +104,10 @@ var/list/holder_mob_icon_cache = list()
|
|||||||
/obj/item/weapon/holder/borer
|
/obj/item/weapon/holder/borer
|
||||||
origin_tech = list(TECH_BIO = 6)
|
origin_tech = list(TECH_BIO = 6)
|
||||||
|
|
||||||
|
/obj/item/weapon/holder/leech
|
||||||
|
color = "#003366"
|
||||||
|
origin_tech = list(TECH_BIO = 5, TECH_PHORON = 2)
|
||||||
|
|
||||||
/obj/item/weapon/holder/fish
|
/obj/item/weapon/holder/fish
|
||||||
attack_verb = list("fished", "disrespected", "smacked", "smackereled")
|
attack_verb = list("fished", "disrespected", "smacked", "smackereled")
|
||||||
hitsound = 'sound/effects/slime_squish.ogg'
|
hitsound = 'sound/effects/slime_squish.ogg'
|
||||||
|
|||||||
@@ -137,7 +137,7 @@
|
|||||||
/mob/living/bot/secbot/attackby(var/obj/item/O, var/mob/user)
|
/mob/living/bot/secbot/attackby(var/obj/item/O, var/mob/user)
|
||||||
var/curhealth = health
|
var/curhealth = health
|
||||||
. = ..()
|
. = ..()
|
||||||
if(health < curhealth)
|
if(health < curhealth && on == 1)
|
||||||
react_to_attack(user)
|
react_to_attack(user)
|
||||||
|
|
||||||
/mob/living/bot/secbot/bullet_act(var/obj/item/projectile/P)
|
/mob/living/bot/secbot/bullet_act(var/obj/item/projectile/P)
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
if(!temp || !temp.is_usable())
|
if(!temp || !temp.is_usable())
|
||||||
H << "<font color='red'>You can't use your hand.</font>"
|
H << "<font color='red'>You can't use your hand.</font>"
|
||||||
return
|
return
|
||||||
|
if(H.lying)
|
||||||
|
return
|
||||||
M.break_cloak()
|
M.break_cloak()
|
||||||
|
|
||||||
..()
|
..()
|
||||||
@@ -113,7 +115,7 @@
|
|||||||
spawn(30)
|
spawn(30)
|
||||||
cpr_time = 1
|
cpr_time = 1
|
||||||
|
|
||||||
H.visible_message("<span class='danger'>\The [H] is trying perform CPR on \the [src]!</span>")
|
H.visible_message("<span class='danger'>\The [H] is trying to perform CPR on \the [src]!</span>")
|
||||||
|
|
||||||
if(!do_after(H, 30))
|
if(!do_after(H, 30))
|
||||||
return
|
return
|
||||||
@@ -143,6 +145,7 @@
|
|||||||
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src)
|
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src)
|
||||||
if(buckled)
|
if(buckled)
|
||||||
M << "<span class='notice'>You cannot grab [src], [TT.he] is buckled in!</span>"
|
M << "<span class='notice'>You cannot grab [src], [TT.he] is buckled in!</span>"
|
||||||
|
return
|
||||||
if(!G) //the grab will delete itself in New if affecting is anchored
|
if(!G) //the grab will delete itself in New if affecting is anchored
|
||||||
return
|
return
|
||||||
M.put_in_active_hand(G)
|
M.put_in_active_hand(G)
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
var/movement_sound = null // If set, will play this sound when it moves on its own will.
|
var/movement_sound = null // If set, will play this sound when it moves on its own will.
|
||||||
var/turn_sound = null // If set, plays the sound when the mob's dir changes in most cases.
|
var/turn_sound = null // If set, plays the sound when the mob's dir changes in most cases.
|
||||||
var/movement_shake_radius = 0 // If set, moving will shake the camera of all living mobs within this radius slightly.
|
var/movement_shake_radius = 0 // If set, moving will shake the camera of all living mobs within this radius slightly.
|
||||||
|
var/aquatic_movement = 0 // If set, the mob will move through fluids with no hinderance.
|
||||||
|
|
||||||
//Mob interaction
|
//Mob interaction
|
||||||
var/response_help = "tries to help" // If clicked on help intent
|
var/response_help = "tries to help" // If clicked on help intent
|
||||||
@@ -230,7 +231,10 @@
|
|||||||
|
|
||||||
// Turf related slowdown
|
// Turf related slowdown
|
||||||
var/turf/T = get_turf(src)
|
var/turf/T = get_turf(src)
|
||||||
if(T && T.movement_cost && !hovering) // Flying mobs ignore turf-based slowdown.
|
if(T && T.movement_cost && !hovering) // Flying mobs ignore turf-based slowdown. Aquatic mobs ignore water slowdown, and can gain bonus speed in it.
|
||||||
|
if(istype(T,/turf/simulated/floor/water) && aquatic_movement)
|
||||||
|
tally -= aquatic_movement - 1
|
||||||
|
else
|
||||||
tally += T.movement_cost
|
tally += T.movement_cost
|
||||||
|
|
||||||
if(purge)//Purged creatures will move more slowly. The more time before their purge stops, the slower they'll move.
|
if(purge)//Purged creatures will move more slowly. The more time before their purge stops, the slower they'll move.
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
// Crystal-feather "ducks" are rather weak, but will become aggressive if you have food.
|
||||||
|
|
||||||
|
/datum/category_item/catalogue/fauna/crystalduck
|
||||||
|
name = "Sivian Fauna - Crystal-Feather Duck"
|
||||||
|
desc = "Classification: S Anatidae vitriae \
|
||||||
|
<br><br>\
|
||||||
|
Small, asocial omnivores with glistening, razor-thin feathers valued for their use as a reflective glitter by poachers. \
|
||||||
|
The Crystal-Feather Duck commonly forms at most a familial group of four, a male, two females, and a single 'chosen' young. Primarily detrivorous browsers, \
|
||||||
|
supplementing their diet with animals living below thinner shore ice-sheets. \
|
||||||
|
Family units have been observed to form gangs and scavenge from Sivian domeciles and \
|
||||||
|
various food transports during stressful months. \
|
||||||
|
It is advised to seal and hide any form of food near even lone individuals, as they will become \
|
||||||
|
increasingly aggressive."
|
||||||
|
value = CATALOGUER_REWARD_EASY
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/duck
|
||||||
|
name = "crystal-feather duck"
|
||||||
|
desc = "A glittering flightless bird."
|
||||||
|
tt_desc = "S Anatidae vitriae"
|
||||||
|
catalogue_data = list(/datum/category_item/catalogue/fauna/crystalduck)
|
||||||
|
|
||||||
|
faction = "duck"
|
||||||
|
|
||||||
|
icon_state = "duck"
|
||||||
|
icon_living = "duck"
|
||||||
|
icon_dead = "duck_dead"
|
||||||
|
icon = 'icons/mob/animal.dmi'
|
||||||
|
has_eye_glow = TRUE
|
||||||
|
|
||||||
|
maxHealth = 50
|
||||||
|
health = 50
|
||||||
|
|
||||||
|
movement_cooldown = 0
|
||||||
|
|
||||||
|
melee_damage_lower = 2
|
||||||
|
melee_damage_upper = 10
|
||||||
|
base_attack_cooldown = 1 SECOND
|
||||||
|
attack_edge = 1 // Razor-edged wings, and 'claws' made for digging through ice.
|
||||||
|
attacktext = list("nipped", "bit", "cut", "clawed")
|
||||||
|
|
||||||
|
say_list_type = /datum/say_list/duck
|
||||||
|
ai_holder_type = /datum/ai_holder/simple_mob/retaliate/cooperative
|
||||||
|
|
||||||
|
/datum/say_list/duck
|
||||||
|
speak = list("Wack!", "Wock?", "Wack.")
|
||||||
|
emote_see = list("ruffles its wings","looks around", "preens itself")
|
||||||
|
emote_hear = list("quacks", "giggles")
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/duck/IIsAlly(mob/living/L)
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
var/has_food = FALSE
|
||||||
|
for(var/obj/item/I in L.get_contents()) // Do they have food?
|
||||||
|
if(istype(I, /obj/item/weapon/reagent_containers/food))
|
||||||
|
has_food = TRUE
|
||||||
|
break
|
||||||
|
if(has_food) // Yes? Gimme the food.
|
||||||
|
return FALSE
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
// Frostflies are large, flightless insects with glittering wings, used as a means of deploying their gaseous self-defense mechanism.
|
||||||
|
/datum/category_item/catalogue/fauna/frostfly
|
||||||
|
name = "Sivian Fauna - Frostfly"
|
||||||
|
desc = "Classification: S Carabidae glacios \
|
||||||
|
<br><br>\
|
||||||
|
A large, flightless insectoid with bioluminescent wings. \
|
||||||
|
Frostflies utilize their vestigial wings as a method of dispersing a chemical that produces a rapid \
|
||||||
|
endothermic reaction on contact with the air, resulting in the flash-freezing of nearby materials. \
|
||||||
|
<br>\
|
||||||
|
Carnivorous in nature, they use their cryogenic compounds to trap smaller prey, or frighten predators. \
|
||||||
|
Individuals are known to slalom when facing other creatures, dispersing clouds of gas, and spitting \
|
||||||
|
condensed globs of the compound. These masses of mucous and ice seem to be intended to impede movement. \
|
||||||
|
<br>\
|
||||||
|
Travelers are advised to avoid frostfly swarms whenever possible, as they will become aggressive \
|
||||||
|
to anything other than Diyaabs, which they seem to have formed a tangential symbiosis with."
|
||||||
|
value = CATALOGUER_REWARD_MEDIUM
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/frostfly
|
||||||
|
name = "frostfly"
|
||||||
|
desc = "A large insect with glittering wings."
|
||||||
|
tt_desc = "S Carabidae glacios"
|
||||||
|
catalogue_data = list(/datum/category_item/catalogue/fauna/frostfly)
|
||||||
|
|
||||||
|
faction = "diyaab"
|
||||||
|
|
||||||
|
icon_state = "firefly"
|
||||||
|
icon_living = "firefly"
|
||||||
|
icon_dead = "firefly_dead"
|
||||||
|
icon_rest = "firefly_dead"
|
||||||
|
icon = 'icons/mob/animal.dmi'
|
||||||
|
has_eye_glow = TRUE
|
||||||
|
|
||||||
|
maxHealth = 65
|
||||||
|
health = 65
|
||||||
|
|
||||||
|
pass_flags = PASSTABLE
|
||||||
|
|
||||||
|
var/energy = 100
|
||||||
|
var/max_energy = 100
|
||||||
|
|
||||||
|
movement_cooldown = 0.5
|
||||||
|
|
||||||
|
melee_damage_lower = 5
|
||||||
|
melee_damage_upper = 10
|
||||||
|
base_attack_cooldown = 1.5 SECONDS
|
||||||
|
attacktext = list("nipped", "bit", "pinched")
|
||||||
|
|
||||||
|
projectiletype = /obj/item/projectile/energy/blob/freezing
|
||||||
|
|
||||||
|
special_attack_cooldown = 5 SECONDS
|
||||||
|
special_attack_min_range = 0
|
||||||
|
special_attack_max_range = 4
|
||||||
|
|
||||||
|
armor = list(
|
||||||
|
"melee" = 20,
|
||||||
|
"bullet" = 10,
|
||||||
|
"laser" = 5,
|
||||||
|
"energy" = 0,
|
||||||
|
"bomb" = 10,
|
||||||
|
"bio" = 100,
|
||||||
|
"rad" = 100
|
||||||
|
)
|
||||||
|
|
||||||
|
// The frostfly's body is incredibly cold at all times, natural resistance to things trying to burn it.
|
||||||
|
armor_soak = list(
|
||||||
|
"melee" = 0,
|
||||||
|
"bullet" = 0,
|
||||||
|
"laser" = 15,
|
||||||
|
"energy" = 0,
|
||||||
|
"bomb" = 0,
|
||||||
|
"bio" = 0,
|
||||||
|
"rad" = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
var/datum/effect/effect/system/smoke_spread/frost/smoke_special
|
||||||
|
|
||||||
|
say_list_type = /datum/say_list/frostfly
|
||||||
|
ai_holder_type = /datum/ai_holder/simple_mob/ranged/kiting/threatening/frostfly
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/frostfly/get_cold_protection()
|
||||||
|
return 1 // It literally produces a cryogenic mist inside itself. Cold doesn't bother it.
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/frostfly/Initialize()
|
||||||
|
..()
|
||||||
|
smoke_special = new
|
||||||
|
verbs += /mob/living/proc/ventcrawl
|
||||||
|
verbs += /mob/living/proc/hide
|
||||||
|
|
||||||
|
/datum/say_list/frostfly
|
||||||
|
speak = list("Zzzz.", "Kss.", "Zzt?")
|
||||||
|
emote_see = list("flutters its wings","looks around", "rubs its mandibles")
|
||||||
|
emote_hear = list("chitters", "clicks", "chirps")
|
||||||
|
|
||||||
|
say_understood = list("Ssst.")
|
||||||
|
say_cannot = list("Zzrt.")
|
||||||
|
say_maybe_target = list("Ki?")
|
||||||
|
say_got_target = list("Ksst!")
|
||||||
|
say_threaten = list("Kszsz.","Kszzt...","Kzzi!")
|
||||||
|
say_stand_down = list("Sss.","Zt.","! clicks.")
|
||||||
|
say_escalate = list("Rszt!")
|
||||||
|
|
||||||
|
threaten_sound = 'sound/effects/refill.ogg'
|
||||||
|
stand_down_sound = 'sound/effects/sparks5.ogg'
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/frostfly/handle_special()
|
||||||
|
..()
|
||||||
|
|
||||||
|
if(energy < max_energy)
|
||||||
|
energy++
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/frostfly/Stat()
|
||||||
|
..()
|
||||||
|
if(client.statpanel == "Status")
|
||||||
|
statpanel("Status")
|
||||||
|
if(emergency_shuttle)
|
||||||
|
var/eta_status = emergency_shuttle.get_status_panel_eta()
|
||||||
|
if(eta_status)
|
||||||
|
stat(null, eta_status)
|
||||||
|
stat("Energy", energy)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/frostfly/should_special_attack(atom/A)
|
||||||
|
if(energy >= 20)
|
||||||
|
return TRUE
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/frostfly/do_special_attack(atom/A)
|
||||||
|
. = TRUE
|
||||||
|
switch(a_intent)
|
||||||
|
if(I_DISARM)
|
||||||
|
if(energy < 20)
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
energy -= 20
|
||||||
|
|
||||||
|
if(smoke_special)
|
||||||
|
smoke_special.set_up(7,0,src)
|
||||||
|
smoke_special.start()
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/ranged/kiting/threatening/frostfly
|
||||||
|
can_flee = TRUE
|
||||||
|
dying_threshold = 0.5
|
||||||
|
flee_when_outmatched = TRUE
|
||||||
|
run_if_this_close = 3
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/ranged/kiting/threatening/frostfly/special_flee_check()
|
||||||
|
var/mob/living/simple_mob/animal/sif/frostfly/F = holder
|
||||||
|
if(F.energy < F.max_energy * 0.2)
|
||||||
|
return TRUE
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/ranged/kiting/threatening/frostfly/pre_special_attack(atom/A)
|
||||||
|
if(isliving(A))
|
||||||
|
holder.a_intent = I_DISARM
|
||||||
|
else
|
||||||
|
holder.a_intent = I_HURT
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/ranged/kiting/threatening/frostfly/post_ranged_attack(atom/A)
|
||||||
|
var/mob/living/simple_mob/animal/sif/frostfly/F = holder
|
||||||
|
if(istype(A,/mob/living))
|
||||||
|
var/new_dir = turn(F.dir, -90)
|
||||||
|
if(prob(50))
|
||||||
|
new_dir = turn(F.dir, 90)
|
||||||
|
holder.IMove(get_step(holder, new_dir))
|
||||||
|
holder.face_atom(A)
|
||||||
|
|
||||||
|
F.energy = max(0, F.energy - 1) // The AI will eventually flee.
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
// Glitterflies! Little butterfly-like creatures that float around and be cute.
|
||||||
|
|
||||||
|
/datum/category_item/catalogue/fauna/glitterfly
|
||||||
|
name = "Sivian Fauna - Glitterfly"
|
||||||
|
desc = "Classification: S Lepidoptera adamas \
|
||||||
|
<br><br>\
|
||||||
|
An herbivorous insectoid beloved for its glittering wings. \
|
||||||
|
<br>\
|
||||||
|
The creature has four wings mirrored laterally, which reflect \
|
||||||
|
the ambient light to provide a measure of camouflage."
|
||||||
|
value = CATALOGUER_REWARD_TRIVIAL
|
||||||
|
|
||||||
|
/datum/category_item/catalogue/fauna/glitterfly_rare
|
||||||
|
name = "Sivian Fauna - Adela's Glitterfly"
|
||||||
|
desc = "Classification: S Lepidoptera adamas \
|
||||||
|
<br><br>\
|
||||||
|
This mutation of the glitterfly is incredibly rare, one of the few and first known individuals\
|
||||||
|
known to exist with it is owned by little-known Sivian ecologist Adela Svingelm, and kept within its own \
|
||||||
|
climate-controlled habitat."
|
||||||
|
value = CATALOGUER_REWARD_HARD
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/glitterfly
|
||||||
|
name = "glitterfly"
|
||||||
|
desc = "A shiny butterfly!"
|
||||||
|
tt_desc = "S Lepidoptera adamas"
|
||||||
|
catalogue_data = list(/datum/category_item/catalogue/fauna/glitterfly)
|
||||||
|
|
||||||
|
faction = "neutral"
|
||||||
|
|
||||||
|
icon_state = "butterfly"
|
||||||
|
icon_living = "butterfly"
|
||||||
|
icon_dead = "butterfly_dead"
|
||||||
|
icon = 'icons/mob/animal.dmi'
|
||||||
|
|
||||||
|
maxHealth = 10
|
||||||
|
health = 10
|
||||||
|
|
||||||
|
movement_cooldown = -1
|
||||||
|
hovering = TRUE
|
||||||
|
|
||||||
|
melee_damage_lower = 1
|
||||||
|
melee_damage_upper = 2
|
||||||
|
attack_armor_pen = 80
|
||||||
|
attack_sharp = TRUE
|
||||||
|
|
||||||
|
density = FALSE // Non-dense, so things can walk through their groups unhindered.
|
||||||
|
|
||||||
|
pass_flags = PASSTABLE
|
||||||
|
|
||||||
|
attacktext = list("bit", "buffeted", "slashed")
|
||||||
|
|
||||||
|
say_list_type = /datum/say_list/glitterfly
|
||||||
|
ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive/glitterfly
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/glitterfly/Initialize()
|
||||||
|
..()
|
||||||
|
var/colorlist = list(rgb(rand(100,255), rand(100,255), rand(100,255)) = 10, rgb(rand(5,100), rand(5,100), rand(5,100)) = 2, "#222222" = 1)
|
||||||
|
color = pickweight(colorlist)
|
||||||
|
|
||||||
|
default_pixel_y = rand(5,12)
|
||||||
|
pixel_y = default_pixel_y
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/glitterfly/rare
|
||||||
|
name = "sparkling glitterfly"
|
||||||
|
desc = "An incredibly shiny butterfly!"
|
||||||
|
catalogue_data = list(/datum/category_item/catalogue/fauna/glitterfly, /datum/category_item/catalogue/fauna/glitterfly_rare)
|
||||||
|
maxHealth = 30
|
||||||
|
health = 30
|
||||||
|
|
||||||
|
movement_cooldown = -2
|
||||||
|
|
||||||
|
melee_damage_upper = 5
|
||||||
|
|
||||||
|
plane = PLANE_LIGHTING_ABOVE
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/glitterfly/rare/Initialize()
|
||||||
|
..()
|
||||||
|
|
||||||
|
/datum/say_list/glitterfly
|
||||||
|
speak = list("Pi..","Po...", "Pa...")
|
||||||
|
emote_see = list("vibrates","flutters", "twirls")
|
||||||
|
emote_hear = list("pips", "clicks", "chirps")
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/melee/evasive/glitterfly
|
||||||
|
hostile = FALSE
|
||||||
|
can_flee = TRUE
|
||||||
|
flee_when_outmatched = TRUE
|
||||||
|
outmatched_threshold = 100
|
||||||
|
max_home_distance = 5
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/melee/evasive/glitterfly/handle_special_strategical()
|
||||||
|
if(prob(1))
|
||||||
|
var/friendly_animal_corpse = FALSE
|
||||||
|
for(var/mob/living/simple_mob/animal/A in view(vision_range,holder))
|
||||||
|
if(holder.IIsAlly(A) && A.stat == DEAD)
|
||||||
|
friendly_animal_corpse = TRUE
|
||||||
|
break
|
||||||
|
|
||||||
|
if(friendly_animal_corpse)
|
||||||
|
hostile = TRUE
|
||||||
|
return
|
||||||
|
hostile = initial(hostile)
|
||||||
@@ -0,0 +1,404 @@
|
|||||||
|
// Kururaks, large pack-hunting felinids that reside in coastal regions. Less slowdown in water, speed on rocky turf.
|
||||||
|
|
||||||
|
/datum/category_item/catalogue/fauna/kururak
|
||||||
|
name = "Sivian Fauna - Kururak"
|
||||||
|
desc = "Classification: S Felidae fluctursora \
|
||||||
|
<br><br>\
|
||||||
|
An uncommon sight to many Sivian residents, these creatures are hypercarnivores, with\
|
||||||
|
their diets almost exclusively consisting of other fauna. This is achieved in the frozen \
|
||||||
|
environments of Sif via the means of fishing, even going to the lengths of evolving a \
|
||||||
|
third, dense lung only inflated for long dives. \
|
||||||
|
<br>\
|
||||||
|
One of the most distinguishing features of these animals are their four tails, capped in \
|
||||||
|
reflective 'mirrors'. These mirrors are used for tricking fish and other prey into ambushes,\
|
||||||
|
or distract would-be rivals. \
|
||||||
|
<br>\
|
||||||
|
Kururak packs are incredibly dangerous if faced alone, and should only be approached if prepared \
|
||||||
|
for a fight."
|
||||||
|
value = CATALOGUER_REWARD_HARD
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/kururak
|
||||||
|
name = "kururak"
|
||||||
|
desc = "A large animal with sleek fur."
|
||||||
|
tt_desc = "S Felidae fluctursora"
|
||||||
|
catalogue_data = list(/datum/category_item/catalogue/fauna/kururak)
|
||||||
|
|
||||||
|
faction = "kururak"
|
||||||
|
|
||||||
|
icon_state = "bigcat"
|
||||||
|
icon_living = "bigcat"
|
||||||
|
icon_dead = "bigcat_dead"
|
||||||
|
icon_rest = "bigcat_rest"
|
||||||
|
icon = 'icons/mob/64x64.dmi'
|
||||||
|
|
||||||
|
default_pixel_x = -16
|
||||||
|
pixel_x = -16
|
||||||
|
|
||||||
|
maxHealth = 200
|
||||||
|
health = 200
|
||||||
|
|
||||||
|
universal_understand = 1
|
||||||
|
|
||||||
|
movement_cooldown = 1
|
||||||
|
|
||||||
|
melee_damage_lower = 15
|
||||||
|
melee_damage_upper = 25
|
||||||
|
attack_armor_pen = 40
|
||||||
|
base_attack_cooldown = 2 SECONDS
|
||||||
|
attacktext = list("gouged", "bit", "cut", "clawed", "whipped")
|
||||||
|
|
||||||
|
armor = list(
|
||||||
|
"melee" = 30,
|
||||||
|
"bullet" = 15,
|
||||||
|
"laser" = 5,
|
||||||
|
"energy" = 0,
|
||||||
|
"bomb" = 10,
|
||||||
|
"bio" = 100,
|
||||||
|
"rad" = 100
|
||||||
|
)
|
||||||
|
|
||||||
|
armor_soak = list(
|
||||||
|
"melee" = 5,
|
||||||
|
"bullet" = 5,
|
||||||
|
"laser" = 5,
|
||||||
|
"energy" = 0,
|
||||||
|
"bomb" = 0,
|
||||||
|
"bio" = 0,
|
||||||
|
"rad" = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
say_list_type = /datum/say_list/kururak
|
||||||
|
ai_holder_type = /datum/ai_holder/simple_mob/intentional/kururak
|
||||||
|
|
||||||
|
special_attack_min_range = 0
|
||||||
|
special_attack_max_range = 4
|
||||||
|
special_attack_cooldown = 30 SECONDS
|
||||||
|
|
||||||
|
// Players have 2 seperate cooldowns for these, while the AI must choose one. Both respect special_attack_cooldown
|
||||||
|
var/last_strike_time = 0
|
||||||
|
var/last_flash_time = 0
|
||||||
|
|
||||||
|
var/instinct // The points used by Kururaks to decide Who Is The Boss
|
||||||
|
var/obey_pack_rule = TRUE // Decides if the Kururak will automatically assign itself to follow the one with the highest instinct.
|
||||||
|
|
||||||
|
/datum/say_list/kururak
|
||||||
|
speak = list("Kurr?","|R|rrh..", "Ksss...")
|
||||||
|
emote_see = list("scratches its ear","flutters its tails", "flicks an ear", "shakes out its hair")
|
||||||
|
emote_hear = list("chirps", "clicks", "grumbles", "chitters")
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/kururak/leader // Going to be the starting leader. Has some base buffs to make it more likely to stay the leader.
|
||||||
|
maxHealth = 250
|
||||||
|
health = 250
|
||||||
|
instinct = 50
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/kururak/Initialize()
|
||||||
|
..()
|
||||||
|
if(!instinct)
|
||||||
|
if(prob(20))
|
||||||
|
instinct = rand(6, 10)
|
||||||
|
return
|
||||||
|
instinct = rand(0, 5)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/kururak/IIsAlly(mob/living/L)
|
||||||
|
. = ..()
|
||||||
|
if(!.)
|
||||||
|
if(issilicon(L)) // Metal things are usually reflective, or in general aggrivating.
|
||||||
|
return FALSE
|
||||||
|
if(ishuman(L)) // Might be metal, but they're humanoid shaped.
|
||||||
|
var/mob/living/carbon/human/H = L
|
||||||
|
if(H.get_active_hand())
|
||||||
|
var/obj/item/I = H.get_active_hand()
|
||||||
|
if(I.force >= 1.20 * melee_damage_upper)
|
||||||
|
return TRUE
|
||||||
|
else if(istype(L, /mob/living/simple_mob))
|
||||||
|
var/mob/living/simple_mob/S = L
|
||||||
|
if(S.melee_damage_upper > 1.20 * melee_damage_upper)
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/kururak/handle_special()
|
||||||
|
..()
|
||||||
|
if(client)
|
||||||
|
pack_gauge()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/kururak/apply_melee_effects(atom/A) // Only gains instinct.
|
||||||
|
instinct += rand(1, 2)
|
||||||
|
return
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/kururak/should_special_attack(atom/A)
|
||||||
|
return has_modifier_of_type(/datum/modifier/ace)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/kururak/do_special_attack(atom/A)
|
||||||
|
. = TRUE
|
||||||
|
switch(a_intent)
|
||||||
|
if(I_DISARM) // Ranged mob flash, will also confuse borgs rather than stun.
|
||||||
|
tail_flash(A)
|
||||||
|
if(I_GRAB) // Armor-ignoring hit, causes agonizing wounds.
|
||||||
|
set_AI_busy(TRUE)
|
||||||
|
rending_strike(A)
|
||||||
|
set_AI_busy(FALSE)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/kururak/verb/do_flash()
|
||||||
|
set category = "Abilities"
|
||||||
|
set name = "Tail Blind"
|
||||||
|
set desc = "Disorient a creature within range."
|
||||||
|
|
||||||
|
if(world.time < last_flash_time + special_attack_cooldown)
|
||||||
|
to_chat(src, span("warning", "You do not have the focus to do this so soon.."))
|
||||||
|
return
|
||||||
|
|
||||||
|
last_flash_time = world.time
|
||||||
|
tail_flash()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/kururak/proc/tail_flash(atom/A)
|
||||||
|
set waitfor = FALSE
|
||||||
|
|
||||||
|
if(stat)
|
||||||
|
to_chat(src, span("warning","You cannot move your tails in this state.."))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!A && src.client)
|
||||||
|
var/list/choices = list()
|
||||||
|
for(var/mob/living/carbon/C in view(1,src))
|
||||||
|
if(src.Adjacent(C))
|
||||||
|
choices += C
|
||||||
|
|
||||||
|
for(var/obj/mecha/M in view(1,src))
|
||||||
|
if(src.Adjacent(M))
|
||||||
|
choices += M
|
||||||
|
|
||||||
|
if(!choices.len)
|
||||||
|
choices["radial"] = get_turf(src)
|
||||||
|
|
||||||
|
A = input(src,"What do we wish to flash?") in null|choices
|
||||||
|
|
||||||
|
|
||||||
|
visible_message(span("alien","\The [src] flares its tails!"))
|
||||||
|
if(isliving(A))
|
||||||
|
var/mob/living/L = A
|
||||||
|
if(iscarbon(L))
|
||||||
|
var/mob/living/carbon/C = L
|
||||||
|
if(C.stat != DEAD)
|
||||||
|
var/safety = C.eyecheck()
|
||||||
|
if(safety <= 0)
|
||||||
|
var/flash_strength = 5
|
||||||
|
if(ishuman(C))
|
||||||
|
var/mob/living/carbon/human/H = C
|
||||||
|
flash_strength *= H.species.flash_mod
|
||||||
|
if(flash_strength > 0)
|
||||||
|
to_chat(H, span("alien","You are disoriented by \the [src]!"))
|
||||||
|
H.Confuse(flash_strength + 5)
|
||||||
|
H.Blind(flash_strength)
|
||||||
|
H.eye_blurry = max(H.eye_blurry, flash_strength + 5)
|
||||||
|
H.flash_eyes()
|
||||||
|
H.adjustHalLoss(flash_strength / 5)
|
||||||
|
H.apply_damage(flash_strength * H.species.flash_burn/5, BURN, BP_HEAD, 0, 0, "Photon burns")
|
||||||
|
|
||||||
|
else if(issilicon(L))
|
||||||
|
if(isrobot(L))
|
||||||
|
var/flashfail = FALSE
|
||||||
|
var/mob/living/silicon/robot/R = L
|
||||||
|
if(R.has_active_type(/obj/item/borg/combat/shield))
|
||||||
|
var/obj/item/borg/combat/shield/shield = locate() in R
|
||||||
|
if(shield)
|
||||||
|
if(shield.active)
|
||||||
|
shield.adjust_flash_count(R, 1)
|
||||||
|
flashfail = TRUE
|
||||||
|
if(!flashfail)
|
||||||
|
to_chat(R, span("alien","Your optics are scrambled by \the [src]!"))
|
||||||
|
R.Confuse(10)
|
||||||
|
R.flash_eyes()
|
||||||
|
|
||||||
|
else
|
||||||
|
L.Confuse(10)
|
||||||
|
L.flash_eyes()
|
||||||
|
|
||||||
|
else
|
||||||
|
for(var/mob/living/carbon/C in oviewers(special_attack_max_range, null))
|
||||||
|
var/safety = C.eyecheck()
|
||||||
|
if(!safety)
|
||||||
|
if(!C.blinded)
|
||||||
|
C.flash_eyes()
|
||||||
|
for(var/mob/living/silicon/robot/R in oviewers(special_attack_max_range, null))
|
||||||
|
if(R.has_active_type(/obj/item/borg/combat/shield))
|
||||||
|
var/obj/item/borg/combat/shield/shield = locate() in R
|
||||||
|
if(shield)
|
||||||
|
if(shield.active)
|
||||||
|
continue
|
||||||
|
R.flash_eyes()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/kururak/verb/do_strike()
|
||||||
|
set category = "Abilities"
|
||||||
|
set name = "Rending Strike"
|
||||||
|
set desc = "Strike viciously at an entity within range."
|
||||||
|
|
||||||
|
if(world.time < last_strike_time + special_attack_cooldown)
|
||||||
|
to_chat(src, span("warning", "Your claws cannot take that much stress in so short a time.."))
|
||||||
|
return
|
||||||
|
|
||||||
|
last_strike_time = world.time
|
||||||
|
rending_strike()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/kururak/proc/rending_strike(atom/A)
|
||||||
|
if(stat)
|
||||||
|
to_chat(src, span("warning","You cannot strike in this state.."))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!A && src.client)
|
||||||
|
var/list/choices = list()
|
||||||
|
for(var/mob/living/carbon/C in view(1,src))
|
||||||
|
if(src.Adjacent(C))
|
||||||
|
choices += C
|
||||||
|
|
||||||
|
for(var/obj/mecha/M in view(1,src))
|
||||||
|
if(src.Adjacent(M))
|
||||||
|
choices += M
|
||||||
|
|
||||||
|
if(!choices.len)
|
||||||
|
to_chat(src, span("warning","There are no viable targets within range..."))
|
||||||
|
return
|
||||||
|
|
||||||
|
A = input(src,"What do we wish to strike?") in null|choices
|
||||||
|
|
||||||
|
if(!A || !src) return
|
||||||
|
|
||||||
|
if(!(src.Adjacent(A))) return
|
||||||
|
|
||||||
|
var/damage_to_apply = rand(melee_damage_lower, melee_damage_upper) + 10
|
||||||
|
if(isliving(A))
|
||||||
|
visible_message(span("danger","\The [src] rakes its claws across [A]."))
|
||||||
|
var/mob/living/L = A
|
||||||
|
if(ishuman(L))
|
||||||
|
var/mob/living/carbon/human/H = L
|
||||||
|
H.apply_damage(damage_to_apply, BRUTE, BP_TORSO, 0, 0, "Animal claws")
|
||||||
|
|
||||||
|
else
|
||||||
|
L.adjustBruteLoss(damage_to_apply)
|
||||||
|
|
||||||
|
L.add_modifier(/datum/modifier/grievous_wounds, 60 SECONDS)
|
||||||
|
|
||||||
|
else if(istype(A, /obj/mecha))
|
||||||
|
visible_message(span("danger","\The [src] rakes its claws against \the [A]."))
|
||||||
|
var/obj/mecha/M = A
|
||||||
|
M.take_damage(damage_to_apply)
|
||||||
|
if(prob(3) && do_after(src, 5))
|
||||||
|
visible_message(span("critical","\The [src]'s strike ripped \the [M]'s access hatch open, allowing it to drag [M.occupant] out!"))
|
||||||
|
M.go_out()
|
||||||
|
|
||||||
|
else
|
||||||
|
A.attack_generic(src, damage_to_apply, "rakes its claws against") // Well it's not a mob, and it's not a mech.
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/kururak/verb/rally_pack() // Mostly for telling other players to follow you. AI Kururaks will auto-follow, if set to.
|
||||||
|
set name = "Rally Pack"
|
||||||
|
set desc = "Tries to command your fellow pack members to follow you."
|
||||||
|
set category = "Abilities"
|
||||||
|
|
||||||
|
if(has_modifier_of_type(/datum/modifier/ace))
|
||||||
|
for(var/mob/living/simple_mob/animal/sif/kururak/K in hearers(7, src))
|
||||||
|
if(K == src)
|
||||||
|
continue
|
||||||
|
if(!K.ai_holder)
|
||||||
|
continue
|
||||||
|
if(K.faction != src.faction)
|
||||||
|
continue
|
||||||
|
var/datum/ai_holder/AI = K.ai_holder
|
||||||
|
to_chat(K, span("notice","The pack leader wishes for you to follow them."))
|
||||||
|
AI.set_follow(src)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/kururak/proc/detect_instinct() // Will return the Kururak within 10 tiles that has the highest instinct.
|
||||||
|
var/mob/living/simple_mob/animal/sif/kururak/A
|
||||||
|
|
||||||
|
var/pack_count = 0
|
||||||
|
|
||||||
|
for(var/mob/living/simple_mob/animal/sif/kururak/K in hearers(10, src))
|
||||||
|
if(K == src)
|
||||||
|
continue
|
||||||
|
if(K.stat != DEAD)
|
||||||
|
pack_count++
|
||||||
|
if(K.instinct > src.instinct)
|
||||||
|
A = K
|
||||||
|
|
||||||
|
if(!A && pack_count)
|
||||||
|
A = src
|
||||||
|
|
||||||
|
return A
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/kururak/proc/pack_gauge() // Check incase we have a client.
|
||||||
|
var/mob/living/simple_mob/animal/sif/kururak/highest_instinct = detect_instinct()
|
||||||
|
if(highest_instinct == src)
|
||||||
|
add_modifier(/datum/modifier/ace, 60 SECONDS)
|
||||||
|
else
|
||||||
|
remove_modifiers_of_type(/datum/modifier/ace)
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/kururak
|
||||||
|
hostile = FALSE
|
||||||
|
retaliate = TRUE
|
||||||
|
cooperative = TRUE
|
||||||
|
can_flee = TRUE
|
||||||
|
flee_when_dying = TRUE
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/kururak/handle_special_strategical()
|
||||||
|
follow_distance = rand(initial(follow_distance), initial(follow_distance) + 2)
|
||||||
|
var/mob/living/simple_mob/animal/sif/kururak/K = holder
|
||||||
|
|
||||||
|
if(istype(K))
|
||||||
|
var/mob/living/simple_mob/animal/sif/kururak/highest_instinct = K.detect_instinct()
|
||||||
|
if(highest_instinct == K)
|
||||||
|
K.add_modifier(/datum/modifier/ace, 60 SECONDS)
|
||||||
|
else
|
||||||
|
K.remove_modifiers_of_type(/datum/modifier/ace)
|
||||||
|
|
||||||
|
if(holder.has_modifier_of_type(/datum/modifier/ace))
|
||||||
|
if(leader && istype(leader, /mob/living/simple_mob/animal/sif/kururak)) // Kururaks will not follow another kururak if they're the pack leader.
|
||||||
|
lose_follow()
|
||||||
|
|
||||||
|
else if(highest_instinct)
|
||||||
|
set_follow(highest_instinct)
|
||||||
|
|
||||||
|
if(holder.has_modifier_of_type(/datum/modifier/ace))
|
||||||
|
hostile = TRUE
|
||||||
|
else
|
||||||
|
hostile = initial(hostile)
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/kururak/pre_special_attack(atom/A)
|
||||||
|
holder.a_intent = I_HURT
|
||||||
|
if(isliving(A))
|
||||||
|
var/mob/living/L = A
|
||||||
|
if(holder.Adjacent(L))
|
||||||
|
holder.a_intent = I_GRAB
|
||||||
|
|
||||||
|
if(iscarbon(L))
|
||||||
|
var/mob/living/carbon/C = L
|
||||||
|
if(!C.eyecheck())
|
||||||
|
if(holder.a_intent != I_GRAB)
|
||||||
|
holder.a_intent = I_DISARM
|
||||||
|
|
||||||
|
if(issilicon(L) && holder.a_intent != I_GRAB)
|
||||||
|
holder.a_intent = I_DISARM
|
||||||
|
|
||||||
|
else if(istype(A, /obj/mecha))
|
||||||
|
holder.a_intent = I_GRAB
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/kururak/post_melee_attack()
|
||||||
|
if(holder.has_modifier_of_type(/datum/modifier/ace))
|
||||||
|
request_help()
|
||||||
|
|
||||||
|
// Kururak Ace modifier, given to the one with the highest Instinct.
|
||||||
|
|
||||||
|
/datum/modifier/ace
|
||||||
|
name = "Ace"
|
||||||
|
desc = "You are universally superior, in terms of physical prowess."
|
||||||
|
on_created_text = "You feel superior."
|
||||||
|
on_expired_text = "You feel your superiority lessen..."
|
||||||
|
stacks = MODIFIER_STACK_EXTEND
|
||||||
|
|
||||||
|
mob_overlay_state = "ace"
|
||||||
|
|
||||||
|
max_health_flat = 25
|
||||||
|
max_health_percent = 1.2
|
||||||
|
disable_duration_percent = 0.8
|
||||||
|
incoming_damage_percent = 0.7
|
||||||
|
incoming_healing_percent = 1.5
|
||||||
|
outgoing_melee_damage_percent = 1.5
|
||||||
|
evasion = 20
|
||||||
|
bleeding_rate_percent = 0.7
|
||||||
|
attack_speed_percent = 0.8
|
||||||
503
code/modules/mob/living/simple_mob/subtypes/animal/sif/leech.dm
Normal file
503
code/modules/mob/living/simple_mob/subtypes/animal/sif/leech.dm
Normal file
@@ -0,0 +1,503 @@
|
|||||||
|
// Small creatures that will embed themselves in unsuspecting victim's bodies, drink their blood, and/or eat their organs. Steals some things from borers.
|
||||||
|
|
||||||
|
/datum/category_item/catalogue/fauna/iceleech
|
||||||
|
name = "Sivian Fauna - River Leech"
|
||||||
|
desc = "Classification: S Hirudinea phorus \
|
||||||
|
<br><br>\
|
||||||
|
An incredibly dangerous species of worm phorogenically mutated from a Sivian river leech, \
|
||||||
|
believed to have resulted from corporate mining in the Ullran Expanse; these accusations are \
|
||||||
|
unfounded, however speculation remains.\
|
||||||
|
<br>\
|
||||||
|
The creatures' heads hold four long prehensile tendrils surrounding a central beak, which are \
|
||||||
|
used as locomotive and grappling appendages. Each is capped in a hollow tooth, capable of pumping \
|
||||||
|
chemicals into an unsuspecting host. \
|
||||||
|
<br>\
|
||||||
|
The rear half of the creature is entirely musculature, capped with a sharp, arrowhead-shaped fin."
|
||||||
|
value = CATALOGUER_REWARD_MEDIUM
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech
|
||||||
|
name = "river leech"
|
||||||
|
desc = "What appears to be an oversized leech."
|
||||||
|
tt_desc = "S Hirudinea phorus"
|
||||||
|
catalogue_data = list(/datum/category_item/catalogue/fauna/iceleech)
|
||||||
|
|
||||||
|
faction = "leech"
|
||||||
|
|
||||||
|
icon_state = "leech"
|
||||||
|
item_state = "brainslug"
|
||||||
|
icon_living = "leech"
|
||||||
|
icon_dead = "leech_dead"
|
||||||
|
icon = 'icons/mob/animal.dmi'
|
||||||
|
|
||||||
|
density = FALSE // Non-dense, so things can pass over them.
|
||||||
|
|
||||||
|
status_flags = CANPUSH
|
||||||
|
pass_flags = PASSTABLE
|
||||||
|
|
||||||
|
maxHealth = 100
|
||||||
|
health = 100
|
||||||
|
|
||||||
|
universal_understand = 1
|
||||||
|
|
||||||
|
special_attack_min_range = 0
|
||||||
|
special_attack_max_range = 1
|
||||||
|
|
||||||
|
var/obj/item/organ/external/host_bodypart // Where in the body we are infesting.
|
||||||
|
var/docile = FALSE
|
||||||
|
var/chemicals = 0
|
||||||
|
var/max_chemicals = 400
|
||||||
|
var/list/bodypart_targets = list(BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_TORSO,BP_GROIN,BP_HEAD)
|
||||||
|
var/infest_target = BP_TORSO // The currently chosen bodypart to infest.
|
||||||
|
var/mob/living/carbon/host // Our humble host.
|
||||||
|
var/list/produceable_chemicals = list("inaprovaline","anti_toxin","alkysine","bicaridine","tramadol","kelotane","leporazine","iron","phoron","condensedcapsaicin_v","frostoil")
|
||||||
|
var/randomized_reagent = "iron" // The reagent chosen at random to be produced, if there's no one piloting the worm.
|
||||||
|
var/passive_reagent = "paracetamol" // Reagent passively produced by the leech. Should usually be a painkiller.
|
||||||
|
|
||||||
|
var/feeding_delay = 30 SECONDS // How long do we have to wait to bite our host's organs?
|
||||||
|
var/last_feeding = 0
|
||||||
|
|
||||||
|
intent = I_HELP
|
||||||
|
|
||||||
|
holder_type = /obj/item/weapon/holder/leech
|
||||||
|
|
||||||
|
movement_cooldown = 0
|
||||||
|
aquatic_movement = -2
|
||||||
|
|
||||||
|
melee_damage_lower = 1
|
||||||
|
melee_damage_upper = 5
|
||||||
|
attack_armor_pen = 15
|
||||||
|
attack_sharp = TRUE
|
||||||
|
attacktext = list("nipped", "bit", "pinched")
|
||||||
|
|
||||||
|
armor = list(
|
||||||
|
"melee" = 10,
|
||||||
|
"bullet" = 15,
|
||||||
|
"laser" = -10,
|
||||||
|
"energy" = 0,
|
||||||
|
"bomb" = 10,
|
||||||
|
"bio" = 100,
|
||||||
|
"rad" = 100
|
||||||
|
)
|
||||||
|
|
||||||
|
armor_soak = list(
|
||||||
|
"melee" = 5,
|
||||||
|
"bullet" = 5,
|
||||||
|
"laser" = 0,
|
||||||
|
"energy" = 0,
|
||||||
|
"bomb" = 0,
|
||||||
|
"bio" = 0,
|
||||||
|
"rad" = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
say_list_type = /datum/say_list/leech
|
||||||
|
ai_holder_type = /datum/ai_holder/simple_mob/intentional/leech
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech/IIsAlly(mob/living/L)
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
var/mob/living/carbon/human/H = L
|
||||||
|
if(!istype(H))
|
||||||
|
return .
|
||||||
|
|
||||||
|
if(istype(L.buckled, /obj/vehicle) || L.hovering) // Ignore people hovering or on boats.
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
if(!.)
|
||||||
|
var/has_organ = FALSE
|
||||||
|
var/obj/item/organ/internal/O = H.get_active_hand()
|
||||||
|
if(istype(O) && O.robotic < ORGAN_ROBOT && !(O.status & ORGAN_DEAD))
|
||||||
|
has_organ = TRUE
|
||||||
|
return has_organ
|
||||||
|
|
||||||
|
/datum/say_list/leech
|
||||||
|
speak = list("...", "Sss..", ". . .","Gss..")
|
||||||
|
emote_see = list("vibrates","looks around", "stares", "extends a proboscis")
|
||||||
|
emote_hear = list("chitters", "clicks", "gurgles")
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech/Initialize()
|
||||||
|
..()
|
||||||
|
|
||||||
|
verbs += /mob/living/proc/ventcrawl
|
||||||
|
verbs += /mob/living/proc/hide
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech/Stat()
|
||||||
|
..()
|
||||||
|
if(client.statpanel == "Status")
|
||||||
|
statpanel("Status")
|
||||||
|
if(emergency_shuttle)
|
||||||
|
var/eta_status = emergency_shuttle.get_status_panel_eta()
|
||||||
|
if(eta_status)
|
||||||
|
stat(null, eta_status)
|
||||||
|
stat("Chemicals", chemicals)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech/do_special_attack(atom/A)
|
||||||
|
. = TRUE
|
||||||
|
if(istype(A, /mob/living/carbon))
|
||||||
|
switch(a_intent)
|
||||||
|
if(I_DISARM) // Poison
|
||||||
|
set_AI_busy(TRUE)
|
||||||
|
poison_inject(src, A)
|
||||||
|
set_AI_busy(FALSE)
|
||||||
|
if(I_GRAB) // Infesting!
|
||||||
|
set_AI_busy(TRUE)
|
||||||
|
do_infest(src, A)
|
||||||
|
set_AI_busy(FALSE)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech/handle_special()
|
||||||
|
if(prob(5))
|
||||||
|
randomized_reagent = pick(produceable_chemicals)
|
||||||
|
|
||||||
|
var/turf/T = get_turf(src)
|
||||||
|
if(istype(T, /turf/simulated/floor/water) && src.loc == T && !stat) // Are we sitting in water, and alive?
|
||||||
|
alpha = max(5, alpha - 10)
|
||||||
|
if(chemicals + 1 < max_chemicals / 3)
|
||||||
|
chemicals++
|
||||||
|
else
|
||||||
|
alpha = min(255, alpha + 20)
|
||||||
|
|
||||||
|
if(!client && !host)
|
||||||
|
infest_target = pick(bodypart_targets)
|
||||||
|
|
||||||
|
if(host && !stat && !host.stat)
|
||||||
|
if(ai_holder)
|
||||||
|
ai_holder.hostile = FALSE
|
||||||
|
ai_holder.lose_target()
|
||||||
|
alpha = 5
|
||||||
|
if(host.reagents.has_reagent("cordradaxon") && !docile) // Overwhelms the leech with food.
|
||||||
|
var/message = "We feel the rush of cardiac pluripotent cells in your host's blood, lulling us into docility."
|
||||||
|
to_chat(src, span("warning", message))
|
||||||
|
docile = TRUE
|
||||||
|
if(chemicals + 5 <= max_chemicals)
|
||||||
|
chemicals += 5
|
||||||
|
|
||||||
|
else if(docile)
|
||||||
|
var/message = "We shake off our lethargy as the pluripotent cell count declines in our host's blood."
|
||||||
|
to_chat(src, span("notice", message))
|
||||||
|
docile = FALSE
|
||||||
|
|
||||||
|
if(!host.reagents.has_reagent(passive_reagent))
|
||||||
|
host.reagents.add_reagent(passive_reagent, 5)
|
||||||
|
chemicals -= 3
|
||||||
|
|
||||||
|
if(!docile && ishuman(host) && chemicals < max_chemicals)
|
||||||
|
var/mob/living/carbon/human/H = host
|
||||||
|
H.vessel.remove_reagent("blood", 1)
|
||||||
|
if(!H.reagents.has_reagent("inaprovaline"))
|
||||||
|
H.reagents.add_reagent("inaprovaline", 1)
|
||||||
|
chemicals += 2
|
||||||
|
|
||||||
|
if(!client && !docile) // Automatic 'AI' to manage damage levels.
|
||||||
|
if(host.getBruteLoss() >= 30 && chemicals > 50)
|
||||||
|
host.reagents.add_reagent("bicaridine", 5)
|
||||||
|
chemicals -= 30
|
||||||
|
|
||||||
|
if(host.getToxLoss() >= 30 && chemicals > 50)
|
||||||
|
var/randomchem = pickweight("tramadol" = 7, "anti_toxin" = 15, "frostoil" = 3)
|
||||||
|
host.reagents.add_reagent(randomchem, 5)
|
||||||
|
chemicals -= 50
|
||||||
|
|
||||||
|
if(host.getFireLoss() >= 30 && chemicals > 50)
|
||||||
|
host.reagents.add_reagent("kelotane", 5)
|
||||||
|
host.reagents.add_reagent("leporazine", 2)
|
||||||
|
chemicals -= 50
|
||||||
|
|
||||||
|
if(host.getOxyLoss() >= 30 && chemicals > 50)
|
||||||
|
host.reagents.add_reagent("iron", 10)
|
||||||
|
chemicals -= 40
|
||||||
|
|
||||||
|
if(host.getBrainLoss() >= 10 && chemicals > 100)
|
||||||
|
host.reagents.add_reagent("alkysine", 5)
|
||||||
|
host.reagents.add_reagent("tramadol", 3)
|
||||||
|
chemicals -= 100
|
||||||
|
|
||||||
|
if(prob(30) && chemicals > 50)
|
||||||
|
inject_meds(randomized_reagent)
|
||||||
|
|
||||||
|
var/heartless_mod = 0
|
||||||
|
if(ishuman(host)) // Species without hearts mean the worm gets hungry faster, if AI controlled.
|
||||||
|
var/mob/living/carbon/human/H = host
|
||||||
|
if(!H.species.has_organ[O_HEART])
|
||||||
|
heartless_mod = 1
|
||||||
|
|
||||||
|
if(prob(15 + (20 * heartless_mod)))
|
||||||
|
feed_on_organ()
|
||||||
|
else
|
||||||
|
if(ai_holder)
|
||||||
|
ai_holder.hostile = initial(ai_holder.hostile)
|
||||||
|
|
||||||
|
if(host && host.stat == DEAD && istype(get_turf(host), /turf/simulated/floor/water))
|
||||||
|
leave_host()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech/verb/infest()
|
||||||
|
set category = "Abilities"
|
||||||
|
set name = "Infest"
|
||||||
|
set desc = "Infest a suitable humanoid host."
|
||||||
|
|
||||||
|
if(docile)
|
||||||
|
to_chat(src, span("alium","We are too tired to do this..."))
|
||||||
|
return
|
||||||
|
|
||||||
|
do_infest(usr)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech/proc/do_infest(var/mob/living/user, var/mob/living/target = null)
|
||||||
|
if(host)
|
||||||
|
to_chat(user, span("alien", "We are already within a host."))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(stat)
|
||||||
|
to_chat(user, span("warning","We cannot infest a target in your current state."))
|
||||||
|
return
|
||||||
|
|
||||||
|
var/mob/living/carbon/M = target
|
||||||
|
|
||||||
|
if(!M && src.client)
|
||||||
|
var/list/choices = list()
|
||||||
|
for(var/mob/living/carbon/C in view(1,src))
|
||||||
|
if(src.Adjacent(C))
|
||||||
|
choices += C
|
||||||
|
|
||||||
|
if(!choices.len)
|
||||||
|
to_chat(user, span("warning","There are no viable hosts within range..."))
|
||||||
|
return
|
||||||
|
|
||||||
|
M = input(src,"Who do we wish to infest?") in null|choices
|
||||||
|
|
||||||
|
if(!M || !src) return
|
||||||
|
|
||||||
|
if(!(src.Adjacent(M))) return
|
||||||
|
|
||||||
|
if(!istype(M) || M.isSynthetic())
|
||||||
|
to_chat(user, "\The [M] cannot be infested.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(istype(M,/mob/living/carbon/human))
|
||||||
|
var/mob/living/carbon/human/H = M
|
||||||
|
|
||||||
|
var/obj/item/organ/external/E = H.organs_by_name[infest_target]
|
||||||
|
if(!E || E.is_stump() || E.robotic >= ORGAN_ROBOT)
|
||||||
|
to_chat(src,"\The [H] does not have an infestable [infest_target]!")
|
||||||
|
|
||||||
|
var/list/covering_clothing = E.get_covering_clothing()
|
||||||
|
for(var/obj/item/clothing/C in covering_clothing)
|
||||||
|
if(C.armor["melee"] >= 20 + attack_armor_pen)
|
||||||
|
to_chat(user, span("notice","We cannot get through that host's protective gear."))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!do_after(src,2))
|
||||||
|
to_chat(user, span("notice", "As [M] moves away, we are dislodged and fall to the ground."))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!M || !src)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(src.stat)
|
||||||
|
to_chat(user, span("warning","We cannot infest a target in your current state."))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(M in view(1, src))
|
||||||
|
to_chat(user,span("alien", "We burrow into [M]'s flesh."))
|
||||||
|
if(!M.stat)
|
||||||
|
to_chat(M, span("critical", "You feel a sharp pain as something digs into your flesh!"))
|
||||||
|
|
||||||
|
src.host = M
|
||||||
|
src.forceMove(M)
|
||||||
|
if(ai_holder)
|
||||||
|
ai_holder.hostile = FALSE
|
||||||
|
ai_holder.lose_target()
|
||||||
|
|
||||||
|
if(istype(M,/mob/living/carbon/human))
|
||||||
|
var/mob/living/carbon/human/H = M
|
||||||
|
host_bodypart = H.get_organ(infest_target)
|
||||||
|
host_bodypart.implants |= src
|
||||||
|
|
||||||
|
return
|
||||||
|
else
|
||||||
|
to_chat(user, span("notice","They are no longer in range."))
|
||||||
|
return
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech/verb/uninfest()
|
||||||
|
set category = "Abilities"
|
||||||
|
set name = "Uninfest"
|
||||||
|
set desc = "Leave your current host."
|
||||||
|
|
||||||
|
if(docile)
|
||||||
|
to_chat(src, span("alium","We are too tired to do this..."))
|
||||||
|
return
|
||||||
|
|
||||||
|
leave_host()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech/proc/leave_host()
|
||||||
|
if(!host)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(ai_holder)
|
||||||
|
ai_holder.hostile = initial(ai_holder.hostile)
|
||||||
|
ai_holder.lose_target()
|
||||||
|
|
||||||
|
host_bodypart.implants -= src
|
||||||
|
host_bodypart = null
|
||||||
|
|
||||||
|
forceMove(get_turf(host))
|
||||||
|
|
||||||
|
reset_view(null)
|
||||||
|
|
||||||
|
host = null
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech/verb/inject_victim()
|
||||||
|
set category = "Abilities"
|
||||||
|
set name = "Incapacitate Potential Host"
|
||||||
|
set desc = "Inject an organic host with an incredibly painful mixture of chemicals."
|
||||||
|
|
||||||
|
if(docile)
|
||||||
|
to_chat(src, span("alium","We are too tired to do this..."))
|
||||||
|
return
|
||||||
|
|
||||||
|
var/mob/living/carbon/M
|
||||||
|
if(src.client)
|
||||||
|
var/list/choices = list()
|
||||||
|
for(var/mob/living/carbon/C in view(1,src))
|
||||||
|
if(src.Adjacent(C))
|
||||||
|
choices += C
|
||||||
|
|
||||||
|
if(!choices.len)
|
||||||
|
to_chat(src, span("warning","There are no viable hosts within range..."))
|
||||||
|
return
|
||||||
|
|
||||||
|
M = input(src,"Who do we wish to inject?") in null|choices
|
||||||
|
|
||||||
|
if(!M || stat)
|
||||||
|
return
|
||||||
|
|
||||||
|
poison_inject(usr, M)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech/proc/poison_inject(var/mob/living/user, var/mob/living/carbon/L)
|
||||||
|
if(!L || !Adjacent(L) || stat)
|
||||||
|
return
|
||||||
|
|
||||||
|
var/mob/living/carbon/human/H = L
|
||||||
|
|
||||||
|
if(!istype(H) || H.isSynthetic())
|
||||||
|
to_chat(user, span("warning","You cannot inject this target..."))
|
||||||
|
|
||||||
|
var/obj/item/organ/external/E = H.organs_by_name[infest_target]
|
||||||
|
if(!E || E.is_stump() || E.robotic >= ORGAN_ROBOT)
|
||||||
|
to_chat(src,"\The [H] does not have an infestable [infest_target]!")
|
||||||
|
|
||||||
|
var/list/covering_clothing = E.get_covering_clothing()
|
||||||
|
for(var/obj/item/clothing/C in covering_clothing)
|
||||||
|
if(C.armor["melee"] >= 40 + attack_armor_pen)
|
||||||
|
to_chat(user, span("notice","You cannot get through that host's protective gear."))
|
||||||
|
return
|
||||||
|
|
||||||
|
H.add_modifier(/datum/modifier/poisoned/paralysis, 15 SECONDS)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech/verb/medicate_host()
|
||||||
|
set category = "Abilities"
|
||||||
|
set name = "Produce Chemicals (50)"
|
||||||
|
set desc = "Inject your host with possibly beneficial chemicals, to keep the blood flowing."
|
||||||
|
|
||||||
|
if(docile)
|
||||||
|
to_chat(src, span("alium","We are too tired to do this..."))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!host || chemicals <= 50)
|
||||||
|
to_chat(usr, span("alien","We cannot produce any chemicals right now."))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(host)
|
||||||
|
var/chem = input("Select a chemical to produce.", "Chemicals") as null|anything in produceable_chemicals
|
||||||
|
inject_meds(chem)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech/proc/inject_meds(var/chem)
|
||||||
|
if(host)
|
||||||
|
chemicals = max(1, chemicals - 50)
|
||||||
|
host.reagents.add_reagent(chem, 5)
|
||||||
|
to_chat(src, span("alien","We injected \the [host] with five units of [chem]."))
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech/verb/feed_on_organ()
|
||||||
|
set category = "Abilities"
|
||||||
|
set name = "Feed on Organ"
|
||||||
|
set desc = "Extend probosci to feed on a piece of your host's organs."
|
||||||
|
|
||||||
|
if(docile)
|
||||||
|
to_chat(src, span("alium","We are too tired to do this..."))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(host && world.time >= last_feeding + feeding_delay)
|
||||||
|
var/list/host_internal_organs = host.internal_organs
|
||||||
|
|
||||||
|
for(var/obj/item/organ/internal/O in host_internal_organs) // Remove organs with maximum damage.
|
||||||
|
if(O.damage >= O.max_damage)
|
||||||
|
host_internal_organs -= O
|
||||||
|
|
||||||
|
var/target
|
||||||
|
if(client)
|
||||||
|
target = input("Select an organ to feed on.", "Organs") as null|anything in host_internal_organs
|
||||||
|
if(!target)
|
||||||
|
to_chat(src, span("alien","We decide not to feed."))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!target)
|
||||||
|
target = pick(host_internal_organs)
|
||||||
|
|
||||||
|
if(target)
|
||||||
|
bite_organ(target)
|
||||||
|
|
||||||
|
else
|
||||||
|
to_chat(src, span("warning","We cannot feed now."))
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/leech/proc/bite_organ(var/obj/item/organ/internal/O)
|
||||||
|
last_feeding = world.time
|
||||||
|
|
||||||
|
if(O)
|
||||||
|
to_chat(src, span("alien","We feed on [O]."))
|
||||||
|
O.take_damage(2,silent=prob(10))
|
||||||
|
chemicals = min(max_chemicals, chemicals + 60)
|
||||||
|
host.add_modifier(/datum/modifier/grievous_wounds, 60 SECONDS)
|
||||||
|
adjustBruteLoss(rand(-10,-60))
|
||||||
|
adjustFireLoss(rand(-10,-60))
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/leech
|
||||||
|
hostile = TRUE
|
||||||
|
retaliate = TRUE
|
||||||
|
vision_range = 3
|
||||||
|
mauling = TRUE
|
||||||
|
returns_home = TRUE
|
||||||
|
can_flee = TRUE
|
||||||
|
home_low_priority = TRUE // If we've got a target, we're going for them.
|
||||||
|
max_home_distance = 1 // Low to ensure the creature doesn't leave the water unless it has a host.
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/leech/handle_special_strategical()
|
||||||
|
var/mob/living/simple_mob/animal/sif/leech/SL = holder
|
||||||
|
if(!SL.host && !istype(get_turf(SL), /turf/simulated/floor/water))
|
||||||
|
var/list/nearby_water = list()
|
||||||
|
for(var/turf/simulated/floor/water/W in view(holder, 10))
|
||||||
|
nearby_water |= W
|
||||||
|
if(nearby_water && nearby_water.len)
|
||||||
|
var/turf/T = pick(nearby_water)
|
||||||
|
if(T && can_attack(T))
|
||||||
|
home_turf = T
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/leech/special_flee_check()
|
||||||
|
var/mob/living/simple_mob/animal/sif/leech/SL = holder
|
||||||
|
|
||||||
|
if(!SL.host && !istype(get_turf(SL), /turf/simulated/floor/water))
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/leech/pre_special_attack(atom/A)
|
||||||
|
if(isliving(A))
|
||||||
|
var/mob/living/L = A
|
||||||
|
if(ishuman(L) && !L.isSynthetic())
|
||||||
|
if(L.incapacitated() || (L.stat && L.stat != DEAD) || L.resting || L.paralysis)
|
||||||
|
holder.a_intent = I_GRAB // Infesting time.
|
||||||
|
else
|
||||||
|
holder.a_intent = I_DISARM // They're standing up! Try to drop or stun them.
|
||||||
|
else
|
||||||
|
holder.a_intent = I_HURT // Otherwise, bite.
|
||||||
|
|
||||||
|
else if(istype(A, /obj/item))
|
||||||
|
var/obj/item/I = A
|
||||||
|
if(istype(I, /obj/item/weapon/reagent_containers/food/snacks))
|
||||||
|
holder.a_intent = I_HURT
|
||||||
|
else
|
||||||
|
holder.a_intent = I_HURT
|
||||||
355
code/modules/mob/living/simple_mob/subtypes/animal/sif/racoon.dm
Normal file
355
code/modules/mob/living/simple_mob/subtypes/animal/sif/racoon.dm
Normal file
@@ -0,0 +1,355 @@
|
|||||||
|
// Sakimm are small scavengers with an adoration for shiny things. They won't attack you for them, but you will be their friend holding something like a coin.
|
||||||
|
|
||||||
|
/datum/category_item/catalogue/fauna/sakimm
|
||||||
|
name = "Sivian Fauna - Sakimm"
|
||||||
|
desc = "Classification: S Procyon cogitae \
|
||||||
|
<br><br>\
|
||||||
|
Small, social omnivores known to collect objects within their dens. \
|
||||||
|
The Sakimm form colonies that have been known to grow up to a hundred individuals. Primarily carnivorous hunters, \
|
||||||
|
they often supplement their diets with nuts, roots, and other fruits. \
|
||||||
|
Individuals are known to steal food and reflective objects from unsuspecting Sivian residents. \
|
||||||
|
It is advised to keep any valuable items within dull wraps when venturing near the den of a Sakimm."
|
||||||
|
value = CATALOGUER_REWARD_EASY
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/sakimm
|
||||||
|
name = "sakimm"
|
||||||
|
desc = "What appears to be an oversized rodent with hands."
|
||||||
|
tt_desc = "S Procyon cogitae"
|
||||||
|
catalogue_data = list(/datum/category_item/catalogue/fauna/sakimm)
|
||||||
|
|
||||||
|
faction = "sakimm"
|
||||||
|
|
||||||
|
icon_state = "raccoon"
|
||||||
|
icon_living = "raccoon"
|
||||||
|
icon_dead = "raccoon_dead"
|
||||||
|
icon_rest = "raccoon_dead"
|
||||||
|
icon = 'icons/mob/animal.dmi'
|
||||||
|
|
||||||
|
maxHealth = 50
|
||||||
|
health = 50
|
||||||
|
has_hands = TRUE
|
||||||
|
humanoid_hands = TRUE
|
||||||
|
|
||||||
|
pass_flags = PASSTABLE
|
||||||
|
|
||||||
|
universal_understand = 1
|
||||||
|
|
||||||
|
movement_cooldown = 0
|
||||||
|
|
||||||
|
melee_damage_lower = 5
|
||||||
|
melee_damage_upper = 15
|
||||||
|
base_attack_cooldown = 1 SECOND
|
||||||
|
attacktext = list("nipped", "bit", "cut", "clawed")
|
||||||
|
|
||||||
|
armor = list(
|
||||||
|
"melee" = 15,
|
||||||
|
"bullet" = 5,
|
||||||
|
"laser" = 5,
|
||||||
|
"energy" = 0,
|
||||||
|
"bomb" = 10,
|
||||||
|
"bio" = 100,
|
||||||
|
"rad" = 100
|
||||||
|
)
|
||||||
|
|
||||||
|
armor_soak = list(
|
||||||
|
"melee" = 2,
|
||||||
|
"bullet" = 2,
|
||||||
|
"laser" = 0,
|
||||||
|
"energy" = 0,
|
||||||
|
"bomb" = 0,
|
||||||
|
"bio" = 0,
|
||||||
|
"rad" = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
say_list_type = /datum/say_list/sakimm
|
||||||
|
ai_holder_type = /datum/ai_holder/simple_mob/retaliate/cooperative/sakimm
|
||||||
|
|
||||||
|
var/obj/item/clothing/head/hat = null // The hat the Sakimm may be wearing.
|
||||||
|
var/list/friend_loot_list = list(/obj/item/weapon/coin) // What will make this animal non-hostile if held?
|
||||||
|
var/randomize_size = TRUE
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/sakimm/verb/remove_hat()
|
||||||
|
set name = "Remove Hat"
|
||||||
|
set desc = "Remove the animal's hat. You monster."
|
||||||
|
set category = "Abilities"
|
||||||
|
set src in view(1)
|
||||||
|
|
||||||
|
drop_hat(usr)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/sakimm/proc/drop_hat(var/mob/user)
|
||||||
|
if(hat)
|
||||||
|
hat.forceMove(get_turf(user))
|
||||||
|
hat = null
|
||||||
|
update_icon()
|
||||||
|
if(user == src)
|
||||||
|
to_chat(user, "<span class='notice'>You removed your hat.</span>")
|
||||||
|
return
|
||||||
|
to_chat(user, "<span class='warning'>You removed \the [src]'s hat. You monster.</span>")
|
||||||
|
else
|
||||||
|
if(user == src)
|
||||||
|
to_chat(user, "<span class='notice'>You are not wearing a hat!</span>")
|
||||||
|
return
|
||||||
|
to_chat(user, "<span class='notice'>\The [src] is not wearing a hat!</span>")
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/sakimm/verb/give_hat()
|
||||||
|
set name = "Give Hat"
|
||||||
|
set desc = "Give the animal a hat. You hero."
|
||||||
|
set category = "Abilities"
|
||||||
|
set src in view(1)
|
||||||
|
|
||||||
|
take_hat(usr)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/sakimm/proc/take_hat(var/mob/user)
|
||||||
|
if(hat)
|
||||||
|
if(user == src)
|
||||||
|
to_chat(user, "<span class='notice'>You already have a hat!</span>")
|
||||||
|
return
|
||||||
|
to_chat(user, "<span class='notice'>\The [src] already has a hat!</span>")
|
||||||
|
else
|
||||||
|
if(user == src)
|
||||||
|
if(istype(get_active_hand(), /obj/item/clothing/head))
|
||||||
|
hat = get_active_hand()
|
||||||
|
drop_from_inventory(hat, src)
|
||||||
|
hat.forceMove(src)
|
||||||
|
to_chat(user, "<span class='notice'>You put on the hat.</span>")
|
||||||
|
update_icon()
|
||||||
|
return
|
||||||
|
else if(ishuman(user))
|
||||||
|
var/mob/living/carbon/human/H = user
|
||||||
|
|
||||||
|
if(istype(H.get_active_hand(), /obj/item/clothing/head) && !get_active_hand())
|
||||||
|
var/obj/item/clothing/head/newhat = H.get_active_hand()
|
||||||
|
H.drop_from_inventory(newhat, get_turf(src))
|
||||||
|
if(!stat)
|
||||||
|
intent = I_HELP
|
||||||
|
newhat.attack_hand(src)
|
||||||
|
else if(src.get_active_hand())
|
||||||
|
to_chat(user, "<span class='notice'>\The [src] seems busy with \the [get_active_hand()] already!</span>")
|
||||||
|
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class='warning'>You aren't holding a hat...</span>")
|
||||||
|
|
||||||
|
/datum/say_list/sakimm
|
||||||
|
speak = list("Shurr.", "|R|rr?", "Hss.")
|
||||||
|
emote_see = list("sniffs","looks around", "rubs its hands")
|
||||||
|
emote_hear = list("chitters", "clicks")
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/sakimm/Destroy()
|
||||||
|
if(hat)
|
||||||
|
drop_hat(src)
|
||||||
|
..()
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/sakimm/update_icon()
|
||||||
|
overlays.Cut()
|
||||||
|
..()
|
||||||
|
if(hat)
|
||||||
|
var/hat_state = hat.item_state ? hat.item_state : hat.icon_state
|
||||||
|
var/image/I = image('icons/mob/head.dmi', src, hat_state)
|
||||||
|
I.pixel_y = -15 // Sakimm are tiny!
|
||||||
|
I.appearance_flags = RESET_COLOR
|
||||||
|
add_overlay(I)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/sakimm/Initialize()
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
verbs += /mob/living/proc/ventcrawl
|
||||||
|
verbs += /mob/living/proc/hide
|
||||||
|
|
||||||
|
if(randomize_size)
|
||||||
|
adjust_scale(rand(8, 11) / 10)
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/sakimm/IIsAlly(mob/living/L)
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
var/mob/living/carbon/human/H = L
|
||||||
|
if(!istype(H))
|
||||||
|
return .
|
||||||
|
|
||||||
|
if(!.)
|
||||||
|
var/has_loot = FALSE
|
||||||
|
var/obj/item/I = H.get_active_hand()
|
||||||
|
if(I)
|
||||||
|
for(var/item_type in friend_loot_list)
|
||||||
|
if(istype(I, item_type))
|
||||||
|
has_loot = TRUE
|
||||||
|
break
|
||||||
|
return has_loot
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/retaliate/cooperative/sakimm/handle_special_strategical() // Just needs to take hats.
|
||||||
|
var/mob/living/simple_mob/animal/sif/sakimm/S = holder
|
||||||
|
|
||||||
|
if(holder.get_active_hand() && istype(holder.get_active_hand(), /obj/item/clothing/head) && !S.hat)
|
||||||
|
var/obj/item/I = holder.get_active_hand()
|
||||||
|
S.take_hat(S)
|
||||||
|
holder.visible_message("<span class='notice'>\The [holder] wears \the [I]</span>")
|
||||||
|
|
||||||
|
/mob/living/simple_mob/animal/sif/sakimm/intelligent
|
||||||
|
desc = "What appears to be an oversized rodent with hands. This one has a curious look in its eyes."
|
||||||
|
ai_holder_type = /datum/ai_holder/simple_mob/intentional/sakimm
|
||||||
|
randomize_size = FALSE // Most likely to have a hat.
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/sakimm
|
||||||
|
hostile = FALSE
|
||||||
|
retaliate = TRUE
|
||||||
|
vision_range = 10
|
||||||
|
can_flee = TRUE
|
||||||
|
flee_when_dying = TRUE
|
||||||
|
|
||||||
|
var/greed = 0 // The probability we will try to steal something. Increases over time if we are not holding something, or wearing a hat.
|
||||||
|
var/list/steal_loot_list = list(/obj/item/weapon/coin, /obj/item/weapon/gun, /obj/item/weapon/fossil, /obj/item/stack/material, /obj/item/weapon/material, /obj/item/weapon/reagent_containers/food/snacks, /obj/item/clothing/head, /obj/item/weapon/reagent_containers/glass, /obj/item/device/flashlight, /obj/item/stack/medical, /obj/item/seeds, /obj/item/weapon/spacecash)
|
||||||
|
var/hoard_items = TRUE
|
||||||
|
var/hoard_distance = 1 // How far an item can be from the Sakimm's home turf to be counted inside its 'hoard'.
|
||||||
|
var/original_home_distance = null
|
||||||
|
var/search_delay = 2 SECONDS // How often can we look for item targets?
|
||||||
|
var/last_search = 0
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/sakimm/New()
|
||||||
|
..()
|
||||||
|
original_home_distance = max_home_distance
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/sakimm/post_melee_attack(atom/A)
|
||||||
|
if(istype(A, /obj/item) && !holder.get_active_hand() && holder.Adjacent(A))
|
||||||
|
var/obj/item/I = A
|
||||||
|
I.attack_hand(holder)
|
||||||
|
lose_target()
|
||||||
|
if(istype(A,/mob/living) && holder.Adjacent(A)) // Not the dumbest tool in the shed. If we're fighting, we're gonna dance around them.
|
||||||
|
holder.IMove(get_step(holder, pick(alldirs)))
|
||||||
|
holder.face_atom(A)
|
||||||
|
request_help() // And we're going to call friends, too.
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/sakimm/list_targets()
|
||||||
|
. = hearers(vision_range, holder) - holder
|
||||||
|
|
||||||
|
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha))
|
||||||
|
|
||||||
|
for(var/HM in typecache_filter_list(range(vision_range, holder), hostile_machines))
|
||||||
|
if(can_see(holder, HM, vision_range))
|
||||||
|
. += HM
|
||||||
|
|
||||||
|
if(holder.get_active_hand()) // We don't want item targets if we have an item!
|
||||||
|
return .
|
||||||
|
|
||||||
|
if(world.time <= last_search + search_delay) // Don't spam searching for item targets, since they can be in areas with a -lot- of items.
|
||||||
|
return .
|
||||||
|
|
||||||
|
for(var/obj/item/I in view(holder, vision_range))
|
||||||
|
last_search = world.time
|
||||||
|
if(!hoard_items || get_dist(I, home_turf) <= 1)
|
||||||
|
continue
|
||||||
|
for(var/itemtype in steal_loot_list)
|
||||||
|
if(istype(I, itemtype))
|
||||||
|
if(!I.anchored)
|
||||||
|
. += I
|
||||||
|
break
|
||||||
|
|
||||||
|
. -= holder.contents
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/sakimm/find_target(var/list/possible_targets, var/has_targets_list = FALSE)
|
||||||
|
var/can_pick_mobs = TRUE
|
||||||
|
|
||||||
|
if(!hostile)
|
||||||
|
can_pick_mobs = FALSE
|
||||||
|
|
||||||
|
. = list()
|
||||||
|
if(!has_targets_list)
|
||||||
|
possible_targets = list_targets()
|
||||||
|
|
||||||
|
for(var/possible_target in possible_targets)
|
||||||
|
var/atom/A = possible_target
|
||||||
|
if(found(A))
|
||||||
|
. = list(A)
|
||||||
|
break
|
||||||
|
if(istype(A, /mob/living) && !can_pick_mobs)
|
||||||
|
continue
|
||||||
|
if(can_attack(A)) // Can we attack it?
|
||||||
|
. += A
|
||||||
|
continue
|
||||||
|
|
||||||
|
for(var/obj/item/I in .)
|
||||||
|
last_search = world.time
|
||||||
|
if(!hoard_items || get_dist(I, home_turf) <= 1)
|
||||||
|
. -= I
|
||||||
|
|
||||||
|
var/new_target = pick_target(.)
|
||||||
|
give_target(new_target)
|
||||||
|
return new_target
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/sakimm/pre_melee_attack(atom/A)
|
||||||
|
if(isliving(A))
|
||||||
|
var/mob/living/L = A
|
||||||
|
if(holder.get_active_hand()) // Are we holding something? If so, drop it, we have a new target to kill, and we shouldn't use their weapons.
|
||||||
|
holder.drop_from_inventory(holder.get_active_hand(), get_turf(holder))
|
||||||
|
|
||||||
|
if(ishuman(L))
|
||||||
|
if(L.incapacitated(INCAPACITATION_DISABLED)) // Is our target on the ground? If so, let's scratch!
|
||||||
|
if(prob(30)) // Unless we decide to cut and run, and take their stuff while we're at it.
|
||||||
|
var/turf/T = get_turf(L)
|
||||||
|
var/obj/item/IT = locate() in T.contents
|
||||||
|
if(IT)
|
||||||
|
lose_target()
|
||||||
|
give_target(IT)
|
||||||
|
return
|
||||||
|
holder.a_intent = I_HURT
|
||||||
|
else
|
||||||
|
holder.a_intent = I_DISARM // Otherwise, try to disarm them!
|
||||||
|
else
|
||||||
|
holder.a_intent = I_HURT // We can't disarm you, so we're going to hurt you.
|
||||||
|
|
||||||
|
else if(istype(A, /obj/item))
|
||||||
|
var/obj/item/I = A
|
||||||
|
if(istype(I, /obj/item/weapon/reagent_containers/food/snacks)) // If we can't pick it up, or it's edible, go to harm.
|
||||||
|
holder.a_intent = I_HURT
|
||||||
|
else
|
||||||
|
holder.a_intent = I_HELP
|
||||||
|
|
||||||
|
else
|
||||||
|
holder.a_intent = I_HURT
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/sakimm/should_go_home()
|
||||||
|
if((!returns_home && !holder.get_active_hand()) || !home_turf) // If we have an item, we want to go home.
|
||||||
|
return FALSE
|
||||||
|
if(get_dist(holder, home_turf) > max_home_distance)
|
||||||
|
if(!home_low_priority)
|
||||||
|
return TRUE
|
||||||
|
else if(!leader && !target)
|
||||||
|
return TRUE
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/sakimm/handle_special_tactic()
|
||||||
|
var/mob/living/simple_mob/animal/sif/sakimm/S = holder
|
||||||
|
if(S.hat)
|
||||||
|
hoard_items = FALSE
|
||||||
|
else
|
||||||
|
hoard_items = TRUE
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/sakimm/handle_special_strategical()
|
||||||
|
var/mob/living/simple_mob/animal/sif/sakimm/S = holder
|
||||||
|
var/carrying_item = FALSE
|
||||||
|
|
||||||
|
if(holder.get_active_hand()) // Do we have loot?
|
||||||
|
if(istype(holder) && istype(holder.get_active_hand(), /obj/item/clothing/head) && !S.hat)
|
||||||
|
var/obj/item/I = holder.get_active_hand()
|
||||||
|
S.take_hat(S)
|
||||||
|
holder.visible_message("<span class='notice'>\The [holder] wears \the [I]</span>")
|
||||||
|
carrying_item = TRUE
|
||||||
|
|
||||||
|
if(istype(holder) && S.hat) // Do we have a hat? Hats are loot.
|
||||||
|
carrying_item = TRUE
|
||||||
|
|
||||||
|
if(!carrying_item) // Not carrying or wearing anything? We want to carry something more.
|
||||||
|
greed++
|
||||||
|
greed = min(95, greed)
|
||||||
|
else
|
||||||
|
greed = 0
|
||||||
|
if(!target && prob(5 + greed) && !holder.get_active_hand())
|
||||||
|
find_target()
|
||||||
|
if(holder.get_active_hand() && hoard_items)
|
||||||
|
lose_target()
|
||||||
|
max_home_distance = 1
|
||||||
|
if(get_dist(holder, home_turf) <= max_home_distance)
|
||||||
|
holder.drop_from_inventory(holder.get_active_hand(), get_turf(holder))
|
||||||
|
if(!holder.get_active_hand())
|
||||||
|
max_home_distance = original_home_distance
|
||||||
|
|
||||||
|
/datum/ai_holder/simple_mob/intentional/sakimm/special_flee_check()
|
||||||
|
return holder.get_active_hand()
|
||||||
@@ -16,7 +16,10 @@
|
|||||||
w_class = ITEMSIZE_NORMAL
|
w_class = ITEMSIZE_NORMAL
|
||||||
var/icon_state_closed = "laptop-closed"
|
var/icon_state_closed = "laptop-closed"
|
||||||
|
|
||||||
/obj/item/modular_computer/laptop/AltClick()
|
/obj/item/modular_computer/laptop/AltClick(mob/living/carbon/user)
|
||||||
|
// We need to be close to it to open it
|
||||||
|
if((!in_range(src, user)) || user.stat || user.restrained())
|
||||||
|
return
|
||||||
// Prevents carrying of open laptops inhand.
|
// Prevents carrying of open laptops inhand.
|
||||||
// While they work inhand, i feel it'd make tablets lose some of their high-mobility advantage they have over laptops now.
|
// While they work inhand, i feel it'd make tablets lose some of their high-mobility advantage they have over laptops now.
|
||||||
if(!istype(loc, /turf/))
|
if(!istype(loc, /turf/))
|
||||||
@@ -41,7 +44,9 @@
|
|||||||
..()
|
..()
|
||||||
else
|
else
|
||||||
overlays.Cut()
|
overlays.Cut()
|
||||||
|
set_light(0) // No glow from closed laptops
|
||||||
icon_state = icon_state_closed
|
icon_state = icon_state_closed
|
||||||
|
|
||||||
/obj/item/modular_computer/laptop/preset
|
/obj/item/modular_computer/laptop/preset
|
||||||
anchored = FALSE
|
anchored = FALSE
|
||||||
|
screen_on = FALSE
|
||||||
|
|||||||
@@ -952,6 +952,13 @@ Note that amputating the affected organ does in fact remove the infection from t
|
|||||||
|
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|
||||||
|
if(victim.l_hand)
|
||||||
|
if(istype(victim.l_hand,/obj/item/weapon/material/twohanded)) //if they're holding a two-handed weapon, drop it now they've lost a hand
|
||||||
|
victim.l_hand.update_held_icon()
|
||||||
|
if(victim.r_hand)
|
||||||
|
if(istype(victim.r_hand,/obj/item/weapon/material/twohanded))
|
||||||
|
victim.r_hand.update_held_icon()
|
||||||
|
|
||||||
/****************************************************
|
/****************************************************
|
||||||
HELPERS
|
HELPERS
|
||||||
****************************************************/
|
****************************************************/
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
..()
|
..()
|
||||||
|
|
||||||
/obj/item/projectile/energy/blob/on_impact(var/atom/A)
|
/obj/item/projectile/energy/blob/on_impact(var/atom/A)
|
||||||
|
if(splatter)
|
||||||
var/turf/location = get_turf(src)
|
var/turf/location = get_turf(src)
|
||||||
var/datum/effect/effect/system/smoke_spread/chem/S = new /datum/effect/effect/system/smoke_spread/chem
|
var/datum/effect/effect/system/smoke_spread/chem/S = new /datum/effect/effect/system/smoke_spread/chem
|
||||||
S.attach(location)
|
S.attach(location)
|
||||||
@@ -61,3 +62,11 @@
|
|||||||
splatter = TRUE
|
splatter = TRUE
|
||||||
flammability = 0.25
|
flammability = 0.25
|
||||||
my_chems = list("fuel", "mold")
|
my_chems = list("fuel", "mold")
|
||||||
|
|
||||||
|
/obj/item/projectile/energy/blob/freezing
|
||||||
|
my_chems = list("frostoil")
|
||||||
|
modifier_type_to_apply = /datum/modifier/chilled
|
||||||
|
modifier_duration = 1 MINUTE
|
||||||
|
|
||||||
|
/obj/item/projectile/energy/blob/freezing/splattering
|
||||||
|
splatter = TRUE
|
||||||
|
|||||||
38
html/changelogs/Mechoid - SifAnimalExpansion1.yml
Normal file
38
html/changelogs/Mechoid - SifAnimalExpansion1.yml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
################################
|
||||||
|
# Example Changelog File
|
||||||
|
#
|
||||||
|
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
|
||||||
|
#
|
||||||
|
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
|
||||||
|
# When it is, any changes listed below will disappear.
|
||||||
|
#
|
||||||
|
# Valid Prefixes:
|
||||||
|
# bugfix
|
||||||
|
# wip (For works in progress)
|
||||||
|
# tweak
|
||||||
|
# soundadd
|
||||||
|
# sounddel
|
||||||
|
# rscadd (general adding of nice things)
|
||||||
|
# rscdel (general deleting of nice things)
|
||||||
|
# imageadd
|
||||||
|
# imagedel
|
||||||
|
# maptweak
|
||||||
|
# spellcheck (typo fixes)
|
||||||
|
# experiment
|
||||||
|
#################################
|
||||||
|
|
||||||
|
# Your name.
|
||||||
|
author: Mechoid
|
||||||
|
|
||||||
|
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
|
||||||
|
delete-after: True
|
||||||
|
|
||||||
|
# Any changes you've made. See valid prefix list above.
|
||||||
|
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
|
||||||
|
# SCREW THIS UP AND IT WON'T WORK.
|
||||||
|
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
|
||||||
|
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
|
||||||
|
changes:
|
||||||
|
- rscadd: "The Shimm, Frostfly, Glitterfly, River Leech, Crystal-Feathered Duck, and Kururak are now able to be used on the map and PoIs."
|
||||||
|
- tweak: "Glass jars can now hold glitterflies, river leeches, and frostflies."
|
||||||
|
- tweak: "Glass jars now respect mobs that exist over the lighting plane, adding a special overlay visible when on the ground."
|
||||||
42
html/changelogs/mistyLuminescence - bugfix.yml
Normal file
42
html/changelogs/mistyLuminescence - bugfix.yml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
################################
|
||||||
|
# Example Changelog File
|
||||||
|
#
|
||||||
|
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
|
||||||
|
#
|
||||||
|
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
|
||||||
|
# When it is, any changes listed below will disappear.
|
||||||
|
#
|
||||||
|
# Valid Prefixes:
|
||||||
|
# bugfix
|
||||||
|
# wip (For works in progress)
|
||||||
|
# tweak
|
||||||
|
# soundadd
|
||||||
|
# sounddel
|
||||||
|
# rscadd (general adding of nice things)
|
||||||
|
# rscdel (general deleting of nice things)
|
||||||
|
# imageadd
|
||||||
|
# imagedel
|
||||||
|
# maptweak
|
||||||
|
# spellcheck (typo fixes)
|
||||||
|
# experiment
|
||||||
|
#################################
|
||||||
|
|
||||||
|
# Your name.
|
||||||
|
author: mistyLuminescence
|
||||||
|
|
||||||
|
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
|
||||||
|
delete-after: True
|
||||||
|
|
||||||
|
# Any changes you've made. See valid prefix list above.
|
||||||
|
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
|
||||||
|
# SCREW THIS UP AND IT WON'T WORK.
|
||||||
|
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
|
||||||
|
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
|
||||||
|
changes:
|
||||||
|
- bugfix: Prone people can no longer interact with an empty hand.
|
||||||
|
- bugfix: Two-handed items are now correctly unwielded when the user's offhand is severed.
|
||||||
|
- bugfix: Mecha syringe guns now respect pierceproof clothing.
|
||||||
|
- bugfix: Securitrons now correctly ignore attacks when disabled.
|
||||||
|
- bugfix: Rechargers now correctly benefit from upgraded capacitors.
|
||||||
|
- bugfix: Medical record laptops and detective TV camera consoles no longer turn into regular consoles when de- and re-constructed.
|
||||||
|
- bugfix: Zaddat Shrouds now retain their base name when damaged, if the shroud has been customized.
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 49 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 248 KiB After Width: | Height: | Size: 228 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
@@ -2393,7 +2393,13 @@
|
|||||||
#include "code\modules\mob\living\simple_mob\subtypes\animal\pets\parrot.dm"
|
#include "code\modules\mob\living\simple_mob\subtypes\animal\pets\parrot.dm"
|
||||||
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\diyaab.dm"
|
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\diyaab.dm"
|
||||||
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\fluffy_vr.dm"
|
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\fluffy_vr.dm"
|
||||||
|
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\duck.dm"
|
||||||
|
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\frostfly.dm"
|
||||||
|
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\glitterfly.dm"
|
||||||
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\hooligan_crab.dm"
|
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\hooligan_crab.dm"
|
||||||
|
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\kururak.dm"
|
||||||
|
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\leech.dm"
|
||||||
|
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\racoon.dm"
|
||||||
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\savik.dm"
|
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\savik.dm"
|
||||||
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\shantak.dm"
|
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\shantak.dm"
|
||||||
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\sif.dm"
|
#include "code\modules\mob\living\simple_mob\subtypes\animal\sif\sif.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user