This commit is contained in:
izac112
2021-01-25 16:47:15 +01:00
126 changed files with 13257 additions and 9472 deletions
+39
View File
@@ -0,0 +1,39 @@
name: Autochangelog
on:
pull_request:
types: closed
branches:
- master
env:
BASENAME: "polaris"
jobs:
autochangelog:
name: Autochangelog
runs-on: ubuntu-16.04
if: github.event.pull_request.merged == true
steps:
- uses: /actions/checkout@v2
- name: Ensure +x on CI directory
run: |
chmod -R +x ./tools/ci
- uses: actions/setup-python@v2
with:
python-version: '3.7'
- name: Generate Changelog
run: |
pip install pyyaml
python tools/GenerateChangelog/ss13_autochangelog.py \
html/changelogs \
${{ github.event.pull_request.number }} \
"${{ github.event.pull_request.user.login }}" \
"${{ github.event.pull_request.body }}"
python tools/GenerateChangelog/ss13_genchangelog.py \
html/changelog.html \
html/changelogs
- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: Automatic changelog generation for ${{ github.events.pull_request.number }}
branch: ${{ github.events.pull_request.base }}
commit_user_name: Autochangelog Bot
-14
View File
@@ -9,25 +9,11 @@
#define DM_SIZE_STEAL "Size Steal"
#define DM_HEAL "Heal"
#define DM_EGG "Encase In Egg"
#define DM_TRANSFORM "Transform"
//#define DM_ITEMWEAK "Digest (Item Friendly)"
//#define DM_STRIPDIGEST "Strip Digest (Items Only)"
//#define DM_DIGEST_NUMB "Digest (Numbing)"
//TF modes
#define DM_TRANSFORM_HAIR_AND_EYES "Transform (Hair and eyes)"
#define DM_TRANSFORM_MALE "Transform (Male)"
#define DM_TRANSFORM_FEMALE "Transform (Female)"
#define DM_TRANSFORM_KEEP_GENDER "Transform (Keep Gender)"
#define DM_TRANSFORM_REPLICA "Transform (Replica Of Self)"
#define DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR "Transform (Change Species and Taur)"
#define DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG "Transform (Change Species and Taur) (EGG)"
#define DM_TRANSFORM_REPLICA_EGG "Transform (Replica Of Self) (EGG)"
#define DM_TRANSFORM_KEEP_GENDER_EGG "Transform (Keep Gender) (EGG)"
#define DM_TRANSFORM_MALE_EGG "Transform (Male) (EGG)"
#define DM_TRANSFORM_FEMALE_EGG "Transform (Female) (EGG)"
//Addon mode flags
#define DM_FLAG_NUMBING 0x1
#define DM_FLAG_STRIPPING 0x2
+14 -1
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"
@@ -480,4 +482,15 @@ GLOBAL_LIST_INIT(all_volume_channels, list(
VOLUME_CHANNEL_ALARMS,
VOLUME_CHANNEL_VORE,
VOLUME_CHANNEL_DOORS,
))
))
#define APPEARANCECHANGER_CHANGED_RACE "Race"
#define APPEARANCECHANGER_CHANGED_GENDER "Gender"
#define APPEARANCECHANGER_CHANGED_GENDER_ID "Gender Identity"
#define APPEARANCECHANGER_CHANGED_SKINTONE "Skin Tone"
#define APPEARANCECHANGER_CHANGED_SKINCOLOR "Skin Color"
#define APPEARANCECHANGER_CHANGED_HAIRSTYLE "Hair Style"
#define APPEARANCECHANGER_CHANGED_HAIRCOLOR "Hair Color"
#define APPEARANCECHANGER_CHANGED_F_HAIRSTYLE "Facial Hair Style"
#define APPEARANCECHANGER_CHANGED_F_HAIRCOLOR "Facial Hair Color"
#define APPEARANCECHANGER_CHANGED_EYES "Eye Color"
+1 -1
View File
@@ -68,7 +68,7 @@
#define LANGUAGE_ALAI "Alai"
#define LANGUAGE_ZADDAT "Vedahq"
#define LANGUAGE_PROMETHEAN "Promethean Biolinguistics"
#define LANGUAGE_BLOB "Blob"
#define LANGUAGE_BLOB "Chemosense Transmission"
#define LANGUAGE_GIBBERISH "Babel"
// Language flags.
+1 -1
View File
@@ -215,7 +215,7 @@ var/global/list/string_slot_flags = list(
GLOB.closet_appearances[T] = app
// VOREStation Add - Vore Modes!
paths = typesof(/datum/digest_mode) - /datum/digest_mode/transform
paths = typesof(/datum/digest_mode)
for(var/T in paths)
var/datum/digest_mode/DM = new T
GLOB.digest_modes[DM.id] = DM
+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
+5
View File
@@ -11,6 +11,11 @@
var/mob/living/simple_mob/shadekin/SK = usr
if(istype(SK))
to_chat(usr,"<span class='notice'><b>Energy:</b> [SK.energy] ([SK.dark_gains])</span>")
if("shadekin status")
var/turf/T = get_turf(usr)
if(T)
var/darkness = round(1 - T.get_lumcount(),0.1)
to_chat(usr,"<span class='notice'><b>Darkness:</b> [darkness]</span>")
var/mob/living/carbon/human/H = usr
if(istype(H) && istype(H.species, /datum/species/shadekin))
to_chat(usr,"<span class='notice'><b>Energy:</b> [H.shadekin_get_energy(H)]</span>")
+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 ..()
+2 -2
View File
@@ -509,8 +509,8 @@
return // Still no brain.
// If the brain'd `defib_timer` var gets below this number, brain damage will happen at a linear rate.
// This is measures in `Life()` ticks. E.g. 10 minute defib timer = 6000 world.time units = 3000 `Life()` ticks.
var/brain_damage_timer = ((config.defib_timer MINUTES) / 2) - ((config.defib_braindamage_timer MINUTES) / 2)
// This is measures in `Life()` ticks. E.g. 10 minute defib timer = 300 `Life()` ticks. // Original math was VERY off. Life() tick occurs every ~2 seconds, not every 2 world.time ticks.
var/brain_damage_timer = ((config.defib_timer MINUTES) / 20) - ((config.defib_braindamage_timer MINUTES) / 20)
if(brain.defib_timer > brain_damage_timer)
return // They got revived before brain damage got a chance to set in.
@@ -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!")
@@ -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>")
+1 -1
View File
@@ -163,7 +163,7 @@
if (recipe.time)
to_chat(user, "<span class='notice'>Building [recipe.title] ...</span>")
if (!do_after(user, recipe.time, exclusive = TRUE))
if (!do_after(user, recipe.time))
return
if (use(required))
@@ -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
+303 -32
View File
@@ -321,73 +321,344 @@
desc = "A warning sign which reads XENOBIOLOGY."
icon_state = "xenobio3"
//direction signs presented by the order they appear in the dmi
/obj/structure/sign/directions
name = "direction sign"
desc = "A direction sign, claiming to know the way."
desc = "A direction sign, claiming to know the way to... somewhere?"
icon_state = "direction"
icon = 'icons/obj/decals_directions.dmi'
//TODO: set up overlay systems, inc. interactions (e.g. vines clear w/ plantbgone or fire, snow can be brushed off or melted, and so on)
//disabled this proc, it serves no purpose except to overwrite the description that already exists. may have been intended for making your own signs?
//seems to defeat the point of having a generic directional sign that mappers could edit and use in POIs? left it here in case something breaks.
/*
/obj/structure/sign/directions/New()
..()
desc = "A direction sign, pointing out which way \the [src] is."
/obj/structure/sign/directions/science
name = "\improper Science department"
desc = "A direction sign, pointing out which way the Science department is."
icon_state = "direction_sci"
desc = "A direction sign, pointing out the way to \the [src]."
*/
//engineering signs
/obj/structure/sign/directions/engineering
name = "\improper Engineering department"
desc = "A direction sign, pointing out which way the Engineering department is."
name = "\improper Engineering Department"
desc = "A direction sign, pointing out the way to the Engineering Department."
icon_state = "direction_eng"
/obj/structure/sign/directions/engineering/reactor
name = "\improper Reactor"
desc = "A direction sign, pointing out the way to the Reactor."
icon_state = "direction_core"
/obj/structure/sign/directions/engineering/solars
name = "\improper Solar Array"
desc = "A direction sign, pointing out the way to the nearest Solar Array."
icon_state = "direction_solar"
/obj/structure/sign/directions/engineering/atmospherics
name = "\improper Atmospherics Department"
desc = "A direction sign, pointing out the way to the Atmospherics Department."
icon_state = "direction_atmos"
/obj/structure/sign/directions/engineering/gravgen
name = "\improper Gravity Generator"
desc = "A direction sign, pointing out the way to the Artificial Gravity Generator."
icon_state = "direction_grav"
/obj/structure/sign/directions/engineering/engeqp
name = "\improper Engineering Equipment Storage"
desc = "A direction sign, pointing out the way to Engineering Equipment Storage."
icon_state = "direction_engeqp"
//security signs
/obj/structure/sign/directions/security
name = "\improper Security department"
desc = "A direction sign, pointing out which way the Security department is."
name = "\improper Security Department"
desc = "A direction sign, pointing out the way to the Security Department."
icon_state = "direction_sec"
/obj/structure/sign/directions/security/armory
name = "\improper Armory"
desc = "A direction sign, pointing out the way to the Armory."
icon_state = "direction_armory"
/obj/structure/sign/directions/security/brig
name = "\improper Brig"
desc = "A direction sign, pointing out the way to the Brig."
icon_state = "direction_brig"
/obj/structure/sign/directions/security/seceqp
name = "\improper Security Equipment Storage"
desc = "A direction sign, pointing out the way to Security Equipment Storage."
icon_state = "direction_seceqp"
/obj/structure/sign/directions/security/internal_affairs
name = "\improper Internal Affairs Office"
desc = "A direction sign, pointing out the way to the Internal Affairs Office."
icon_state = "direction_intaff"
/obj/structure/sign/directions/security/forensics
name = "\improper Forensics Lab"
desc = "A direction sign, pointing out the way to the Forensics Lab."
icon_state = "direction_forensics"
/obj/structure/sign/directions/security/forensics/alt
icon_state = "direction_lab"
/obj/structure/sign/directions/security/interrogation
name = "\improper Interrogations"
desc = "A direction sign, pointing out the way to Interrogations."
icon_state = "direction_interrogation"
//science signs
/obj/structure/sign/directions/science
name = "\improper Science Department"
desc = "A direction sign, pointing out the way to the Science Department."
icon_state = "direction_sci"
/obj/structure/sign/directions/science/rnd
name = "\improper Research & Development"
desc = "A direction sign, pointing out the way to Research & Development."
icon_state = "direction_rnd"
/obj/structure/sign/directions/science/toxins
name = "\improper Toxins Lab"
desc = "A direction sign, pointing out the way to the Toxins Lab."
icon_state = "direction_sci"
/obj/structure/sign/directions/science/robotics
name = "\improper Robotics Workshop"
desc = "A direction sign, pointing out the way to the Robotics Workshop."
icon_state = "direction_robotics"
/obj/structure/sign/directions/science/xenoarch
name = "\improper Xenoarchaeology Lab"
desc = "A direction sign, pointing out the way to the Xenoarchaeology Lab."
icon_state = "direction_xenoarch"
/obj/structure/sign/directions/science/xenobiology
name = "\improper Xenobiology Lab"
desc = "A direction sign, pointing out the way to the Xenobiology Lab."
icon_state = "direction_xbio"
/obj/structure/sign/directions/science/xenoflora
name = "\improper Xenoflora Lab"
desc = "A direction sign, pointing out the way to the Xenoflora Lab."
icon_state = "direction_xflora"
/obj/structure/sign/directions/science/exploration
name = "\improper Exploration Department"
desc = "A direction sign, pointing out the way to the Exploration Department."
icon_state = "direction_explo"
//medical signs
/obj/structure/sign/directions/medical
name = "\improper Medical Bay"
desc = "A direction sign, pointing out which way the Medical Bay is."
desc = "A direction sign, pointing out the way to the Medical Bay."
icon_state = "direction_med"
/obj/structure/sign/directions/medical/chemlab
name = "\improper Chemistry Lab"
desc = "A direction sign, pointing out the way to the Chemistry Lab."
icon_state = "direction_med"
/obj/structure/sign/directions/medical/surgery
name = "\improper Surgery"
desc = "A direction sign, pointing out the way to Surgery."
icon_state = "direction_surgery"
/obj/structure/sign/directions/medical/operating_1
name = "\improper Operating Theatre 1"
desc = "A direction sign, pointing out the way to Operating Theatre 1."
icon_state = "direction_op1"
/obj/structure/sign/directions/medical/operating_2
name = "\improper Operating Theatre 2"
desc = "A direction sign, pointing out the way to Operating Theatre 2."
icon_state = "direction_op2"
/obj/structure/sign/directions/medical/virology
name = "\improper Virology"
desc = "A direction sign, pointing out the way to the Virology Lab."
icon_state = "direction_viro"
/obj/structure/sign/directions/medical/medeqp
name = "\improper Medical Equipment Storage"
desc = "A direction sign, pointing out the way to Medical Equipment Storage."
icon_state = "direction_medeqp"
/obj/structure/sign/directions/medical/morgue
name = "\improper Morgue"
desc = "A direction sign, pointing out the way to the Morgue."
icon_state = "direction_morgue"
/obj/structure/sign/directions/medical/cloning
name = "\improper Cloning Lab"
desc = "A direction sign, pointing out the way to the Cloning Lab."
icon_state = "direction_cloning"
/obj/structure/sign/directions/medical/resleeving
name = "\improper Resleeving Lab"
desc = "A direction sign, pointing out the way to the Resleeving Lab."
icon_state = "direction_resleeve"
//special signs
/obj/structure/sign/directions/evac
name = "\improper Evacuation"
desc = "A direction sign, pointing out which way the Escape Shuttle dock is."
desc = "A direction sign, pointing out the way to the Escape Shuttle Dock."
icon_state = "direction_evac"
/obj/structure/sign/directions/eva
name = "\improper Extra-Vehicular Activity"
desc = "A direction sign, pointing out the way to the EVA Bay."
icon_state = "direction_eva"
//command signs
/obj/structure/sign/directions/ai_core
name = "\improper AI Core"
desc = "A direction sign, pointing out the way to the AI Core."
icon_state = "direction_ai_core"
/obj/structure/sign/directions/bridge
name = "\improper Bridge"
desc = "A direction sign, pointing out the way to the Bridge."
icon_state = "direction_bridge"
/obj/structure/sign/directions/command
name = "\improper Command"
desc = "A direction sign, pointing out the way to the Command Center."
icon_state = "direction_command"
/obj/structure/sign/directions/teleporter
name = "\improper Teleporter"
desc = "A direction sign, pointing out the way to the Teleporter."
icon_state = "direction_teleport"
/obj/structure/sign/directions/telecomms
name = "\improper Telecommunications Hub"
desc = "A direction sign, pointing out the way to the Telecommunications Hub."
icon_state = "direction_tcomms"
//cargonia signs
/obj/structure/sign/directions/cargo
name = "\improper Cargo department"
desc = "A direction sign, pointing out which way the Cargo department is."
name = "\improper Cargo Department"
desc = "A direction sign, pointing out the way to the Cargo Department."
icon_state = "direction_crg"
// VOREStation Edit - New signs for us
/obj/structure/sign/directions/command
icon = 'icons/obj/decals_vr.dmi'
name = "\improper Command department"
desc = "A direction sign, pointing out which way the Command department is."
icon_state = "direction_cmd"
/obj/structure/sign/directions/cargo/mining
name = "\improper Mining Department"
desc = "A direction sign, pointing out the way to the Mining Department."
icon_state = "direction_mining"
/obj/structure/sign/directions/elevator
icon = 'icons/obj/decals_vr.dmi'
name = "\improper Space Elevator"
desc = "A direction sign, pointing out which way the Space Elevator is."
icon_state = "direction_elv"
// VOREStation Edit End
/obj/structure/sign/directions/cryo
name = "\improper Cryogenic Storage"
desc = "A direction sign, pointing out which way cryogenic storage is."
icon_state = "direction_cry"
/obj/structure/sign/directions/cargo/refinery
name = "\improper Refinery"
desc = "A direction sign, pointing out the way to the Refinery."
icon_state = "direction_refinery"
//civilian/misc signs
/obj/structure/sign/directions/roomnum
name = "room number"
desc = "A sign detailing the number of the room beside it."
icon_state = "roomnum"
/obj/structure/sign/directions/cryo
name = "\improper Cryogenic Storage"
desc = "A direction sign, pointing out the way to Cryogenic Storage."
icon_state = "direction_cry"
/obj/structure/sign/directions/elevator
name = "\improper Elevator"
desc = "A direction sign, pointing out the way to the nearest elevator."
icon_state = "direction_elv"
/obj/structure/sign/directions/bar
name = "\improper Bar"
desc = "A direction sign, pointing out the way to the nearest watering hole."
icon_state = "direction_bar"
/obj/structure/sign/directions/kitchen
name = "\improper Kitchen"
desc = "A pictographic direction sign with a knife, plate, and fork, pointing out the way to the nearest dining establishment."
icon_state = "direction_kitchen"
/obj/structure/sign/directions/tram
name = "\improper Public Transit Station"
desc = "A direction sign, pointing out the way to the nearest public transit station."
icon_state = "direction_tram"
/obj/structure/sign/directions/janitor
name = "\improper Custodial Closet"
desc = "A direction sign, pointing out the way to the Custodial Closet."
icon_state = "direction_janitor"
/obj/structure/sign/directions/chapel
name = "\improper Chapel"
desc = "A direction sign, pointing out the way to the Chapel."
icon_state = "direction_chapel"
/obj/structure/sign/directions/dorms
name = "\improper Dormitories"
desc = "A direction sign, pointing out the way to the Dormitories."
icon_state = "direction_dorms"
/obj/structure/sign/directions/library
name = "\improper Library"
desc = "A direction sign, pointing out the way to the Library."
icon_state = "direction_library"
/obj/structure/sign/directions/dock
name = "\improper Dock"
desc = "A direction sign, pointing out the way to the nearest docking area."
icon_state = "direction_dock"
/obj/structure/sign/directions/gym
name = "\improper Gym"
desc = "A direction sign, pointing out the way to the Gym."
icon_state = "direction_gym"
/obj/structure/sign/directions/pool
name = "\improper Pool"
desc = "A direction sign, pointing out the way to the Pool."
icon_state = "direction_pool"
/obj/structure/sign/directions/recreation
name = "\improper Recreation Area"
desc = "A direction sign, pointing out the way to the nearest Recreation Area."
icon_state = "direction_recreation"
/obj/structure/sign/directions/stairwell
name = "\improper Stairwell"
desc = "A direction sign with stairs and a door, pointing out the way to the nearest stairwell."
icon_state = "stairwell"
/obj/structure/sign/directions/stairs_up
name = "\improper Stairs Up"
desc = "A direction sign with stairs and an upward-slanted arrow, pointing out the way to the nearest set of stairs that go up."
icon_state = "stairs_up"
/obj/structure/sign/directions/stairs_down
name = "\improper Stairs Down"
desc = "A direction sign with stairs and a downward-slanted arrow, pointing out the way to the nearest set of stairs that go down."
icon_state = "stairs_down"
/obj/structure/sign/directions/ladderwell
name = "\improper Access Shaft"
desc = "A direction sign with a ladder and a door, pointing out the way to the nearest access shaft."
icon_state = "ladderwell"
/obj/structure/sign/directions/ladder_up
name = "\improper Ladder Up"
desc = "A direction sign with a ladder and an upward arrow, pointing out the way to the nearest ladder that goes up."
icon_state = "ladder_up"
/obj/structure/sign/directions/ladder_down
name = "\improper Ladder Down"
desc = "A direction sign with a ladder and a downward arrow, pointing out the way to the nearest ladder that goes down."
icon_state = "ladder_down"
/obj/structure/sign/directions/exit
name = "\improper Emergency Exit"
desc = "A lurid green sign that unmistakably identifies that the door it's next to as an emergency exit route."
icon_state = "exit_sign"
//OTHER STUFF
/obj/structure/sign/christmas/lights
name = "Christmas lights"
desc = "Flashy and pretty."
+5
View File
@@ -0,0 +1,5 @@
/turf/simulated/floor/beach/sand/outdoors
outdoors = TRUE
/turf/simulated/floor/beach/sand/desert/outdoors
outdoors = TRUE
+113 -18
View File
@@ -23,7 +23,11 @@
var/corpseidjob = null // Needs to be in quotes, such as "Clown" or "Chef." This just determines what the ID reads as, not their access
var/corpseidaccess = null //This is for access. See access.dm for which jobs give what access. Again, put in quotes. Use "Captain" if you want it to be all access.
var/corpseidicon = null //For setting it to be a gold, silver, CentCom etc ID
var/species = SPECIES_HUMAN
var/species = SPECIES_HUMAN //defaults to generic-ass humans
var/random_species = FALSE //flip to TRUE to randomize species from the list below
var/list/random_species_list = list(SPECIES_HUMAN,SPECIES_TAJ,SPECIES_UNATHI,SPECIES_SKRELL) //preset list that can be overriden downstream. only includes common humanoids for voidsuit compatibility's sake.
// var/random_appearance = FALSE //TODO: make this work
// var/cause_of_death = null //TODO: set up a cause-of-death system. needs to support both damage types and actual wound types, so a body can have been bitten/stabbed/clawed/shot/burned/lasered/etc. to death
delete_me = TRUE
/obj/effect/landmark/corpse/Initialize()
@@ -33,13 +37,20 @@
/obj/effect/landmark/corpse/proc/createCorpse() //Creates a mob and checks for gear in each slot before attempting to equip it.
var/mob/living/carbon/human/M = new /mob/living/carbon/human (src.loc)
M.set_species(species)
if(random_species)
var/random_pick = pick(random_species_list)
M.set_species(random_pick)
src.species = random_pick
else
M.set_species(species)
//TODO: insert appearance randomization, needs to be species-based
M.real_name = src.name
M.death(1) //Kills the new mob
//TODO: insert cause of death handling/wound simulation here
if(src.corpseuniform)
M.equip_to_slot_or_del(new src.corpseuniform(M), slot_w_uniform)
if(src.corpsesuit)
M.equip_to_slot_or_del(new src.corpsesuit(M), slot_wear_suit)
M.equip_voidsuit_to_slot_or_del_with_refit(new src.corpsesuit(M), slot_wear_suit, src.species)
if(src.corpseshoes)
M.equip_to_slot_or_del(new src.corpseshoes(M), slot_shoes)
if(src.corpsegloves)
@@ -51,7 +62,7 @@
if(src.corpsemask)
M.equip_to_slot_or_del(new src.corpsemask(M), slot_wear_mask)
if(src.corpsehelmet)
M.equip_to_slot_or_del(new src.corpsehelmet(M), slot_head)
M.equip_voidhelm_to_slot_or_del_with_refit(new src.corpsehelmet(M), slot_head, src.species)
if(src.corpsebelt)
M.equip_to_slot_or_del(new src.corpsebelt(M), slot_belt)
if(src.corpsepocket1)
@@ -84,10 +95,6 @@
// I'll work on making a list of corpses people request for maps, or that I think will be commonly used. Syndicate operatives for example.
/obj/effect/landmark/corpse/syndicatesoldier
name = "Mercenary"
corpseuniform = /obj/item/clothing/under/syndicate
@@ -102,8 +109,6 @@
corpseidjob = "Operative"
corpseidaccess = "Syndicate"
/obj/effect/landmark/corpse/syndicatecommando
name = "Syndicate Commando"
corpseuniform = /obj/item/clothing/under/syndicate
@@ -119,10 +124,14 @@
corpseidjob = "Operative"
corpseidaccess = "Syndicate"
///////////Civilians//////////////////////
/obj/effect/landmark/corpse/random_civ
name = "Civilian"
corpseuniform = /obj/item/clothing/under/color/grey
corpseshoes = /obj/item/clothing/shoes/black
random_species = TRUE
/obj/effect/landmark/corpse/chef
name = "Chef"
corpseuniform = /obj/item/clothing/under/rank/chef
@@ -165,6 +174,7 @@
corpsesuit = /obj/item/clothing/suit/space/void/engineering
corpsemask = /obj/item/clothing/mask/breath
corpsehelmet = /obj/item/clothing/head/helmet/space/void/engineering
corpseback = /obj/item/weapon/tank/oxygen
/obj/effect/landmark/corpse/clown
name = "Clown"
@@ -188,6 +198,39 @@
corpseid = 1
corpseidjob = "Scientist"
corpseidaccess = "Scientist"
/obj/effect/landmark/corpse/security
name = "Security Officer"
corpseradio = /obj/item/device/radio/headset/headset_sec
corpseuniform = /obj/item/clothing/under/rank/security
corpsesuit = /obj/item/clothing/suit/armor/vest
corpseback = /obj/item/weapon/storage/backpack/security
corpseshoes = /obj/item/clothing/shoes/boots/jackboots
corpseglasses = /obj/item/clothing/glasses/sunglasses/sechud
corpsegloves = /obj/item/clothing/gloves/black
corpsehelmet = /obj/item/clothing/head/helmet
corpseid = 1
corpseidjob = "Security Officer"
corpseidaccess = "Security Officer"
/obj/effect/landmark/corpse/security/rig
corpsesuit = /obj/item/clothing/suit/space/void/security
corpsemask = /obj/item/clothing/mask/breath
corpsehelmet = /obj/item/clothing/head/helmet/space/void/security
corpseback = /obj/item/weapon/tank/jetpack/oxygen
/obj/effect/landmark/corpse/security/rig/eva
corpsesuit = /obj/item/clothing/suit/space/void/security/alt
corpsehelmet = /obj/item/clothing/head/helmet/space/void/security/alt
corpseidjob = "Starship Security Officer"
/obj/effect/landmark/corpse/prisoner
name = "Unknown Prisoner"
corpseuniform = /obj/item/clothing/under/color/prison
corpseshoes = /obj/item/clothing/shoes/orange
corpseid = 1
corpseidjob = "Prisoner"
random_species = TRUE
/obj/effect/landmark/corpse/miner
corpseradio = /obj/item/device/radio/headset/headset_cargo
@@ -203,17 +246,69 @@
corpsesuit = /obj/item/clothing/suit/space/void/mining
corpsemask = /obj/item/clothing/mask/breath
corpsehelmet = /obj/item/clothing/head/helmet/space/void/mining
corpseback = /obj/item/weapon/tank/oxygen
//VORESTATION ADD START
/////////////////Vintage//////////////////////
//define the basic props at this level and only change specifics for variants, e.z.
/obj/effect/landmark/corpse/vintage
name = "Unknown Crewmate"
corpseuniform = /obj/item/clothing/under/utility
corpsesuit = /obj/item/clothing/suit/space/void/refurb
corpsehelmet = /obj/item/clothing/head/helmet/space/void/refurb
corpsemask = /obj/item/clothing/mask/breath
corpseback = /obj/item/weapon/tank/oxygen
corpseid = 1
corpseidjob = "Crewmate"
/obj/effect/landmark/corpse/vintage/engineering
name = "Unknown Engineer"
corpsesuit = /obj/item/clothing/suit/space/void/refurb/engineering
corpsehelmet = /obj/item/clothing/head/helmet/space/void/refurb/engineering
corpsebelt = /obj/item/weapon/storage/belt/utility/full
corpseback = /obj/item/weapon/tank/oxygen/yellow
corpseidjob = "Engineer"
/obj/effect/landmark/corpse/vintage/marine
name = "Unknown Marine"
corpsesuit = /obj/item/clothing/suit/space/void/refurb/marine
corpsehelmet = /obj/item/clothing/head/helmet/space/void/refurb/marine
corpsebelt = /obj/item/weapon/storage/belt/security/tactical
corpseidjob = "Marine"
/obj/effect/landmark/corpse/vintage/medical
name = "Unknown Medic"
corpsesuit = /obj/item/clothing/suit/space/void/refurb/medical
corpsehelmet = /obj/item/clothing/head/helmet/space/void/refurb/medical
corpsebelt = /obj/item/weapon/storage/belt/medical
corpseidjob = "Medic"
/obj/effect/landmark/corpse/vintage/mercenary
name = "Unknown Mercenary"
corpsesuit = /obj/item/clothing/suit/space/void/refurb/mercenary
corpsehelmet = /obj/item/clothing/head/helmet/space/void/refurb/mercenary
corpsebelt = /obj/item/weapon/storage/belt/security/tactical
corpseback = /obj/item/weapon/tank/oxygen/red
corpseidjob = "Mercenary"
/obj/effect/landmark/corpse/vintage/officer
name = "Unknown Captain"
corpsesuit = /obj/item/clothing/suit/space/void/refurb/officer
corpsehelmet = /obj/item/clothing/head/helmet/space/void/refurb/officer
corpseback = /obj/item/weapon/tank/oxygen/yellow
corpseidjob = "Captain"
/obj/effect/landmark/corpse/vintage/pilot
name = "Pilot"
corpseuniform = /obj/item/clothing/under/color/grey
name = "Unknown Pilot"
corpsesuit = /obj/item/clothing/suit/space/void/refurb/pilot
corpsehelmet = /obj/item/clothing/head/helmet/space/void/refurb/pilot
corpseshoes = /obj/item/clothing/shoes/black
corpseback = /obj/item/weapon/tank/oxygen
//VORESTATION ADD END
corpseidjob = "Pilot"
/obj/effect/landmark/corpse/vintage/research
name = "Unknown Researcher"
corpsesuit = /obj/item/clothing/suit/space/void/refurb/research
corpsehelmet = /obj/item/clothing/head/helmet/space/void/refurb/research
corpseidjob = "Researcher"
/////////////////Officers//////////////////////
+41 -4
View File
@@ -22,6 +22,7 @@ GLOBAL_LIST_EMPTY(all_blobs)
/obj/structure/blob/Initialize(newloc, new_overmind)
if(new_overmind)
overmind = new_overmind
faction = overmind.blob_type.faction
update_icon()
if(!integrity)
integrity = max_integrity
@@ -47,19 +48,24 @@ GLOBAL_LIST_EMPTY(all_blobs)
color = null
set_light(0)
/obj/structure/blob/update_transform()
var/matrix/M = matrix()
M.Scale(icon_scale_x, icon_scale_y)
animate(src, transform = M, time = 10)
// Blob tiles are not actually dense so we need Special Code(tm).
/obj/structure/blob/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && mover.checkpass(PASSBLOB))
return TRUE
else if(istype(mover, /mob/living))
var/mob/living/L = mover
if(L.faction == "blob")
if(L.faction == faction)
return TRUE
else if(istype(mover, /obj/item/projectile))
var/obj/item/projectile/P = mover
if(istype(P.firer, /obj/structure/blob))
return TRUE
if(istype(P.firer) && P.firer.faction == "blob")
if(istype(P.firer) && P.firer.faction == faction)
return TRUE
return FALSE
@@ -88,6 +94,7 @@ GLOBAL_LIST_EMPTY(all_blobs)
update_icon()
pulse_timestamp = world.time + 1 SECOND
if(overmind)
faction = overmind.blob_type.faction
overmind.blob_type.on_pulse(src)
return TRUE //we did it, we were pulsed!
return FALSE //oh no we failed
@@ -106,6 +113,9 @@ GLOBAL_LIST_EMPTY(all_blobs)
for(var/L in blobs_to_affect)
var/obj/structure/blob/B = L
if(B.faction != faction)
continue
if(!B.overmind && !istype(B, /obj/structure/blob/core) && prob(30))
B.overmind = pulsing_overmind //reclaim unclaimed, non-core blobs.
B.update_icon()
@@ -138,7 +148,8 @@ GLOBAL_LIST_EMPTY(all_blobs)
var/dirn = pick(dirs)
dirs.Remove(dirn)
T = get_step(src, dirn)
if(!(locate(/obj/structure/blob) in T))
var/obj/structure/blob/B = locate(/obj/structure/blob) in T
if(!B || B.faction != faction) // Allow opposing blobs to fight.
break
else
T = null
@@ -164,6 +175,7 @@ GLOBAL_LIST_EMPTY(all_blobs)
if(make_blob) //well, can we?
var/obj/structure/blob/B = new /obj/structure/blob/normal(src.loc)
B.faction = faction
if(controller)
B.overmind = controller
else
@@ -340,7 +352,7 @@ GLOBAL_LIST_EMPTY(all_blobs)
if(!P)
return
if(istype(P.firer) && P.firer.faction == "blob")
if(istype(P.firer) && P.firer.faction == faction)
return
var/damage = P.get_structure_damage() // So tasers don't hurt the blob.
@@ -366,6 +378,31 @@ GLOBAL_LIST_EMPTY(all_blobs)
if(overmind)
overmind.blob_type.on_water(src, amount)
/obj/structure/blob/blob_act(var/obj/structure/blob/B)
. = ..()
if(B)
if(!B.overmind)
return
if(B.faction != faction)
var/damage = rand(B.overmind.blob_type.damage_lower, B.overmind.blob_type.damage_upper)
var/inc_damage_type = B.overmind.blob_type.damage_type
if(overmind)
damage = overmind.blob_type.on_received_damage(src, damage, inc_damage_type, B)
else
faction = B.faction
overmind = B.overmind
update_icon()
return
adjust_integrity(-1 * damage)
return
/obj/structure/blob/proc/adjust_integrity(amount)
integrity = between(0, integrity + amount, max_integrity)
if(integrity == 0)
+1 -1
View File
@@ -35,7 +35,7 @@
var/mob/living/simple_mob/blob/spore/S = null
if(overmind)
S = new overmind.blob_type.spore_type(src.loc, src)
S.faction = "blob"
S.faction = overmind.blob_type.faction
if(istype(S))
S.overmind = overmind
overmind.blob_mobs.Add(S)
+10 -1
View File
@@ -19,4 +19,13 @@
if(overmind)
name = "[overmind.blob_type.name]"
else
name = "inert [base_name]"
name = "inert [base_name]"
/obj/structure/blob/normal/pulsed()
..()
if(prob(30))
adjust_scale((rand(10, 13) / 10), (rand(10, 13) / 10))
else
adjust_scale(1)
+55 -1
View File
@@ -5,6 +5,7 @@
description_info = "Some blob types will have core effects when the chunk is used in-hand, toggled with an alt click, or constantly active."
icon = 'icons/mob/blob.dmi'
icon_state = "blobcore"
flags = OPENCONTAINER
var/datum/blob_type/blob_type // The blob type this dropped from.
var/active_ability_cooldown = 20 SECONDS
@@ -15,11 +16,17 @@
var/passive_ability_cooldown = 5 SECONDS
var/last_passive_use = 0
var/can_genesis = TRUE // Can the core chunk be used to grow a new blob?
drop_sound = 'sound/effects/slime_squish.ogg'
/obj/item/weapon/blobcore_chunk/is_open_container()
return 1
/obj/item/weapon/blobcore_chunk/New(var/atom/newloc, var/datum/blob_type/parentblob = null)
..(newloc)
create_reagents(120)
setup_blobtype(parentblob)
/obj/item/weapon/blobcore_chunk/Destroy()
@@ -91,10 +98,57 @@
blob_type.on_chunk_tick(src)
/obj/item/weapon/blobcore_chunk/AltClick(mob/living/carbon/user)
if(blob_type &&blob_type.chunk_active_type == BLOB_CHUNK_TOGGLE)
if(blob_type && blob_type.chunk_active_type == BLOB_CHUNK_TOGGLE)
should_tick = !should_tick
if(should_tick)
to_chat(user, "<span class='alien'>\The [src] shudders with life.</span>")
else
to_chat(user, "<span class='alien'>\The [src] stills, returning to a death-like state.</span>")
/obj/item/weapon/blobcore_chunk/proc/regen(var/newfaction = null)
if(istype(blob_type))
if(newfaction)
blob_type.faction = newfaction
var/obj/structure/blob/core/NC = new (get_turf(src))
NC.overmind.blob_type = blob_type
NC.overmind.blob_core.update_icon()
return TRUE
return FALSE
/datum/chemical_reaction/blob_reconstitution
name = "Hostile Blob Revival"
id = "blob_revival"
result = null
required_reagents = list("phoron" = 60)
result_amount = 1
/datum/chemical_reaction/blob_reconstitution/can_happen(var/datum/reagents/holder)
if(holder.my_atom && istype(holder.my_atom, /obj/item/weapon/blobcore_chunk))
return ..()
return FALSE
/datum/chemical_reaction/blob_reconstitution/on_reaction(var/datum/reagents/holder)
var/obj/item/weapon/blobcore_chunk/chunk = holder.my_atom
if(chunk.can_genesis && chunk.regen())
chunk.visible_message("<span class='notice'>[chunk] bubbles, surrounding itself with a rapidly expanding mass of [chunk.blob_type.name]!</span>")
chunk.can_genesis = FALSE
else
chunk.visible_message("<span class='warning'>[chunk] shifts strangely, but falls still.</span>")
/datum/chemical_reaction/blob_reconstitution/domination
name = "Allied Blob Revival"
id = "blob_friend"
result = null
required_reagents = list("hydrophoron" = 40, "peridaxon" = 20, "mutagen" = 20)
result_amount = 1
/datum/chemical_reaction/blob_reconstitution/domination/on_reaction(var/datum/reagents/holder)
var/obj/item/weapon/blobcore_chunk/chunk = holder.my_atom
if(chunk.can_genesis && chunk.regen("neutral"))
chunk.visible_message("<span class='notice'>[chunk] bubbles, surrounding itself with a rapidly expanding mass of [chunk.blob_type.name]!</span>")
chunk.can_genesis = FALSE
else
chunk.visible_message("<span class='warning'>[chunk] shifts strangely, but falls still.</span>")
+74 -2
View File
@@ -23,6 +23,14 @@ var/list/overminds = list()
var/ai_controlled = TRUE
var/auto_pilot = FALSE // If true, and if a client is attached, the AI routine will continue running.
universal_understand = TRUE
var/list/has_langs = list(LANGUAGE_BLOB)
var/datum/language/default_language = null
/mob/observer/blob/get_default_language()
return default_language
/mob/observer/blob/Initialize(newloc, pre_placed = 0, starting_points = 60, desired_blob_type = null)
blob_points = starting_points
if(pre_placed) //we already have a core!
@@ -41,6 +49,11 @@ var/list/overminds = list()
if(blob_core)
blob_core.update_icon()
for(var/L in has_langs)
languages |= GLOB.all_languages[L]
if(languages.len)
default_language = languages[1]
return ..(newloc)
/mob/observer/blob/Destroy()
@@ -67,9 +80,9 @@ var/list/overminds = list()
stat(null, "Power Stored: [blob_points]/[max_blob_points]")
stat(null, "Total Blobs: [GLOB.all_blobs.len]")
/mob/observer/blob/Move(NewLoc, Dir = 0)
/mob/observer/blob/Move(var/atom/NewLoc, Dir = 0)
if(placed)
var/obj/structure/blob/B = locate() in range("3x3", NewLoc)
var/obj/structure/blob/B = (locate() in view("5x5", NewLoc))
if(B)
forceMove(NewLoc)
return TRUE
@@ -93,3 +106,62 @@ var/list/overminds = list()
if(blob_points >= 100)
if(!auto_factory() && !auto_resource())
auto_node()
/mob/observer/blob/say(var/message, var/datum/language/speaking = null, var/whispering = 0)
message = sanitize(message)
if(!message)
return
//If you're muted for IC chat
if(client)
if(message)
client.handle_spam_prevention(MUTE_IC)
if((client.prefs.muted & MUTE_IC) || say_disabled)
to_chat(src, "<span class='warning'>You cannot speak in IC (Muted).</span>")
return
//These will contain the main receivers of the message
var/list/listening = list()
var/list/listening_obj = list()
var/turf/T = get_turf(src)
if(T)
//Obtain the mobs and objects in the message range
var/list/results = get_mobs_and_objs_in_view_fast(T, world.view, remote_ghosts = client ? TRUE : FALSE)
listening = results["mobs"]
listening_obj = results["objs"]
else
return 1 //If we're in nullspace, then forget it.
var/list/message_pieces = parse_languages(message)
if(istype(message_pieces, /datum/multilingual_say_piece)) // Little quirk for dealing with hivemind/signlang languages.
var/datum/multilingual_say_piece/S = message_pieces // Yay for BYOND's hilariously broken typecasting for allowing us to do this.
S.speaking.broadcast(src, S.message)
return 1
if(!LAZYLEN(message_pieces))
log_runtime(EXCEPTION("Message failed to generate pieces. [message] - [json_encode(message_pieces)]"))
return 0
//Handle nonverbal languages here
for(var/datum/multilingual_say_piece/S in message_pieces)
if(S.speaking.flags & NONVERBAL)
custom_emote(1, "[pick(S.speaking.signlang_verb)].")
for(var/mob/M in listening)
spawn()
if(M && src)
if(get_dist(M, src) <= world.view || (M.stat == DEAD && !forbid_seeing_deadchat))
M.hear_say(message_pieces, "conveys", (M.faction == blob_type.faction), src)
//Object message delivery
for(var/obj/O in listening_obj)
spawn(0)
if(O && src) //If we still exist, when the spawn processes
var/dst = get_dist(get_turf(O),get_turf(src))
if(dst <= world.view)
O.hear_talk(src, message_pieces, "conveys")
log_say(message, src)
return 1
+7 -7
View File
@@ -80,8 +80,8 @@
potential_blobs -= temp // Don't take up the core's shield spot.
else if(!istype(temp, /obj/structure/blob/normal))
potential_blobs -= temp // Not a normal blob.
else if(temp.overmind != src)
potential_blobs -= temp // Not our blob.
else if(temp.overmind != src || temp.overmind.blob_type.faction != blob_type.faction)
potential_blobs -= temp // Not our blob, or even an ally.
else
B = temp
break
@@ -123,8 +123,8 @@
potential_blobs -= temp // Don't take up the core's shield spot.
else if(!istype(temp, /obj/structure/blob/normal))
potential_blobs -= temp // Not a normal blob.
else if(temp.overmind != src)
potential_blobs -= temp // Not our blob.
else if(temp.overmind != src || temp.overmind.blob_type.faction != blob_type.faction)
potential_blobs -= temp // Not our blob, or even an ally
else
B = temp
break
@@ -165,8 +165,8 @@
potential_blobs -= temp
else if(!istype(temp, /obj/structure/blob/normal))
potential_blobs -= temp
else if(temp.overmind != src)
potential_blobs -= temp // Not our blob.
else if(temp.overmind != src || temp.overmind.blob_type.faction != blob_type.faction)
potential_blobs -= temp // Not our blob, or even our ally.
else
B = temp
break
@@ -216,7 +216,7 @@
for(var/mob/living/L in view(src))
if(L.stat == DEAD)
continue // Already dying or dead.
if(L.faction == "blob")
if(L.faction == blob_type.faction)
continue // No friendly fire.
if(locate(/obj/structure/blob) in L.loc)
continue // Already has a blob over them.
+2
View File
@@ -9,6 +9,8 @@
var/color = "#FFFFFF" // The actual blob's color.
var/complementary_color = "#000000" //a color that's complementary to the normal blob color. Blob mobs are colored in this.
var/faction = "blob" // The blob's faction.
var/attack_message = "The blob attacks you" // Base message the mob gets when blob_act() gets called on them by the blob. An exclaimation point is added to the end.
var/attack_message_living = null // Appended to attack_message, if the target fails isSynthetic() check.
var/attack_message_synth = null // Ditto, but if they pass isSynthetic().
@@ -33,6 +33,8 @@
env.add_thermal_energy(10 * 1000)
/datum/blob_type/blazing_oil/on_chunk_tick(obj/item/weapon/blobcore_chunk/B)
B.reagents.add_reagent("thermite_v", 0.5)
var/turf/T = get_turf(B)
if(!T)
return
@@ -46,6 +46,8 @@
env.add_thermal_energy(-10 * 1000)
/datum/blob_type/cryogenic_goo/on_chunk_tick(obj/item/weapon/blobcore_chunk/B)
B.reagents.add_reagent("cryoslurry", 0.5)
var/turf/simulated/T = get_turf(B)
if(!istype(T))
return
@@ -35,7 +35,7 @@
listclearnulls(active_beams)
var/atom/movable/beam_origin = B
for(var/mob/living/L in oview(world.view, B))
if(L.stat == DEAD || L.faction == "blob")
if(L.stat == DEAD || L.faction == faction)
continue
if(prob(5))
var/beamtarget_exists = FALSE
@@ -82,7 +82,7 @@
if(nearby_mobs.len)
listclearnulls(active_beams)
for(var/mob/living/L in nearby_mobs)
if(L.stat == DEAD || L.faction == "blob")
if(L.stat == DEAD || L.faction == faction)
continue
if(prob(5))
var/beamtarget_exists = FALSE
@@ -30,7 +30,7 @@
for(var/mob/living/L in range(get_turf(victim), 1)) // We don't use orange(), in case there is more than one mob on the target tile.
if(L == victim) // Already hit.
continue
if(L.faction == "blob") // No friendly fire
if(L.faction == faction) // No friendly fire
continue
L.blob_act()
@@ -24,9 +24,10 @@
var/mob/living/simple_mob/blob/spore/S = new spore_type(T)
if(istype(S))
S.overmind = O
S.faction = faction
O.blob_mobs.Add(S)
else
S.faction = "blob"
S.faction = faction
S.update_icons()
/datum/blob_type/fulminant_organism/on_death(obj/structure/blob/B)
@@ -35,9 +36,10 @@
B.visible_message("<span class='danger'>\The [S] floats free from the [name]!</span>")
if(istype(S))
S.overmind = B.overmind
S.faction = faction
B.overmind.blob_mobs.Add(S)
else
S.faction = "blob"
S.faction = faction
S.update_icons()
/datum/blob_type/fulminant_organism/on_chunk_use(obj/item/weapon/blobcore_chunk/B, mob/living/user)
@@ -14,6 +14,7 @@
attack_message = "The tide tries to swallow you"
attack_message_living = ", and you feel your skin dissolve"
attack_message_synth = ", and your external plating dissolves"
faction = "nanomachines"
/datum/blob_type/grey_goo/on_emp(obj/structure/blob/B, severity)
B.adjust_integrity(-(20 / severity))
@@ -44,7 +44,7 @@
if(!istype(L))
return
if(istype(B, /obj/structure/blob/factory) && L.stat != DEAD && prob(ai_aggressiveness) && L.faction != "blob")
if(istype(B, /obj/structure/blob/factory) && L.stat != DEAD && prob(ai_aggressiveness) && L.faction != faction)
var/obj/item/projectile/arc/spore/P = new(get_turf(B))
P.launch_projectile(L, BP_TORSO, B)
-1
View File
@@ -228,7 +228,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.
@@ -18,4 +18,28 @@
/datum/gear/head/detective_alt
display_name = "cyberscope headgear, detective"
path = /obj/item/clothing/head/helmet/detective_alt
allowed_roles = list("Head of Security", "Detective")
allowed_roles = list("Head of Security", "Detective")
/datum/gear/head/bearpelt
display_name = "brown bear pelt"
path = /obj/item/clothing/head/pelt
/datum/gear/head/wolfpelt
display_name = "brown wolf pelt"
path = /obj/item/clothing/head/pelt/wolfpelt
/datum/gear/head/wolfpeltblack
display_name = "black wolf pelt"
path = /obj/item/clothing/head/pelt/wolfpeltblack
/datum/gear/head/tigerpelt
display_name = "shiny tiger pelt"
path = /obj/item/clothing/head/pelt/tigerpelt
/datum/gear/head/tigerpeltsnow
display_name = "snow tiger pelt"
path = /obj/item/clothing/head/pelt/tigerpeltsnow
/datum/gear/head/tigerpeltpink
display_name = "pink tiger pelt"
path = /obj/item/clothing/head/pelt/tigerpeltpink
@@ -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,23 +82,27 @@
/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
if(selected_species.selects_bodytype)
var/datum/species/custom/CS = character.species
var/S = pref.custom_base ? pref.custom_base : "Human"
var/datum/species/custom/new_CS = CS.produceCopy(S, pref.pos_traits + pref.neu_traits + pref.neg_traits, character)
var/datum/species/S = character.species
var/SB
if(S.selects_bodytype)
SB = pref.custom_base ? pref.custom_base : "Human"
else
SB = S.name
var/datum/species/new_S = S.produceCopy(SB, pref.pos_traits + pref.neu_traits + pref.neg_traits, character)
//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> "
@@ -109,15 +113,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>"
@@ -128,19 +133,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>"
@@ -213,8 +217,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
+41 -1
View File
@@ -46,4 +46,44 @@
/obj/item/clothing/head/shiny_hood/closed/poly
name = "polychromic closed shiny hood"
icon_state = "hood_col_o"
polychromic = TRUE
polychromic = TRUE
/obj/item/clothing/head/pelt
name = "Bear pelt"
desc = "A luxurious bear pelt, good to keep warm in winter. Or to sleep through winter."
icon = 'icons/obj/clothing/hats_vr.dmi'
icon_override = 'icons/mob/head_vr.dmi'
icon_state = "bearpelt_brown"
item_state = "bearpelt_brown"
/obj/item/clothing/head/pelt/wolfpelt
name = "Wolf pelt"
desc = "A fuzzy wolf pelt, demanding respect as a hunter, well if it isn't synthetic or anything at least. Or bought."
icon_override = 'icons/mob/wolfpelt_vr.dmi'
icon_state = "wolfpelt_brown"
item_state = "wolfpelt_brown"
/obj/item/clothing/head/pelt/wolfpeltblack
name = "Wolf pelt"
desc = "A fuzzy wolf pelt, demanding respect as a hunter, well if it isn't synthetic or anything at least. Or bought."
icon_override = 'icons/mob/wolfpelt_vr.dmi'
icon_state = "wolfpelt_gray"
item_state = "wolfpelt_gray"
/obj/item/clothing/head/pelt/tigerpelt
name = "Shiny tiger pelt"
desc = "A vibrant tiger pelt, particularly fabulous."
icon_state = "tigerpelt_shiny"
item_state = "tigerpelt_shiny"
/obj/item/clothing/head/pelt/tigerpeltsnow
name = "Snow tiger pelt"
desc = "A pelt of a less vibrant tiger, but rather warm."
icon_state = "tigerpelt_snow"
item_state = "tigerpelt_snow"
/obj/item/clothing/head/pelt/tigerpeltpink
name = "Pink tiger pelt"
desc = "A particularly vibrant tiger pelt, for those who want to be the most fabulous at parties."
icon_state = "tigerpelt_pink"
item_state = "tigerpelt_pink"
+18 -1
View File
@@ -6049,6 +6049,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/chilicheesefries
name = "chili cheese fries"
gender = PLURAL
@@ -6559,4 +6576,4 @@
/obj/item/weapon/reagent_containers/food/snacks/cinnamonbun/New()
..()
reagents.add_reagent("nutriment", 8)
bitesize = 1
bitesize = 1
+8 -1
View File
@@ -941,6 +941,13 @@ I said no!
)
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/chilicheesefries
items = list(
/obj/item/weapon/reagent_containers/food/snacks/fries,
@@ -1436,4 +1443,4 @@ I said no!
/obj/item/weapon/reagent_containers/food/snacks/dough
)
result = /obj/item/weapon/reagent_containers/food/snacks/cinnamonbun
result_quantity = 4
result_quantity = 4
@@ -33,8 +33,8 @@
/datum/event2/event/brand_intelligence/announce()
if(prob(90))
command_announcement.Announce("An ongoing mass upload of malware for venders has been detected onboard \the [location_name()], \
which appears to transmit to nearby vendors. The original infected machine is believed to be \a [vender_zero].", "Vender Service Alert")
command_announcement.Announce("An ongoing mass upload of malware for vendors has been detected onboard \the [location_name()], \
which appears to transmit to nearby vendors. The original infected machine is believed to be \a [vender_zero].", "Vendor Service Alert")
/datum/event2/event/brand_intelligence/start()
infect_vender(vender_zero)
+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()
..()
@@ -222,7 +223,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)
@@ -237,6 +238,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()
@@ -269,4 +271,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
+9
View File
@@ -71,6 +71,15 @@ var/list/slot_equipment_priority = list( \
/mob/proc/equip_to_slot_or_del(obj/item/W as obj, slot)
return equip_to_slot_if_possible(W, slot, 1, 1, 0)
//hurgh. these feel hacky, but they're the only way I could get the damn thing to work. I guess they could be handy for antag spawners too?
/mob/proc/equip_voidsuit_to_slot_or_del_with_refit(obj/item/clothing/suit/space/void/W as obj, slot, species = SPECIES_HUMAN)
W.refit_for_species(species)
return equip_to_slot_if_possible(W, slot, 1, 1, 0)
/mob/proc/equip_voidhelm_to_slot_or_del_with_refit(obj/item/clothing/head/helmet/space/void/W as obj, slot, species = SPECIES_HUMAN)
W.refit_for_species(species)
return equip_to_slot_if_possible(W, slot, 1, 1, 0)
//Checks if a given slot can be accessed at this time, either to equip or unequip I
/mob/proc/slot_is_accessible(var/slot, var/obj/item/I, mob/user=null)
return 1
+28
View File
@@ -154,3 +154,31 @@
key = "]"
flags = RESTRICTED
syllables = list("chan","ange","thi","se")
//Bloblang.
/datum/language/blob
name = LANGUAGE_BLOB
desc = "The massive processing power of the Blob's core gives the overmind finely tuned abilities to transmit messages to nearby life-forms through chemical signals."
speech_verb = "resonates"
ask_verb = "reverberates"
exclaim_verb = "shudders"
colour = "blob"
key = "}"
machine_understands = TRUE
flags = RESTRICTED
syllables = list("^", "˅", "-", "°", "~")
/datum/language/corticalborer/broadcast(var/mob/living/speaker,var/message,var/speaker_mask)
var/mob/living/simple_mob/animal/borer/B
if(istype(speaker,/mob/living/carbon))
var/mob/living/carbon/M = speaker
B = M.has_brain_worms()
else if(istype(speaker,/mob/living/simple_mob/animal/borer))
B = speaker
if(B)
speaker_mask = B.true_name
..(speaker,message,speaker_mask)
@@ -54,8 +54,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!"
@@ -66,8 +64,7 @@
speech_bubble_appearance = "ghost"
genders = list(PLURAL, NEUTER) //no sexual dymorphism
ambiguous_genders = TRUE //but just in case
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
@@ -46,10 +46,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
@@ -58,7 +54,7 @@
flesh_color = "#9ee02c"
blood_color = "#edf4d0" //sap!
base_color = "#1a5600"
reagent_tag = IS_ALRAUNE
blurb = "Alraunes are a rare sight in space. Their bodies are reminiscent of that of plants, and yet they share many\
@@ -449,7 +445,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))
@@ -475,6 +471,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
@@ -29,11 +29,11 @@
num_alternate_languages = 3
assisted_langs = list(LANGUAGE_EAL, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
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"),
@@ -55,7 +55,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))
@@ -13,6 +13,10 @@
"Rapala", "Neaera", "Stok", "Farwa", "Sobaka",
"Wolpin", "Saru", "Sparra")
spawn_flags = SPECIES_CAN_JOIN
wikilink="https://wiki.vore-station.net/Promethean"
genders = list(MALE, FEMALE, PLURAL, NEUTER)
color_mult = 1
mob_size = MOB_MEDIUM //As of writing, original was MOB_SMALL - Allows normal swapping
trashcan = 1 //They have goopy bodies. They can just dissolve things within them.
@@ -30,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,
)
@@ -59,6 +59,8 @@
siemens_coefficient = 1.5 //Very bad zappy times
rarity_value = 5
genders = list(MALE, FEMALE, PLURAL, NEUTER)
has_organ = list(
O_BRAIN = /obj/item/organ/internal/mmi_holder/posibrain/nano,
O_ORCH = /obj/item/organ/internal/nano/orchestrator,
@@ -96,9 +98,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()
@@ -170,7 +170,7 @@
H.forceMove(H.temporary_form.drop_location())
H.ckey = H.temporary_form.ckey
QDEL_NULL(H.temporary_form)
to_chat(H, "<span class='warning'>You died as a Protean. Please sit out of the round for at least 60 minutes before respawning, to represent the time it would take to ship a new-you to the station.</span>")
for(var/obj/item/organ/I in H.internal_organs)
@@ -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.
@@ -57,6 +52,8 @@
flags = NO_SCAN | NO_INFECT //Dying as a chimera is, quite literally, a death sentence. Well, if it wasn't for their revive, that is.
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
genders = list(MALE, FEMALE, PLURAL, NEUTER)
has_organ = list( //Same organ list as tajarans.
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
@@ -295,7 +292,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))
@@ -321,6 +318,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
@@ -402,6 +406,8 @@
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)
flesh_color = "#AFA59E" //Gray-ish. Not sure if this is really needed, but eh.
base_color = "#333333" //Blackish-gray
blood_color = "#0952EF" //Spiders have blue blood.
@@ -458,13 +464,12 @@
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED | SPECIES_WHITELIST_SELECTABLE
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)
heat_discomfort_strings = list(
"Your fur prickles in the heat.",
"You feel uncomfortably warm.",
@@ -36,11 +36,12 @@
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)
heat_discomfort_strings = list(
"Your fur prickles in the heat.",
"You feel uncomfortably warm.",
@@ -78,7 +79,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
@@ -98,6 +98,8 @@
primitive_form = "Sobaka"
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
@@ -125,7 +127,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
@@ -142,6 +144,8 @@
primitive_form = "Sparra"
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
@@ -191,6 +195,8 @@
blood_color = "#240bc4"
color_mult = 1
genders = list(MALE, FEMALE, PLURAL, NEUTER)
heat_discomfort_strings = list(
"Your fur prickles in the heat.",
"You feel uncomfortably warm.",
@@ -215,7 +221,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)
blurb = "Vulpkanin are a species of sharp-witted canine-pideds residing on the planet Altam just barely within the \
dual-star Vazzend system. Their politically de-centralized society and independent natures have led them to become a species and \
@@ -232,6 +238,8 @@
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)
flesh_color = "#966464"
base_color = "#B43214"
@@ -247,7 +255,7 @@
color_mult = 1
min_age = 18
gluttonous = 0
inherent_verbs = list(/mob/living/proc/shred_limb)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
descriptors = list()
wikilink="https://yawn.izac.live/Unathi"
@@ -259,8 +267,9 @@
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
genders = list(MALE, FEMALE, PLURAL, NEUTER)
wikilink="https://yawn.izac.live/Tajaran"
agility = 90
@@ -272,12 +281,14 @@
min_age = 18
reagent_tag = null
assisted_langs = list(LANGUAGE_EAL, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
wikilink="https://yawn.izac.live/Skrell"
/datum/species/zaddat
spawn_flags = SPECIES_CAN_JOIN
min_age = 18
gluttonous = 0
genders = list(MALE, FEMALE, PLURAL, NEUTER)
descriptors = list()
wikilink="https://yawn.izac.live/Zaddat"
@@ -292,6 +303,7 @@
/datum/species/diona
spawn_flags = SPECIES_CAN_JOIN
min_age = 18
genders = list(MALE, FEMALE, PLURAL, NEUTER)
wikilink="https://yawn.izac.live/Diona"
/datum/species/teshari
@@ -305,6 +317,7 @@
push_flags = ~HEAVY //Allows them to use micro step code.
swap_flags = ~HEAVY
gluttonous = 0
genders = list(MALE, FEMALE, PLURAL, NEUTER)
descriptors = list()
wikilink="https://yawn.izac.live/Teshari"
agility = 90
@@ -312,7 +325,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
)
@@ -326,6 +338,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)
base_color = "#EECEB3"
wikilink="https://yawn.izac.live/Human"
@@ -338,7 +351,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
)
@@ -356,6 +368,7 @@ datum/species/harpy
secondary_langs = list(LANGUAGE_BIRDSONG)
name_language = null
color_mult = 1
genders = list(MALE, FEMALE, PLURAL, NEUTER)
inherent_verbs = list(/mob/living/proc/flying_toggle,/mob/living/proc/start_wings_hovering)
min_age = 18
@@ -441,8 +454,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
@@ -452,8 +463,7 @@ datum/species/harpy
speech_bubble_appearance = "ghost"
genders = list(PLURAL, NEUTER) //no sexual dymorphism
ambiguous_genders = TRUE //but just in case
genders = list(MALE, FEMALE, PLURAL, NEUTER)
breath_type = null
poison_type = null
@@ -514,6 +524,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)
flesh_color = "#AFA59E"
base_color = "#333333"
@@ -553,6 +564,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)
blood_color = "#12ff12"
flesh_color = "#201730"
@@ -563,4 +575,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 = "Brutal Predation"
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)
+1 -1
View File
@@ -181,7 +181,7 @@
..()
/mob/living/blob_act(var/obj/structure/blob/B)
if(stat == DEAD || faction == "blob")
if(stat == DEAD || faction == B.faction)
return
var/damage = rand(30, 40)
@@ -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
@@ -141,6 +141,8 @@
to_chat(cleaned_human, "<span class='warning'>[src] cleans your face!</span>")
/mob/living/silicon/robot/proc/vr_sprite_check()
if(custom_sprite == TRUE)
return
if(wideborg == TRUE)
if(icontype== "Drake") // Why, Why can't we have normal nice things
icon = 'icons/mob/drakeborg/drakeborg_vr.dmi'
@@ -50,9 +50,13 @@
/mob/living/simple_mob/blob/blob_act(obj/structure/blob/B)
if(!overmind && B.overmind)
overmind = B.overmind
faction = B.overmind.blob_type.faction
update_icon()
if(stat != DEAD && health < maxHealth)
if(faction != B.faction && B.overmind)
adjustBruteLoss(rand(B.overmind.blob_type.damage_lower, B.overmind.blob_type.damage_upper))
else if(stat != DEAD && health < maxHealth)
adjustBruteLoss(-maxHealth*0.0125)
adjustFireLoss(-maxHealth*0.0125)
@@ -73,7 +77,7 @@
for(var/obj/item/I in items)
if(istype(I, /obj/item/weapon/blobcore_chunk))
var/obj/item/weapon/blobcore_chunk/BC = I
if(!overmind || (BC.blob_type && overmind.blob_type.type == BC.blob_type.type))
if(!overmind || (BC.blob_type && overmind.blob_type.type == BC.blob_type.type) || BC.blob_type.faction == faction)
ally = TRUE
break
@@ -81,6 +81,13 @@
max_n2 = 0
has_eye_glow = TRUE
/mob/living/simple_mob/otie/feral/chubby
name = "chubby mutated feral otie"
desc = "The classic bioengineered longdog. No pets. Only bite. This one has mutated from too much time out on the surface of Virgo-3B. What an absolute unit."
icon_state = "photiec"
icon_living = "photiec"
icon_rest = "photiec_rest"
/mob/living/simple_mob/otie/red
name = "feral red otie"
desc = "Seems this ominous looking longdog has been infused with wicked infernal forces."
@@ -109,6 +116,15 @@
faction = "neutral"
tamed = 1
/mob/living/simple_mob/otie/red/chubby //gets the pet2tame feature and doesn't kill you right away
name = "chubby red otie"
desc = "Seems this ominous looking longdog has been infused with wicked infernal forces. What an absolute unit."
icon_state = "hotiec"
icon_living = "hotiec"
icon_rest = "hotiec_rest"
faction = "neutral"
tamed = 1
/mob/living/simple_mob/otie/friendly //gets the pet2tame feature and doesn't kill you right away
name = "otie"
desc = "The classic bioengineered longdog. This one might even tolerate you!"
@@ -158,7 +174,7 @@
/mob/living/simple_mob/otie/security //tame by default unless you're a marked crimester. can be befriended to follow with pets tho.
name = "guard otie"
desc = "The VARMAcorp bioengineering division flagship product on trained optimal snowflake guard dogs."
desc = "The VARMAcorp bioengineering division flagship product on big mean guard dogs."
icon_state = "sotie"
icon_living = "sotie"
icon_rest = "sotie_rest"
@@ -176,7 +192,7 @@
/mob/living/simple_mob/otie/security/chubby
name = "chubby guard otie"
desc = "The VARMAcorp bioengineering division flagship product on trained optimal snowflake guard dogs. What an absolute unit."
desc = "The VARMAcorp bioengineering division flagship product on big mean guard dogs. What an absolute unit."
icon_state = "fsotie"
icon_living = "fsotie"
icon_rest = "fsotie_rest"
@@ -184,7 +200,7 @@
/mob/living/simple_mob/otie/security/phoron
name = "mutated guard otie"
desc = "An extra rare phoron resistant version of the VARMAcorp trained snowflake guard dogs for infernal environments."
desc = "An extra rare phoron resistant version of the VARMAcorp trained guard dogs adapted for hostile environments."
tt_desc = "Otus phoronis"
icon_state = "secphotie"
icon_living = "secphotie"
@@ -201,7 +217,7 @@
/mob/living/simple_mob/otie/security/phoron/red
name = "red guard otie"
desc = "An ominous looking version of the VARMAcorp trained snowflake guard dogs."
desc = "An ominous looking version of the big mean VARMAcorp guard dogs."
tt_desc = "Otus infernalis"
icon_state = "sechotie"
icon_living = "sechotie"
@@ -209,6 +225,13 @@
icon_dead = "sechotie-dead"
maxbodytemp = 1000
/mob/living/simple_mob/otie/security/phoron/red/chubby
name = "chubby red guard otie"
desc = "An ominous looking version of the big mean VARMAcorp guard dogs. What an absolute unit."
icon_state = "hotiesc"
icon_living = "hotiesc"
icon_rest = "hotiesc_rest"
/mob/living/simple_mob/otie/attackby(var/obj/item/O, var/mob/user) // Trade donuts for bellybrig victims.
if(istype(O, /obj/item/weapon/reagent_containers/food))
qdel(O)
@@ -66,7 +66,6 @@
name = "dire wolf"
desc = "The biggest and baddest wolf around."
tt_desc = "Canis maxdirus"
icon = 'icons/mob/vore64x32.dmi'
icon_dead = "direwolf-dead"
icon_living = "direwolf"
@@ -108,12 +107,27 @@
name = "large dog"
desc = "The biggest and goodest dog around."
tt_desc = "Canis maxdirus familiaris"
icon_dead = "diredog-dead"
icon_living = "diredog"
icon_state = "diredog"
icon_rest = "diredog_rest"
/mob/living/simple_mob/animal/wolf/direwolf/dog/sec
name = "large guard dog"
desc = "The biggest and goodest guard dog around."
icon_dead = "diredogs-dead"
icon_living = "diredogs"
icon_state = "diredogs"
icon_rest = "diredogs_rest"
/mob/living/simple_mob/animal/wolf/direwolf/sec
name = "dire guard wolf"
desc = "The biggest and baddest guard wolf around."
icon_dead = "direwolfs-dead"
icon_living = "direwolfs"
icon_state = "direwolfs"
icon_rest = "direwolfs_rest"
/mob/living/simple_mob/animal/wolf/direwolf/rykka
name = "Rykka"
desc = "This big canine looks like a GSD. It has a collar tagged, 'Bitch'"
+1 -1
View File
@@ -289,7 +289,7 @@
// If we have a grab
var/list/grablist = my_mob.ret_grab()
if(grablist.len)
if(LAZYLEN(grablist))
grablist -= my_mob // Just in case we're in a circular grab chain
// It's just us and another person
+1 -1
View File
@@ -37,7 +37,7 @@
if(input)
log_subtle(message,src)
message = "<span class='emote'><B>[src]</B> <I>[input]</I></span>"
message = "<span class='emote_subtle'><B>[src]</B> <I>[input]</I></span>"
else
return
+3 -3
View File
@@ -33,7 +33,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain)
if(!owner || owner.stat == DEAD)
defib_timer = max(--defib_timer, 0)
else
defib_timer = min(++defib_timer, (config.defib_timer MINUTES) / 2)
defib_timer = min(++defib_timer, (config.defib_timer MINUTES) / 20) // Time vars measure things in ticks. Life tick happens every ~2 seconds, therefore dividing by 20
/obj/item/organ/internal/brain/proc/can_assist()
return can_assist
@@ -81,7 +81,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain)
/obj/item/organ/internal/brain/New()
..()
health = config.default_brain_health
defib_timer = (config.defib_timer MINUTES) / 2
defib_timer = (config.defib_timer MINUTES) / 20 // Time vars measure things in ticks. Life tick happens every ~2 seconds, therefore dividing by 20
spawn(5)
if(brainmob)
butcherable = FALSE
@@ -103,7 +103,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain)
if(istype(H))
brainmob.dna = H.dna.Clone()
brainmob.timeofhostdeath = H.timeofdeath
brainmob.ooc_notes = H.ooc_notes //VOREStation Edit
brainmob.ooc_notes = H.ooc_notes //VOREStation Edit
// Copy modifiers.
for(var/datum/modifier/M in H.modifiers)
+522
View File
@@ -0,0 +1,522 @@
var/datum/planet/virgo4/planet_virgo4 = null
/datum/time/virgo4
seconds_in_day = 24 HOURS
/datum/planet/virgo4
name = "Virgo-4"
desc = "Zorren homeworld. Mostly dry and desolate, but ocean and fresh water are present, with scattered vegitation." //rewrite me
current_time = new /datum/time/virgo4()
// expected_z_levels = list(1) // This is defined elsewhere.
planetary_wall_type = /turf/unsimulated/wall/planetary/normal/virgo4
/datum/planet/virgo4/New()
..()
planet_virgo4 = src
weather_holder = new /datum/weather_holder/virgo4(src)
/datum/planet/virgo4/update_sun()
..()
var/datum/time/time = current_time
var/length_of_day = time.seconds_in_day / 10 / 60 / 60
var/noon = length_of_day / 2
var/distance_from_noon = abs(text2num(time.show_time("hh")) - noon)
sun_position = distance_from_noon / noon
sun_position = abs(sun_position - 1)
var/low_brightness = null
var/high_brightness = null
var/low_color = null
var/high_color = null
var/min = 0
switch(sun_position)
if(0 to 0.30) // Night
low_brightness = 0.1
low_color = "#000066"
high_brightness = 0.2
high_color = "#66004D"
min = 0
if(0.30 to 0.40) // Twilight
low_brightness = 0.4
low_color = "#66004D"
high_brightness = 0.6
high_color = "#CC3300"
min = 0.40
if(0.40 to 0.50) // Sunrise/set
low_brightness = 0.7
low_color = "#CC3300"
high_brightness = 0.9
high_color = "#FF9933"
min = 0.50
if(0.50 to 1.00) // Noon
low_brightness = 1
low_color = "#DDDDDD"
high_brightness = 2
high_color = "#FFFFFF"
min = 0.70
var/interpolate_weight = (abs(min - sun_position)) * 4
var/weather_light_modifier = 1
if(weather_holder && weather_holder.current_weather)
weather_light_modifier = weather_holder.current_weather.light_modifier
var/new_brightness = (LERP(low_brightness, high_brightness, interpolate_weight) ) * weather_light_modifier
var/new_color = null
if(weather_holder && weather_holder.current_weather && weather_holder.current_weather.light_color)
new_color = weather_holder.current_weather.light_color
else
var/list/low_color_list = hex2rgb(low_color)
var/low_r = low_color_list[1]
var/low_g = low_color_list[2]
var/low_b = low_color_list[3]
var/list/high_color_list = hex2rgb(high_color)
var/high_r = high_color_list[1]
var/high_g = high_color_list[2]
var/high_b = high_color_list[3]
var/new_r = LERP(low_r, high_r, interpolate_weight)
var/new_g = LERP(low_g, high_g, interpolate_weight)
var/new_b = LERP(low_b, high_b, interpolate_weight)
new_color = rgb(new_r, new_g, new_b)
spawn(1)
update_sun_deferred(2, new_brightness, new_color)
/datum/weather_holder/virgo4
temperature = T0C
allowed_weather_types = list(
WEATHER_CLEAR = new /datum/weather/virgo4/clear(),
WEATHER_OVERCAST = new /datum/weather/virgo4/overcast(),
WEATHER_LIGHT_SNOW = new /datum/weather/virgo4/light_snow(),
WEATHER_SNOW = new /datum/weather/virgo4/snow(),
WEATHER_BLIZZARD = new /datum/weather/virgo4/blizzard(),
WEATHER_RAIN = new /datum/weather/virgo4/rain(),
WEATHER_STORM = new /datum/weather/virgo4/storm(),
WEATHER_HAIL = new /datum/weather/virgo4/hail(),
WEATHER_BLOOD_MOON = new /datum/weather/virgo4/blood_moon(),
WEATHER_EMBERFALL = new /datum/weather/virgo4/emberfall(),
WEATHER_ASH_STORM = new /datum/weather/virgo4/ash_storm(),
WEATHER_FALLOUT = new /datum/weather/virgo4/fallout()
)
roundstart_weather_chances = list(
WEATHER_CLEAR = 50,
WEATHER_OVERCAST = 10,
WEATHER_RAIN = 1
)
/datum/weather/virgo4
name = "virgo4"
temp_high = 303.15 // 30c
temp_low = 298.15 // 25c
/datum/weather/virgo4/clear
name = "clear"
transition_chances = list(
WEATHER_CLEAR = 60,
WEATHER_OVERCAST = 20)
transition_messages = list(
"The sky clears up.",
"The sky is visible.",
"The weather is calm."
)
sky_visible = TRUE
observed_message = "The sky is clear."
/datum/weather/virgo4/overcast
name = "overcast"
temp_high = 293.15 // 20c
temp_low = 288.15 // 15c
light_modifier = 0.8
transition_chances = list(
WEATHER_CLEAR = 25,
WEATHER_OVERCAST = 50,
WEATHER_RAIN = 5
)
observed_message = "It is overcast, all you can see are clouds."
transition_messages = list(
"All you can see above are clouds.",
"Clouds cut off your view of the sky.",
"It's very cloudy."
)
/datum/weather/virgo4/light_snow
name = "light snow"
icon_state = "snowfall_light"
temp_high = 268.15 // -5c
temp_low = 263.15 // -10c
light_modifier = 0.7
transition_chances = list(
WEATHER_LIGHT_SNOW = 100
)
observed_message = "It is snowing lightly."
transition_messages = list(
"Small snowflakes begin to fall from above.",
"It begins to snow lightly.",
)
/datum/weather/virgo4/snow
name = "moderate snow"
icon_state = "snowfall_med"
temp_high = 268.15 // -5c
temp_low = 263.15 // -10c
wind_high = 2
wind_low = 0
light_modifier = 0.5
flight_failure_modifier = 5
transition_chances = list(
WEATHER_LIGHT_SNOW = 100
)
observed_message = "It is snowing."
transition_messages = list(
"It's starting to snow.",
"The air feels much colder as snowflakes fall from above."
)
outdoor_sounds_type = /datum/looping_sound/weather/outside_snow
indoor_sounds_type = /datum/looping_sound/weather/inside_snow
/datum/weather/virgo4/snow/process_effects()
..()
for(var/turf/simulated/floor/outdoors/snow/S in SSplanets.new_outdoor_turfs) //This didn't make any sense before SSplanets, either
if(S.z in holder.our_planet.expected_z_levels)
for(var/dir_checked in cardinal)
var/turf/simulated/floor/T = get_step(S, dir_checked)
if(istype(T))
if(istype(T, /turf/simulated/floor/outdoors) && prob(33))
T.chill()
/datum/weather/virgo4/blizzard
name = "blizzard"
icon_state = "snowfall_heavy"
temp_high = 268.15 // -5c
temp_low = 263.15 // -10c
wind_high = 4
wind_low = 2
light_modifier = 0.3
flight_failure_modifier = 10
transition_chances = list(
WEATHER_BLIZZARD = 100
)
observed_message = "A blizzard blows snow everywhere."
transition_messages = list(
"Strong winds howl around you as a blizzard appears.",
"It starts snowing heavily, and it feels extremly cold now."
)
outdoor_sounds_type = /datum/looping_sound/weather/outside_blizzard
indoor_sounds_type = /datum/looping_sound/weather/inside_blizzard
/datum/weather/virgo4/blizzard/process_effects()
..()
for(var/turf/simulated/floor/outdoors/snow/S in SSplanets.new_outdoor_turfs) //This didn't make any sense before SSplanets, either
if(S.z in holder.our_planet.expected_z_levels)
for(var/dir_checked in cardinal)
var/turf/simulated/floor/T = get_step(S, dir_checked)
if(istype(T))
if(istype(T, /turf/simulated/floor/outdoors) && prob(50))
T.chill()
/datum/weather/virgo4/rain
name = "rain"
icon_state = "rain"
temp_high = 288.15 // 15c
temp_low = 283.15 // 10c
wind_high = 2
wind_low = 1
light_modifier = 0.5
effect_message = "<span class='warning'>Rain falls on you.</span>"
transition_chances = list(
WEATHER_OVERCAST = 25,
WEATHER_RAIN = 50
)
observed_message = "It is raining."
transition_messages = list(
"The sky is dark, and rain falls down upon you."
)
/datum/weather/virgo4/rain/process_effects()
..()
for(var/mob/living/L in living_mob_list)
if(L.z in holder.our_planet.expected_z_levels)
var/turf/T = get_turf(L)
if(!T.outdoors)
continue // They're indoors, so no need to rain on them.
// If they have an open umbrella, it'll guard from rain
if(istype(L.get_active_hand(), /obj/item/weapon/melee/umbrella))
var/obj/item/weapon/melee/umbrella/U = L.get_active_hand()
if(U.open)
if(show_message)
to_chat(L, "<span class='notice'>Rain patters softly onto your umbrella.</span>")
continue
else if(istype(L.get_inactive_hand(), /obj/item/weapon/melee/umbrella))
var/obj/item/weapon/melee/umbrella/U = L.get_inactive_hand()
if(U.open)
if(show_message)
to_chat(L, "<span class='notice'>Rain patters softly onto your umbrella.</span>")
continue
L.water_act(1)
if(show_message)
to_chat(L, effect_message)
/datum/weather/virgo4/storm
name = "storm"
icon_state = "storm"
wind_high = 4
wind_low = 2
light_modifier = 0.3
flight_failure_modifier = 10
effect_message = "<span class='warning'>Rain falls on you, drenching you in water.</span>"
var/next_lightning_strike = 0 // world.time when lightning will strike.
var/min_lightning_cooldown = 5 SECONDS
var/max_lightning_cooldown = 1 MINUTE
observed_message = "An intense storm pours down over the region."
transition_messages = list(
"You feel intense winds hit you as the weather takes a turn for the worst.",
"Loud thunder is heard in the distance.",
"A bright flash heralds the approach of a storm."
)
transition_chances = list(
WEATHER_STORM = 100
)
/datum/weather/virgo4/storm/process_effects()
..()
for(var/mob/living/L in living_mob_list)
if(L.z in holder.our_planet.expected_z_levels)
var/turf/T = get_turf(L)
if(!T.outdoors)
continue // They're indoors, so no need to rain on them.
// If they have an open umbrella, it'll guard from rain
if(istype(L.get_active_hand(), /obj/item/weapon/melee/umbrella))
var/obj/item/weapon/melee/umbrella/U = L.get_active_hand()
if(U.open)
if(show_message)
to_chat(L, "<span class='notice'>Rain showers loudly onto your umbrella!</span>")
continue
else if(istype(L.get_inactive_hand(), /obj/item/weapon/melee/umbrella))
var/obj/item/weapon/melee/umbrella/U = L.get_inactive_hand()
if(U.open)
if(show_message)
to_chat(L, "<span class='notice'>Rain showers loudly onto your umbrella!</span>")
continue
L.water_act(2)
if(show_message)
to_chat(L, effect_message)
handle_lightning()
// This gets called to do lightning periodically.
// There is a seperate function to do the actual lightning strike, so that badmins can play with it.
/datum/weather/virgo4/storm/proc/handle_lightning()
if(world.time < next_lightning_strike)
return // It's too soon to strike again.
next_lightning_strike = world.time + rand(min_lightning_cooldown, max_lightning_cooldown)
var/turf/T = pick(holder.our_planet.planet_floors) // This has the chance to 'strike' the sky, but that might be a good thing, to scare reckless pilots.
lightning_strike(T)
/datum/weather/virgo4/hail
name = "hail"
icon_state = "hail"
light_modifier = 0.3
flight_failure_modifier = 15
timer_low_bound = 2
timer_high_bound = 5
effect_message = "<span class='warning'>The hail smacks into you!</span>"
transition_chances = list(
WEATHER_HAIL = 100
)
observed_message = "Ice is falling from the sky."
transition_messages = list(
"Ice begins to fall from the sky.",
"It begins to hail.",
"An intense chill is felt, and chunks of ice start to fall from the sky, towards you."
)
/datum/weather/virgo4/hail/process_effects()
..()
for(var/humie in human_mob_list)
var/mob/living/carbon/human/H = humie
if(H.z in holder.our_planet.expected_z_levels)
var/turf/T = get_turf(H)
if(!T.outdoors)
continue // They're indoors, so no need to pelt them with ice.
// If they have an open umbrella, it'll guard from hail
var/obj/item/weapon/melee/umbrella/U
if(istype(H.get_active_hand(), /obj/item/weapon/melee/umbrella))
U = H.get_active_hand()
else if(istype(H.get_inactive_hand(), /obj/item/weapon/melee/umbrella))
U = H.get_inactive_hand()
if(U && U.open)
if(show_message)
to_chat(H, "<span class='notice'>Hail patters onto your umbrella.</span>")
continue
var/target_zone = pick(BP_ALL)
var/amount_blocked = H.run_armor_check(target_zone, "melee")
var/amount_soaked = H.get_armor_soak(target_zone, "melee")
var/damage = rand(1,3)
if(amount_blocked >= 30)
continue // No need to apply damage. Hardhats are 30. They should probably protect you from hail on your head.
//Voidsuits are likewise 40, and riot, 80. Clothes are all less than 30.
if(amount_soaked >= damage)
continue // No need to apply damage.
H.apply_damage(damage, BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail")
if(show_message)
to_chat(H, effect_message)
/datum/weather/virgo4/blood_moon
name = "blood moon"
light_modifier = 0.5
light_color = "#FF0000"
temp_high = 293.15 // 20c
temp_low = 283.15 // 10c
flight_failure_modifier = 25
transition_chances = list(
WEATHER_BLOODMOON = 100
)
observed_message = "Everything is red. Something really ominous is going on."
transition_messages = list(
"The sky turns blood red!"
)
outdoor_sounds_type = /datum/looping_sound/weather/wind
indoor_sounds_type = /datum/looping_sound/weather/wind/indoors
// Ash and embers fall forever, such as from a volcano or something.
/datum/weather/virgo4/emberfall
name = "emberfall"
icon_state = "ashfall_light"
light_modifier = 0.7
light_color = "#880000"
temp_high = 293.15 // 20c
temp_low = 283.15 // 10c
flight_failure_modifier = 20
transition_chances = list(
WEATHER_EMBERFALL = 100
)
observed_message = "Soot, ash, and embers float down from above."
transition_messages = list(
"Gentle embers waft down around you like grotesque snow."
)
outdoor_sounds_type = /datum/looping_sound/weather/wind
indoor_sounds_type = /datum/looping_sound/weather/wind/indoors
// Like the above but a lot more harmful.
/datum/weather/virgo4/ash_storm
name = "ash storm"
icon_state = "ashfall_heavy"
light_modifier = 0.1
light_color = "#FF0000"
temp_high = 323.15 // 50c
temp_low = 313.15 // 40c
wind_high = 6
wind_low = 3
flight_failure_modifier = 50
transition_chances = list(
WEATHER_ASH_STORM = 100
)
observed_message = "All that can be seen is black smoldering ash."
transition_messages = list(
"Smoldering clouds of scorching ash billow down around you!"
)
// Lets recycle.
outdoor_sounds_type = /datum/looping_sound/weather/outside_blizzard
indoor_sounds_type = /datum/looping_sound/weather/inside_blizzard
/datum/weather/virgo4/ash_storm/process_effects()
..()
for(var/thing in living_mob_list)
var/mob/living/L = thing
if(L.z in holder.our_planet.expected_z_levels)
var/turf/T = get_turf(L)
if(!T.outdoors)
continue // They're indoors, so no need to burn them with ash.
L.inflict_heat_damage(rand(1, 3))
// Totally radical.
/datum/weather/virgo4/fallout
name = "fallout"
icon_state = "fallout"
light_modifier = 0.7
light_color = "#CCFFCC"
flight_failure_modifier = 30
transition_chances = list(
WEATHER_FALLOUT = 100
)
observed_message = "Radioactive soot and ash rains down from the heavens."
transition_messages = list(
"Radioactive soot and ash start to float down around you, contaminating whatever they touch."
)
outdoor_sounds_type = /datum/looping_sound/weather/wind
indoor_sounds_type = /datum/looping_sound/weather/wind/indoors
// How much radiation a mob gets while on an outside tile.
var/direct_rad_low = RAD_LEVEL_LOW
var/direct_rad_high = RAD_LEVEL_MODERATE
// How much radiation is bursted onto a random tile near a mob.
var/fallout_rad_low = RAD_LEVEL_HIGH
var/fallout_rad_high = RAD_LEVEL_VERY_HIGH
/datum/weather/virgo4/fallout/process_effects()
..()
for(var/thing in living_mob_list)
var/mob/living/L = thing
if(L.z in holder.our_planet.expected_z_levels)
irradiate_nearby_turf(L)
var/turf/T = get_turf(L)
if(!T.outdoors)
continue // They're indoors, so no need to irradiate them with fallout.
L.rad_act(rand(direct_rad_low, direct_rad_high))
// This makes random tiles near people radioactive for awhile.
// Tiles far away from people are left alone, for performance.
/datum/weather/virgo4/fallout/proc/irradiate_nearby_turf(mob/living/L)
if(!istype(L))
return
var/list/turfs = RANGE_TURFS(world.view, L)
var/turf/T = pick(turfs) // We get one try per tick.
if(!istype(T))
return
if(T.outdoors)
SSradiation.radiate(T, rand(fallout_rad_low, fallout_rad_high))
/turf/unsimulated/wall/planetary/normal/virgo4
name = "deep ocean"
alpha = 0
/obj/machinery/power/smes/buildable/offmap_spawn/empty/New()
..(1)
charge = 0
RCon = TRUE
input_level = input_level_max
output_level = output_level_max
input_attempt = TRUE
@@ -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
+237 -26
View File
@@ -1,3 +1,4 @@
/datum/tgui_module/appearance_changer
name = "Appearance Editor"
tgui_id = "AppearanceChanger"
@@ -24,6 +25,10 @@
var/camera_diff_y = -1
var/camera_diff_z = -1
var/list/valid_earstyles = list()
var/list/valid_tailstyles = list()
var/list/valid_wingstyles = list()
/datum/tgui_module/appearance_changer/New(
var/host,
mob/living/carbon/human/H,
@@ -68,6 +73,7 @@
qdel(cam_screen)
QDEL_LIST(cam_plane_masters)
qdel(cam_background)
cut_data()
return ..()
/datum/tgui_module/appearance_changer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
@@ -84,22 +90,28 @@
if("race")
if(can_change(APPEARANCE_RACE) && (params["race"] in valid_species))
if(target.change_species(params["race"]))
cut_and_generate_data()
cut_data()
generate_data(usr)
changed_hook(APPEARANCECHANGER_CHANGED_RACE)
return 1
if("gender")
if(can_change(APPEARANCE_GENDER) && (params["gender"] in get_genders()))
if(target.change_gender(params["gender"]))
cut_and_generate_data()
cut_data()
generate_data(usr)
changed_hook(APPEARANCECHANGER_CHANGED_GENDER)
return 1
if("gender_id")
if(can_change(APPEARANCE_GENDER) && (params["gender_id"] in all_genders_define_list))
target.identifying_gender = params["gender_id"]
changed_hook(APPEARANCECHANGER_CHANGED_GENDER_ID)
return 1
if("skin_tone")
if(can_change_skin_tone())
var/new_s_tone = input(usr, "Choose your character's skin-tone:\n(Light 1 - 220 Dark)", "Skin Tone", -target.s_tone + 35) as num|null
if(isnum(new_s_tone) && can_still_topic(usr, state))
new_s_tone = 35 - max(min( round(new_s_tone), 220),1)
changed_hook(APPEARANCECHANGER_CHANGED_SKINTONE)
return target.change_skin_tone(new_s_tone)
if("skin_color")
if(can_change_skin_color())
@@ -110,11 +122,13 @@
var/b_skin = hex2num(copytext(new_skin, 6, 8))
if(target.change_skin_color(r_skin, g_skin, b_skin))
update_dna()
changed_hook(APPEARANCECHANGER_CHANGED_SKINCOLOR)
return 1
if("hair")
if(can_change(APPEARANCE_HAIR) && (params["hair"] in valid_hairstyles))
if(target.change_hair(params["hair"]))
update_dna()
changed_hook(APPEARANCECHANGER_CHANGED_HAIRSTYLE)
return 1
if("hair_color")
if(can_change(APPEARANCE_HAIR_COLOR))
@@ -125,11 +139,13 @@
var/b_hair = hex2num(copytext(new_hair, 6, 8))
if(target.change_hair_color(r_hair, g_hair, b_hair))
update_dna()
changed_hook(APPEARANCECHANGER_CHANGED_HAIRCOLOR)
return 1
if("facial_hair")
if(can_change(APPEARANCE_FACIAL_HAIR) && (params["facial_hair"] in valid_facial_hairstyles))
if(target.change_facial_hair(params["facial_hair"]))
update_dna()
changed_hook(APPEARANCECHANGER_CHANGED_F_HAIRSTYLE)
return 1
if("facial_hair_color")
if(can_change(APPEARANCE_FACIAL_HAIR_COLOR))
@@ -140,6 +156,7 @@
var/b_facial = hex2num(copytext(new_facial, 6, 8))
if(target.change_facial_hair_color(r_facial, g_facial, b_facial))
update_dna()
changed_hook(APPEARANCECHANGER_CHANGED_F_HAIRCOLOR)
return 1
if("eye_color")
if(can_change(APPEARANCE_EYE_COLOR))
@@ -150,10 +167,115 @@
var/b_eyes = hex2num(copytext(new_eyes, 6, 8))
if(target.change_eye_color(r_eyes, g_eyes, b_eyes))
update_dna()
changed_hook(APPEARANCECHANGER_CHANGED_EYES)
return 1
// VOREStation Add - Ears/Tails/Wings
if("ear")
if(can_change(APPEARANCE_ALL_HAIR))
var/datum/sprite_accessory/ears/instance = locate(params["ref"])
if(params["clear"])
instance = null
if(!istype(instance) && !params["clear"])
return FALSE
owner.ear_style = instance
owner.update_hair()
update_dna()
changed_hook(APPEARANCECHANGER_CHANGED_HAIRSTYLE)
return TRUE
if("ears_color")
if(can_change(APPEARANCE_HAIR_COLOR))
var/new_hair = input("Please select ear color.", "Ear Color", rgb(target.r_ears, target.g_ears, target.b_ears)) as color|null
if(new_hair && can_still_topic(usr, state))
target.r_ears = hex2num(copytext(new_hair, 2, 4))
target.g_ears = hex2num(copytext(new_hair, 4, 6))
target.b_ears = hex2num(copytext(new_hair, 6, 8))
update_dna()
owner.update_hair()
changed_hook(APPEARANCECHANGER_CHANGED_HAIRCOLOR)
return 1
if("ears2_color")
if(can_change(APPEARANCE_HAIR_COLOR))
var/new_hair = input("Please select secondary ear color.", "2nd Ear Color", rgb(target.r_ears2, target.g_ears2, target.b_ears2)) as color|null
if(new_hair && can_still_topic(usr, state))
target.r_ears2 = hex2num(copytext(new_hair, 2, 4))
target.g_ears2 = hex2num(copytext(new_hair, 4, 6))
target.b_ears2 = hex2num(copytext(new_hair, 6, 8))
update_dna()
owner.update_hair()
changed_hook(APPEARANCECHANGER_CHANGED_HAIRCOLOR)
return 1
if("tail")
if(can_change(APPEARANCE_ALL_HAIR))
var/datum/sprite_accessory/tail/instance = locate(params["ref"])
if(params["clear"])
instance = null
if(!istype(instance) && !params["clear"])
return FALSE
owner.tail_style = instance
owner.update_tail_showing()
update_dna()
changed_hook(APPEARANCECHANGER_CHANGED_HAIRSTYLE)
return TRUE
if("tail_color")
if(can_change(APPEARANCE_HAIR_COLOR))
var/new_hair = input("Please select tail color.", "Tail Color", rgb(target.r_tail, target.g_tail, target.b_tail)) as color|null
if(new_hair && can_still_topic(usr, state))
target.r_tail = hex2num(copytext(new_hair, 2, 4))
target.g_tail = hex2num(copytext(new_hair, 4, 6))
target.b_tail = hex2num(copytext(new_hair, 6, 8))
update_dna()
owner.update_tail_showing()
changed_hook(APPEARANCECHANGER_CHANGED_HAIRCOLOR)
return 1
if("tail2_color")
if(can_change(APPEARANCE_HAIR_COLOR))
var/new_hair = input("Please select secondary tail color.", "2nd Tail Color", rgb(target.r_tail2, target.g_tail2, target.b_tail2)) as color|null
if(new_hair && can_still_topic(usr, state))
target.r_tail2 = hex2num(copytext(new_hair, 2, 4))
target.g_tail2 = hex2num(copytext(new_hair, 4, 6))
target.b_tail2 = hex2num(copytext(new_hair, 6, 8))
update_dna()
owner.update_tail_showing()
changed_hook(APPEARANCECHANGER_CHANGED_HAIRCOLOR)
return 1
if("wing")
if(can_change(APPEARANCE_ALL_HAIR))
var/datum/sprite_accessory/wing/instance = locate(params["ref"])
if(params["clear"])
instance = null
if(!istype(instance) && !params["clear"])
return FALSE
owner.wing_style = instance
owner.update_wing_showing()
update_dna()
changed_hook(APPEARANCECHANGER_CHANGED_HAIRSTYLE)
return TRUE
if("wing_color")
if(can_change(APPEARANCE_HAIR_COLOR))
var/new_hair = input("Please select wing color.", "Wing Color", rgb(target.r_wing, target.g_wing, target.b_wing)) as color|null
if(new_hair && can_still_topic(usr, state))
target.r_wing = hex2num(copytext(new_hair, 2, 4))
target.g_wing = hex2num(copytext(new_hair, 4, 6))
target.b_wing = hex2num(copytext(new_hair, 6, 8))
update_dna()
owner.update_wing_showing()
changed_hook(APPEARANCECHANGER_CHANGED_HAIRCOLOR)
return 1
if("wing2_color")
if(can_change(APPEARANCE_HAIR_COLOR))
var/new_hair = input("Please select secondary wing color.", "2nd Wing Color", rgb(target.r_wing2, target.g_wing2, target.b_wing2)) as color|null
if(new_hair && can_still_topic(usr, state))
target.r_wing2 = hex2num(copytext(new_hair, 2, 4))
target.g_wing2 = hex2num(copytext(new_hair, 4, 6))
target.b_wing2 = hex2num(copytext(new_hair, 6, 8))
update_dna()
owner.update_wing_showing()
changed_hook(APPEARANCECHANGER_CHANGED_HAIRCOLOR)
return 1
// VOREStation Add End
return FALSE
/datum/tgui_module/appearance_changer/tgui_interact(mob/user, datum/tgui/ui = null, datum/tgui/parent_ui = null, datum/tgui_state/custom_state = GLOB.tgui_default_state)
/datum/tgui_module/appearance_changer/tgui_interact(mob/user, datum/tgui/ui = null, datum/tgui/parent_ui = null, datum/tgui_state/custom_state)
var/mob/living/carbon/human/target = owner
if(customize_usr)
if(!ishuman(user))
@@ -177,10 +299,39 @@
if(custom_state)
ui.set_state(custom_state)
/datum/tgui_module/appearance_changer/tgui_static_data(mob/user)
var/list/data = ..()
generate_data(usr)
if(can_change(APPEARANCE_RACE))
var/species[0]
for(var/specimen in valid_species)
species[++species.len] = list("specimen" = specimen)
data["species"] = species
if(can_change(APPEARANCE_HAIR))
var/hair_styles[0]
for(var/hair_style in valid_hairstyles)
hair_styles[++hair_styles.len] = list("hairstyle" = hair_style)
data["hair_styles"] = hair_styles
// VOREStation Add - Ears/Tails/Wings
data["ear_styles"] = valid_earstyles
data["tail_styles"] = valid_tailstyles
data["wing_styles"] = valid_wingstyles
// VOREStation Add End
if(can_change(APPEARANCE_FACIAL_HAIR))
var/facial_hair_styles[0]
for(var/facial_hair_style in valid_facial_hairstyles)
facial_hair_styles[++facial_hair_styles.len] = list("facialhairstyle" = facial_hair_style)
data["facial_hair_styles"] = facial_hair_styles
return data
/datum/tgui_module/appearance_changer/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
generate_data(check_whitelist, whitelist, blacklist)
differential_check()
var/mob/living/carbon/human/target = owner
@@ -194,11 +345,6 @@
data["gender"] = target.gender
data["gender_id"] = target.identifying_gender
data["change_race"] = can_change(APPEARANCE_RACE)
if(data["change_race"])
var/species[0]
for(var/specimen in valid_species)
species[++species.len] = list("specimen" = specimen)
data["species"] = species
data["change_gender"] = can_change(APPEARANCE_GENDER)
if(data["change_gender"])
@@ -213,30 +359,39 @@
data["change_hair"] = can_change(APPEARANCE_HAIR)
if(data["change_hair"])
var/hair_styles[0]
for(var/hair_style in valid_hairstyles)
hair_styles[++hair_styles.len] = list("hairstyle" = hair_style)
data["hair_styles"] = hair_styles
data["hair_style"] = target.h_style
// VOREStation Add - Ears/Tails/Wings
data["ear_style"] = target.ear_style
data["tail_style"] = target.tail_style
data["wing_style"] = target.wing_style
// VOREStation Add End
data["change_facial_hair"] = can_change(APPEARANCE_FACIAL_HAIR)
if(data["change_facial_hair"])
var/facial_hair_styles[0]
for(var/facial_hair_style in valid_facial_hairstyles)
facial_hair_styles[++facial_hair_styles.len] = list("facialhairstyle" = facial_hair_style)
data["facial_hair_styles"] = facial_hair_styles
data["facial_hair_style"] = target.f_style
data["change_skin_tone"] = can_change_skin_tone()
data["change_skin_color"] = can_change_skin_color()
if(data["change_skin_color"])
data["skin_color"] = rgb(target.r_skin, target.g_skin, target.b_skin)
data["change_eye_color"] = can_change(APPEARANCE_EYE_COLOR)
if(data["change_eye_color"])
data["eye_color"] = rgb(target.r_eyes, target.g_eyes, target.b_eyes)
data["change_hair_color"] = can_change(APPEARANCE_HAIR_COLOR)
if(data["change_hair_color"])
data["hair_color"] = rgb(target.r_hair, target.g_hair, target.b_hair)
// VOREStation Add - Ears/Tails/Wings
data["ears_color"] = rgb(target.r_ears, target.g_ears, target.b_ears)
data["ears2_color"] = rgb(target.r_ears2, target.g_ears2, target.b_ears2)
data["tail_color"] = rgb(target.r_tail, target.g_tail, target.b_tail)
data["tail2_color"] = rgb(target.r_tail2, target.g_tail2, target.b_tail2)
data["wing_color"] = rgb(target.r_wing, target.g_wing, target.b_wing)
data["wing2_color"] = rgb(target.r_wing2, target.g_wing2, target.b_wing2)
// VOREStation Add End
data["change_facial_hair_color"] = can_change(APPEARANCE_FACIAL_HAIR_COLOR)
if(data["change_facial_hair_color"])
data["facial_hair_color"] = rgb(target.r_facial, target.g_facial, target.b_facial)
@@ -315,26 +470,67 @@
return target && (flags & APPEARANCE_SKIN) && target.species.appearance_flags & HAS_SKIN_COLOR
/datum/tgui_module/appearance_changer/proc/cut_and_generate_data()
/datum/tgui_module/appearance_changer/proc/cut_data()
// Making the assumption that the available species remain constant
valid_hairstyles.Cut()
valid_facial_hairstyles.Cut()
valid_facial_hairstyles.Cut()
generate_data()
// VOREStation Add - Ears/Tails/Wings
valid_earstyles.Cut()
valid_tailstyles.Cut()
valid_wingstyles.Cut()
// VOREStation Add End
/datum/tgui_module/appearance_changer/proc/generate_data()
/datum/tgui_module/appearance_changer/proc/generate_data(mob/user)
var/mob/living/carbon/human/target = owner
if(customize_usr)
if(!ishuman(usr))
if(!ishuman(user))
return TRUE
target = usr
target = user
if(!target)
return
if(!valid_species.len)
if(!LAZYLEN(valid_species))
valid_species = target.generate_valid_species(check_whitelist, whitelist, blacklist)
if(!valid_hairstyles.len || !valid_facial_hairstyles.len)
if(!LAZYLEN(valid_hairstyles) || !LAZYLEN(valid_facial_hairstyles))
valid_hairstyles = target.generate_valid_hairstyles(check_gender = 0)
valid_facial_hairstyles = target.generate_valid_facial_hairstyles()
// VOREStation Add - Ears/Tails/Wings
if(!LAZYLEN(valid_earstyles))
for(var/path in ear_styles_list)
var/datum/sprite_accessory/ears/instance = ear_styles_list[path]
if(can_use_sprite(instance, target, user))
valid_earstyles.Add(list(list(
"name" = instance.name,
"instance" = REF(instance),
"color" = !!instance.do_colouration,
"second_color" = !!instance.extra_overlay,
)))
if(!LAZYLEN(valid_tailstyles))
for(var/path in tail_styles_list)
var/datum/sprite_accessory/tail/instance = tail_styles_list[path]
if(can_use_sprite(instance, target, user))
valid_tailstyles.Add(list(list(
"name" = instance.name,
"instance" = REF(instance),
"color" = !!instance.do_colouration,
"second_color" = !!instance.extra_overlay,
)))
if(!LAZYLEN(valid_wingstyles))
for(var/path in wing_styles_list)
var/datum/sprite_accessory/wing/instance = wing_styles_list[path]
if(can_use_sprite(instance, target, user))
valid_wingstyles.Add(list(list(
"name" = instance.name,
"instance" = REF(instance),
"color" = !!instance.do_colouration,
"second_color" = !!instance.extra_overlay,
)))
// VOREStation Add End
/datum/tgui_module/appearance_changer/proc/get_genders()
var/mob/living/carbon/human/target = owner
if(customize_usr)
@@ -349,10 +545,25 @@
possible_genders |= NEUTER
return possible_genders
// Used for subtypes to handle messaging or whatever.
/datum/tgui_module/appearance_changer/proc/changed_hook(flag)
return
// VOREStation Add - Ears/Tails/Wings
/datum/tgui_module/appearance_changer/proc/can_use_sprite(datum/sprite_accessory/X, mob/living/carbon/human/target, mob/user)
if(X.apply_restrictions && !(target.species.name in X.species_allowed))
return FALSE
if(LAZYLEN(X.ckeys_allowed) && !(user?.ckey in X.ckeys_allowed) && !(target.ckey in X.ckeys_allowed))
return FALSE
return TRUE
// VOREStation Add End
/datum/tgui_module/appearance_changer/mirror
name = "SalonPro Nano-Mirror&trade;"
flags = APPEARANCE_ALL_HAIR
customize_usr = TRUE
/datum/tgui_module/appearance_changer/mirror/coskit
name = "SalonPro Porta-Makeover Deluxe&trade;"
name = "SalonPro Porta-Makeover Deluxe&trade;"
@@ -0,0 +1,45 @@
/datum/tgui_module/appearance_changer/vore
name = "Appearance Editor (Vore)"
flags = APPEARANCE_ALL
/datum/tgui_module/appearance_changer/vore/tgui_state(mob/user)
return GLOB.tgui_conscious_state
/datum/tgui_module/appearance_changer/vore/tgui_status(mob/user, datum/tgui_state/state)
if(!isbelly(owner.loc))
return STATUS_CLOSE
return ..()
/datum/tgui_module/appearance_changer/vore/reload_cameraview()
cam_screen.vis_contents = list(owner)
cam_background.icon_state = "clear"
cam_background.fill_rect(1, 1, 1, 1)
local_skybox.cut_overlays()
/datum/tgui_module/appearance_changer/vore/tgui_close(mob/user)
. = ..()
QDEL_IN(src, 1)
/datum/tgui_module/appearance_changer/vore/changed_hook(flag)
var/mob/living/carbon/human/M = owner
var/mob/living/O = usr
switch(flag)
if(APPEARANCECHANGER_CHANGED_RACE)
to_chat(M, "<span class='notice'>You lose sensation of your body, feeling only the warmth of everything around you... </span>")
to_chat(O, "<span class='notice'>Your body shifts as you make dramatic changes to your captive's body.</span>")
if(APPEARANCECHANGER_CHANGED_GENDER)
to_chat(M, "<span class='notice'>Your body feels very strange...</span>")
to_chat(O, "<span class='notice'>You feel strange as you alter your captive's gender.</span>")
if(APPEARANCECHANGER_CHANGED_GENDER_ID)
to_chat(M, "<span class='notice'>You start to feel... [capitalize(M.gender)]?</span>")
to_chat(O, "<span class='notice'>You feel strange as you alter your captive's gender identity.</span>")
if(APPEARANCECHANGER_CHANGED_SKINTONE, APPEARANCECHANGER_CHANGED_SKINCOLOR)
to_chat(M, "<span class='notice'>Your body tingles all over...</span>")
to_chat(O, "<span class='notice'>You tingle as you make noticeable changes to your captive's body.</span>")
if(APPEARANCECHANGER_CHANGED_HAIRSTYLE, APPEARANCECHANGER_CHANGED_HAIRCOLOR, APPEARANCECHANGER_CHANGED_F_HAIRSTYLE, APPEARANCECHANGER_CHANGED_F_HAIRCOLOR)
to_chat(M, "<span class='notice'>Your body tingles all over...</span>")
to_chat(O, "<span class='notice'>You tingle as you make noticeable changes to your captive's body.</span>")
if(APPEARANCECHANGER_CHANGED_EYES)
to_chat(M, "<span class='notice'>You feel lightheaded and drowsy...</span>")
to_chat(O, "<span class='notice'>You feel warm as you make subtle changes to your captive's body.</span>")
+1
View File
@@ -173,6 +173,7 @@ h1.alert, h2.alert {color: #000000;}
.terminus {font-family: "Times New Roman", Times, serif, sans-serif}
.interface {color: #330033;}
.spacer {color: #9c660b;} /* VOREStation Add */
.blob {color: #ff950d; font-weight: bold; font-style: italic;}
/* YW Edit start */
.psionic {color: #993399;}
.wingdings {font-family: Wingdings, Webdings}
@@ -201,6 +201,7 @@
name = "SynthWolf dual-color (Taur)"
icon_state = "synthwolf_s"
extra_overlay = "synthwolf_markings"
extra_overlay2 = "synthwolf_glow"
//icon_sprite_tag = "synthwolf"
/datum/sprite_accessory/tail/taur/skunk
@@ -275,6 +276,7 @@
name = "SynthHorse dual-color (Taur)"
icon_state = "synthhorse_s"
extra_overlay = "synthhorse_markings"
extra_overlay2 = "synthhorse_glow"
//icon_sprite_tag = "synthhorse"
/datum/sprite_accessory/tail/taur/cow
@@ -336,6 +338,7 @@
name = "SynthLizard dual-color (Taur)"
icon_state = "synthlizard_s"
extra_overlay = "synthlizard_markings"
extra_overlay2 = "synthlizard_glow"
//icon_sprite_tag = "synthlizard"
/datum/sprite_accessory/tail/taur/spider
@@ -422,6 +425,7 @@
name = "SynthFeline dual-color (Taur)"
icon_state = "synthfeline_s"
extra_overlay = "synthfeline_markings"
extra_overlay2 = "synthfeline_glow"
//icon_sprite_tag = "synthfeline"
/datum/sprite_accessory/tail/taur/slug
@@ -42,6 +42,13 @@
// Ears avaliable to anyone
/datum/sprite_accessory/ears/alt_ram_horns
name = "Solid ram horns"
desc = ""
icon_state = "ram_horns_s"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/ears/hyena
name = "hyena ears, dual-color"
desc = ""
@@ -2008,4 +2015,4 @@
desc = ""
icon_state = "verie_hair_glow"
ignores_lighting = 1
//ckeys_allowed = list("vitoras") // This probably won't come into play EVER but better safe than sorry
//ckeys_allowed = list("vitoras") // This probably won't come into play EVER but better safe than sorry
+1 -2
View File
@@ -31,8 +31,7 @@
var/datum/belly/transferlocation = null // Location that the prey is released if they struggle and get dropped off.
var/tmp/digest_mode = DM_HOLD // Whether or not to digest. Default to not digest.
var/tmp/list/digest_modes = list(DM_HOLD,DM_DIGEST,DM_HEAL,DM_ABSORB,DM_DRAIN,DM_UNABSORB,DM_SHRINK,DM_GROW,DM_SIZE_STEAL) // Possible digest modes
var/tmp/list/transform_modes = list(DM_TRANSFORM_MALE,DM_TRANSFORM_FEMALE,DM_TRANSFORM_KEEP_GENDER,DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR,DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG,DM_TRANSFORM_REPLICA,DM_TRANSFORM_REPLICA_EGG,DM_TRANSFORM_KEEP_GENDER_EGG,DM_TRANSFORM_MALE_EGG,DM_TRANSFORM_FEMALE_EGG, DM_EGG)
var/tmp/list/digest_modes = list(DM_HOLD,DM_DIGEST,DM_HEAL,DM_ABSORB,DM_DRAIN,DM_UNABSORB,DM_SHRINK,DM_GROW,DM_SIZE_STEAL,DM_EGG) // Possible digest modes
var/tmp/mob/living/owner // The mob whose belly this is.
var/tmp/list/internal_contents = list() // People/Things you've eaten into this belly!
var/tmp/emotePend = FALSE // If there's already a spawned thing counting for the next emote
+1 -3
View File
@@ -41,11 +41,9 @@
//I don't think we've ever altered these lists. making them static until someone actually overrides them somewhere.
//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)
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)
//Transformation modes
var/tmp/static/list/transform_modes = list(DM_TRANSFORM_MALE,DM_TRANSFORM_FEMALE,DM_TRANSFORM_KEEP_GENDER,DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR,DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG,DM_TRANSFORM_REPLICA,DM_TRANSFORM_REPLICA_EGG,DM_TRANSFORM_KEEP_GENDER_EGG,DM_TRANSFORM_MALE_EGG,DM_TRANSFORM_FEMALE_EGG, DM_EGG)
//Item related modes
var/tmp/static/list/item_digest_modes = list(IM_HOLD,IM_DIGEST_FOOD,IM_DIGEST)
+5 -126
View File
@@ -129,132 +129,11 @@ GLOBAL_LIST_INIT(digest_modes, list())
B.owner.adjust_nutrition(-1)
L.adjust_nutrition(1)
// TRANSFORM MODES
/datum/digest_mode/transform
var/stabilize_nutrition = FALSE
var/changes_eyes = FALSE
var/changes_hair_solo = FALSE
var/changes_hairandskin = FALSE
var/changes_gender = FALSE
var/changes_gender_to = null
var/changes_species = FALSE
var/changes_ears_tail_wing_nocolor = FALSE
var/changes_ears_tail_wing_color = FALSE
var/eggs = FALSE
/datum/digest_mode/transform/process_mob(obj/belly/B, mob/living/carbon/human/H)
if(!istype(H) || H.stat == DEAD)
return null
if(stabilize_nutrition)
if(B.owner.nutrition > 400 && H.nutrition < 400)
B.owner.adjust_nutrition(-2)
H.adjust_nutrition(1.5)
var/datum/species/target_species = H.species
if(!((target_species.spawn_flags & SPECIES_IS_WHITELISTED) || (target_species.spawn_flags & SPECIES_IS_RESTRICTED)))
if(changes_eyes && B.check_eyes(H))
B.change_eyes(H, 1)
return null
if(changes_hair_solo && B.check_hair(H))
B.change_hair(H)
return null
if(changes_hairandskin && (B.check_hair(H) || B.check_skin(H)))
B.change_hair(H)
B.change_skin(H, 1)
return null
if(changes_species)
if(changes_ears_tail_wing_nocolor && (B.check_ears(H) || B.check_tail_nocolor(H) || B.check_wing_nocolor(H) || B.check_species(H)))
B.change_ears(H)
B.change_tail_nocolor(H)
B.change_wing_nocolor(H)
B.change_species(H, 1, 1) // ,1) preserves coloring
H.species.create_organs(H)
H.sync_organ_dna()
return null
if(changes_ears_tail_wing_color && (B.check_ears(H) || B.check_tail(H) || B.check_wing(H) || B.check_species(H)))
B.change_ears(H)
B.change_tail(H)
B.change_wing(H)
B.change_species(H, 1, 2) // ,2) does not preserve coloring.
H.species.create_organs(H)
H.sync_organ_dna()
return null
if(changes_gender && B.check_gender(H, changes_gender_to))
B.change_gender(H, changes_gender_to, 1)
return null
if(eggs && (!H.absorbed))
B.put_in_egg(H, 1)
return null
// Regular TF Modes
/datum/digest_mode/transform/hairandeyes
id = DM_TRANSFORM_HAIR_AND_EYES
stabilize_nutrition = TRUE
changes_eyes = TRUE
changes_hair_solo = TRUE
/datum/digest_mode/transform/gender
id = DM_TRANSFORM_FEMALE
changes_eyes = TRUE
changes_hairandskin = TRUE
changes_gender = TRUE
changes_gender_to = FEMALE
stabilize_nutrition = TRUE
/datum/digest_mode/transform/gender/male
id = DM_TRANSFORM_FEMALE
changes_gender_to = MALE
/datum/digest_mode/transform/keepgender
id = DM_TRANSFORM_KEEP_GENDER
changes_eyes = TRUE
changes_hairandskin = TRUE
stabilize_nutrition = TRUE
/datum/digest_mode/transform/speciesandtaur
id = DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR
changes_species = TRUE
changes_ears_tail_wing_nocolor = TRUE
stabilize_nutrition = TRUE
/datum/digest_mode/transform/replica
id = DM_TRANSFORM_REPLICA
changes_eyes = TRUE
changes_hairandskin = TRUE
changes_species = TRUE
changes_ears_tail_wing_color = TRUE
// E G G
/datum/digest_mode/transform/egg
/datum/digest_mode/egg
id = DM_EGG
eggs = TRUE
/datum/digest_mode/transform/egg/gender
id = DM_TRANSFORM_FEMALE_EGG
changes_eyes = TRUE
changes_hairandskin = TRUE
changes_gender = TRUE
changes_gender_to = FEMALE
stabilize_nutrition = TRUE
/datum/digest_mode/transform/egg/gender/male
id = DM_TRANSFORM_MALE_EGG
changes_gender_to = MALE
/datum/digest_mode/transform/egg/nogender
id = DM_TRANSFORM_KEEP_GENDER_EGG
changes_eyes = TRUE
changes_hairandskin = TRUE
stabilize_nutrition = TRUE
/datum/digest_mode/transform/egg/speciesandtaur
id = DM_TRANSFORM_CHANGE_SPECIES_AND_TAUR_EGG
changes_species = TRUE
changes_ears_tail_wing_nocolor = TRUE
stabilize_nutrition = TRUE
/datum/digest_mode/transform/egg/replica
id = DM_TRANSFORM_REPLICA_EGG
changes_eyes = TRUE
changes_hairandskin = TRUE
changes_species = TRUE
changes_ears_tail_wing_color = TRUE
/datum/digest_mode/egg/process_mob(obj/belly/B, mob/living/carbon/human/H)
if(!istype(H) || H.stat == DEAD || H.absorbed)
return null
B.put_in_egg(H, 1)
-247
View File
@@ -1,250 +1,3 @@
/obj/belly/proc/check_eyes(var/mob/living/carbon/human/M)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return 0
return (M.r_eyes != O.r_eyes || M.g_eyes != O.g_eyes || M.b_eyes != O.b_eyes)
/obj/belly/proc/change_eyes(var/mob/living/carbon/human/M, message=0)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return
M.r_eyes = O.r_eyes
M.g_eyes = O.g_eyes
M.b_eyes = O.b_eyes
M.update_eyes()
M.update_icons_body()
if(message)
to_chat(M, "<span class='notice'>You feel lightheaded and drowsy...</span>")
to_chat(O, "<span class='notice'>You feel warm as you make subtle changes to your captive's body.</span>")
/obj/belly/proc/check_hair(var/mob/living/carbon/human/M)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return 0
if(M.r_hair != O.r_hair || M.g_hair != O.g_hair || M.b_hair != O.b_hair)
return 1
if(M.r_facial != O.r_facial || M.g_facial != O.g_facial || M.b_facial != O.b_facial)
return 1
if(M.h_style != O.h_style || M.f_style != O.f_style)
return 1
return 0
/obj/belly/proc/change_hair(var/mob/living/carbon/human/M, message=0)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return
M.r_hair = O.r_hair
M.g_hair = O.g_hair
M.b_hair = O.b_hair
M.r_facial = O.r_facial
M.g_facial = O.g_facial
M.b_facial = O.b_facial
M.h_style = O.h_style
M.f_style = O.f_style
M.update_hair()
if(message)
to_chat(M, "<span class='notice'>Your body tingles all over...</span>")
to_chat(O, "<span class='notice'>You tingle as you make noticeable changes to your captive's body.</span>")
/obj/belly/proc/check_skin(var/mob/living/carbon/human/M)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return 0
return (M.r_skin != O.r_skin || M.g_skin != O.g_skin || M.b_skin != O.b_skin)
/obj/belly/proc/change_skin(var/mob/living/carbon/human/M, message=0)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return
M.r_skin = O.r_skin
M.g_skin = O.g_skin
M.b_skin = O.b_skin
for(var/obj/item/organ/external/Z in M.organs)
Z.sync_colour_to_human(M)
M.update_icons_body()
if(message)
to_chat(M, "<span class='notice'>Your body tingles all over...</span>")
to_chat(O, "<span class='notice'>You tingle as you make noticeable changes to your captive's body.</span>")
/obj/belly/proc/check_gender(var/mob/living/carbon/human/M, target_gender)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return 0
if(!target_gender)
target_gender = O.gender
return (M.gender != target_gender || M.identifying_gender != target_gender)
/obj/belly/proc/change_gender(var/mob/living/carbon/human/M, target_gender, message=0)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return
if(!target_gender)
target_gender = O.gender
M.gender = target_gender
M.identifying_gender = target_gender
if(target_gender == FEMALE)
M.f_style = "Shaved"
M.dna.SetUIState(DNA_UI_GENDER,M.gender!=MALE,1)
M.sync_organ_dna()
M.update_icons_body()
if(message)
to_chat(M, "<span class='notice'>Your body feels very strange...</span>")
to_chat(O, "<span class='notice'>You feel strange as you alter your captive's gender.</span>")
/obj/belly/proc/check_tail(var/mob/living/carbon/human/M)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return 0
if(M.tail_style != O.tail_style)
return 1
if(M.r_tail != O.r_tail || M.g_tail != O.g_tail || M.b_tail != O.b_tail)
return 1
return 0
/obj/belly/proc/change_tail(var/mob/living/carbon/human/M, message=0)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return
M.r_tail = O.r_tail
M.g_tail = O.g_tail
M.b_tail = O.b_tail
M.tail_style = O.tail_style
M.update_tail_showing()
if(message)
to_chat(M, "<span class='notice'>Your body tingles all over...</span>")
to_chat(O, "<span class='notice'>You tingle as you make noticeable changes to your captive's body.</span>")
/obj/belly/proc/check_tail_nocolor(var/mob/living/carbon/human/M)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return 0
return (M.tail_style != O.tail_style)
/obj/belly/proc/change_tail_nocolor(var/mob/living/carbon/human/M, message=0)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return
M.tail_style = O.tail_style
M.update_tail_showing()
if(message)
to_chat(M, "<span class='notice'>Your body tingles all over...</span>")
to_chat(O, "<span class='notice'>You tingle as you make noticeable changes to your captive's body.</span>")
/obj/belly/proc/check_wing(var/mob/living/carbon/human/M)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return 0
if(M.wing_style != O.wing_style)
return 1
if(M.r_wing != O.r_wing || M.g_wing != O.g_wing || M.b_wing != O.b_wing)
return 1
return 0
/obj/belly/proc/change_wing(var/mob/living/carbon/human/M, message=0)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return
M.r_wing = O.r_wing
M.g_wing = O.g_wing
M.b_wing = O.b_wing
M.wing_style = O.wing_style
M.update_wing_showing()
if(message)
to_chat(M, "<span class='notice'>Your body tingles all over...</span>")
to_chat(O, "<span class='notice'>You tingle as you make noticeable changes to your captive's body.</span>")
/obj/belly/proc/check_wing_nocolor(var/mob/living/carbon/human/M)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return 0
return (M.wing_style != O.wing_style)
/obj/belly/proc/change_wing_nocolor(var/mob/living/carbon/human/M, message=0)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return
M.wing_style = O.wing_style
M.update_wing_showing()
if(message)
to_chat(M, "<span class='notice'>Your body tingles all over...</span>")
to_chat(O, "<span class='notice'>You tingle as you make noticeable changes to your captive's body.</span>")
/obj/belly/proc/check_ears(var/mob/living/carbon/human/M)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return 0
return (M.ear_style != O.ear_style)
/obj/belly/proc/change_ears(var/mob/living/carbon/human/M, message=0)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return
M.ear_style = O.ear_style
M.update_hair()
/obj/belly/proc/check_species(var/mob/living/carbon/human/M)
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return 0
if(M.species.name != O.species.name || M.custom_species != O.custom_species)
return 1
return 0
/obj/belly/proc/change_species(var/mob/living/carbon/human/M, message=0, color_action = 0) //color_action: 0 for default species, 1 to preserve, 2 to transfer from pred
var/mob/living/carbon/human/O = owner
if(!istype(M) || !istype(O))
return
M.verbs -= M.species.inherent_verbs //Take away their unique stuff
var/list/backup_implants = list()
for(var/obj/item/organ/I in M.organs)
for(var/obj/item/weapon/implant/backup/BI in I.contents)
backup_implants += BI
if(backup_implants.len)
for(var/obj/item/weapon/implant/backup/BI in backup_implants)
BI.forceMove(src)
if(color_action == 1)
M.set_species(O.species.name,0,1,M)
else if(color_action == 2)
M.species = O.species
else
M.set_species(O.species.name)
M.custom_species = O.custom_species
M.update_icons_body()
M.update_tail_showing()
if(backup_implants.len)
var/obj/item/organ/external/torso = M.get_organ(BP_TORSO)
for(var/obj/item/weapon/implant/backup/BI in backup_implants)
BI.forceMove(torso)
torso.implants += BI
if(message)
to_chat(M, "<span class='notice'>You lose sensation of your body, feeling only the warmth of everything around you... </span>")
to_chat(O, "<span class='notice'>Your body shifts as you make dramatic changes to your captive's body.</span>")
/obj/belly/proc/put_in_egg(var/atom/movable/M, message=0)
var/mob/living/carbon/human/O = owner
var/egg_path = /obj/structure/closet/secure_closet/egg
+19 -13
View File
@@ -509,8 +509,10 @@
var/atom/movable/target = locate(params["pick"])
if(!(target in host.vore_selected))
return TRUE // Not in our X anymore, update UI
intent = "Examine"
intent = alert("Examine, Eject, Move? Examine if you want to leave this box.","Query","Examine","Eject","Move")
var/list/available_options = list("Examine", "Eject", "Move")
if(ishuman(target))
available_options += "Transform"
intent = input(user, "What would you like to do with [target]?", "Vore Pick", "Examine") as null|anything in available_options
switch(intent)
if("Examine")
var/list/results = target.examine(host)
@@ -525,6 +527,7 @@
return TRUE
host.vore_selected.release_specific_contents(target)
return TRUE
if("Move")
if(host.stat)
@@ -537,6 +540,20 @@
to_chat(target,"<span class='warning'>You're squished from [host]'s [lowertext(host.vore_selected.name)] to their [lowertext(choice.name)]!</span>")
host.vore_selected.transfer_contents(target, choice)
return TRUE
if("Transform")
if(host.stat)
to_chat(user,"<span class='warning'>You can't do that in your state!</span>")
return TRUE
var/mob/living/carbon/human/H = target
if(!istype(H))
return
var/datum/tgui_module/appearance_changer/vore/V = new(host, H)
V.tgui_interact(user)
return TRUE
/datum/vore_look/proc/set_attr(mob/user, params)
if(!host.vore_selected)
@@ -573,21 +590,10 @@
. = TRUE
if("b_mode")
var/list/menu_list = host.vore_selected.digest_modes.Copy()
if(istype(usr,/mob/living/carbon/human))
menu_list += DM_TRANSFORM
var/new_mode = input("Choose Mode (currently [host.vore_selected.digest_mode])") as null|anything in menu_list
if(!new_mode)
return FALSE
if(new_mode == DM_TRANSFORM) //Snowflek submenu
var/list/tf_list = host.vore_selected.transform_modes
var/new_tf_mode = input("Choose TF Mode (currently [host.vore_selected.digest_mode])") as null|anything in tf_list
if(!new_tf_mode)
return FALSE
host.vore_selected.digest_mode = new_tf_mode
return
host.vore_selected.digest_mode = new_mode
. = TRUE
if("b_addons")
+7 -2
View File
@@ -67,7 +67,11 @@ em {font-style: normal;font-weight: bold;}
h1.alert, h2.alert {color: #000000;}
.ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;}
.emote {font-style: italic;}
// VOREStation Edit Start
.emote {}
.emote_subtle {font-style: italic;}
// VOREStation Edit End
/* Game Messages */
@@ -111,7 +115,8 @@ h1.alert, h2.alert {color: #000000;}
.say_quote {font-family: Georgia, Verdana, sans-serif;}
.terminus {font-family: "Times New Roman", Times, serif, sans-serif}
.interface {color: #330033;}
.spacer {color: #9c660b;}
.spacer {color: #9c660b;} /* VOREStation Add */
.blob {color: #ff950d; font-weight: bold; font-style: italic;}
.psionic {color: #993399;} /*YWedit*/
BIG IMG.icon {width: 32px; height: 32px;}
+1 -1
View File
@@ -23,6 +23,7 @@ flurriee - Protean
funnyman2003 - Xenochimera
hawkerthegreat - Vox
hollifex - Diona
h0lysquirr3l - Protean
inuzari - Diona
jademanique - Xenochimera
khanivore - Protean
@@ -80,4 +81,3 @@ xioen - Xenochimera
xonkon - Protean
zalvine - Shadekin Empathy
zammyman215 - Vox
@@ -1,36 +1,4 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
#################################
# Your name.
author: Cerebulon
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- soundadd: "Added button sounds to various machines."
+1 -33
View File
@@ -1,37 +1,5 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
#################################
# Your name.
author: KasparoVy
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- imageadd: Adds orange Teshari goggles, selectable in the loadout.
- imageadd: Adds blindfold & new white (recolorable) blindfold to loadout.
@@ -42,4 +10,4 @@ changes:
- rscadd: Adds a bunch of Teshari worksuits (sprites already existed).
- imageadd: Adds some species-fitted Teshari jacket accessories (tan, charcoal, navy, burgundy, checkered).
- tweak: Updates all Teshari undercoats and cloaks with new sprites from downstreams.
- fix: Fixes Teshari captain glove sprites.
- bugfix: Fixes Teshari captain glove sprites.
-32
View File
@@ -1,36 +1,4 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
#################################
# Your name.
author: Mechoid
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- rscadd: "Added system for exosuit over-encumbrance. Combat mechs and Ripleys have higher than default."
@@ -1,4 +1,4 @@
author: Meghan-Rossi
delete-after: True
changes:
- rscadd: "The Tesla Generator is now available from cargo. Coils and grounding rods for it may be printed on the protolathe and autolathe, respectively."
- rscadd: "The Tesla Generator is now available from cargo. Coils and grounding rods for it may be printed on the protolathe and autolathe, respectively."
@@ -1,37 +1,5 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
#################################
# Your name.
author: N3X15
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
author: RunaDacino
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- rscadd: "Enabled research borgs equipped with 'exosuit gripper' to be able to replace internal exosuit parts like actuators, to upgrade or to repair"
@@ -1,36 +1,4 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
#################################
# Your name.
author: Subber
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- rscadd: "Added two new antag augments to traitor uplink: armblade and handblade."
-32
View File
@@ -1,36 +1,4 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
#################################
# Your name.
author: Woodrat
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- tweak: "Changes vote notification sound to that of World Server in order to help people realize there is a vote occurring."
+1 -1
View File
@@ -34,4 +34,4 @@ delete-after: True
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- rscadd: "Animals can be butchered for organs and hide. Requires scraping (sharp), washing (water or washing machine), and then drying (bonfire or drying rack)."
- rscadd: "Organs can be butchered for meat, named "[organ] meat". Heart meat, liver meat, etc. Brains from player mobs cannot be butchered."
- rscadd: "Organs can be butchered for meat, named \"[organ] meat\". Heart meat, liver meat, etc. Brains from player mobs cannot be butchered."
-32
View File
@@ -1,37 +1,5 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
#################################
# Your name.
author: Mechoid
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- rscadd: "Adds Wurmwoad, a suspiciously worm-like plant that produces pods of spice."
- rscadd: "Adds Wurmwoad to the service borg synthesizer."
Binary file not shown.

Before

Width:  |  Height:  |  Size: 417 KiB

After

Width:  |  Height:  |  Size: 417 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 KiB

After

Width:  |  Height:  |  Size: 426 KiB

Some files were not shown because too many files have changed in this diff Show More