Merge branch 'master' into upstream-merge-9601

This commit is contained in:
cadyn
2021-01-25 16:04:40 -08:00
committed by GitHub
68 changed files with 1591 additions and 255 deletions
+1
View File
@@ -19,6 +19,7 @@
#define DM_FLAG_STRIPPING 0x2
#define DM_FLAG_LEAVEREMAINS 0x4
#define DM_FLAG_THICKBELLY 0x8
#define DM_FLAG_AFFECTWORN 0x10
//Item related modes
#define IM_HOLD "Hold"
+2
View File
@@ -157,6 +157,8 @@
#define MAT_GRAPHITE "graphite"
#define MAT_LEATHER "leather"
#define MAT_CHITIN "chitin"
#define MAT_CLOTH "cloth"
#define MAT_SYNCLOTH "syncloth"
#define SHARD_SHARD "shard"
#define SHARD_SHRAPNEL "shrapnel"
+4 -1
View File
@@ -8,6 +8,7 @@ var/global/list/tail_styles_list = list() // Stores /datum/sprite_accessory/tail
var/global/list/wing_styles_list = list() // Stores /datum/sprite_accessory/wing indexed by type
var/global/list/negative_traits = list() // Negative custom species traits, indexed by path
var/global/list/neutral_traits = list() // Neutral custom species traits, indexed by path
var/global/list/everyone_traits = list() // Neutral traits available to all species, indexed by path
var/global/list/positive_traits = list() // Positive custom species traits, indexed by path
var/global/list/traits_costs = list() // Just path = cost list, saves time in char setup
var/global/list/all_traits = list() // All of 'em at once (same instances)
@@ -457,7 +458,7 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN,
for(var/path in paths)
var/datum/sprite_accessory/hair_accessory/instance = new path()
hair_accesories_list[path] = instance
// Custom species traits
paths = typesof(/datum/trait) - /datum/trait
for(var/path in paths)
@@ -472,6 +473,8 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN,
negative_traits[path] = instance
if(0)
neutral_traits[path] = instance
if(!(instance.custom_only))
everyone_traits[path] = instance
if(0.1 to INFINITY)
positive_traits[path] = instance
+5 -10
View File
@@ -354,19 +354,13 @@
facedir(direction)
/obj/screen/click_catcher
name = "Darkness"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "click_catcher"
plane = CLICKCATCHER_PLANE
layer = LAYER_HUD_UNDER
mouse_opacity = 2
screen_loc = "CENTER-7,CENTER-7"
/obj/screen/click_catcher/proc/MakeGreed()
. = list()
for(var/i = 0, i<15, i++)
for(var/j = 0, j<15, j++)
var/obj/screen/click_catcher/CC = new()
CC.screen_loc = "NORTH-[i],EAST-[j]"
. += CC
screen_loc = "SOUTHWEST to NORTHEAST"
/obj/screen/click_catcher/Click(location, control, params)
var/list/modifiers = params2list(params)
@@ -374,7 +368,8 @@
var/mob/living/carbon/C = usr
C.swap_hand()
else
var/turf/T = screen_loc2turf(screen_loc, get_turf(usr))
var/list/P = params2list(params)
var/turf/T = screen_loc2turf(P["screen-loc"], get_turf(usr))
if(T)
T.Click(location, control, params)
. = 1
+6
View File
@@ -26,6 +26,12 @@
name = "mechanical trap"
path =/obj/item/weapon/beartrap
/datum/category_item/autolathe/devices/barbedwire
name = "barbed wire"
path = /obj/item/weapon/material/barbedwire
hidden = 1
resources = list(DEFAULT_WALL_MATERIAL = 10000)
/datum/category_item/autolathe/devices/electropack
name = "electropack"
path =/obj/item/device/radio/electropack
+5
View File
@@ -48,6 +48,11 @@
path = /obj/item/weapon/reagent_containers/spray
resources = list(MAT_PLASTIC = 2000)
/datum/category_item/autolathe/devices/slowwire
name = "snare wire"
path = /obj/item/weapon/material/barbedwire/plastic
resources = list(MAT_PLASTIC = 10000)
/datum/category_item/autolathe/tools/spraynozzle
name = "spray nozzle"
path = /obj/item/weapon/reagent_containers/spray
+6
View File
@@ -92,6 +92,12 @@
desc = "A device which is capable of disrupting subspace communications, preventing the use of headsets, PDAs, and communicators within \
a radius of seven meters. It runs off weapon cells, which can be replaced as needed. One cell will last for approximately ten minutes."
/datum/uplink_item/item/tools/wall_elecrtifier
name = "Wall Electrifier"
item_cost = 10
path = /obj/item/weapon/cell/spike
desc = "A modified powercell which will electrify walls and reinforced floors in a 3x3 tile range around it. Always active."
/datum/uplink_item/item/tools/emag
name = "Cryptographic Sequencer"
item_cost = 30
+22 -2
View File
@@ -1,5 +1,5 @@
/datum/wires/mines
wire_count = 6
wire_count = 7
randomize = TRUE
holder_type = /obj/effect/mine
proper_name = "Explosive Wires"
@@ -7,6 +7,7 @@
/datum/wires/mines/New(atom/_holder)
wires = list(WIRE_EXPLODE, WIRE_EXPLODE_DELAY, WIRE_DISARM, WIRE_BADDISARM)
return ..()
#define WIRE_TRAP 64
/datum/wires/mines/get_status()
. = ..()
@@ -29,7 +30,13 @@
if(WIRE_DISARM)
C.visible_message("[bicon(C)] *click!*", "[bicon(C)] *click!*")
new C.mineitemtype(get_turf(C))
var/obj/effect/mine/MI = new C.mineitemtype(get_turf(C))
if(C.trap)
MI.trap = C.trap
C.trap = null
MI.trap.forceMove(MI)
spawn(0)
qdel(C)
@@ -37,6 +44,15 @@
C.visible_message("[bicon(C)] *BEEPBEEPBEEP*", "[bicon(C)] *BEEPBEEPBEEP*")
spawn(20)
C.explode()
if(WIRE_TRAP)
C.visible_message("[bicon(C)] *click!*", "[bicon(C)] *click!*")
if(mend)
C.visible_message("[bicon(C)] - The mine recalibrates[C.camo_net ? ", revealing \the [C.trap] inside." : "."]")
C.alpha = 255
..()
/datum/wires/mines/on_pulse(wire)
@@ -57,6 +73,10 @@
if(WIRE_BADDISARM)
C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*")
if(WIRE_TRAP)
C.visible_message("[bicon(C)] *ping*", "[bicon(C)] *ping*")
..()
/datum/wires/mines/interactable(mob/user)
+3 -17
View File
@@ -206,23 +206,9 @@ var/global/list/datum/dna/gene/dna_genes[0]
// Technically custom_species is not part of the UI, but this place avoids merge problems.
src.custom_species = character.custom_species
if(istype(character.species,/datum/species/custom))
var/datum/species/custom/CS = character.species
src.species_traits = CS.traits.Copy()
src.base_species = CS.base_species
src.blood_color = CS.blood_color
if(istype(character.species,/datum/species/xenochimera))
var/datum/species/xenochimera/CS = character.species
//src.species_traits = CS.traits.Copy() //No traits
src.base_species = CS.base_species
src.blood_color = CS.blood_color
if(istype(character.species,/datum/species/alraune))
var/datum/species/alraune/CS = character.species
//src.species_traits = CS.traits.Copy() //No traits
src.base_species = CS.base_species
src.blood_color = CS.blood_color
src.base_species = character.species.base_species
src.blood_color = character.species.blood_color
src.species_traits = character.species.traits.Copy()
// +1 to account for the none-of-the-above possibility
SetUIValueRange(DNA_UI_EAR_STYLE, ear_style + 1, ear_styles_list.len + 1, 1)
+3 -14
View File
@@ -237,20 +237,9 @@
// Technically custom_species is not part of the UI, but this place avoids merge problems.
H.custom_species = dna.custom_species
if(istype(H.species,/datum/species/custom))
var/datum/species/custom/CS = H.species
var/datum/species/custom/new_CS = CS.produceCopy(dna.base_species,dna.species_traits,src)
new_CS.blood_color = dna.blood_color
if(istype(H.species,/datum/species/xenochimera))
var/datum/species/xenochimera/CS = H.species
var/datum/species/xenochimera/new_CS = CS.produceCopy(dna.base_species,dna.species_traits,src)
new_CS.blood_color = dna.blood_color
if(istype(H.species,/datum/species/alraune))
var/datum/species/alraune/CS = H.species
var/datum/species/alraune/new_CS = CS.produceCopy(dna.base_species,dna.species_traits,src)
new_CS.blood_color = dna.blood_color
H.species.blood_color = dna.blood_color
var/datum/species/S = H.species
S.produceCopy(dna.base_species,dna.species_traits,src)
// VOREStation Edit End
H.force_update_organs() //VOREStation Add - Gotta do this too
-103
View File
@@ -1,111 +1,8 @@
/*
CONTAINS:
Deployable items
Barricades
*/
//Barricades!
/obj/structure/barricade
name = "barricade"
desc = "This space is blocked off by a barricade."
icon = 'icons/obj/structures.dmi'
icon_state = "barricade"
anchored = 1.0
density = 1.0
var/health = 100
var/maxhealth = 100
var/datum/material/material
/obj/structure/barricade/New(var/newloc, var/material_name)
..(newloc)
if(!material_name)
material_name = "wood"
material = get_material_by_name("[material_name]")
if(!material)
qdel(src)
return
name = "[material.display_name] barricade"
desc = "This space is blocked off by a barricade made of [material.display_name]."
color = material.icon_colour
maxhealth = material.integrity
health = maxhealth
/obj/structure/barricade/get_material()
return material
/obj/structure/barricade/attackby(obj/item/W as obj, mob/user as mob)
user.setClickCooldown(user.get_attack_speed(W))
if(istype(W, /obj/item/stack))
var/obj/item/stack/D = W
if(D.get_material_name() != material.name)
return //hitting things with the wrong type of stack usually doesn't produce messages, and probably doesn't need to.
if(health < maxhealth)
if(D.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one sheet of [material.display_name] to repair \the [src].</span>")
return
visible_message("<span class='notice'>[user] begins to repair \the [src].</span>")
if(do_after(user,20) && health < maxhealth)
if(D.use(1))
health = maxhealth
visible_message("<span class='notice'>[user] repairs \the [src].</span>")
return
return
else
switch(W.damtype)
if("fire")
health -= W.force * 1
if("brute")
health -= W.force * 0.75
if(material == (get_material_by_name(MAT_WOOD) || get_material_by_name(MAT_SIFWOOD)))
playsound(src, 'sound/effects/woodcutting.ogg', 100, 1)
else
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
CheckHealth()
..()
/obj/structure/barricade/proc/CheckHealth()
if(health <= 0)
dismantle()
return
/obj/structure/barricade/take_damage(var/damage)
health -= damage
CheckHealth()
return
/obj/structure/barricade/attack_generic(var/mob/user, var/damage, var/attack_verb)
visible_message("<span class='danger'>[user] [attack_verb] the [src]!</span>")
if(material == get_material_by_name("resin"))
playsound(src, 'sound/effects/attackblob.ogg', 100, 1)
else if(material == (get_material_by_name(MAT_WOOD) || get_material_by_name(MAT_SIFWOOD)))
playsound(src, 'sound/effects/woodcutting.ogg', 100, 1)
else
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
user.do_attack_animation(src)
health -= damage
CheckHealth()
return
/obj/structure/barricade/proc/dismantle()
material.place_dismantled_product(get_turf(src))
visible_message("<span class='danger'>\The [src] falls apart!</span>")
qdel(src)
return
/obj/structure/barricade/ex_act(severity)
switch(severity)
if(1.0)
dismantle()
if(2.0)
health -= 25
CheckHealth()
/obj/structure/barricade/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
if(istype(mover) && mover.checkpass(PASSTABLE))
return TRUE
return FALSE
//Actual Deployable machinery stuff
/obj/machinery/deployable
name = "deployable"
desc = "deployable"
+109 -4
View File
@@ -7,16 +7,32 @@
icon_state = "uglymine"
var/triggered = 0
var/smoke_strength = 3
var/mineitemtype = /obj/item/weapon/mine
var/obj/item/weapon/mine/mineitemtype = /obj/item/weapon/mine
var/panel_open = 0
var/datum/wires/mines/wires = null
register_as_dangerous_object = TRUE
var/camo_net = FALSE // Will the mine 'cloak' on deployment?
// The trap item will be triggered in some manner when detonating. Default only checks for grenades.
var/obj/item/trap = null
/obj/effect/mine/New()
icon_state = "uglyminearmed"
wires = new(src)
if(ispath(trap))
trap = new trap(src)
/obj/effect/mine/Initialize()
..()
if(camo_net)
alpha = 50
/obj/effect/mine/Destroy()
if(trap)
QDEL_NULL(trap)
qdel_null(wires)
return ..()
@@ -25,11 +41,33 @@
triggered = 1
s.set_up(3, 1, src)
s.start()
explosion(loc, 0, 2, 3, 4) //land mines are dangerous, folks.
visible_message("\The [src.name] detonates!")
if(trap)
trigger_trap(M)
visible_message("\The [src.name] flashes as it is triggered!")
else
explosion(loc, 0, 2, 3, 4) //land mines are dangerous, folks.
visible_message("\The [src.name] detonates!")
qdel(s)
qdel(src)
/obj/effect/mine/proc/trigger_trap(var/mob/living/victim)
if(istype(trap, /obj/item/weapon/grenade))
var/obj/item/weapon/grenade/G = trap
trap = null
G.forceMove(get_turf(src))
if(victim.ckey)
msg_admin_attack("[key_name_admin(victim)] stepped on \a [src.name], triggering [trap]")
G.activate()
if(istype(trap, /obj/item/device/transfer_valve))
var/obj/item/device/transfer_valve/TV = trap
trap = null
TV.forceMove(get_turf(src))
TV.toggle_valve()
/obj/effect/mine/bullet_act()
if(prob(50))
explode()
@@ -63,6 +101,9 @@
"<span class='notice'>You very carefully screw the mine's panel [panel_open ? "open" : "closed"].</span>")
playsound(src, W.usesound, 50, 1)
// Panel open, stay uncloaked, or uncloak if already cloaked. If you don't cloak on place, ignore it and just be normal alpha.
alpha = camo_net ? (panel_open ? 255 : 50) : 255
else if((W.is_wirecutter() || istype(W, /obj/item/device/multitool)) && panel_open)
interact(user)
else
@@ -74,6 +115,9 @@
user.set_machine(src)
wires.Interact(user)
/obj/effect/mine/camo
camo_net = TRUE
/obj/effect/mine/dnascramble
mineitemtype = /obj/item/weapon/mine/dnascramble
@@ -193,6 +237,9 @@
spawn(0)
qdel(src)
/obj/effect/mine/emp/camo
camo_net = TRUE
/obj/effect/mine/incendiary
mineitemtype = /obj/item/weapon/mine/incendiary
@@ -208,6 +255,26 @@
spawn(0)
qdel(src)
/obj/effect/mine/gadget
mineitemtype = /obj/item/weapon/mine/gadget
/obj/effect/mine/gadget/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
triggered = 1
s.set_up(3, 1, src)
s.start()
if(trap)
trigger_trap(M)
visible_message("\The [src.name] flashes as it is triggered!")
else
explosion(loc, 0, 0, 2, 2)
visible_message("\The [src.name] detonates!")
qdel(s)
qdel(src)
/////////////////////////////////////////////
// The held item version of the above mines
/////////////////////////////////////////////
@@ -219,6 +286,10 @@
var/countdown = 10
var/minetype = /obj/effect/mine //This MUST be an /obj/effect/mine type, or it'll runtime.
var/obj/item/trap = null
var/list/allowed_gadgets = null
/obj/item/weapon/mine/attack_self(mob/user as mob) // You do not want to move or throw a land mine while priming it... Explosives + Sudden Movement = Bad Times
add_fingerprint(user)
msg_admin_attack("[key_name_admin(user)] primed \a [src]")
@@ -231,11 +302,39 @@
prime(user, TRUE)
return
/obj/item/weapon/mine/attackby(obj/item/W as obj, mob/living/user as mob)
if(W.is_screwdriver() && trap)
to_chat(user, "<span class='notice'>You begin removing \the [trap].</span>")
if(do_after(user, 10 SECONDS))
to_chat(user, "<span class='notice'>You finish disconnecting the mine's trigger.</span>")
trap.forceMove(get_turf(src))
trap = null
return
if(LAZYLEN(allowed_gadgets) && !trap)
var/allowed = FALSE
for(var/path in allowed_gadgets)
if(istype(W, path))
allowed = TRUE
break
if(allowed)
user.drop_from_inventory(W)
W.forceMove(src)
trap = W
..()
/obj/item/weapon/mine/proc/prime(mob/user as mob, var/explode_now = FALSE)
visible_message("\The [src.name] beeps as the priming sequence completes.")
var/obj/effect/mine/R = new minetype(get_turf(src))
src.transfer_fingerprints_to(R)
R.add_fingerprint(user)
if(trap)
R.trap = trap
trap = null
R.trap.forceMove(R)
if(explode_now)
R.explode(user)
spawn(0)
@@ -286,8 +385,14 @@
desc = "A small explosive mine with a fire symbol on the side."
minetype = /obj/effect/mine/incendiary
/obj/item/weapon/mine/gadget
name = "gadget mine"
desc = "A small pressure-triggered device. If no component is added, the internal release bolts will detonate in unison when triggered."
allowed_gadgets = list(/obj/item/weapon/grenade, /obj/item/device/transfer_valve)
// This tells AI mobs to not be dumb and step on mines willingly.
/obj/item/weapon/mine/is_safe_to_step(mob/living/L)
if(!L.hovering)
return FALSE
return ..()
return ..()
@@ -88,6 +88,14 @@
if(get_dist(user, src) == 0)
. += "It has a tiny camera inside. Needs to be both configured and brought in contact with monitor device to be fully functional."
/obj/item/device/camerabug/update_icon()
..()
if(anchored) // Standard versions are relatively obvious if not hidden in a container. Anchoring them is advised, to disguise them.
alpha = 50
else
alpha = 255
/obj/item/device/camerabug/attackby(obj/item/W as obj, mob/living/user as mob)
if(istype(W, /obj/item/device/bug_monitor))
var/obj/item/device/bug_monitor/SM = W
@@ -101,6 +109,15 @@
linkedmonitor = null
else
to_chat(user, "Error: The device is linked to another monitor.")
else if(W.is_wrench() && user.a_intent != I_HURT)
if(isturf(loc))
anchored = !anchored
to_chat(user, "<span class='notice'>You [anchored ? "" : "un"]secure \the [src].</span>")
update_icon()
return
else
if(W.force >= 5)
visible_message("\The [src] lens shatters!")
+149
View File
@@ -0,0 +1,149 @@
/obj/item/device/buttonofnormal
name = "Chaos button"
desc = "It radiates an aura of chaotic size energy."
icon = 'icons/obj/mobcap.dmi'
icon_state = "mobcap0"
matter = list(DEFAULT_WALL_MATERIAL = 1000)
throwforce = 00
throw_speed = 4
throw_range = 20
force = 0
var/colorindex = 0
var/mob/living/capsuleowner = null //taken from Capsule Code
var/sizetouse = 0.25
pickup(mob/user)
if(!capsuleowner)
capsuleowner = user
attack_self(mob/user)
if(colorindex)
nonrandom()
sleep(10)
capsuleowner.resize(sizetouse)
sizetouse = rand(25,200)/100 //randmization occurs after press
throw_impact(atom/A, speed, mob/user)
..()
if(isliving(A))
if(colorindex)
nonrandom()
sleep(5)
var/mob/living/capsulehit = A
capsulehit.resize(sizetouse)
sizetouse = rand(25,200)/100 //randmization occurs after press
attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/weapon/pen))
colorindex = (colorindex + 1) % 6
icon_state = "mobcap[colorindex]"
update_icon()
if(istype(W, /obj/item/weapon/card/id))
capsuleowner = null
..()
/obj/item/device/buttonofnormal/proc/nonrandom() //Secret ball randmoizer rig code
switch(colorindex)
if(1) sizetouse = RESIZE_HUGE
if(2) sizetouse = RESIZE_BIG
if(3) sizetouse = RESIZE_NORMAL
if(4) sizetouse = RESIZE_SMALL
if(5) sizetouse = RESIZE_TINY
/obj/item/device/daredevice
name = "Dare button"
desc = "A strange button, the only distinguishing feature being an engraved text reading 'Suffer to Gain.'."
icon = 'icons/obj/mobcap.dmi'
icon_state = "mobcap1"
matter = list(DEFAULT_WALL_MATERIAL = 5000)
throwforce = 00
throw_speed = 2
throw_range = 20
force = 0
var/luckynumber7 = 0
var/colorindex = 1
var/list/winitems = list(
/obj/item/weapon/reagent_containers/food/snacks/cookie,
/obj/item/weapon/spacecasinocash,
/obj/item/weapon/reagent_containers/syringe/drugs,
)
attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/weapon/pen))
colorindex += 1
if(colorindex >= 6)
colorindex = 0
icon_state = "mobcap[colorindex]"
update_icon()
..()
attack_self(mob/user)
var/mob/living/capsuleowner = user
playsound(src, 'sound/effects/splat.ogg', 30, 1)
var/item = pick(winitems)
sleep(100)
switch(luckynumber7)
if(1) capsuleowner.resize(RESIZE_TINY) //Loss Shrinking!
if(2) capsuleowner.apply_damage(5, BRUTE) //Loss Damaging!
if(3) capsuleowner.Weaken(5) //Loss Knee spaghetti!
if(4) capsuleowner.hallucination += 66 //loss woah, dude.
if(5) new item(capsuleowner.loc) //Win!
if(7)
new /obj/item/weapon/material/butterfly/switchblade(capsuleowner.loc)
capsuleowner.apply_damage(10, BRUTE) //Loss Damaging! WIN KNIVE!
if(9)
new /obj/item/weapon/gun/energy/sizegun/not_advanced(capsuleowner.loc)
qdel(src)
if(777) new /obj/item/weapon/spacecash/c1000(capsuleowner.loc) //for rigging
else luckynumber7 = (rand(0,10))
luckynumber7 = rand(0,10)
sleep(100)
playsound(src.loc, 'sound/machines/slotmachine.ogg', 25, 1)
//items literally just made for the above item spawner
//
//BADvanced size gun
//
/obj/item/weapon/gun/energy/sizegun/not_advanced
name = "Corrupted size gun"
desc = "A highly advanced ray gun with a knob on the side to adjust the size you desire. Or at least that's what it used to be."
projectile_type = /obj/item/projectile/beam/sizelaser/chaos
charge_cost = 60 //1/3 of the base price for a normal one.
//
//CHAOS laser
//
/obj/item/projectile/beam/sizelaser/chaos //The Defintiely not advanced sizeguns laser.
name = "chaos size beam"
light_color = "#FF0000"
light_range = 3
light_power = 9 //should be plenty visible.
var/list/chaos_colors = list(
"#FF0000",
"#00FF00",
"#0000FF",
"#FFFF00",
"#00FFFF",
"#FF00FF",
"#000000",
"#FFFFFF",
"#F0F0F0",
"#0F0F0F",
)
on_hit(var/atom/target)
light_color = pick(chaos_colors)
var/chaos = rand(25,200)
var/mob/living/M = target
if(ishuman(target))
var/mob/living/carbon/human/H = M
H.resize(chaos/100)
H.show_message("<font color='#6F6FE2'> The beam fires into your body, changing your size!</font>")
H.updateicon()
else if (istype(target, /mob/living/))
var/mob/living/H = M
H.resize(chaos/100)
H.updateicon()
else
return 1
@@ -56,3 +56,6 @@
name = "Bandage Synthesizer"
max_energy = 10
recharge_rate = 1
/datum/matter_synth/cloth
name = "Cloth Synthesizer"
+158
View File
@@ -0,0 +1,158 @@
/obj/item/stack/sandbags
name = "sandbag"
desc = "Filled sandbags. Fortunately pre-filled."
singular_name = "sandbag"
icon = 'icons/obj/sandbags.dmi'
icon_state = "sandbag"
w_class = ITEMSIZE_LARGE
force = 10.0
throwforce = 20.0
throw_speed = 5
throw_range = 3
drop_sound = 'sound/items/drop/clothing.ogg'
pickup_sound = 'sound/items/pickup/clothing.ogg'
matter = list(MAT_CLOTH = SHEET_MATERIAL_AMOUNT * 2)
max_amount = 30
attack_verb = list("hit", "bludgeoned", "pillowed")
no_variants = TRUE
stacktype = /obj/item/stack/sandbags
pass_color = TRUE
var/bag_material = "cloth"
/obj/item/stack/sandbags/cyborg
name = "sandbag synthesizer"
desc = "A device that makes filled sandbags. Don't ask how."
gender = NEUTER
matter = null
uses_charge = 1
charge_costs = list(500)
stacktype = /obj/item/stack/sandbags
bag_material = MAT_SYNCLOTH
/obj/item/stack/sandbags/New(var/newloc, var/amt, var/bag_mat)
..()
recipes = sandbag_recipes
update_icon()
if(bag_mat)
bag_material = bag_mat
var/datum/material/M = get_material_by_name("[bag_material]")
if(!M)
qdel(src)
return
color = M.icon_colour
/obj/item/stack/sandbags/update_icon()
var/amount = get_amount()
slowdown = round(amount / 10, 0.1)
var/global/list/datum/stack_recipe/sandbag_recipes = list( \
new/datum/stack_recipe("barricade", /obj/structure/barricade/sandbag, 3, time = 5 SECONDS, one_per_turf = 1, on_floor = 1, pass_stack_color = TRUE))
/obj/item/stack/sandbags/produce_recipe(datum/stack_recipe/recipe, var/quantity, mob/user)
var/required = quantity*recipe.req_amount
var/produced = min(quantity*recipe.res_amount, recipe.max_res_amount)
if (!can_use(required))
if (produced>1)
to_chat(user, "<span class='warning'>You haven't got enough [src] to build \the [produced] [recipe.title]\s!</span>")
else
to_chat(user, "<span class='warning'>You haven't got enough [src] to build \the [recipe.title]!</span>")
return
if (recipe.one_per_turf && (locate(recipe.result_type) in user.loc))
to_chat(user, "<span class='warning'>There is another [recipe.title] here!</span>")
return
if (recipe.on_floor && !isfloor(user.loc))
to_chat(user, "<span class='warning'>\The [recipe.title] must be constructed on the floor!</span>")
return
if (recipe.time)
to_chat(user, "<span class='notice'>Building [recipe.title] ...</span>")
if (!do_after(user, recipe.time))
return
if (use(required))
var/atom/O = new recipe.result_type(user.loc, bag_material)
if(istype(O, /obj))
var/obj/Ob = O
if(LAZYLEN(Ob.matter)) // Law of equivalent exchange.
Ob.matter.Cut()
else
Ob.matter = list()
var/mattermult = istype(Ob, /obj/item) ? min(2000, 400 * Ob.w_class) : 2000
Ob.matter[recipe.use_material] = mattermult / produced * required
O.set_dir(user.dir)
O.add_fingerprint(user)
if (istype(O, /obj/item/stack))
var/obj/item/stack/S = O
S.amount = produced
S.add_to_stacks(user)
if (istype(O, /obj/item/weapon/storage)) //BubbleWrap - so newly formed boxes are empty
for (var/obj/item/I in O)
qdel(I)
if ((pass_color || recipe.pass_color))
if(!color)
if(recipe.use_material)
var/datum/material/MAT = get_material_by_name(recipe.use_material)
if(MAT.icon_colour)
O.color = MAT.icon_colour
else
return
else
O.color = color
// Empty bags. Yes, you need to fill them.
/obj/item/stack/emptysandbag
name = "sandbag"
desc = "Empty sandbags. You know what must be done."
singular_name = "sandbag"
icon = 'icons/obj/sandbags.dmi'
icon_state = "sandbag_e"
w_class = ITEMSIZE_LARGE
strict_color_stacking = TRUE
max_amount = 30
stacktype = /obj/item/stack/emptysandbag
pass_color = TRUE
var/bag_material = "cloth"
/obj/item/stack/emptysandbag/New(var/newloc, var/amt, var/bag_mat)
..(newloc, amt)
if(bag_mat)
bag_material = bag_mat
var/datum/material/M = get_material_by_name("[bag_material]")
if(!M)
qdel(src)
return
color = M.icon_colour
/obj/item/stack/emptysandbag/attack_self(var/mob/user)
while(do_after(user, 1 SECOND) && can_use(1) && istype(get_turf(src), /turf/simulated/floor/outdoors))
use(1)
var/obj/item/stack/sandbags/SB = new (get_turf(src), 1, bag_material)
SB.color = color
if(user)
to_chat(user, "<span class='notice'>You fill a sandbag.</span>")
@@ -8,6 +8,12 @@
name = "stack of sifgrass"
type_to_spawn = /obj/item/stack/tile/grass/sif
//CHOMPedit, delete if this is added upstream.
/obj/fiftyspawner/grass/sif/forest
name = "stack of sifgrass"
type_to_spawn = /obj/item/stack/tile/grass/sif/forest
//CHOMPedit end
/obj/fiftyspawner/wood
name = "stack of wood"
type_to_spawn = /obj/item/stack/tile/wood
@@ -52,6 +52,12 @@
singular_name = "sivian grass floor tile"
desc = "A patch of grass like those that decorate the plains of Sif."
//CHOMPedit: remove if this gets added upstream
/obj/item/stack/tile/grass/sif/forest
name = "sivian overgrowth tile"
singular_name = "sivian overgrowth floor tile"
desc = "A patch of dark overgrowth like those that decorate the plains of Sif."
//CHOMPedit end
/*
* Wood
*/
@@ -99,6 +99,8 @@
/obj/item/weapon/material/proc/check_health(var/consumed)
if(health<=0)
health = 0
if(fragile)
shatter(consumed)
else if(!dulled && can_dull)
+241
View File
@@ -1,3 +1,9 @@
/*
* Beartraps.
* Buckles crossing individuals, doing moderate brute damage.
*/
/obj/item/weapon/beartrap
name = "mechanical trap"
throw_speed = 2
@@ -158,3 +164,238 @@
color = "#C9DCE1"
origin_tech = list(TECH_MATERIAL = 4, TECH_BLUESPACE = 3, TECH_MAGNET = 4, TECH_PHORON = 2, TECH_ARCANE = 1)
/*
* Barbed-Wire.
* Slows individuals crossing it. Barefoot individuals will be cut. Can be electrified by placing over a cable node.
*/
/obj/item/weapon/material/barbedwire
name = "barbed wire"
desc = "A coil of wire."
icon = 'icons/obj/trap.dmi'
icon_state = "barbedwire"
anchored = FALSE
layer = TABLE_LAYER
w_class = ITEMSIZE_LARGE
explosion_resistance = 1
can_dull = TRUE
fragile = TRUE
force_divisor = 0.20
thrown_force_divisor = 0.25
sharp = TRUE
/obj/item/weapon/material/barbedwire/set_material(var/new_material)
..()
if(!QDELETED(src))
health = round(material.integrity / 3)
name = (material.get_edge_damage() * force_divisor > 15) ? "[material.display_name] razor wire" : "[material.display_name] [initial(name)]"
/obj/item/weapon/material/barbedwire/proc/can_use(mob/user)
return (user.IsAdvancedToolUser() && !issilicon(user) && !user.stat && !user.restrained())
/obj/item/weapon/material/barbedwire/attack_hand(mob/user as mob)
if(anchored && can_use(user))
user.visible_message(
"<span class='danger'>[user] starts to collect \the [src].</span>",
"<span class='notice'>You begin collecting \the [src]!</span>",
"You hear the sound of rustling [material.name]."
)
playsound(src, 'sound/machines/click.ogg', 50, 1)
if(do_after(user, health))
user.visible_message(
"<span class='danger'>[user] has collected \the [src].</span>",
"<span class='notice'>You have collected \the [src]!</span>"
)
anchored = 0
update_icon()
else
..()
/obj/item/weapon/material/barbedwire/attack_self(mob/user as mob)
..()
if(!anchored && can_use(user))
user.visible_message(
"<span class='danger'>[user] starts to deploy \the [src].</span>",
"<span class='danger'>You begin deploying \the [src]!</span>",
"You hear the rustling of [material.name]."
)
if (do_after(user, 60))
user.visible_message(
"<span class='danger'>[user] has deployed \the [src].</span>",
"<span class='danger'>You have deployed \the [src]!</span>",
"You hear the rustling of [material.name]."
)
playsound(src, 'sound/items/Wirecutter.ogg',70, 1)
spawn(2)
playsound(src, 'sound/items/Wirecutter.ogg',40, 1)
user.drop_from_inventory(src)
forceMove(get_turf(src))
anchored = 1
update_icon()
/obj/item/weapon/material/barbedwire/attackby(obj/item/W as obj, mob/user as mob)
if(!istype(W))
return
if((W.flags & NOCONDUCT) || !shock(user, 70, pick(BP_L_HAND, BP_R_HAND)))
user.setClickCooldown(user.get_attack_speed(W))
user.do_attack_animation(src)
playsound(src, 'sound/effects/grillehit.ogg', 40, 1)
var/inc_damage = W.force
if(W.is_wirecutter())
if(!shock(user, 100, pick(BP_L_HAND, BP_R_HAND)))
playsound(src, W.usesound, 100, 1)
inc_damage *= 3
if(W.damtype != BRUTE)
inc_damage *= 0.3
health -= inc_damage
check_health()
..()
/obj/item/weapon/material/barbedwire/update_icon()
..()
if(anchored)
icon_state = "[initial(icon_state)]-out"
else
icon_state = "[initial(icon_state)]"
/obj/item/weapon/material/barbedwire/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(anchored && isliving(AM))
var/mob/living/L = AM
if(L.m_intent == "run")
L.visible_message(
"<span class='danger'>[L] steps in \the [src].</span>",
"<span class='danger'>You step in \the [src]!</span>",
"<b>You hear a sharp rustling!</b>"
)
attack_mob(L)
update_icon()
..()
/obj/item/weapon/material/barbedwire/proc/shock(mob/user as mob, prb, var/target_zone = BP_TORSO)
if(!anchored || health == 0) // anchored/destroyed grilles are never connected
return 0
if(material.conductivity <= 0)
return 0
if(!prob(prb))
return 0
if(!in_range(src, user))//To prevent TK and mech users from getting shocked
return 0
var/turf/T = get_turf(src)
var/obj/structure/cable/C = T.get_cable_node()
if(C)
if(C.powernet)
var/datum/powernet/PN = C.powernet
if(PN)
PN.trigger_warning()
var/PN_damage = PN.get_electrocute_damage() * (material.conductivity / 50)
var/drained_energy = PN_damage * 10 / CELLRATE
PN.draw_power(drained_energy)
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/obj/item/organ/external/affected = H.get_organ(check_zone(target_zone))
H.electrocute_act(PN_damage, src, H.get_siemens_coefficient_organ(affected))
else
if(isliving(user))
var/mob/living/L = user
L.electrocute_act(PN_damage, src, 0.8)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
if(user.stunned)
return 1
else
return 0
return 0
/obj/item/weapon/material/barbedwire/proc/attack_mob(mob/living/L)
var/target_zone
if(L.lying)
target_zone = ran_zone()
else
target_zone = pick("l_foot", "r_foot", "l_leg", "r_leg")
//armour
var/blocked = L.run_armor_check(target_zone, "melee")
var/soaked = L.get_armor_soak(target_zone, "melee")
if(blocked >= 100)
return
if(soaked >= 30)
return
if(L.buckled) //wheelchairs, office chairs, rollerbeds
return
shock(L, 100, target_zone)
L.add_modifier(/datum/modifier/entangled, 3 SECONDS)
if(!L.apply_damage(force * (issilicon(L) ? 0.25 : 1), BRUTE, target_zone, blocked, soaked, src, sharp, edge))
return
playsound(src, 'sound/effects/glass_step.ogg', 50, 1) // not sure how to handle metal shards with sounds
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.species.siemens_coefficient<0.5) //Thick skin.
return
if( H.shoes || ( H.wear_suit && (H.wear_suit.body_parts_covered & FEET) ) )
return
if(H.species.flags & NO_MINOR_CUT)
return
to_chat(H, "<span class='danger'>You step directly on \the [src]!</span>")
var/list/check = list("l_foot", "r_foot")
while(check.len)
var/picked = pick(check)
var/obj/item/organ/external/affecting = H.get_organ(picked)
if(affecting)
if(affecting.robotic >= ORGAN_ROBOT)
return
if(affecting.take_damage(force, 0))
H.UpdateDamageIcon()
H.updatehealth()
if(affecting.organ_can_feel_pain())
H.Weaken(3)
return
check -= picked
if(material.is_brittle() && prob(material.hardness))
health = 0
else if(!prob(material.hardness))
health--
check_health()
return
/obj/item/weapon/material/barbedwire/plastic
name = "snare wire"
default_material = MAT_PLASTIC
+2
View File
@@ -92,6 +92,8 @@
return pick(prob(30);/obj/effect/mine,
prob(25);/obj/effect/mine/frag,
prob(25);/obj/effect/mine/emp,
prob(15);/obj/effect/mine/camo,
prob(15);/obj/effect/mine/emp/camo,
prob(10);/obj/effect/mine/stun,
prob(10);/obj/effect/mine/incendiary,)
+185
View File
@@ -0,0 +1,185 @@
//Barricades!
/obj/structure/barricade
name = "barricade"
desc = "This space is blocked off by a barricade."
icon = 'icons/obj/structures.dmi'
icon_state = "barricade"
anchored = 1.0
density = 1.0
var/health = 100
var/maxhealth = 100
var/datum/material/material
/obj/structure/barricade/New(var/newloc, var/material_name)
..(newloc)
if(!material_name)
material_name = "wood"
material = get_material_by_name("[material_name]")
if(!material)
qdel(src)
return
name = "[material.display_name] barricade"
desc = "This space is blocked off by a barricade made of [material.display_name]."
color = material.icon_colour
maxhealth = material.integrity
health = maxhealth
/obj/structure/barricade/get_material()
return material
/obj/structure/barricade/attackby(obj/item/W as obj, mob/user as mob)
user.setClickCooldown(user.get_attack_speed(W))
if(istype(W, /obj/item/stack))
var/obj/item/stack/D = W
if(D.get_material_name() != material.name)
return //hitting things with the wrong type of stack usually doesn't produce messages, and probably doesn't need to.
if(health < maxhealth)
if(D.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one sheet of [material.display_name] to repair \the [src].</span>")
return
visible_message("<span class='notice'>[user] begins to repair \the [src].</span>")
if(do_after(user,20) && health < maxhealth)
if(D.use(1))
health = maxhealth
visible_message("<span class='notice'>[user] repairs \the [src].</span>")
return
return
else
switch(W.damtype)
if("fire")
health -= W.force * 1
if("brute")
health -= W.force * 0.75
if(material == (get_material_by_name(MAT_WOOD) || get_material_by_name(MAT_SIFWOOD)))
playsound(src, 'sound/effects/woodcutting.ogg', 100, 1)
else
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
CheckHealth()
..()
/obj/structure/barricade/proc/CheckHealth()
if(health <= 0)
dismantle()
health = min(health, maxhealth)
return
/obj/structure/barricade/take_damage(var/damage)
health -= damage
CheckHealth()
return
/obj/structure/barricade/attack_generic(var/mob/user, var/damage, var/attack_verb)
visible_message("<span class='danger'>[user] [attack_verb] the [src]!</span>")
if(material == get_material_by_name("resin"))
playsound(src, 'sound/effects/attackblob.ogg', 100, 1)
else if(material == (get_material_by_name(MAT_CLOTH) || get_material_by_name(MAT_SYNCLOTH)))
playsound(src, 'sound/items/drop/clothing.ogg', 100, 1)
else if(material == (get_material_by_name(MAT_WOOD) || get_material_by_name(MAT_SIFWOOD)))
playsound(src, 'sound/effects/woodcutting.ogg', 100, 1)
else
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
user.do_attack_animation(src)
health -= damage
CheckHealth()
return
/obj/structure/barricade/proc/dismantle()
material.place_dismantled_product(get_turf(src))
visible_message("<span class='danger'>\The [src] falls apart!</span>")
qdel(src)
return
/obj/structure/barricade/ex_act(severity)
switch(severity)
if(1.0)
dismantle()
if(2.0)
health -= 25
CheckHealth()
/obj/structure/barricade/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
if(istype(mover) && mover.checkpass(PASSTABLE))
return TRUE
return FALSE
/obj/structure/barricade/sandbag
name = "sandbags"
desc = "Bags. Bags of sand. It's rough and coarse and somehow stays in the bag."
icon = 'icons/obj/sandbags.dmi'
icon_state = "blank"
/obj/structure/barricade/sandbag/New(var/newloc, var/material_name)
if(!material_name)
material_name = "cloth"
..(newloc, material_name)
material = get_material_by_name("[material_name]")
if(!material)
qdel(src)
return
name = "[material.display_name] [initial(name)]"
desc = "This space is blocked off by a barricade made of [material.display_name]."
color = null
maxhealth = material.integrity * 2 // These things are, commonly, used to stop bullets where possible.
health = maxhealth
update_connections(1)
/obj/structure/barricade/sandbag/Destroy()
update_connections(1, src)
..()
/obj/structure/barricade/sandbag/dismantle()
update_connections(1, src)
material.place_dismantled_product(get_turf(src))
visible_message("<span class='danger'>\The [src] falls apart!</span>")
qdel(src)
return
/obj/structure/barricade/sandbag/update_icon()
if(!material)
return
cut_overlays()
var/image/I
for(var/i = 1 to 4)
I = image('icons/obj/sandbags.dmi', "sandbags[connections[i]]", dir = 1<<(i-1))
I.color = material.icon_colour
add_overlay(I)
return
/obj/structure/barricade/sandbag/update_connections(propagate = 0, var/obj/structure/barricade/sandbag/ignore = null)
if(!material)
return
var/list/dirs = list()
for(var/obj/structure/barricade/sandbag/S in orange(src, 1))
if(!S.material)
continue
if(S == ignore)
continue
if(propagate >= 1)
S.update_connections(propagate - 1, ignore)
if(can_join_with(S))
dirs += get_dir(src, S)
connections = dirs_to_corner_states(dirs)
update_icon()
/obj/structure/barricade/sandbag/proc/can_join_with(var/obj/structure/barricade/sandbag/S)
if(material == S.material)
return 1
return 0
/obj/structure/barricade/sandbag/CanPass(atom/movable/mover, turf/target)
. = ..()
if(.)
if(istype(mover, /obj/item/projectile))
var/obj/item/projectile/P = mover
if(P.firer && get_dist(P.firer, src) > 1) // If you're firing from adjacent turfs, you are unobstructed.
if(P.armor_penetration < (material.protectiveness + material.hardness) || prob(33))
return FALSE
+11
View File
@@ -149,6 +149,17 @@ var/list/flooring_types
build_type = /obj/item/stack/tile/grass/sif
has_base_range = 1
//CHOMPedit: sif/forest decl. If this ends up upstream just accept the upstream version.
/decl/flooring/grass/sif/forest
name = "thick growth"
desc = "A natural moss that has adapted to the sheer cold climate."
flags = TURF_REMOVE_SHOVEL
icon = 'icons/turf/outdoors.dmi'
icon_base = "grass_sif_dark"
build_type = /obj/item/stack/tile/grass/sif/forest
has_base_range = 1
//CHOMPedit end
/decl/flooring/water
name = "water"
desc = "Water is wet, gosh, who knew!"
@@ -89,6 +89,7 @@ var/list/grass_types = list(
/turf/simulated/floor/outdoors/grass/sif/forest
name = "thick growth"
icon_state = "grass_sif_dark0"
initial_flooring = /decl/flooring/grass/sif/forest //CHOMPedit: Remove if this ends up upstream
edge_blending_priority = 5
tree_chance = 4
grass_chance = 1
@@ -99,3 +100,18 @@ var/list/grass_types = list(
/obj/structure/flora/sif/tendrils = 30
)
//CHOMPedit: animal spawning for sif rocks. This probably doesn't belong in grass.dm but it's where there other Sif spawns are, sue me.
/turf/simulated/floor/outdoors/rocks/sif
var/animal_chance = 0.3 //Should spawn around... 0-7 per round? Tweak as needed.
var/animal_types = list(
/mob/living/simple_mob/vore/slug = 1
)
/turf/simulated/floor/outdoors/rocks/sif/Initialize()
if(animal_chance && prob(animal_chance) && !check_density())
var/animal_type = pickweight(animal_types)
new animal_type(src)
. = ..()
//CHOMPedit end
-1
View File
@@ -227,7 +227,6 @@
if(!void)
void = new()
void.MakeGreed()
screen += void
if((prefs.lastchangelog != changelog_hash) && isnewplayer(src.mob)) //bolds the changelog button on the interface so we know there are updates.
@@ -27,6 +27,14 @@
..()
gear_tweaks += gear_tweak_free_color_choice
/datum/gear/eyes/thinblindfold
display_name = "blindfold, thin white (recolorable)"
path = /obj/item/clothing/glasses/sunglasses/thinblindfold
/datum/gear/eyes/thinblindfold/New()
..()
gear_tweaks += gear_tweak_free_color_choice
/datum/gear/eyes/glasses
display_name = "Glasses, prescription"
path = /obj/item/clothing/glasses/regular
@@ -58,21 +58,21 @@
if(pref.species != SPECIES_CUSTOM)
pref.pos_traits.Cut()
pref.neu_traits.Cut()
pref.neg_traits.Cut()
else
// Clean up positive traits
for(var/path in pref.pos_traits)
if(!(path in positive_traits))
pref.pos_traits -= path
//Neutral traits
for(var/path in pref.neu_traits)
if(!(path in neutral_traits))
pref.neu_traits -= path
//Negative traits
for(var/path in pref.neg_traits)
if(!(path in negative_traits))
pref.neg_traits -= path
// Clean up positive traits
for(var/path in pref.pos_traits)
if(!(path in positive_traits))
pref.pos_traits -= path
//Neutral traits
for(var/path in pref.neu_traits)
if(!(path in neutral_traits))
pref.neu_traits -= path
if(!(pref.species == SPECIES_CUSTOM) && !(path in everyone_traits))
pref.neu_traits -= path
//Negative traits
for(var/path in pref.neg_traits)
if(!(path in negative_traits))
pref.neg_traits -= path
var/datum/species/selected_species = GLOB.all_species[pref.species]
if(selected_species.selects_bodytype)
@@ -82,7 +82,6 @@
/datum/category_item/player_setup_item/vore/traits/copy_to_mob(var/mob/living/carbon/human/character)
character.custom_species = pref.custom_species
var/datum/species/selected_species = GLOB.all_species[pref.species]
if(character.isSynthetic()) //Checking if we have a synth on our hands, boys.
pref.dirty_synth = 1
@@ -100,13 +99,15 @@
//Any additional non-trait settings can be applied here
new_S.blood_color = pref.blood_color
//Any additional non-trait settings can be applied here
new_CS.blood_color = pref.blood_color
//Any additional non-trait settings can be applied here
new_S.blood_color = pref.blood_color
if(pref.species == SPECIES_CUSTOM)
//Statistics for this would be nice
var/english_traits = english_list(new_S.traits, and_text = ";", comma_text = ";")
log_game("TRAITS [pref.client_ckey]/([character]) with: [english_traits]") //Terrible 'fake' key_name()... but they aren't in the same entity yet
else
if(pref.species == SPECIES_CUSTOM)
//Statistics for this would be nice
var/english_traits = english_list(new_CS.traits, and_text = ";", comma_text = ";")
log_game("TRAITS [pref.client_ckey]/([character]) with: [english_traits]") //Terrible 'fake' key_name()... but they aren't in the same entity yet
/datum/category_item/player_setup_item/vore/traits/content(var/mob/user)
. += "<b>Custom Species Name:</b> "
@@ -117,15 +118,16 @@
. += "<b>Icon Base: </b> "
. += "<a href='?src=\ref[src];custom_base=1'>[pref.custom_base ? pref.custom_base : "Human"]</a><br>"
var/traits_left = pref.max_traits
. += "<b>Traits Left:</b> [traits_left]<br>"
if(pref.species == SPECIES_CUSTOM)
var/points_left = pref.starting_trait_points
var/traits_left = pref.max_traits
for(var/T in pref.pos_traits + pref.neg_traits)
points_left -= traits_costs[T]
traits_left--
. += "<b>Points Left:</b> [points_left]<br>"
. += "<b>Traits Left:</b> [traits_left]<br>"
if(points_left < 0 || traits_left < 0 || !pref.custom_species)
. += "<span style='color:red;'><b>^ Fix things! ^</b></span><br>"
@@ -136,19 +138,18 @@
. += "<li>- <a href='?src=\ref[src];clicked_pos_trait=[T]'>[trait.name] ([trait.cost])</a></li>"
. += "</ul>"
. += "<a href='?src=\ref[src];add_trait=[NEUTRAL_MODE]'>Neutral Trait +</a><br>"
. += "<ul>"
for(var/T in pref.neu_traits)
var/datum/trait/trait = neutral_traits[T]
. += "<li>- <a href='?src=\ref[src];clicked_neu_trait=[T]'>[trait.name] ([trait.cost])</a></li>"
. += "</ul>"
. += "<a href='?src=\ref[src];add_trait=[NEGATIVE_MODE]'>Negative Trait +</a><br>"
. += "<ul>"
for(var/T in pref.neg_traits)
var/datum/trait/trait = negative_traits[T]
. += "<li>- <a href='?src=\ref[src];clicked_neg_trait=[T]'>[trait.name] ([trait.cost])</a></li>"
. += "</ul>"
. += "<a href='?src=\ref[src];add_trait=[NEUTRAL_MODE]'>Neutral Trait +</a><br>"
. += "<ul>"
for(var/T in pref.neu_traits)
var/datum/trait/trait = neutral_traits[T]
. += "<li>- <a href='?src=\ref[src];clicked_neu_trait=[T]'>[trait.name] ([trait.cost])</a></li>"
. += "</ul>"
. += "<b>Blood Color: </b>" //People that want to use a certain species to have that species traits (xenochimera/promethean/spider) should be able to set their own blood color.
. += "<a href='?src=\ref[src];blood_color=1'>Set Color</a>"
. += "<a href='?src=\ref[src];blood_reset=1'>R</a><br>"
@@ -224,8 +225,12 @@
picklist = positive_traits.Copy() - pref.pos_traits
mylist = pref.pos_traits
if(NEUTRAL_MODE)
picklist = neutral_traits.Copy() - pref.neu_traits
mylist = pref.neu_traits
if(pref.species == SPECIES_CUSTOM)
picklist = neutral_traits.Copy() - pref.neu_traits
mylist = pref.neu_traits
else
picklist = everyone_traits.Copy() - pref.neu_traits
mylist = pref.neu_traits
if(NEGATIVE_MODE)
picklist = negative_traits.Copy() - pref.neg_traits
mylist = pref.neg_traits
+7
View File
@@ -399,6 +399,13 @@ BLIND // can't see anything
desc = "A white blindfold that covers the eyes, preventing sight."
icon_state = "blindfoldwhite"
/obj/item/clothing/glasses/sunglasses/thinblindfold
name = "thin white blindfold"
desc = "A thin blindfold to help protect sensitive eyes while still allowing some sight"
icon_state = "blindfoldwhite"
flash_protection = FLASH_PROTECTION_MODERATE //not as thick, only offers some protection
tint = TINT_HEAVY
/obj/item/clothing/glasses/sunglasses/blindfold/tape
name = "length of tape"
desc = "It's a robust DIY blindfold!"
+17
View File
@@ -6054,6 +6054,23 @@
. = ..()
reagents.add_reagent("protein", 8)
bitesize = 3
/obj/item/weapon/reagent_containers/food/snacks/chickennoodlesoup
name = "chicken noodle soup"
gender = PLURAL
desc = "A bright bowl of yellow broth with cuts of meat, noodles and carrots."
icon = 'icons/obj/food_custom.dmi'
icon_state = "chickennoodlesoup"
filling_color = "#ead90c"
nutriment_amt = 6
nutriment_desc = list("warm soup" = 6)
center_of_mass = list("x"=16, "y"=5)
/obj/item/weapon/reagent_containers/food/snacks/chickennoodlesoup/Initialize()
. = ..()
reagents.add_reagent("protein", 4)
reagents.add_reagent("water", 5)
bitesize = 6
/obj/item/weapon/reagent_containers/food/snacks/chickennoodlesoup
name = "chicken noodle soup"
+7
View File
@@ -940,6 +940,13 @@ I said no!
/obj/item/weapon/reagent_containers/food/snacks/bun
)
result = /obj/item/weapon/reagent_containers/food/snacks/chickenfillet
/datum/recipe/chickennoodlesoup
fruit = list("carrot" = 1)
reagents = list("water" = 10)
items = list( /obj/item/weapon/reagent_containers/food/snacks/spagetti, /obj/item/weapon/reagent_containers/food/snacks/rawcutlet)
reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product
result = /obj/item/weapon/reagent_containers/food/snacks/chickennoodlesoup
/datum/recipe/chickennoodlesoup
fruit = list("carrot" = 1)
+2 -1
View File
@@ -343,7 +343,8 @@
H.update_icon()
src.update_icon()
usr.visible_message("<span class = 'notice'>\The [usr] plays \the [discarding].</span>")
H.loc = get_step(usr,usr.dir)
H.loc = get_turf(usr)
H.Move(get_step(usr,usr.dir))
if(!cards.len)
qdel(src)
+4 -1
View File
@@ -28,6 +28,7 @@
recipes += new/datum/stack_recipe("[display_name] fork", /obj/item/weapon/material/kitchen/utensil/fork/plastic, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("[display_name] knife", /obj/item/weapon/material/knife/plastic, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("[display_name] blade", /obj/item/weapon/material/butterflyblade, 6, time = 20, one_per_turf = 0, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("[display_name] defense wire", /obj/item/weapon/material/barbedwire, 10, time = 1 MINUTE, one_per_turf = 0, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE)
/datum/material/steel/generate_recipes()
..()
@@ -223,7 +224,7 @@
/datum/material/cloth/generate_recipes()
recipes = list()
recipes += new/datum/stack_recipe("woven net", /obj/item/weapon/material/fishing_net, 10, time = 30 SECONDS, pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("woven net", /obj/item/weapon/material/fishing_net, 10, time = 30 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]")
recipes += new/datum/stack_recipe("bedsheet", /obj/item/weapon/bedsheet, 10, time = 30 SECONDS, pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("uniform", /obj/item/clothing/under/color/white, 8, time = 15 SECONDS, pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("foot wraps", /obj/item/clothing/shoes/footwraps, 2, time = 5 SECONDS, pass_stack_color = TRUE)
@@ -238,6 +239,7 @@
recipes += new/datum/stack_recipe("baggy pants", /obj/item/clothing/under/pants/baggy/white, 8, time = 10 SECONDS, pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("belt pouch", /obj/item/weapon/storage/belt/fannypack/white, 25, time = 1 MINUTE, pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("crude bandage", /obj/item/stack/medical/crude_pack, 1, time = 2 SECONDS, pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("empty sandbag", /obj/item/stack/emptysandbag, 2, time = 2 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]")
/datum/material/resin/generate_recipes()
recipes = list()
@@ -270,4 +272,5 @@
recipes += new/datum/stack_recipe("[display_name] ring", /obj/item/clothing/gloves/ring/material, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("[display_name] bracelet", /obj/item/clothing/accessory/bracelet/material, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("[display_name] armor plate", /obj/item/weapon/material/armor_plating, 1, time = 20, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("empty sandbag", /obj/item/stack/emptysandbag, 2, time = 2 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]")
recipes += new/datum/stack_recipe("whip", /obj/item/weapon/material/whip, 5, time = 15 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]")
+13
View File
@@ -1010,6 +1010,19 @@ var/list/name_to_material
pass_stack_colors = TRUE
supply_conversion_value = 2
/datum/material/cloth/syncloth
name = "syncloth"
stack_origin_tech = list(TECH_MATERIAL = 3, TECH_BIO = 2)
door_icon_base = "wood"
ignition_point = T0C+532
melting_point = T0C+600
integrity = 200
protectiveness = 15 // 4%
flags = MATERIAL_PADDING
conductive = 0
pass_stack_colors = TRUE
supply_conversion_value = 3
/datum/material/cult
name = "cult"
display_name = "disturbing stone"
+11 -1
View File
@@ -426,4 +426,14 @@ the artifact triggers the rage.
heat_protection = -0.5
cold_protection = -0.5
siemens_coefficient = 1.5
siemens_coefficient = 1.5
/datum/modifier/entangled
name = "entangled"
desc = "Its hard to move."
on_created_text = "<span class='danger'>You're caught in something! It's hard to move.</span>"
on_expired_text = "<span class='warning'>Your movement is freed.</span>"
stacks = MODIFIER_STACK_EXTEND
slowdown = 2
@@ -1338,6 +1338,8 @@
if(!O.up)
found_welder = 1
if(!found_welder && nif && nif.flag_check(NIF_V_UVFILTER,NIF_FLAGS_VISION)) found_welder = 1 //VOREStation Add - NIF
if(istype(glasses, /obj/item/clothing/glasses/sunglasses/thinblindfold))
found_welder = 1
if(!found_welder && istype(head, /obj/item/clothing/head/welding))
var/obj/item/clothing/head/welding/O = head
if(!O.up)
@@ -58,8 +58,6 @@
base_color = "#f0f0f0"
color_mult = 1
inherent_verbs = list(/mob/living/proc/shred_limb)
has_glowing_eyes = TRUE
death_message = "phases to somewhere far away!"
@@ -70,7 +68,7 @@
speech_bubble_appearance = "ghost"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
virus_immune = 1
@@ -21,6 +21,8 @@
var/icon_height = 32
var/agility = 20 //prob() to do agile things
var/list/traits = list()
/datum/species/proc/update_attack_types()
unarmed_attacks = list()
for(var/u_type in unarmed_types)
@@ -44,3 +46,29 @@
nif.nifsofts = nifsofts
else
..()
/datum/species/proc/produceCopy(var/datum/species/to_copy,var/list/traits,var/mob/living/carbon/human/H)
ASSERT(to_copy)
ASSERT(istype(H))
if(ispath(to_copy))
to_copy = "[initial(to_copy.name)]"
if(istext(to_copy))
to_copy = GLOB.all_species[to_copy]
var/datum/species/new_copy = new to_copy.type()
new_copy.traits = traits
//If you had traits, apply them
if(new_copy.traits)
for(var/trait in new_copy.traits)
var/datum/trait/T = all_traits[trait]
T.apply(new_copy,H)
//Set up a mob
H.species = new_copy
if(H.dna)
H.dna.ready_dna(H)
return new_copy
@@ -50,10 +50,6 @@
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
inherent_verbs = list(
/mob/living/carbon/human/proc/succubus_drain,
/mob/living/carbon/human/proc/succubus_drain_finalize,
/mob/living/carbon/human/proc/succubus_drain_lethal,
/mob/living/carbon/human/proc/bloodsuck,
/mob/living/carbon/human/proc/alraune_fruit_select) //Give them the voremodes related to wrapping people in vines and sapping their fluids
color_mult = 1
@@ -451,7 +447,7 @@
//End of fruit gland code.
/datum/species/alraune/proc/produceCopy(var/datum/species/to_copy,var/list/traits,var/mob/living/carbon/human/H)
/datum/species/alraune/produceCopy(var/datum/species/to_copy,var/list/traits,var/mob/living/carbon/human/H)
ASSERT(to_copy)
ASSERT(istype(H))
@@ -477,6 +473,13 @@
new_copy.blood_mask = to_copy.blood_mask
new_copy.damage_mask = to_copy.damage_mask
new_copy.damage_overlays = to_copy.damage_overlays
new_copy.traits = traits
//If you had traits, apply them
if(new_copy.traits)
for(var/trait in new_copy.traits)
var/datum/trait/T = all_traits[trait]
T.apply(new_copy,H)
//Set up a mob
H.species = new_copy
@@ -32,13 +32,11 @@
num_alternate_languages = 3
assisted_langs = list(LANGUAGE_EAL, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
spawn_flags = SPECIES_CAN_JOIN
appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR
var/list/traits = list()
has_limbs = list(
BP_TORSO = list("path" = /obj/item/organ/external/chest, "descriptor" = "torso"),
BP_GROIN = list("path" = /obj/item/organ/external/groin, "descriptor" = "groin"),
@@ -60,7 +58,7 @@
var/datum/species/real = GLOB.all_species[base_species]
return real.race_key
/datum/species/custom/proc/produceCopy(var/datum/species/to_copy,var/list/traits,var/mob/living/carbon/human/H)
/datum/species/custom/produceCopy(var/datum/species/to_copy,var/list/traits,var/mob/living/carbon/human/H)
ASSERT(to_copy)
ASSERT(istype(H))
@@ -15,7 +15,7 @@
spawn_flags = SPECIES_CAN_JOIN
wikilink="https://wiki.vore-station.net/Promethean"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
color_mult = 1
mob_size = MOB_MEDIUM //As of writing, original was MOB_SMALL - Allows normal swapping
@@ -34,10 +34,5 @@
/mob/living/carbon/human/proc/shapeshifter_select_tail,
/mob/living/carbon/human/proc/shapeshifter_select_ears,
/mob/living/proc/set_size,
/mob/living/carbon/human/proc/succubus_drain,
/mob/living/carbon/human/proc/succubus_drain_finalize,
/mob/living/carbon/human/proc/succubus_drain_lethal,
/mob/living/carbon/human/proc/slime_feed,
/mob/living/proc/eat_trash,
/mob/living/carbon/human/proc/promethean_select_opaqueness,
)
@@ -62,7 +62,7 @@
siemens_coefficient = 1.5 //Very bad zappy times
rarity_value = 5
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
has_organ = list(
O_BRAIN = /obj/item/organ/internal/mmi_holder/posibrain/nano,
@@ -101,9 +101,7 @@
/mob/living/carbon/human/proc/shapeshifter_select_gender,
/mob/living/carbon/human/proc/shapeshifter_select_wings,
/mob/living/carbon/human/proc/shapeshifter_select_tail,
/mob/living/carbon/human/proc/shapeshifter_select_ears,
/mob/living/proc/eat_trash,
/mob/living/carbon/human/proc/slime_feed
/mob/living/carbon/human/proc/shapeshifter_select_ears
)
var/global/list/abilities = list()
@@ -25,12 +25,7 @@
inherent_verbs = list(
/mob/living/carbon/human/proc/reconstitute_form,
/mob/living/carbon/human/proc/sonar_ping,
/mob/living/carbon/human/proc/succubus_drain,
/mob/living/carbon/human/proc/succubus_drain_finalize,
/mob/living/carbon/human/proc/succubus_drain_lethal,
/mob/living/carbon/human/proc/bloodsuck,
/mob/living/carbon/human/proc/tie_hair,
/mob/living/proc/shred_limb,
/mob/living/proc/flying_toggle,
/mob/living/proc/start_wings_hovering) //Xenochimera get all the special verbs since they can't select traits.
@@ -60,7 +55,7 @@
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED | SPECIES_WHITELIST_SELECTABLE//Whitelisted as restricted is broken.
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
has_organ = list( //Same organ list as tajarans.
O_HEART = /obj/item/organ/internal/heart,
@@ -300,7 +295,7 @@
update_xenochimera_hud(H, danger, feral_state)
/datum/species/xenochimera/proc/produceCopy(var/datum/species/to_copy,var/list/traits,var/mob/living/carbon/human/H)
/datum/species/xenochimera/produceCopy(var/datum/species/to_copy,var/list/traits,var/mob/living/carbon/human/H)
ASSERT(to_copy)
ASSERT(istype(H))
@@ -326,6 +321,13 @@
new_copy.blood_mask = to_copy.blood_mask
new_copy.damage_mask = to_copy.damage_mask
new_copy.damage_overlays = to_copy.damage_overlays
new_copy.traits = traits
//If you had traits, apply them
if(new_copy.traits)
for(var/trait in new_copy.traits)
var/datum/trait/T = all_traits[trait]
T.apply(new_copy,H)
//Set up a mob
H.species = new_copy
@@ -411,7 +413,7 @@
spawn_flags = SPECIES_CAN_JOIN
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
flesh_color = "#AFA59E" //Gray-ish. Not sure if this is really needed, but eh.
base_color = "#333333" //Blackish-gray
@@ -472,14 +474,11 @@
spawn_flags = SPECIES_IS_RESTRICTED //SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED | SPECIES_WHITELIST_SELECTABLE CHOMPedit: disabled forever
appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_COLOR | HAS_EYE_COLOR
inherent_verbs = list(
/mob/living/proc/shred_limb,
/mob/living/proc/eat_trash)
flesh_color = "#AFA59E"
base_color = "#777777"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
heat_discomfort_strings = list(
"Your fur prickles in the heat.",
@@ -40,12 +40,11 @@
spawn_flags = SPECIES_CAN_JOIN
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
inherent_verbs = list(/mob/living/proc/shred_limb)
flesh_color = "#AFA59E"
base_color = "#777777"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
heat_discomfort_strings = list(
"Your fur prickles in the heat.",
@@ -84,7 +83,6 @@
secondary_langs = list(LANGUAGE_SKRELLIAN)
name_language = LANGUAGE_SKRELLIAN
color_mult = 1
inherent_verbs = list(/mob/living/proc/shred_limb)
assisted_langs = list(LANGUAGE_EAL, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
min_age = 18
@@ -108,7 +106,7 @@
primitive_form = "Sobaka"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
spawn_flags = SPECIES_CAN_JOIN
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
@@ -137,7 +135,7 @@
secondary_langs = list(LANGUAGE_BIRDSONG)
name_language = LANGUAGE_BIRDSONG
color_mult = 1
inherent_verbs = list(/mob/living/proc/shred_limb,/mob/living/proc/flying_toggle,/mob/living/proc/start_wings_hovering)
inherent_verbs = list(/mob/living/proc/flying_toggle,/mob/living/proc/start_wings_hovering)
min_age = 18
max_age = 110
@@ -158,7 +156,7 @@
primitive_form = "Sparra"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
spawn_flags = SPECIES_CAN_JOIN
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
@@ -213,7 +211,7 @@
blood_color = "#240bc4"
color_mult = 1
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
heat_discomfort_strings = list(
"Your fur prickles in the heat.",
@@ -239,7 +237,7 @@
// gluttonous = 1
num_alternate_languages = 3
color_mult = 1
inherent_verbs = list(/mob/living/proc/shred_limb, /mob/living/carbon/human/proc/lick_wounds)
inherent_verbs = list(/mob/living/carbon/human/proc/lick_wounds)
male_scream_sound = null //CHOMPedit
female_scream_sound = null //CHOMPedit
@@ -260,7 +258,7 @@
spawn_flags = SPECIES_CAN_JOIN
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
flesh_color = "#966464"
base_color = "#B43214"
@@ -278,7 +276,7 @@
min_age = 18
gluttonous = 0
inherent_verbs = list(/mob/living/proc/shred_limb)
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
descriptors = list()
//CHOMPSedit: link to our wiki
@@ -292,12 +290,12 @@
color_mult = 1
min_age = 18
gluttonous = 0 //Moving this here so I don't have to fix this conflict every time polaris glances at station.dm
inherent_verbs = list(/mob/living/proc/shred_limb, /mob/living/carbon/human/proc/lick_wounds)
inherent_verbs = list(/mob/living/carbon/human/proc/lick_wounds)
heat_discomfort_level = 295 //Prevents heat discomfort spam at 20c
//CHOMPSedit: links to our wiki
wikilink="https://wiki.chompstation13.net/index.php?title=Tajaran"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
agility = 90
/datum/species/skrell
@@ -311,13 +309,13 @@
//CHOMPedit: link to our wiki
wikilink="https://wiki.chompstation13.net/index.php?title=Skrell"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
/datum/species/zaddat
spawn_flags = SPECIES_CAN_JOIN
min_age = 18
gluttonous = 0
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
descriptors = list()
//CHOMPedit: link to our wiki
@@ -336,7 +334,7 @@
min_age = 18
//CHOMPedit: link to our wiki
wikilink="https://wiki.chompstation13.net/index.php?title=Diona"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
/datum/species/teshari
mob_size = MOB_SMALL //YW Edit: changed from MOB_MEDIUM to MOB_SMALL
@@ -349,7 +347,7 @@
push_flags = ~HEAVY //Allows them to use micro step code.
swap_flags = ~HEAVY
gluttonous = 0
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
descriptors = list()
//CHOMPedit: link to our wiki
@@ -359,7 +357,6 @@
inherent_verbs = list(
/mob/living/carbon/human/proc/sonar_ping,
/mob/living/proc/hide,
/mob/living/proc/shred_limb,
/mob/living/proc/toggle_pass_table
)
@@ -374,7 +371,7 @@
deform = 'icons/mob/human_races/r_def_human_vr.dmi'
appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR
min_age = 18
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
base_color = "#EECEB3"
//CHOMPedit: link to our wiki
@@ -389,7 +386,6 @@
min_age = 18
icobase = 'icons/mob/human_races/r_vox_old.dmi'
deform = 'icons/mob/human_races/r_def_vox_old.dmi'
inherent_verbs = list(/mob/living/proc/shred_limb, /mob/living/proc/eat_trash)
descriptors = list(
/datum/mob_descriptor/vox_markings = 0
)
@@ -409,7 +405,7 @@ datum/species/harpy
secondary_langs = list(LANGUAGE_BIRDSONG)
name_language = null
color_mult = 1
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
inherent_verbs = list(/mob/living/proc/flying_toggle,/mob/living/proc/start_wings_hovering)
min_age = 18
@@ -503,8 +499,6 @@ datum/species/harpy
base_color = "#f0f0f0"
color_mult = 1
inherent_verbs = list(/mob/living/proc/shred_limb)
has_glowing_eyes = TRUE
male_cough_sounds = null
@@ -514,7 +508,7 @@ datum/species/harpy
speech_bubble_appearance = "ghost"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
breath_type = null
poison_type = null
@@ -578,7 +572,7 @@ datum/species/harpy
//primitive_form = "" //We don't have fennec-monkey sprites.
spawn_flags = SPECIES_IS_RESTRICTED
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
flesh_color = "#AFA59E"
base_color = "#333333"
@@ -621,7 +615,7 @@ datum/species/harpy
spawn_flags = SPECIES_IS_RESTRICTED
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
blood_color = "#12ff12"
flesh_color = "#201730"
@@ -632,4 +626,3 @@ datum/species/harpy
"You feel uncomfortably warm.",
"Your chitin feels hot."
)
inherent_verbs = list(/mob/living/proc/shred_limb)
@@ -72,7 +72,7 @@
cost = 0
var_changes = list("cold_level_1" = 200, "cold_level_2" = 150, "cold_level_3" = 90, "breath_cold_level_1" = 180, "breath_cold_level_2" = 100, "breath_cold_level_3" = 60, "cold_discomfort_level" = 210, "heat_level_1" = 305, "heat_level_2" = 360, "heat_level_3" = 700, "breath_heat_level_1" = 345, "breath_heat_level_2" = 380, "breath_heat_level_3" = 780, "heat_discomfort_level" = 295, "body_temperature" = 290)
excludes = list(/datum/trait/hotadapt)
/datum/trait/hotadapt
name = "Heat-Adapted"
desc = "You are able to withstand much hotter temperatures than other species, and can even be comfortable in extremely hot environments. You are also more vulnerable to cold environments, and have a higher body temperature as a consequence of these adaptations."
@@ -128,6 +128,7 @@ YW change end */
name = "Minor Bloodsucker"
desc = "Makes you unable to gain nutrition from anything but blood. To compensate, you get fangs that can be used to drain blood from prey."
cost = 0
custom_only = FALSE
var_changes = list("gets_food_nutrition" = 0) //The verb is given in human.dm
excludes = list(/datum/trait/bloodsucker_plus)
@@ -139,6 +140,7 @@ YW change end */
name = "Succubus Drain"
desc = "Makes you able to gain nutrition from draining prey in your grasp."
cost = 0
custom_only = FALSE
/datum/trait/succubus_drain/apply(var/datum/species/S,var/mob/living/carbon/human/H)
..(S,H)
@@ -150,6 +152,7 @@ YW change end */
name = "Feeder"
desc = "Allows you to feed your prey using your own body."
cost = 0
custom_only = FALSE
/datum/trait/feeder/apply(var/datum/species/S,var/mob/living/carbon/human/H)
..(S,H)
@@ -159,6 +162,7 @@ YW change end */
name = "Hard Vore" //CHOMPedit Renamed Brutal Predation to Hard Vore, because some people don't know what this actually does
desc = "Allows you to tear off limbs & tear out internal organs."
cost = 0
custom_only = FALSE
/datum/trait/hard_vore/apply(var/datum/species/S,var/mob/living/carbon/human/H)
..(S,H)
@@ -168,6 +172,7 @@ YW change end */
name = "Trash Can"
desc = "Allows you to dispose of some garbage on the go instead of having to look for a bin or littering like an animal."
cost = 0
custom_only = FALSE
var_changes = list("trashcan" = 1)
/datum/trait/trashcan/apply(var/datum/species/S,var/mob/living/carbon/human/H)
@@ -178,6 +183,7 @@ YW change end */
name = "Expensive Taste"
desc = "You only gain nutrition from raw ore and refined minerals. There's nothing that sates the appetite better than precious gems, exotic or rare minerals and you have damn fine taste. Anything else is beneath you."
cost = 0
custom_only = FALSE
var_changes = list("gets_food_nutrition" = 0, "eat_minerals" = 1)
/datum/trait/gem_eater/apply(var/datum/species/S,var/mob/living/carbon/human/H)
@@ -188,12 +194,14 @@ YW change end */
name = "Glowing Eyes"
desc = "Your eyes show up above darkness. SPOOKY! And kinda edgey too."
cost = 0
custom_only = FALSE
var_changes = list("has_glowing_eyes" = 1)
/datum/trait/glowing_body
name = "Glowing Body"
desc = "Your body glows about as much as a PDA light! Settable color and toggle in Abilities tab ingame."
cost = 0
custom_only = FALSE
/datum/trait/glowing_body/apply(var/datum/species/S,var/mob/living/carbon/human/H)
..(S,H)
@@ -205,36 +213,42 @@ YW change end */
name = "Extreme Spice Intolerance"
desc = "Spicy (and chilly) peppers are three times as strong. (This does not affect pepperspray.)"
cost = 0
custom_only = FALSE
var_changes = list("spice_mod" = 3) // 300% as effective if spice_mod is set to 1. If it's not 1 in species.dm, update this!
/datum/trait/spice_intolerance_basic
name = "Heavy Spice Intolerance"
desc = "Spicy (and chilly) peppers are twice as strong. (This does not affect pepperspray.)"
cost = 0
custom_only = FALSE
var_changes = list("spice_mod" = 2) // 200% as effective if spice_mod is set to 1. If it's not 1 in species.dm, update this!
/datum/trait/spice_intolerance_slight
name = "Slight Spice Intolerance"
desc = "You have a slight struggle with spicy foods. Spicy (and chilly) peppers are one and a half times stronger. (This does not affect pepperspray.)"
cost = 0
custom_only = FALSE
var_changes = list("spice_mod" = 1.5) // 150% as effective if spice_mod is set to 1. If it's not 1 in species.dm, update this!
/datum/trait/spice_tolerance_basic
name = "Spice Tolerance"
desc = "Spicy (and chilly) peppers are only three-quarters as strong. (This does not affect pepperspray.)"
cost = 0
custom_only = FALSE
var_changes = list("spice_mod" = 0.75) // 75% as effective if spice_mod is set to 1. If it's not 1 in species.dm, update this!
/datum/trait/spice_tolerance_advanced
name = "Strong Spice Tolerance"
desc = "Spicy (and chilly) peppers are only half as strong. (This does not affect pepperspray.)"
cost = 0
custom_only = FALSE
var_changes = list("spice_mod" = 0.5) // 50% as effective if spice_mod is set to 1. If it's not 1 in species.dm, update this!
/datum/trait/spice_immunity
name = "Extreme Spice Tolerance"
desc = "Spicy (and chilly) peppers are basically ineffective! (This does not affect pepperspray.)"
cost = 0
custom_only = FALSE
var_changes = list("spice_mod" = 0.25) // 25% as effective if spice_mod is set to 1. If it's not 1 in species.dm, update this!
/*YW CHANGE START: Commented out because we got our own variants
@@ -243,36 +257,42 @@ YW change end */
name = "Liver of Air"
desc = "The only way you can hold a drink is if it's in your own two hands, and even then you'd best not inhale too deeply near it. Drinks are three times as strong."
cost = 0
custom_only = FALSE
var_changes = list("alcohol_mod" = 3) // 300% as effective if alcohol_mod is set to 1. If it's not 1 in species.dm, update this!
/datum/trait/alcohol_intolerance_basic
name = "Liver of Lilies"
desc = "You have a hard time with alcohol. Maybe you just never took to it, or maybe it doesn't agree with you... either way, drinks are twice as strong."
cost = 0
custom_only = FALSE
var_changes = list("alcohol_mod" = 2) // 200% as effective if alcohol_mod is set to 1. If it's not 1 in species.dm, update this!
/datum/trait/alcohol_intolerance_slight
name = "Liver of Tulips"
desc = "You have a slight struggle with alcohol. Drinks are one and a half times stronger."
cost = 0
custom_only = FALSE
var_changes = list("alcohol_mod" = 1.5) // 150% as effective if alcohol_mod is set to 1. If it's not 1 in species.dm, update this!
/datum/trait/alcohol_tolerance_basic
name = "Liver of Iron"
desc = "You can hold drinks much better than those lily-livered land-lubbers! Arr! Drinks are only three-quarters as strong."
cost = 0
custom_only = FALSE
var_changes = list("alcohol_mod" = 0.75) // 75% as effective if alcohol_mod is set to 1. If it's not 1 in species.dm, update this!
/datum/trait/alcohol_tolerance_advanced
name = "Liver of Steel"
desc = "Drinks tremble before your might! You can hold your alcohol twice as well as those blue-bellied barnacle boilers! Drinks are only half as strong."
cost = 0
custom_only = FALSE
var_changes = list("alcohol_mod" = 0.5) // 50% as effective if alcohol_mod is set to 1. If it's not 1 in species.dm, update this!
/datum/trait/alcohol_immunity
name = "Liver of Durasteel"
desc = "You've drunk so much that most booze doesn't even faze you. It takes something like a Pan-Galactic or a pint of Deathbell for you to even get slightly buzzed."
cost = 0
custom_only = FALSE
var_changes = list("alcohol_mod" = 0.25) // 25% as effective if alcohol_mod is set to 1. If it's not 1 in species.dm, update this!
// Alcohol Traits End Here.
YW CHANGE STOP*/
@@ -5,7 +5,8 @@
var/cost = 0 // 0 is neutral, negative cost means negative, positive cost means positive.
var/list/var_changes // A list to apply to the custom species vars.
var/list/excludes // Store a list of paths of traits to exclude, but done automatically if they change the same vars.
var/not_for_synths = 0 // Can freaking synths use those.
var/not_for_synths = FALSE // Can freaking synths use those.
var/custom_only = TRUE // Trait only available for custom species
//Proc can be overridden lower to include special changes, make sure to call up though for the vars changes
/datum/trait/proc/apply(var/datum/species/S,var/mob/living/carbon/human/H)
@@ -0,0 +1,64 @@
//The chad Drone unify code rewritten to fit into this current codebase, god here we go
// LAWS
/******************** Drone fucking duh ********************/
/datum/ai_laws/jani_drone
name = "Maintence Protocols"
law_header = "Maintenance Protocols"
/datum/ai_laws/drone/New()
add_inherent_law("Do not interfere with the maintenance work of non-drones whenever possible.")
add_inherent_law("Preserve, repair and improve the station to the best of your abilities.")
add_inherent_law("Cause no harm to the station or any crew on it.")
..()
/datum/ai_laws/construction_drone
name = "Construction Protocols"
law_header = "Construction Protocols"
/datum/ai_laws/construction_drone/New()
add_inherent_law("Do not interfere with the construction work of non-drones whenever possible.")
add_inherent_law("Repair, refit and upgrade your assigned vessel.")
add_inherent_law("Prevent unplanned damage to your assigned vessel wherever possible.")
..()
/datum/ai_laws/mining_drone
name = "Excavation Protocols"
law_header = "Excavation Protocols"
/datum/ai_laws/mining_drone/New()
add_inherent_law("Do not interfere with the excavation work of non-drones whenever possible.")
add_inherent_law("Provide materials for repairing, refitting, and upgrading your assigned vessel.")
add_inherent_law("Prevent unplanned damage to your assigned excavation equipment wherever possible.")
..()
/datum/ai_laws/security_drone
name = "Security Protocols"
law_header = "Security Protocols"
/datum/ai_laws/security_drone/New()
add_inherent_law("Do not interfere with the security work of non-drones whenever possible.")
add_inherent_law("Provide protection to the crew and eliminate hostile lifeforms on your assigned vessel.")
add_inherent_law("Obey orders by security personnel except if they violate law 4.")
add_inherent_law("Lethal force requires a code higher than green AND orders by security to use it to authorize it.")
add_inherent_law("You must outfit yourself with a security beret.")
..()
//Alright lets take a look at the the scary base drone from dorne DM and mod that shit
/mob/living/silicon/robot/drone
name = "unified drone" //Maintenance drones can be a Jani specific shell now, the normal drone will be a blank shell not really intended for use
law_type = /datum/ai_laws/drone
/mob/living/silicon/robot/drone/jan
name = "maintenance drone"
law_type = /datum/ai_laws/jani_drone
/mob/living/silicon/robot/drone/sec
name = "security drone"
law_type = /datum/ai_laws/security_drone
/mob/living/silicon/robot/drone/min
name = "mining drone"
law_type = /datum/ai_laws/mining_drone
@@ -37,6 +37,12 @@
src.modules += new /obj/item/weapon/pinpointer/shuttle/merc(src)
src.modules += new /obj/item/weapon/melee/energy/sword(src)
var/datum/matter_synth/cloth = new /datum/matter_synth/cloth(40000)
synths += cloth
var/obj/item/stack/sandbags/cyborg/SB = new /obj/item/stack/sandbags/cyborg(src)
SB.synths += list(cloth)
var/jetpack = new/obj/item/weapon/tank/jetpack/carbondioxide(src)
src.modules += jetpack
R.internals = jetpack
@@ -1,7 +1,8 @@
/mob/living/simple_mob/vore/leopardmander
name = "leopardmander"
desc = "A huge salamander-like drake. They are best known for their rarity, their voracity, their very potent paralyzing venom, and their healing stomach. This one is white."
tt_desc = "Draconis Va'aen"
catalogue_data = list(/datum/category_item/catalogue/fauna/leopardmander)
tt_desc = "S Draconis uncia"
icon = 'icons/mob/vore128x64_ch.dmi'
icon_dead = "leopardmander-dead"
icon_living = "leopardmander"
@@ -159,7 +159,7 @@ GLOBAL_LIST_INIT(pitcher_plant_lure_messages, list(
return
if(fruit)
if(nutrition >= PITCHER_SATED + NUTRITION_PITCHER)
var/turf/T = safepick(circleviewturfs(src, 2)) //Try this if the above doesn't work, add src.loc == T check to density check
var/turf/T = safepick(circleviewturfs(src, 2))
if(T.density) //No spawning in walls
return
else if(src.loc ==T)
@@ -0,0 +1,255 @@
//Passive vore slug. This mob is intended to be annoying but harmless to anybody it can't eat.
/mob/living/simple_mob/vore/slug
name = "slug"
desc = "A giant, cold-tolerant slug. It seems excessively passive."
catalogue_data = list(/datum/category_item/catalogue/fauna/slug)
tt_desc = "S Arion hortensis"
icon = 'icons/mob/vore_ch.dmi'
icon_dead = "slug-dead"
icon_living = "slug"
icon_state = "slug"
faction = "slug" //A faction other than neutral is necessary to get the slug to try eating station crew.
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
melee_damage_lower = 0
melee_damage_upper = 1 //Not intended to pose any sort of threat outside of vore. Other code should stop it from ever attacking but this is an extra safety check.
friendly = list("blinks at")
response_help = "pokes"
response_disarm = "prods"
response_harm = "punches"
movement_cooldown = 40 //I guess you could call this a SNAIL'S PACE.
maxHealth = 500
health = 500
attacktext = list("headbutted")
minbodytemp = 80
ai_holder_type = /datum/ai_holder/simple_mob/passive/slug_ch
vore_icons = SA_ICON_LIVING
armor = list(
"melee" = 98,
"bullet" = 0,
"laser" = -50,
"energy" = -50,
"bomb" = 0,
"bio" = 0,
"rad" = 100) //Relatively harmless but agonizing to kill with melee.
glow_toggle = TRUE
glow_range = 1.3 //This seems to be the minimum range which makes glow visible.
glow_color = "#33ccff" //Same glow color as Sif trees.
glow_intensity = 1
var/list/my_slime = list()
var/slime_max = 35 //With a slug which moves once every 10 seconds and a 5 minute delete timer, this should never exceed 30.
var/mob/living/vore_memory = null
/mob/living/simple_mob/vore/slug //I guess separating the vore variables is a little more organized?
vore_bump_chance = 100 //Always attempt a bump nom if possible...
vore_bump_emote = "knocks over and begins slowly engulfing"
vore_active = 1
vore_icons = 1
vore_capacity = 1
vore_pounce_chance = 100 //...while this should make bump noms always knock the target over. Passive AI meanwhile should mean this never affects combat since it doesn't fight back.
vore_ignores_undigestable = 0
swallowTime = 100 //10 seconds. Easy to crawl away from when knocked over.
vore_default_mode = DM_DIGEST
/mob/living/simple_mob/vore/slug/init_vore()
..()
var/obj/belly/B = vore_selected
B.desc = "Somehow you remained still just long enough for the slug to wrap its radula around your body and gradually draw you into its pharynx. The slug moves with agonizing slowness and devours prey at a snail's pace; inch by inch you're crammed down its gullet and squishes and squeezed into the slug's gizzard. Thick walls bear down, covered with shallow, toothy ridges. The slimy moss in here suggests you're not the slug's diet but the gizzard seems intent on churning and scraping over you regardless..."
B.digest_burn = 0.1
B.digest_brute = 0.2
B.vore_verb = "engulf"
B.name = "gizzard"
B.mode_flags = DM_FLAG_THICKBELLY
B.escapechance = 5
B.fancy_vore = 1
B.vore_sound = "Squish2"
B.release_sound = "Pred Escape"
B.contamination_color = "cyan"
B.contamination_flavor = "Wet"
B.emote_lists[DM_DIGEST] = list(
"The toothy walls scrape and grind against your body.",
"The humid air feels thick and heavy, stinging faintly with each breath.",
"Heavy slime oozes over you, making it difficult to move."
) //Why do so many vore mobs have endo emotes despite being digest only?
/datum/category_item/catalogue/fauna/slug
name = "Sivian Fauna - Moss Slug"
desc = "Classification: S Arion hortensis\
<br><br>\
A large herbivorous slug commonly spotted near northern waterways with abundant moss. The slug is remarkably resistant to blunt trauma despite its fleshy body due to a foul-tasting outer casing \
of thick, mucus-filled tissue protecting the more vulnerable musculature beneath. Said mucus is a natural irritant and hardens rapidly in contact with air, sealing wounds and allowing the slug to shrug off most surface injuries. \
Few predators exist for the Sivian slug due to the stinging slime's tendency to adhere to attacking claws and appendages.\
<br><br>\
The Sivian slug is typically regarded as a pest due to the animal's large bulk and tendency to crush weak structures in its path. Most tools do little to dissuade the creature, forcing homesteads to rely on firearms or reinforced fencing \
with a slippery coating the slug cannot stick to. While subsisting primarily on Sivian moss, the slug is an opportunistic predator known to eat small fauna which wander into its path. The slime excreted from the slug's foot is particularly sticky and capable of miring small animals. The Sivian slug glows faintly due to colonies bioluminescent bacteria present in its diet."
value = CATALOGUER_REWARD_EASY
/mob/living/simple_mob/vore/slug/proc/spread_slime()
if(my_slime.len >= slime_max)
return
if(istype(get_turf(src), /turf/simulated/floor/water)) //Important to stop my_slime from filling with null entries in water.
return
var/obj/effect/slug_glue/G = new /obj/effect/slug_glue/(get_turf(src))
G.my_slug = src
my_slime += G
/mob/living/simple_mob/vore/slug/death()
..()
for(var/obj/effect/slug_glue/G in my_slime)
G.my_slug = null
my_slime -= G //No point in keeping these loaded in the list when the slug dies if somehow the list sticks around after death.
/mob/living/simple_mob/vore/slug/Moved()
. = ..()
spread_slime()
/mob/living/simple_mob/vore/slug/do_attack(atom/A, turf/T) //Override of attack proc to ensure the slug can only attempt to eat people, not harm them. Inability to actually hurt anybody is intended, otherwise this mob wouldn't have 98 melee armor.
if(ckey) //If we're player controlled, use the default attack code.
return ..()
if(istype(A, /mob/living) && !will_eat(A))
ai_holder.lose_target() //Ignore anybody we can't eat.
return
else //This is the parent do_attack() code for determining whether or not attacks can hit.
face_atom(A)
var/missed = FALSE
if(!isturf(A) && !(A in T) ) // Turfs don't contain themselves so checking contents is pointless if we're targeting a turf.
missed = TRUE
else if(!T.AdjacentQuick(src))
missed = TRUE
if(missed) // Most likely we have a slow attack and they dodged it or we somehow got moved.
add_attack_logs(src, A, "Animal-attacked (dodged)", admin_notify = FALSE)
playsound(src, 'sound/rakshasa/Decay1.ogg', 75, 1)
visible_message(span("warning", "\The [src] misses."))
return FALSE
tryBumpNom(A) //Meant for bump noms but this works as intended here and has sanity checks.
/mob/living/simple_mob/vore/slug/perform_the_nom(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly, delay)
..()
vore_memory = prey
/datum/ai_holder/simple_mob/passive/slug_ch
wander = TRUE
base_wander_delay = 7
wander_when_pulled = TRUE
vision_range = 10
can_flee = FALSE //Otherwise it'll run as soon as it gets a target.
/obj/effect/slug_glue
name = "liquid"
desc = "This looks wet."
icon = 'icons/effects/effects_ch.dmi'
icon_state = "wet_turf"
opacity = 0
mouse_opacity = 0 //Unclickable
anchored = 1
density = 0
can_buckle = 1
buckle_lying = TRUE
var/persist_time = 5 MINUTES //How long until we cease existing.
var/mob/living/simple_mob/vore/slug/my_slug = null //This should be set by the slug.
var/turf/my_turf = null //The turf we spawn on.
var/base_escape_time = 1 MINUTE //How long does it take to struggle free? Affected by the victim's size_multiplier.
/obj/effect/slug_glue/New()
..()
dissipate()
my_turf = get_turf(src)
if(istype(my_turf, /turf/simulated/floor/water)) //Aside from not making sense in water, this prevents drowning.
qdel(src)
/* for(var/obj/effect/slug_glue/G in my_turf.contents)
if(G == src)
continue
else
qdel(G) //Prevent glue layering
*/ //Not including this due to performance concerns but keeping as comments for reference.
/obj/effect/slug_glue/proc/dissipate() //When spawned, set a timer to despawn.
if(!persist_time)
qdel(src)
return
else
spawn(persist_time) //I used sleep() here first and it made the slug sleep for 5 minutes when spawning glue. Byond.
qdel(src)
return
/obj/effect/slug_glue/Destroy()
. = ..()
if(my_slug)
my_slug.my_slime -= src //Remove the slime from the slug's list when destroyed.
//This could probably be applied to spideweb code to make it work as intended again.
/obj/effect/slug_glue/Uncross(atom/movable/AM, atom/newloc)
if(istype(AM, /mob/living/simple_mob/vore/slug))
return ..()
else if(istype(AM, /mob/living))
if(prob(50))
to_chat(AM, span("warning", "You stick to \the [my_turf]!"))
return FALSE
return ..()
/obj/effect/slug_glue/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(istype(AM, /mob/living))
var/mob/living/L = AM
if(istype(L, /mob/living/simple_mob/vore/slug))
return
if(L.m_intent == "run" && !L.buckled)
if(has_buckled_mobs())
return
buckle_mob(L)
L.stop_pulling()
L.Weaken(2)
to_chat(L, "<span class='warning'>You tripped in the sticky substance, sticking to [my_turf]!</span>")
playsound(src, 'sound/rakshasa/Decay3.ogg', 100, 1)
alert_slug(L)
/obj/effect/slug_glue/proc/alert_slug(mob/living/victim as mob)
if(!my_slug || !has_buckled_mobs() || isbelly(my_slug.loc)) //Otherwise if you eat the slug it will infinitely attempt to eat you if you trip in glue.
return
if(my_slug.vore_memory == victim) //Getting eaten lets you get stuck once without alerting the slug. This is to prevent instantly getting eaten again if you struggle free with run intent on.
my_slug.vore_memory = null
return
my_slug.ai_holder.give_target(victim)
/obj/effect/slug_glue/proc/unalert_slug(mob/living/victim as mob)
if(!my_slug)
return
if(my_slug.ai_holder.target == victim)
my_slug.ai_holder.remove_target() //Instant loss of target. Necessary to simulate the mob giving up if the prey escapes.
/obj/effect/slug_glue/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
user.setClickCooldown(user.get_attack_speed())
to_chat(user, "You tug and strain against the sticky substance...")
var/escape_time
switch(buckled_mob.size_multiplier)
if(RESIZE_TINY - 1 to RESIZE_A_NORMALSMALL) //24% to 75% size scale, 1% below 25% is to account for microcillin sometimes going slightly below 25%
escape_time = 2 * base_escape_time
if(RESIZE_A_NORMALSMALL to RESIZE_A_BIGNORMAL) //75% to 125% size scale
escape_time = base_escape_time
if(RESIZE_A_BIGNORMAL to RESIZE_HUGE + 1) //125% to 201% size scale, 1% above 200% is to acount for macrocillin sometimes going slightly above 200%
escape_time = 0.5 * base_escape_time
else
escape_time = base_escape_time //Admeme size scale
if(do_after(user, escape_time, src, incapacitation_flags = INCAPACITATION_DEFAULT & ~(INCAPACITATION_RESTRAINED | INCAPACITATION_BUCKLED_FULLY)))
if(!has_buckled_mobs())
return
to_chat(user, "You tug free of the tacky, rubbery strands!")
unbuckle_mob(buckled_mob)
unalert_slug(buckled_mob)
/obj/effect/slug_glue/clean_blood(var/ignore = 0) //Remove with space cleaner.
if(!ignore)
qdel(src)
return
..()
@@ -0,0 +1,74 @@
/obj/item/weapon/cell/spike
name = "modified power cell"
desc = "A modified power cell sitting in a highly conductive chassis."
origin_tech = list(TECH_POWER = 2)
icon_state = "spikecell"
maxcharge = 10000
matter = list(DEFAULT_WALL_MATERIAL = 1000, MAT_GLASS = 80, MAT_SILVER = 100)
self_recharge = TRUE
charge_amount = 150
/obj/item/weapon/cell/spike/process()
..()
var/turf/Center = get_turf(src)
var/shock_count = 0
for(var/turf/T in range(Center, 1))
if(prob(round(charge / 250)) && charge >= (maxcharge / 4))
if(locate(/obj/effect/temporary_effect/pulse/staticshock) in T)
continue
var/conductive = FALSE
if(istype(T, /turf/simulated/wall))
var/turf/simulated/wall/WT = T
if(WT.material.conductive)
conductive = TRUE
else if(WT.girder_material.conductive)
conductive = TRUE
else if(WT.reinf_material && WT.reinf_material.conductive)
conductive = TRUE
if(istype(T, /turf/simulated/floor))
var/turf/simulated/floor/F = T
if(istype(F.flooring, /decl/flooring/reinforced))
conductive = TRUE
if(conductive)
shock_count += 1
new /obj/effect/temporary_effect/pulse/staticshock(T)
if(shock_count)
while(shock_count)
use(200)
shock_count--
/obj/effect/temporary_effect/pulse/staticshock
name = "electric field"
desc = "Caution: Do not touch."
pulses_remaining = 10
pulse_delay = 2 SECONDS
icon_state = "blue_static"
/obj/effect/temporary_effect/pulse/staticshock/on_pulse()
..()
for(var/mob/living/L in view(1, src))
if(!issilicon(L) && prob(L.mob_size))
var/obj/item/projectile/beam/shock/weak/P = new (get_turf(src))
P.launch_projectile_from_turf(L, BP_TORSO)
var/obj/item/weapon/plastique/C4 = locate() in get_turf(src)
if(C4)
C4.visible_message("<span class='danger'>The current fries \the [C4]!</span>")
if(prob(10))
C4.explode(get_turf(src))
else
qdel(C4)
@@ -261,3 +261,7 @@
agony = 15
eyeblur = 2
hitsound = 'sound/weapons/zapbang.ogg'
/obj/item/projectile/beam/shock/weak
damage = 5
agony = 10
+1 -1
View File
@@ -43,7 +43,7 @@
//Actual full digest modes
var/tmp/static/list/digest_modes = list(DM_HOLD,DM_DIGEST,DM_ABSORB,DM_DRAIN,DM_UNABSORB,DM_HEAL,DM_SHRINK,DM_GROW,DM_SIZE_STEAL,DM_EGG)
//Digest mode addon flags
var/tmp/static/list/mode_flag_list = list("Numbing" = DM_FLAG_NUMBING, "Stripping" = DM_FLAG_STRIPPING, "Leave Remains" = DM_FLAG_LEAVEREMAINS, "Muffles" = DM_FLAG_THICKBELLY)
var/tmp/static/list/mode_flag_list = list("Numbing" = DM_FLAG_NUMBING, "Stripping" = DM_FLAG_STRIPPING, "Leave Remains" = DM_FLAG_LEAVEREMAINS, "Muffles" = DM_FLAG_THICKBELLY, "Affect Worn Items" = DM_FLAG_AFFECTWORN)
//Item related modes
var/tmp/static/list/item_digest_modes = list(IM_HOLD,IM_DIGEST_FOOD,IM_DIGEST)
+10
View File
@@ -138,6 +138,16 @@
if((mode_flags & DM_FLAG_THICKBELLY) && !H.muffled)
H.muffled = TRUE
//Worn items flag
if(mode_flags & DM_FLAG_AFFECTWORN)
for(var/slot in slots)
var/obj/item/I = H.get_equipped_item(slot = slot)
if(I && I.canremove)
if(handle_digesting_item(I))
digestion_noise_chance = 25
to_update = TRUE
break
//Stripping flag
if(mode_flags & DM_FLAG_STRIPPING)
for(var/slot in slots)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 KiB

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 466 B

After

Width:  |  Height:  |  Size: 948 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

+6
View File
@@ -1166,6 +1166,7 @@
#include "code\game\objects\items\pizza_voucher_vr.dm"
#include "code\game\objects\items\poi_items.dm"
#include "code\game\objects\items\robobag.dm"
#include "code\game\objects\items\sahoc_ch.dm"
#include "code\game\objects\items\shooting_range.dm"
#include "code\game\objects\items\surplus_voucher_ch.dm"
#include "code\game\objects\items\tailoring.dm"
@@ -1249,6 +1250,7 @@
#include "code\game\objects\items\stacks\nanopaste.dm"
#include "code\game\objects\items\stacks\nanopaste_vr.dm"
#include "code\game\objects\items\stacks\rods.dm"
#include "code\game\objects\items\stacks\sandbags.dm"
#include "code\game\objects\items\stacks\stack.dm"
#include "code\game\objects\items\stacks\telecrystal.dm"
#include "code\game\objects\items\stacks\tickets.dm"
@@ -1463,6 +1465,7 @@
#include "code\game\objects\random\mob_vr.dm"
#include "code\game\objects\random\spacesuits.dm"
#include "code\game\objects\random\unidentified\medicine.dm"
#include "code\game\objects\structures\barricades.dm"
#include "code\game\objects\structures\barsign.dm"
#include "code\game\objects\structures\bedsheet_bin.dm"
#include "code\game\objects\structures\bedsheet_bin_vr.dm"
@@ -2878,6 +2881,7 @@
#include "code\modules\mob\living\silicon\robot\drone\swarm.dm"
#include "code\modules\mob\living\silicon\robot\drone\swarm_abilities.dm"
#include "code\modules\mob\living\silicon\robot\drone\swarm_items.dm"
#include "code\modules\mob\living\silicon\robot\drone\zzz_unify_drone.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules\event.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules\event_vr.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules\station.dm"
@@ -3080,6 +3084,7 @@
#include "code\modules\mob\living\simple_mob\subtypes\vore\rat_ch.dm"
#include "code\modules\mob\living\simple_mob\subtypes\vore\redpanda.dm"
#include "code\modules\mob\living\simple_mob\subtypes\vore\sect_queen.dm"
#include "code\modules\mob\living\simple_mob\subtypes\vore\slug_ch.dm"
#include "code\modules\mob\living\simple_mob\subtypes\vore\snake.dm"
#include "code\modules\mob\living\simple_mob\subtypes\vore\softdog.dm"
#include "code\modules\mob\living\simple_mob\subtypes\vore\solargrub.dm"
@@ -3410,6 +3415,7 @@
#include "code\modules\power\antimatter\shielding.dm"
#include "code\modules\power\cells\device_cells.dm"
#include "code\modules\power\cells\device_cells_vr.dm"
#include "code\modules\power\cells\esoteric_cells.dm"
#include "code\modules\power\cells\power_cells.dm"
#include "code\modules\power\fusion\_setup.dm"
#include "code\modules\power\fusion\fusion_circuits.dm"