mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-08-27 23:29:10 +01:00
Merge remote-tracking branch 'origin/master' into petasucks
This commit is contained in:
@@ -11,8 +11,13 @@ on:
|
||||
paths:
|
||||
- 'maps/**'
|
||||
|
||||
permissions: {}
|
||||
jobs:
|
||||
generate_maps:
|
||||
permissions:
|
||||
contents: write # to push to branch
|
||||
pull-requests: write # to create pull requests (repo-sync/pull-request)
|
||||
|
||||
name: 'Generate NanoMaps'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
Vendored
-1
@@ -7,7 +7,6 @@
|
||||
"oderwat.indent-rainbow",
|
||||
"rexebin.darkpurple-black",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"editorconfig.editorconfig",
|
||||
"donkie.vscode-tgstation-test-adapter",
|
||||
"icrawl.discord-vscode",
|
||||
"esbenp.prettier-vscode"
|
||||
|
||||
@@ -161,16 +161,14 @@
|
||||
|
||||
if(istype(target, /turf/simulated))
|
||||
var/turf/simulated/modeled_location = target
|
||||
|
||||
if(modeled_location.special_temperature)//First do special interactions then the usuall stuff
|
||||
|
||||
var/delta_temp = modeled_location.special_temperature - air.temperature//2200C - 20C = 2180K
|
||||
//assuming aluminium with thermal conductivity 235 W * K / m, Copper (400), Silver (430), steel (50), gold (320)
|
||||
var/heat_gain = 23500 * 100 * delta_temp
|
||||
air.add_thermal_energy(heat_gain)
|
||||
if(network)
|
||||
network.update = 1
|
||||
|
||||
if (modeled_location.special_temperature)
|
||||
air.temperature += thermal_conductivity * (modeled_location.special_temperature - air.temperature)
|
||||
if (air.temperature < TCMB)
|
||||
air.temperature = TCMB
|
||||
if (network)
|
||||
network.update = TRUE
|
||||
|
||||
if(modeled_location.blocks_air)
|
||||
|
||||
if((modeled_location.heat_capacity>0) && (partial_heat_capacity>0))
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
#define MAT_PLATINUM "platinum"
|
||||
#define MAT_TRITIUM "tritium"
|
||||
#define MAT_DEUTERIUM "deuterium"
|
||||
#define MAT_CONCRETE "concrete"
|
||||
#define MAT_PLASTEELREBAR "plasteel rebar"
|
||||
|
||||
|
||||
#define DEFAULT_TABLE_MATERIAL MAT_PLASTIC
|
||||
|
||||
@@ -40,9 +40,10 @@
|
||||
#define NIF_SIZECHANGE 33
|
||||
#define NIF_SOULCATCHER 34
|
||||
#define NIF_WORLDBEND 35
|
||||
#define NIF_MALWARE 36
|
||||
|
||||
// Must be equal to the highest number above
|
||||
#define TOTAL_NIF_SOFTWARE 35
|
||||
#define TOTAL_NIF_SOFTWARE 36
|
||||
|
||||
//////////////////////
|
||||
// NIF flag list hints
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/obj/screen/popup
|
||||
name = "popup"
|
||||
desc = "NOTICE ME!"
|
||||
|
||||
icon = 'icons/mob/screen1_popups.dmi'
|
||||
plane = PLANE_PLAYER_HUD_ABOVE
|
||||
layer = INFINITY
|
||||
|
||||
var/close_button_x_start
|
||||
var/close_button_x_end
|
||||
var/close_button_y_start
|
||||
var/close_button_y_end
|
||||
|
||||
var/client/holder
|
||||
|
||||
/obj/screen/popup/Click(location, control,params)
|
||||
var/list/PL = params2list(params)
|
||||
var/icon_x = text2num(PL["icon-x"])
|
||||
var/icon_y = text2num(PL["icon-y"])
|
||||
if(check_click_spot(icon_x, icon_y))
|
||||
close_popup()
|
||||
else
|
||||
popup_action()
|
||||
|
||||
/obj/screen/popup/proc/popup_action()
|
||||
return
|
||||
|
||||
/obj/screen/popup/proc/close_popup()
|
||||
holder.screen -= src
|
||||
qdel(src)
|
||||
|
||||
/obj/screen/popup/proc/check_click_spot(click_x, click_y)
|
||||
if((click_x <= close_button_x_end) && (click_x >= close_button_x_start))
|
||||
if((click_y <= close_button_y_end) && (click_y >= close_button_y_start))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/screen/popup/proc/get_random_screen_location()
|
||||
var/loc_x = rand(1,11)
|
||||
var/loc_x_offset = rand(0,16)
|
||||
var/loc_y = rand(1,12)
|
||||
var/loc_y_offset = rand(0,16)
|
||||
return "[loc_x]:[loc_x_offset],[loc_y]:[loc_y_offset]"
|
||||
|
||||
/client/proc/create_fake_ad_popup(popup_type)
|
||||
if(!src)
|
||||
return
|
||||
var/obj/screen/popup/ad = new popup_type()
|
||||
ad.screen_loc = ad.get_random_screen_location()
|
||||
src.screen |= ad
|
||||
ad.holder = src
|
||||
|
||||
/client/proc/create_fake_ad_popup_multiple(popup_type, popup_amount)
|
||||
if(!src)
|
||||
return
|
||||
for(var/i = 0, i < popup_amount, i++)
|
||||
create_fake_ad_popup(popup_type)
|
||||
|
||||
/obj/screen/popup/default
|
||||
name = "CLICK ME"
|
||||
|
||||
icon_state = "popup1"
|
||||
|
||||
close_button_x_start = 118
|
||||
close_button_x_end = 126
|
||||
close_button_y_start = 86
|
||||
close_button_y_end = 94
|
||||
|
||||
/obj/screen/popup/default/New()
|
||||
..()
|
||||
icon_state = "popup[rand(1,4)]"
|
||||
@@ -167,6 +167,9 @@
|
||||
vis_contents -= hover_overlays_cache[hovering_choice]
|
||||
hovering_choice = choice
|
||||
|
||||
if(!choice)
|
||||
return
|
||||
|
||||
var/obj/effect/overlay/zone_sel/overlay_object = hover_overlays_cache[choice]
|
||||
if(!overlay_object)
|
||||
overlay_object = new
|
||||
@@ -174,7 +177,6 @@
|
||||
hover_overlays_cache[choice] = overlay_object
|
||||
vis_contents += overlay_object
|
||||
|
||||
|
||||
/obj/effect/overlay/zone_sel
|
||||
icon = 'icons/mob/zone_sel.dmi'
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
@@ -240,7 +242,7 @@
|
||||
update_icon()
|
||||
|
||||
/obj/screen/zone_sel/update_icon()
|
||||
cut_overlay(selecting_appearance)
|
||||
cut_overlays()
|
||||
selecting_appearance = mutable_appearance('icons/mob/zone_sel.dmi', "[selecting]")
|
||||
add_overlay(selecting_appearance)
|
||||
|
||||
@@ -985,4 +987,4 @@
|
||||
else //"0" is still length 1 so this means it's over 999
|
||||
overlays += image('icons/mob/screen_ammo.dmi', src, "o9")
|
||||
overlays += image('icons/mob/screen_ammo.dmi', src, "t9")
|
||||
overlays += image('icons/mob/screen_ammo.dmi', src, "h9")
|
||||
overlays += image('icons/mob/screen_ammo.dmi', src, "h9")
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
cost = 10
|
||||
containertype = /obj/structure/closet/crate/gilthari
|
||||
containername = "crate of bar supplies"
|
||||
|
||||
|
||||
/datum/supply_pack/hospitality/cookingoil
|
||||
name = "Cooking oil tank crate"
|
||||
contains = list(/obj/structure/reagent_dispensers/cookingoil)
|
||||
@@ -96,6 +96,15 @@
|
||||
containertype = /obj/structure/closet/crate/centauri
|
||||
containername = "Painting equipment"
|
||||
|
||||
/datum/supply_pack/hospitality/holywater
|
||||
name = "Holy water crate"
|
||||
contains = list(
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/holywater = 3
|
||||
)
|
||||
cost = 15
|
||||
containertype = /obj/structure/closet/crate/gilthari
|
||||
containername = "holy water crate"
|
||||
|
||||
/datum/supply_pack/randomised/hospitality/
|
||||
group = "Hospitality"
|
||||
|
||||
|
||||
@@ -83,4 +83,11 @@
|
||||
containertype = /obj/structure/closet/crate/grayson
|
||||
containername = "Linoleum crate"
|
||||
cost = 15
|
||||
contains = list(/obj/fiftyspawner/linoleum)
|
||||
contains = list(/obj/fiftyspawner/linoleum)
|
||||
|
||||
/datum/supply_pack/materials/concrete
|
||||
name = "Concrete"
|
||||
cost = 10
|
||||
containertype = /obj/structure/closet/crate/grayson
|
||||
contains = list(/obj/fiftyspawner/concrete)
|
||||
containername = "Concrete bricks crate"
|
||||
@@ -75,6 +75,19 @@
|
||||
containername = "Shotgun crate"
|
||||
access = access_armory
|
||||
/* VOREStation edit -- This is a bad idea. -- So is this.
|
||||
|
||||
/datum/supply_pack/munitions/shotgunsemi
|
||||
name = "Weapons - Semi-Automatic Shotgun crate"
|
||||
contains = list(
|
||||
/obj/item/ammo_magazine/ammo_box/b12g,
|
||||
/obj/item/ammo_magazine/ammo_box/b12g/pellet,
|
||||
/obj/item/weapon/gun/projectile/shotgun/semi = 2
|
||||
)
|
||||
cost = 100
|
||||
containertype = /obj/structure/closet/crate/secure/weapon
|
||||
containername = "Semi-Auto Shotgun crate"
|
||||
access = access_armory
|
||||
|
||||
/datum/supply_pack/munitions/erifle
|
||||
name = "Weapons - Energy marksman"
|
||||
contains = list(/obj/item/weapon/gun/energy/sniperrifle = 2)
|
||||
@@ -307,4 +320,4 @@
|
||||
cost = 500
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "Light machine gun crate"
|
||||
access = access_armory
|
||||
access = access_armory
|
||||
|
||||
@@ -18,11 +18,6 @@
|
||||
name = "SweatMAX Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/hotfood
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/food/hotfood)
|
||||
name = "Hot Foods Vendor Refill Cartridge"
|
||||
cost = 10
|
||||
|
||||
/datum/supply_pack/vending_refills/weeb
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/food/weeb)
|
||||
name = "Nippon-tan Vendor Refill Cartridge"
|
||||
@@ -122,7 +117,6 @@
|
||||
num_contained = 5
|
||||
contains = list(/obj/item/weapon/refill_cartridge/autoname/food/snack,
|
||||
/obj/item/weapon/refill_cartridge/autoname/food/fitness,
|
||||
/obj/item/weapon/refill_cartridge/autoname/food/hotfood,
|
||||
/obj/item/weapon/refill_cartridge/autoname/food/weeb,
|
||||
/obj/item/weapon/refill_cartridge/autoname/food/sol,
|
||||
/obj/item/weapon/refill_cartridge/autoname/food/snix,
|
||||
|
||||
@@ -266,4 +266,13 @@
|
||||
cost = 150
|
||||
containertype = /obj/structure/closet/crate/oculum
|
||||
containername = "Vox Engineering Hardsuit"
|
||||
|
||||
/datum/supply_pack/voidsuits/voxsec
|
||||
name = "Vox Security Hardsuit"
|
||||
contains = list (/obj/item/weapon/rig/vox/security)
|
||||
cost = 90
|
||||
containertype = /obj/structure/closet/crate/secure/heph
|
||||
containername = "Vox security Rigsuit Crate"
|
||||
access = access_security
|
||||
|
||||
//ChompEdit End
|
||||
|
||||
@@ -6,25 +6,25 @@
|
||||
|
||||
/datum/uplink_item/item/armor/combat
|
||||
name = "Combat Armor Set"
|
||||
item_cost = 60
|
||||
item_cost = 30
|
||||
path = /obj/item/weapon/storage/box/syndie_kit/combat_armor
|
||||
|
||||
/datum/uplink_item/item/armor/heavy_vest
|
||||
name = "Heavy Armor Vest"
|
||||
item_cost = 40
|
||||
item_cost = 20
|
||||
path = /obj/item/clothing/suit/storage/vest/heavy/merc
|
||||
|
||||
/datum/uplink_item/item/armor/gorlexsuit
|
||||
name = "Mercenary Voidsuit"
|
||||
item_cost = 40
|
||||
item_cost = 20
|
||||
path = /obj/item/weapon/storage/box/syndie_kit/voidsuit
|
||||
|
||||
/datum/uplink_item/item/armor/gorlexsuit_fire
|
||||
name = "Mercenary Voidsuit (Fire)"
|
||||
item_cost = 40
|
||||
item_cost = 20
|
||||
path = /obj/item/weapon/storage/box/syndie_kit/voidsuit/fire
|
||||
|
||||
/datum/uplink_item/item/armor/combat
|
||||
name = "Combat Platecarrier Set"
|
||||
item_cost = 60
|
||||
item_cost = 30
|
||||
path = /obj/item/clothing/suit/armor/pcarrier/merc
|
||||
|
||||
@@ -6,88 +6,108 @@
|
||||
|
||||
/datum/uplink_item/item/medical/onegativeblood
|
||||
name = "O- Blood Pack"
|
||||
item_cost = 5
|
||||
item_cost = 1
|
||||
path = /obj/item/weapon/reagent_containers/blood/OMinus
|
||||
|
||||
/datum/uplink_item/item/medical/sinpockets
|
||||
name = "Box of Sin-Pockets"
|
||||
item_cost = 5
|
||||
item_cost = 1
|
||||
path = /obj/item/weapon/storage/box/sinpockets
|
||||
|
||||
/datum/uplink_item/item/medical/ambrosiaseeds
|
||||
name = "Box of 7x ambrosia seed packets"
|
||||
item_cost = 5
|
||||
item_cost = 1
|
||||
path = /obj/item/weapon/storage/box/ambrosia
|
||||
|
||||
/datum/uplink_item/item/medical/clotting
|
||||
name = "Clotting Medicine injector"
|
||||
item_cost = 10
|
||||
item_cost = 5
|
||||
path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/clotting
|
||||
|
||||
/datum/uplink_item/item/medical/clotting_case
|
||||
name = "Clotting Medicine case"
|
||||
item_cost = 20
|
||||
item_cost = 10
|
||||
desc = "A case of three myelamine injectors. Can rapidly remove and stow up to six injectors."
|
||||
path = /obj/item/weapon/storage/quickdraw/syringe_case/clotting
|
||||
|
||||
/datum/uplink_item/item/medical/bonemeds
|
||||
name = "Bone Repair injector"
|
||||
item_cost = 10
|
||||
item_cost = 5
|
||||
path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/bonemed
|
||||
|
||||
/datum/uplink_item/item/medical/clonemeds
|
||||
name = "Clone injector"
|
||||
item_cost = 15
|
||||
item_cost = 5
|
||||
path = /obj/item/weapon/reagent_containers/hypospray/autoinjector/clonemed
|
||||
|
||||
/datum/uplink_item/item/medical/bonemeds_case
|
||||
name = "Bone Repair case"
|
||||
item_cost = 20
|
||||
item_cost = 10
|
||||
desc = "A case of three osteodaxon injectors. Can rapidly remove and stow up to six injectors."
|
||||
path = /obj/item/weapon/storage/quickdraw/syringe_case/bonemed
|
||||
|
||||
/datum/uplink_item/item/medical/clonemeds_case
|
||||
name = "Clone case"
|
||||
item_cost = 30
|
||||
item_cost = 10
|
||||
desc = "A case of three rezadone injectors. Can rapidly remove and stow up to six injectors."
|
||||
path = /obj/item/weapon/storage/quickdraw/syringe_case/clonemed
|
||||
|
||||
/datum/uplink_item/item/medical/ambrosiadeusseeds
|
||||
name = "Box of 7x ambrosia deus seed packets"
|
||||
item_cost = 10
|
||||
item_cost = 5
|
||||
path = /obj/item/weapon/storage/box/ambrosiadeus
|
||||
|
||||
/datum/uplink_item/item/medical/freezer
|
||||
name = "Portable Freezer"
|
||||
item_cost = 10
|
||||
item_cost = 1
|
||||
path = /obj/item/weapon/storage/box/freezer
|
||||
|
||||
/datum/uplink_item/item/medical/monkeycubes
|
||||
name = "Box, Monkey Cubes"
|
||||
item_cost = 10
|
||||
item_cost = 1
|
||||
path = /obj/item/weapon/storage/box/monkeycubes
|
||||
|
||||
/datum/uplink_item/item/medical/farwacubes
|
||||
name = "Box, Farwa Cubes"
|
||||
item_cost = 10
|
||||
item_cost = 1
|
||||
path = /obj/item/weapon/storage/box/monkeycubes
|
||||
|
||||
/datum/uplink_item/item/medical/neaeracubes
|
||||
name = "Box, Neaera Cubes"
|
||||
item_cost = 10
|
||||
item_cost = 1
|
||||
path = /obj/item/weapon/storage/box/monkeycubes/neaeracubes
|
||||
|
||||
/datum/uplink_item/item/medical/stokcubes
|
||||
name = "Box, Stok Cubes"
|
||||
item_cost = 10
|
||||
item_cost = 1
|
||||
path = /obj/item/weapon/storage/box/monkeycubes/stokcubes
|
||||
|
||||
/datum/uplink_item/item/medical/surgery
|
||||
name = "Surgery kit"
|
||||
item_cost = 45
|
||||
item_cost = 5
|
||||
path = /obj/item/weapon/storage/firstaid/surgery
|
||||
|
||||
/datum/uplink_item/item/medical/toxins
|
||||
name = "Anti-toxins medical kit"
|
||||
item_cost = 5
|
||||
path = /obj/item/weapon/storage/firstaid/toxin
|
||||
|
||||
/datum/uplink_item/item/medical/o2
|
||||
name = "oxygen deprivation medical kit"
|
||||
item_cost = 5
|
||||
path = /obj/item/weapon/storage/firstaid/o2
|
||||
|
||||
/datum/uplink_item/item/medical/fire
|
||||
name = "fire medical kit"
|
||||
item_cost = 5
|
||||
path = /obj/item/weapon/storage/firstaid/fire
|
||||
|
||||
/datum/uplink_item/item/medical/adv
|
||||
name = "advanced medical kit"
|
||||
item_cost = 10
|
||||
path = /obj/item/weapon/storage/firstaid/adv
|
||||
|
||||
/datum/uplink_item/item/medical/combat
|
||||
name = "Combat medical kit"
|
||||
item_cost = 60
|
||||
item_cost = 20
|
||||
path = /obj/item/weapon/storage/firstaid/combat
|
||||
|
||||
@@ -139,6 +139,11 @@
|
||||
item_cost = 75
|
||||
path = /obj/item/weapon/gun/projectile/shotgun/pump/combat
|
||||
|
||||
/datum/uplink_item/item/visible_weapons/semishotgun
|
||||
name = "Semi-Automatic Shotgun"
|
||||
item_cost = 100
|
||||
path = /obj/item/weapon/gun/projectile/shotgun/semi
|
||||
|
||||
/datum/uplink_item/item/visible_weapons/leveraction
|
||||
name = "Lever Action Rifle"
|
||||
item_cost = 50
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
var/mob/M = grab.affecting
|
||||
qdel(grab)
|
||||
put_mob(M)
|
||||
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/unary/cryo_cell/MouseDrop_T(var/mob/target, var/mob/user) //Allows borgs to put people into cryo without external assistance
|
||||
@@ -226,6 +226,9 @@
|
||||
if(occupant.bodytemperature < 225)
|
||||
if(occupant.getToxLoss())
|
||||
occupant.adjustToxLoss(max(-1, -20/occupant.getToxLoss()))
|
||||
if(occupant.radiation || occupant.accumulated_rads)
|
||||
occupant.radiation -= 25
|
||||
occupant.accumulated_rads -= 25
|
||||
var/heal_brute = occupant.getBruteLoss() ? min(1, 20/occupant.getBruteLoss()) : 0
|
||||
var/heal_fire = occupant.getFireLoss() ? min(1, 20/occupant.getFireLoss()) : 0
|
||||
occupant.heal_organ_damage(heal_brute,heal_fire)
|
||||
|
||||
@@ -475,8 +475,8 @@
|
||||
|
||||
//Handle job slot/tater cleanup.
|
||||
var/job = to_despawn.mind.assigned_role
|
||||
|
||||
job_master.FreeRole(job)
|
||||
to_despawn.mind.assigned_role = null
|
||||
|
||||
if(to_despawn.mind.objectives.len)
|
||||
qdel(to_despawn.mind.objectives)
|
||||
|
||||
@@ -149,6 +149,41 @@
|
||||
M.close()
|
||||
return
|
||||
|
||||
//CHOMP Add start
|
||||
/obj/machinery/button/remote/blast_door/bear
|
||||
name = "stuffed bear"
|
||||
icon = 'icons/obj/stationobjs_vr.dmi'
|
||||
icon_state = "stuffedbear"
|
||||
desc = "A stuffed and mounted bear. Quite a statement piece, but holds a curious glare."
|
||||
density = 1
|
||||
|
||||
/obj/machinery/button/remote/blast_door/bear/attack_hand(mob/user as mob) //code to stop bear ever reverting to standard button sprites
|
||||
if(..())
|
||||
return
|
||||
|
||||
add_fingerprint(user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
|
||||
if(!allowed(user) && (wires & 1))
|
||||
to_chat(user, "<span class='warning'>Access Denied</span>")
|
||||
flick("doorctrl-denied",src)
|
||||
return
|
||||
|
||||
use_power(5)
|
||||
icon_state = "stuffedbear"
|
||||
desiredstate = !desiredstate
|
||||
trigger(user)
|
||||
spawn(15)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/button/remote/blast_door/bear/update_icon()
|
||||
if(stat & NOPOWER)
|
||||
icon_state = "stuffedbear"
|
||||
else
|
||||
icon_state = "stuffedbear"
|
||||
//CHOMP Add end
|
||||
|
||||
/*
|
||||
Emitter remote control
|
||||
*/
|
||||
|
||||
@@ -319,6 +319,15 @@
|
||||
density = FALSE
|
||||
opacity = 0
|
||||
|
||||
/obj/machinery/door/blast/regular/bookcase //CHOMP Add code block
|
||||
name = "bookcase"
|
||||
desc = "On closer inspection, the array of books is decorative and built into the frame."
|
||||
icon_state = "bookcase1"
|
||||
icon_state_open = "bookcase0"
|
||||
icon_state_opening = "bookcasec0"
|
||||
icon_state_closed = "bookcase1"
|
||||
icon_state_closing = "bookcasec1"
|
||||
|
||||
// SUBTYPE: Shutters
|
||||
// Nicer looking, and also weaker, shutters. Found in kitchen and similar areas.
|
||||
/obj/machinery/door/blast/shutters
|
||||
@@ -456,4 +465,4 @@
|
||||
|
||||
|
||||
#undef BLAST_DOOR_CRUSH_DAMAGE
|
||||
#undef SHUTTER_CRUSH_DAMAGE
|
||||
#undef SHUTTER_CRUSH_DAMAGE
|
||||
|
||||
@@ -81,31 +81,6 @@
|
||||
frame_class = FRAME_CLASS_MACHINE
|
||||
frame_size = 4
|
||||
|
||||
/datum/frame/frame_types/oven
|
||||
name = "Oven"
|
||||
frame_class = FRAME_CLASS_MACHINE
|
||||
frame_size = 4
|
||||
|
||||
/datum/frame/frame_types/fryer
|
||||
name = "Fryer"
|
||||
frame_class = FRAME_CLASS_MACHINE
|
||||
frame_size = 4
|
||||
|
||||
/datum/frame/frame_types/grill
|
||||
name = "Grill"
|
||||
frame_class = FRAME_CLASS_MACHINE
|
||||
frame_size = 4
|
||||
|
||||
/datum/frame/frame_types/cerealmaker
|
||||
name = "Cereal Maker"
|
||||
frame_class = FRAME_CLASS_MACHINE
|
||||
frame_size = 4
|
||||
|
||||
/datum/frame/frame_types/candymachine
|
||||
name = "Candy Machine"
|
||||
frame_class = FRAME_CLASS_MACHINE
|
||||
frame_size = 4
|
||||
|
||||
/datum/frame/frame_types/fax
|
||||
name = "Fax"
|
||||
frame_class = FRAME_CLASS_MACHINE
|
||||
@@ -221,7 +196,7 @@
|
||||
frame_style = FRAME_STYLE_WALL
|
||||
x_offset = 28
|
||||
y_offset = 28
|
||||
|
||||
|
||||
/datum/frame/frame_types/arfgs
|
||||
name = "ARF Generator"
|
||||
frame_class = FRAME_CLASS_MACHINE
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
active_power_usage = 40000 //40 kW
|
||||
var/efficiency = 40000 //will provide the modified power rate when upgraded
|
||||
var/obj/item/charging = null
|
||||
var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/modular_computer, /obj/item/weapon/computer_hardware/battery_module, /obj/item/weapon/cell, /obj/item/device/suit_cooling_unit/emergency, /obj/item/device/flashlight, /obj/item/device/electronic_assembly, /obj/item/weapon/weldingtool/electric, /obj/item/ammo_magazine/smart, /obj/item/device/flash, /obj/item/device/defib_kit, /obj/item/ammo_casing/microbattery, /obj/item/device/paicard, /obj/item/ammo_magazine/cell_mag, /obj/item/weapon/gun/projectile/cell_loaded) // CHOMPedit: medigun stuff
|
||||
var/list/allowed_devices = list(/obj/item/weapon/gun/energy, /obj/item/weapon/melee/baton, /obj/item/modular_computer, /obj/item/weapon/computer_hardware/battery_module, /obj/item/weapon/cell, /obj/item/device/suit_cooling_unit/emergency, /obj/item/device/flashlight, /obj/item/device/electronic_assembly, /obj/item/weapon/weldingtool/electric, /obj/item/ammo_magazine/smart, /obj/item/device/flash, /obj/item/device/defib_kit, /obj/item/ammo_casing/microbattery, /obj/item/device/paicard, /obj/item/ammo_magazine/cell_mag, /obj/item/weapon/gun/projectile/cell_loaded, /obj/item/device/personal_shield_generator) // CHOMPedit: medigun stuff
|
||||
var/icon_state_charged = "recharger2"
|
||||
var/icon_state_charging = "recharger1"
|
||||
var/icon_state_idle = "recharger0" //also when unpowered
|
||||
@@ -28,7 +28,8 @@
|
||||
. += "[charging ? "[charging]" : "Nothing"] is in [src]."
|
||||
if(charging)
|
||||
var/obj/item/weapon/cell/C = charging.get_cell()
|
||||
. += "Current charge: [C.charge] / [C.maxcharge]"
|
||||
if(C) // Sometimes we get things without cells in it.
|
||||
. += "Current charge: [C.charge] / [C.maxcharge]"
|
||||
|
||||
/obj/machinery/recharger/attackby(obj/item/weapon/G as obj, mob/user as mob)
|
||||
var/allowed = 0
|
||||
|
||||
@@ -104,8 +104,9 @@
|
||||
cell.use(7000/450*10)
|
||||
|
||||
// And clear up radiation
|
||||
if(H.radiation > 0)
|
||||
H.radiation = max(H.radiation - rand(5, 15), 0)
|
||||
if(H.radiation > 0 || H.accumulated_rads > 0)
|
||||
H.radiation = max(H.radiation - 25, 0)
|
||||
H.accumulated_rads = max(H.accumulated_rads - 25, 0)
|
||||
|
||||
if(H.wearing_rig) // stepping into a borg charger to charge your rig and fix your shit
|
||||
var/obj/item/weapon/rig/wornrig = H.get_rig()
|
||||
|
||||
@@ -25,4 +25,4 @@
|
||||
|
||||
C.name = name
|
||||
|
||||
qdel(src)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
@@ -24,6 +24,18 @@
|
||||
icon_state = "smoke"
|
||||
duration = 50
|
||||
|
||||
/obj/effect/temp_visual/glitch
|
||||
icon_state = "glitch"
|
||||
duration = 5
|
||||
|
||||
/obj/effect/temp_visual/confuse
|
||||
icon_state = "confuse"
|
||||
duration = 5
|
||||
|
||||
/obj/effect/temp_visual/pre_confuse
|
||||
icon_state = "pre_confuse"
|
||||
duration = 5
|
||||
|
||||
/obj/effect/temp_visual/impact_effect
|
||||
icon_state = "impact_bullet"
|
||||
plane = PLANE_LIGHTING_ABOVE // So they're visible even in a shootout in maint.
|
||||
|
||||
@@ -0,0 +1,601 @@
|
||||
// TO ANYBODY LOOKING AT THIS FILE:
|
||||
// Everything is mostly commented on to give as much detailed information as possible.
|
||||
// Some things may be difficult to understand, but every variable in here has a comment explaining what it is/does.
|
||||
// The base unit, the 'personal_shield_generator' is a backpack, comes with a gun, and has normal numbers for everything.
|
||||
// The belt units do NOT come with a gun and have a cell that is half the capacity of backpack units.
|
||||
// These can be VERY, VERY, VERY strong if too many are handed out, the cell is too strong, or the modifier is too strong.
|
||||
// Additionally, if you are mapping any of these in, ensure you map in the /loaded versions or else they won't have a battery.
|
||||
// I have also made it so you can modify everything about them, including the modifier they give and the cell, which can be changed via mapping.
|
||||
|
||||
// In essence, these can be viewed as an extra layer of armor that has upsides and downsides with more extensive features.
|
||||
// Shield generators apply PRE armor. Ultimately this shouldn't matter too much, but it makes more sense this way.
|
||||
// There are a good amount of variants in here, ranging from mining to security to misc ones.
|
||||
// If you want to make a variant, you need to only change modifier_type and make the modifier desired.
|
||||
|
||||
|
||||
/obj/item/device/personal_shield_generator
|
||||
name = "personal shield generator"
|
||||
desc = "A personal shield generator."
|
||||
icon = 'icons/obj/items_vr.dmi'
|
||||
icon_state = "shieldpack_basic"
|
||||
item_state = "defibunit" //Placeholder
|
||||
slot_flags = SLOT_BACK
|
||||
force = 5
|
||||
throwforce = 6
|
||||
preserve_item = 1
|
||||
w_class = ITEMSIZE_HUGE //It's a giant shield generator!!!
|
||||
unacidable = TRUE
|
||||
origin_tech = list(TECH_MATERIAL = 6, TECH_COMBAT = 8, TECH_POWER = 6, TECH_DATA = 4) //These are limited AND high tech. Breaking one of them down is massive.
|
||||
action_button_name = "Toggle Shield"
|
||||
var/obj/item/weapon/gun/energy/gun/generator/active_weapon
|
||||
var/obj/item/weapon/cell/device/bcell = null
|
||||
|
||||
|
||||
var/generator_hit_cost = 100 // Power used when a special effect (such as a bullet being blocked) is performed! Could also be expanded to other things.
|
||||
var/generator_active_cost = 10 // Power used when turned on.
|
||||
var/damage_cost = 25 // 40 damage absorbed per 1000 charge.
|
||||
var/modifier_type = /datum/modifier/shield_projection // What type of modifier will it add? Used for variant modifiers!
|
||||
|
||||
var/has_weapon = 1 // Backpack units generally have weapons.
|
||||
var/shield_active = 0 // If the shield gen is active.
|
||||
var/effect_color = "#99FFFF" // Allows for changing shield colors. Default cyan.
|
||||
|
||||
/obj/item/device/personal_shield_generator/get_cell()
|
||||
return bcell
|
||||
|
||||
/obj/item/device/personal_shield_generator/New()
|
||||
..()
|
||||
if(ispath(bcell))
|
||||
bcell = new bcell(src)
|
||||
|
||||
if(has_weapon)
|
||||
if(ispath(active_weapon))
|
||||
active_weapon = new active_weapon(src, src)
|
||||
active_weapon.power_supply = bcell
|
||||
else
|
||||
active_weapon = new(src, src)
|
||||
active_weapon.power_supply = bcell
|
||||
else
|
||||
verbs -= /obj/item/device/personal_shield_generator/verb/weapon_toggle
|
||||
STOP_PROCESSING(SSobj, src) //We do this so it doesn't start processing until it's first used.
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/personal_shield_generator/Destroy()
|
||||
. = ..()
|
||||
QDEL_NULL(active_weapon)
|
||||
QDEL_NULL(bcell)
|
||||
|
||||
/obj/item/device/personal_shield_generator/loaded //starts with a cell
|
||||
bcell = /obj/item/weapon/cell/device/shield_generator/backpack
|
||||
|
||||
|
||||
/obj/item/device/personal_shield_generator/update_icon()
|
||||
if(shield_active)
|
||||
icon_state = "shieldpack_basic_on"
|
||||
else
|
||||
icon_state = "shieldpack_basic"
|
||||
|
||||
/obj/item/device/personal_shield_generator/examine(mob/user)
|
||||
. = ..()
|
||||
if(Adjacent(user))
|
||||
if(bcell)
|
||||
. += "The internal cell is [round(bcell.percent() )]% charged."
|
||||
else
|
||||
. += "The device has no cell installed."
|
||||
return
|
||||
if(damage_cost) //Prevention of dividing by 0 errors.
|
||||
. += "It reads that it can take [bcell.charge/damage_cost] more damage before the shield goes down."
|
||||
if(bcell.self_recharge && bcell.charge_amount)
|
||||
. += "This model is self charging and will take [bcell.maxcharge/bcell.charge_amount] seconds to fully charge from empty."
|
||||
if(bcell.rigged)
|
||||
. += "A red flashing 'WARNING' is visible on the display, noting that the cell is unstable and requires replacement."
|
||||
|
||||
|
||||
/* //This would be cool, but we need sprites.
|
||||
cut_overlays()
|
||||
|
||||
if(has_weapon && active_weapon && active_weapon.loc == src) //in case gun gets destroyed somehow.
|
||||
add_overlay("[initial(icon_state)]-paddles")
|
||||
if(bcell)
|
||||
if(bcell.check_charge(generator_hit_cost)) //Can we take a blow?
|
||||
add_overlay("[initial(icon_state)]-powered")
|
||||
else if(has_weapon && active_weapon)
|
||||
if(bcell.check_charge(active_weapon.charge_cost)) //We got enough to go pew pew?
|
||||
add_overlay("[initial(icon_state)]-powered")
|
||||
|
||||
var/ratio = CEILING(bcell.percent()/25, 1) * 25
|
||||
add_overlay("[initial(icon_state)]-charge[ratio]")
|
||||
else
|
||||
add_overlay("[initial(icon_state)]-nocell")
|
||||
*/
|
||||
|
||||
/obj/item/device/personal_shield_generator/emp_act(severity)
|
||||
if(bcell && shield_active)
|
||||
switch(severity)
|
||||
if(1) //Point blank EMP shots have a good chance of burning the cell charge.
|
||||
if(prob(50))
|
||||
bcell.emp_act(severity)
|
||||
if(prob(5)) //1 in 20% chance to fry the battery completly, which has a 1/10 chance of making the battery explode on next use.
|
||||
bcell.corrupt() //Not too bad if you slotted a battery in. Disasterous if it has a self-charging battery.
|
||||
if(bcell.rigged) //Did the above just rig the cell? Turn it off. Don't immediately have it go boom. Instead have the cell blow soon-ish.
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
shield_active = 0
|
||||
if(bcell.charge_delay) //It WILL blow up soon. Downside of self-charging cells.
|
||||
to_chat(src.loc, "<span class='critical'>Your shield generator sparks and suddenly goes down! A warning message pops up on screen: \
|
||||
'WARNING, INTERNAL CELL MELTDOWN IMMINENT. TIME TILL EXPLOSION: [bcell.charge_delay/10] SECONDS. DISCARD UNIT IMMEDIATELY!'</span>")
|
||||
else //It won't blow up unless you turn it back on again. Upside of using non-charging cells.
|
||||
to_chat(src.loc, "<span class='critical'>Your shield generator sparks and suddenly goes down! A warning message pops up on screen: \
|
||||
'WARNING, INTERNAL CELL CRITICALLY DAMAGED. REPLACE CELL IMMEDIATELY.'</span>")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
else
|
||||
if(prob(25))
|
||||
bcell.emp_act(severity)
|
||||
..()
|
||||
|
||||
/obj/item/device/personal_shield_generator/ui_action_click()
|
||||
toggle_shield()
|
||||
|
||||
/obj/item/device/personal_shield_generator/attack_hand(mob/user)
|
||||
if(loc == user)
|
||||
toggle_shield()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/device/personal_shield_generator/AltClick(mob/living/user)
|
||||
weapon_toggle()
|
||||
|
||||
/obj/item/device/personal_shield_generator/MouseDrop()
|
||||
if(ismob(src.loc))
|
||||
if(!CanMouseDrop(src))
|
||||
return
|
||||
var/mob/M = src.loc
|
||||
if(!M.unEquip(src))
|
||||
return
|
||||
src.add_fingerprint(usr)
|
||||
M.put_in_any_hand_if_possible(src)
|
||||
|
||||
|
||||
/obj/item/device/personal_shield_generator/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(W == active_weapon)
|
||||
reattach_gun(user)
|
||||
else if(istype(W, /obj/item/weapon/cell))
|
||||
if(bcell)
|
||||
to_chat(user, "<span class='notice'>\The [src] already has a cell.</span>")
|
||||
else if(!istype(W, /obj/item/weapon/cell/device/weapon)) //Weapon cells only!
|
||||
to_chat(user, "<span class='notice'>This cell will not fit in the device.</span>")
|
||||
else
|
||||
if(!user.unEquip(W))
|
||||
return
|
||||
W.forceMove(src)
|
||||
bcell = W
|
||||
if(active_weapon)
|
||||
active_weapon.power_supply = bcell
|
||||
to_chat(user, "<span class='notice'>You install a cell in \the [src].</span>")
|
||||
update_icon()
|
||||
|
||||
else if(W.is_screwdriver())
|
||||
if(bcell)
|
||||
if(istype(bcell, /obj/item/weapon/cell/device/shield_generator)) //No stealing self charging batteries!
|
||||
var/choice = tgui_alert(user, "A popup appears on the device 'REMOVING THE INTERNAL CELL WILL DESTROY THE BATTERY. DO YOU WISH TO CONTINUE?'...Well, do you?", "Selection List", list("Cancel", "Remove"))
|
||||
if(choice == "Remove") //Warned you...
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
bcell.forceMove(get_turf(src.loc))
|
||||
qdel(bcell)
|
||||
bcell = null //Sanity.
|
||||
if(active_weapon)
|
||||
reattach_gun() //Put the gun back if it's out. No shooting if we don't have a cell!
|
||||
active_weapon.power_supply = null //No power cell anymore!
|
||||
to_chat(user, "<span class='notice'>You remove the cell from \the [src], destroying the battery.</span>")
|
||||
update_icon()
|
||||
return
|
||||
else
|
||||
return
|
||||
else
|
||||
bcell.update_icon()
|
||||
bcell.forceMove(get_turf(src.loc))
|
||||
bcell = null
|
||||
if(active_weapon)
|
||||
reattach_gun() //Put the gun back if it's out. No shooting if we don't have a cell!
|
||||
active_weapon.power_supply = null //No power cell anymore!
|
||||
to_chat(user, "<span class='notice'>You remove the cell from \the [src].</span>")
|
||||
update_icon()
|
||||
else if(istype(W,/obj/item/device/multitool))
|
||||
var/new_color = input(usr, "Choose a color to set the shield to!", "", effect_color) as color|null
|
||||
if(new_color)
|
||||
effect_color = new_color
|
||||
else
|
||||
return ..()
|
||||
|
||||
// TODO: EMAG ACT
|
||||
// Perhaps make it so emagging the generator gives two options: One to rig the cell (stealthily) and one to disable the safeties (supercharge it)
|
||||
// Disabling the safeties would make it a stronger variant but boost the 'damage_cost' perhaps. Dunno.
|
||||
// We're an RP server so emags don't come into play except for random trash finds. Meaning it'd be RNG if you could 'supercharge' your shield genrator.
|
||||
// This would kind of be like people being able to emag the NIFSoft for bloodletters & all the buffs that come with an emagged NIFSoft.
|
||||
// Making it so emagging the weapon it comes with would also be a good idea. Different modes, perhaps?
|
||||
|
||||
/*
|
||||
/obj/item/device/personal_shield_generator/emag_act(var/remaining_charges, var/mob/user)
|
||||
if(active_weapon)
|
||||
. = active_weapon.emag_act(user)
|
||||
update_icon()
|
||||
return
|
||||
*/
|
||||
|
||||
//Gun stuff
|
||||
|
||||
|
||||
/obj/item/device/personal_shield_generator/verb/toggle_shield()
|
||||
set name = "Toggle Shield"
|
||||
set category = "Object"
|
||||
|
||||
var/mob/living/carbon/human/user = usr
|
||||
|
||||
if(user.last_special > world.time)
|
||||
return
|
||||
user.last_special = world.time + 10 //No spamming!
|
||||
|
||||
if(!bcell || !bcell.check_charge(generator_hit_cost) || !bcell.check_charge(generator_active_cost))
|
||||
to_chat(user, "<span class='warning'>You require a charged cell to do this!</span>")
|
||||
return
|
||||
|
||||
if(!slot_check())
|
||||
to_chat(user, "<span class='warning'>You need to equip [src] before starting the shield up!</span>")
|
||||
return
|
||||
else
|
||||
if(shield_active)
|
||||
shield_active = !shield_active //Deactivate the shield!
|
||||
to_chat(user, "<span class='warning'>You deactive the shield!</span>")
|
||||
user.remove_modifiers_of_type(/datum/modifier/shield_projection)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
playsound(src, 'sound/weapons/saberoff.ogg', 50, 1) //Shield turning off! PLACEHOLDER
|
||||
else
|
||||
shield_active = !shield_active
|
||||
to_chat(user, "<span class='warning'>You activate the shield!</span>")
|
||||
user.remove_modifiers_of_type(/datum/modifier/shield_projection) //Just to make sure they aren't using two at once!
|
||||
user.add_modifier(modifier_type)
|
||||
user.update_modifier_visuals() //Forces coloration to WORK.
|
||||
START_PROCESSING(SSobj, src) //Let's only bother draining power when we're being used!
|
||||
playsound(src, 'sound/weapons/saberon.ogg', 50, 1) //Shield turning off! PLACEHOLDER
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/personal_shield_generator/verb/weapon_toggle() //Make this work on Alt-Click
|
||||
set name = "Toggle Gun"
|
||||
set category = "Object"
|
||||
|
||||
var/mob/living/carbon/human/user = usr
|
||||
|
||||
if(user.last_special > world.time)
|
||||
return
|
||||
user.last_special = world.time + 10 //No spamming!
|
||||
|
||||
if(!active_weapon)
|
||||
to_chat(user, "<span class='warning'>The gun is missing!</span>")
|
||||
return
|
||||
|
||||
if(!bcell)
|
||||
to_chat(user, "<span class='warning'>The gun requires a power supply!</span>")
|
||||
return
|
||||
|
||||
if(active_weapon.loc != src)
|
||||
reattach_gun(user) //Remove from their hands and back onto the defib unit
|
||||
return
|
||||
|
||||
if(!slot_check())
|
||||
to_chat(user, "<span class='warning'>You need to equip [src] before taking out [active_weapon].</span>")
|
||||
else
|
||||
if(!usr.put_in_hands(active_weapon)) //Detach the gun into the user's hands
|
||||
to_chat(user, "<span class='warning'>You need a free hand to hold the gun!</span>")
|
||||
update_icon() //success
|
||||
|
||||
/obj/item/device/personal_shield_generator/process()
|
||||
if(!bcell) //They removed the battery midway.
|
||||
if(istype(loc, /mob/living/carbon/human)) //We on someone? Tell them it turned off.
|
||||
var/mob/living/carbon/human/user = loc
|
||||
to_chat(user, "<span class='warning'>The shield deactivates! An error message pops up on screen: 'Cell missing. Cell replacement required.'</span>")
|
||||
user.remove_modifiers_of_type(/datum/modifier/shield_projection)
|
||||
shield_active = 0
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
playsound(src, 'sound/weapons/saberoff.ogg', 50, 1) //Shield turning off! PLACEHOLDER
|
||||
return
|
||||
|
||||
if(shield_active)
|
||||
if(bcell.rigged) //They turned it back on after it was rigged to go boom.
|
||||
if(istype(loc, /mob/living/carbon/human)) //Deactivate the shield, first. You're not getting reduced damage...
|
||||
var/mob/living/carbon/human/user = loc
|
||||
to_chat(user, "<span class='warning'>The shield deactivates, an error message popping up on screen: 'Cell Reactor Critically damaged. Cell replacement required.'</span>")
|
||||
user.remove_modifiers_of_type(/datum/modifier/shield_projection)
|
||||
|
||||
if(active_weapon) //Retract the gun. There's about to be no cell anymore.
|
||||
reattach_gun()
|
||||
active_weapon.power_supply = null
|
||||
|
||||
bcell.use(generator_active_cost) //Causes it to go boom.
|
||||
bcell = null
|
||||
shield_active = 0
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
else //Normal operation.
|
||||
bcell.use(generator_active_cost)
|
||||
|
||||
if(bcell.charge < generator_hit_cost || bcell.charge < generator_active_cost) //Out of charge...
|
||||
shield_active = 0
|
||||
if(istype(loc, /mob/living/carbon/human)) //We on someone? Tell them it turned off.
|
||||
var/mob/living/carbon/human/user = loc
|
||||
to_chat(user, "<span class='warning'>The shield deactivates, an error message popping up on screen: 'Cell out of charge.'</span>")
|
||||
user.remove_modifiers_of_type(/datum/modifier/shield_projection)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
playsound(src, 'sound/weapons/saberoff.ogg', 50, 1) //Shield turning off! PLACEHOLDER
|
||||
return
|
||||
|
||||
|
||||
|
||||
//checks that the base unit is in the correct slot to be used
|
||||
/obj/item/device/personal_shield_generator/proc/slot_check()
|
||||
var/mob/M = loc
|
||||
if(!istype(M))
|
||||
return 0 //not equipped
|
||||
|
||||
if((slot_flags & SLOT_BACK) && M.get_equipped_item(slot_back) == src)
|
||||
return 1
|
||||
if((slot_flags & SLOT_BELT) && M.get_equipped_item(slot_belt) == src)
|
||||
return 1
|
||||
//RIGSuit compatability. This shouldn't be possible, however, except for select RIGs.
|
||||
if((slot_flags & SLOT_BACK) && M.get_equipped_item(slot_s_store) == src)
|
||||
return 1
|
||||
if((slot_flags & SLOT_BELT) && M.get_equipped_item(slot_s_store) == src)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/item/device/personal_shield_generator/dropped(mob/user)
|
||||
..()
|
||||
reattach_gun(user) //A gun attached to a base unit should never exist outside of their base unit or the mob equipping the base unit
|
||||
|
||||
/obj/item/device/personal_shield_generator/proc/reattach_gun(mob/user)
|
||||
if(!active_weapon) return
|
||||
|
||||
if(ismob(active_weapon.loc))
|
||||
var/mob/M = active_weapon.loc
|
||||
if(M.drop_from_inventory(active_weapon, src))
|
||||
to_chat(user, "<span class='notice'>\The [active_weapon] snaps back into the main unit.</span>")
|
||||
else
|
||||
active_weapon.forceMove(src)
|
||||
|
||||
update_icon()
|
||||
|
||||
//The gun
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/generator //The gun attached to the personal shield generator.
|
||||
name = "generator gun"
|
||||
desc = "A gun that is attached to the battery of the personal shield generator."
|
||||
icon_state = "egunstun"
|
||||
item_state = null //so the human update icon uses the icon_state instead.
|
||||
fire_delay = 8
|
||||
use_external_power = TRUE
|
||||
cell_type = null //No cell! It runs off the cell in the shield_gen!
|
||||
|
||||
projectile_type = /obj/item/projectile/beam/stun/med
|
||||
modifystate = "egunstun"
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun/med, modifystate="egunstun", fire_sound='sound/weapons/Taser.ogg', charge_cost = 240),
|
||||
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, modifystate="egunkill", fire_sound='sound/weapons/Laser.ogg', charge_cost = 480),
|
||||
)
|
||||
|
||||
var/obj/item/device/personal_shield_generator/shield_generator //The generator we are linked to!
|
||||
var/wielded = 0
|
||||
var/cooldown = 0
|
||||
var/busy = 0
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/generator/New(newloc, obj/item/device/personal_shield_generator/shield_gen)
|
||||
..(newloc)
|
||||
shield_generator = shield_gen
|
||||
power_supply = shield_generator.bcell
|
||||
|
||||
/* //Unused. Use for large guns.
|
||||
/obj/item/weapon/gun/energy/gun/generator/update_held_icon()
|
||||
var/mob/living/M = loc
|
||||
if(istype(M) && M.item_is_in_hands(src) && !M.hands_are_full())
|
||||
wielded = 1
|
||||
name = "[initial(name)] (wielded)"
|
||||
else
|
||||
wielded = 0
|
||||
name = initial(name)
|
||||
update_icon()
|
||||
..()
|
||||
*/
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/generator/proc/can_use(mob/user, mob/M)
|
||||
if(busy)
|
||||
return 0
|
||||
if(!check_charge(charge_cost))
|
||||
to_chat(user, "<span class='warning'>\The [src] doesn't have enough charge left to do that.</span>")
|
||||
return 0
|
||||
if(!wielded && !isrobot(user))
|
||||
to_chat(user, "<span class='warning'>You need to wield the gun with both hands before you can use it on someone!</span>")
|
||||
return 0
|
||||
if(cooldown)
|
||||
to_chat(user, "<span class='warning'>\The [src] are re-energizing!</span>")
|
||||
return 0
|
||||
return 1
|
||||
|
||||
// TODO: EMP ACT
|
||||
// The cell already gets hit and can have some nasty effects when EMP'd, so this isn't too much of a concern.
|
||||
|
||||
/*
|
||||
/obj/item/weapon/gun/energy/gun/generator/emp_act(severity)
|
||||
..()
|
||||
*/
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/generator/dropped(mob/user)
|
||||
..() //update twohanding
|
||||
if(shield_generator)
|
||||
shield_generator.reattach_gun(user)
|
||||
|
||||
/obj/item/weapon/gun/energy/proc/check_charge(var/charge_amt) //In case using any other guns.
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/gun/energy/proc/checked_use(var/charge_amt) //In case using any other guns.
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/generator/check_charge(var/charge_amt)
|
||||
return (shield_generator.bcell && shield_generator.bcell.check_charge(charge_amt))
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/generator/checked_use(var/charge_amt)
|
||||
return (shield_generator.bcell && shield_generator.bcell.checked_use(charge_amt))
|
||||
|
||||
|
||||
|
||||
//VARIANTS.
|
||||
|
||||
/obj/item/device/personal_shield_generator/belt
|
||||
name = "personal shield generator"
|
||||
desc = "A personal shield generator."
|
||||
icon_state = "shieldpack_basic"
|
||||
item_state = "defibunit"
|
||||
w_class = ITEMSIZE_LARGE //No putting these in backpacks!
|
||||
slot_flags = SLOT_BELT
|
||||
has_weapon = 0 //No gun with the belt!
|
||||
|
||||
/obj/item/device/personal_shield_generator/belt/loaded
|
||||
bcell = /obj/item/weapon/cell/device/shield_generator
|
||||
|
||||
/obj/item/device/personal_shield_generator/belt/update_icon()
|
||||
if(shield_active)
|
||||
icon_state = "shieldpack_basic_on"
|
||||
else
|
||||
icon_state = "shieldpack_basic"
|
||||
|
||||
/obj/item/device/personal_shield_generator/belt/bruteburn //Example of a modified generator.
|
||||
modifier_type = /datum/modifier/shield_projection/bruteburn
|
||||
/obj/item/device/personal_shield_generator/belt/bruteburn/loaded //If mapped in, ONLY put loaded ones down.
|
||||
bcell = /obj/item/weapon/cell/device/shield_generator
|
||||
|
||||
// Mining belts
|
||||
/obj/item/device/personal_shield_generator/belt/mining
|
||||
name = "mining PSG"
|
||||
desc = "A personal shield generator designed for mining. It has a warning on the back: 'Do NOT expose the shield to stun-based weaponry.'"
|
||||
modifier_type = /datum/modifier/shield_projection/mining
|
||||
|
||||
/obj/item/device/personal_shield_generator/belt/mining/loaded
|
||||
bcell = /obj/item/weapon/cell/device/shield_generator
|
||||
|
||||
/obj/item/device/personal_shield_generator/belt/mining/update_icon()
|
||||
if(shield_active)
|
||||
icon_state = "shieldpack_mining_on"
|
||||
else
|
||||
icon_state = "shieldpack_mining"
|
||||
|
||||
/obj/item/borg/upgrade/shield_upgrade
|
||||
name = "mining PSG upgrade disk."
|
||||
desc = "A upgrade disk that, when slotted into a mining shield generator, upgrades the efficiency of the internal software, providing a stronger shield \
|
||||
in exchange for being weaker to stun-based weaponry."
|
||||
icon = 'icons/obj/objects_vr.dmi'
|
||||
icon_state = "modkit"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
|
||||
/obj/item/device/personal_shield_generator/belt/mining/attackby(obj/item/weapon/W, mob/user, params)
|
||||
if(modifier_type == /datum/modifier/shield_projection/mining/strong)
|
||||
to_chat(user, "<span class='warning'>This shield generator is already upgraded!</span>")
|
||||
return
|
||||
if(istype(W, /obj/item/borg/upgrade/shield_upgrade))
|
||||
modifier_type = /datum/modifier/shield_projection/mining/strong
|
||||
to_chat(user, "<span class='notice'>You upgrade the [src] with the [W]!</span>")
|
||||
user.drop_from_inventory(W)
|
||||
qdel(W)
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
//Security belts
|
||||
|
||||
/obj/item/device/personal_shield_generator/belt/security
|
||||
name = "security PSG"
|
||||
desc = "A personal shield generator designed for security."
|
||||
modifier_type = /datum/modifier/shield_projection/security/weak
|
||||
|
||||
/obj/item/device/personal_shield_generator/belt/security/loaded
|
||||
bcell = /obj/item/weapon/cell/device/shield_generator
|
||||
|
||||
/obj/item/device/personal_shield_generator/belt/security/update_icon()
|
||||
if(shield_active)
|
||||
icon_state = "shieldpack_security_on"
|
||||
else
|
||||
icon_state = "shieldpack_security"
|
||||
|
||||
//Misc belts. Admin-spawn only atm.
|
||||
|
||||
/obj/item/device/personal_shield_generator/belt/adminbus
|
||||
desc = "You should not see this. You REALLY should not see this. If you do, you have either been blessed or are about to be the target of some sick prank."
|
||||
modifier_type = /datum/modifier/shield_projection/admin
|
||||
generator_hit_cost = 0
|
||||
generator_active_cost = 0
|
||||
shield_active = 0
|
||||
damage_cost = 0
|
||||
bcell = /obj/item/weapon/cell/device/shield_generator
|
||||
|
||||
/obj/item/device/personal_shield_generator/belt/parry //The 'provides one second of pure immunity to brute/burn/halloss' belt.
|
||||
name = "PSG variant-P" //Not meant to be used in any serious capacity.
|
||||
desc = "A personal shield generator that sacrifices long-term usability in exchange for a strong, short-lived shield projection, enabling the user to be nigh \
|
||||
impervious for a second."
|
||||
modifier_type = /datum/modifier/shield_projection/parry
|
||||
generator_hit_cost = 0 //No cost for being hit.
|
||||
damage_cost = 0//No cost for blocking effects.
|
||||
generator_active_cost = 100 //However, it disables the tick immediately after being turned on.
|
||||
shield_active = 0
|
||||
bcell = /obj/item/weapon/cell/device/shield_generator/parry
|
||||
|
||||
// Backpacks. These are meant to be MUCH stronger in exchange for the fact that you are giving up a backpack slot.
|
||||
// HOWEVER, be careful with these. They come loaded with a gun in them, so they shouldn't be handed out willy-nilly.
|
||||
|
||||
/obj/item/device/personal_shield_generator/security
|
||||
name = "security PSG"
|
||||
desc = "A personal shield generator designed for security. Comes with a built in defense pistol."
|
||||
modifier_type = /datum/modifier/shield_projection/security
|
||||
|
||||
/obj/item/device/personal_shield_generator/security/loaded
|
||||
bcell = /obj/item/weapon/cell/device/shield_generator/backpack
|
||||
|
||||
/obj/item/device/personal_shield_generator/security/strong
|
||||
modifier_type = /datum/modifier/shield_projection/security/strong
|
||||
|
||||
/obj/item/device/personal_shield_generator/security/strong/loaded
|
||||
bcell = /obj/item/weapon/cell/device/shield_generator/backpack
|
||||
|
||||
/obj/item/device/personal_shield_generator/security/update_icon()
|
||||
if(shield_active)
|
||||
icon_state = "shieldpack_security_on"
|
||||
else
|
||||
icon_state = "shieldpack_security"
|
||||
|
||||
//Power cells.
|
||||
/obj/item/weapon/cell/device/shield_generator //The base power cell the shield gen comes with.
|
||||
name = "shield generator battery"
|
||||
desc = "A self charging battery which houses a micro-nuclear reactor. Takes a while to start charging."
|
||||
maxcharge = 2400
|
||||
self_recharge = TRUE
|
||||
charge_amount = 80 //After the charge_delay is over, charges the cell over 30 seconds.
|
||||
charge_delay = 600 //Takes a minute before it starts to recharge.
|
||||
|
||||
/obj/item/weapon/cell/device/shield_generator/backpack //The base power cell the backpack units come with. Double the charge vs the belt.
|
||||
maxcharge = 4800
|
||||
charge_amount = 160
|
||||
|
||||
/obj/item/weapon/cell/device/shield_generator/upgraded //A stronger version of the normal cell. Double the maxcharge, halved charge time.
|
||||
maxcharge = 4800
|
||||
charge_amount = 320
|
||||
charge_delay = 300
|
||||
|
||||
/obj/item/weapon/cell/device/shield_generator/parry //The cell for the 'parry' shield gen.
|
||||
maxcharge = 100
|
||||
charge_amount = 100
|
||||
charge_delay = 20 //Starts charging two seconds after it's discharged.
|
||||
@@ -322,7 +322,7 @@ GLOBAL_DATUM(autospeaker, /mob/living/silicon/ai/announcer)
|
||||
GLOB.autospeaker.SetName(from)
|
||||
Broadcast_Message(connection, GLOB.autospeaker,
|
||||
0, "*garbled automated announcement*", src,
|
||||
message_to_multilingual(message), from, "Automated Announcement", from, "synthesized voice",
|
||||
message_to_multilingual(message, GLOB.all_languages[LANGUAGE_GALCOM]), from, "Automated Announcement", from, "synthesized voice",
|
||||
DATA_FAKE, 0, zlevels, connection.frequency, states) //VOREStation Edit
|
||||
|
||||
// Interprets the message mode when talking into a radio, possibly returning a connection datum
|
||||
|
||||
@@ -105,17 +105,40 @@
|
||||
if(M.radiation)
|
||||
if(advscan >= 2 && showadvscan == 1)
|
||||
var/severity = ""
|
||||
if(M.radiation >= 75)
|
||||
if(M.radiation >= 1500)
|
||||
severity = "Lethal"
|
||||
else if(M.radiation >= 600)
|
||||
severity = "Critical"
|
||||
else if(M.radiation >= 50)
|
||||
else if(M.radiation >= 400)
|
||||
severity = "Severe"
|
||||
else if(M.radiation >= 25)
|
||||
else if(M.radiation >= 300)
|
||||
severity = "Moderate"
|
||||
else if(M.radiation >= 1)
|
||||
else if(M.radiation >= 100)
|
||||
severity = "Low"
|
||||
dat += "<span class='warning'>[severity] levels of radiation detected. [(severity == "Critical") ? " Immediate treatment advised." : ""]</span><br>"
|
||||
dat += "<span class='warning'>[severity] levels of acute radiation sickness detected. [round(M.radiation/50)]Gy. [(severity == "Critical" || severity == "Lethal") ? " Immediate treatment advised." : ""]</span><br>"
|
||||
else
|
||||
dat += "<span class='warning'>Radiation detected.</span><br>"
|
||||
dat += "<span class='warning'>Acute radiation sickness detected.</span><br>"
|
||||
if(M.accumulated_rads)
|
||||
if(advscan >= 2 && showadvscan == 1)
|
||||
var/severity = ""
|
||||
if(M.accumulated_rads >= 1500)
|
||||
severity = "Critical"
|
||||
else if(M.accumulated_rads >= 600)
|
||||
severity = "Severe"
|
||||
else if(M.accumulated_rads >= 400)
|
||||
severity = "Moderate"
|
||||
else if(M.accumulated_rads >= 300)
|
||||
severity = "Mild"
|
||||
else if(M.accumulated_rads >= 100)
|
||||
severity = "Low"
|
||||
dat += "<span class='warning'>[severity] levels of chronic radiation sickness detected. [round(M.accumulated_rads/50)]Gy.</span><br>"
|
||||
else
|
||||
dat += "<span class='warning'>Chronic radiation sickness detected.</span><br>"
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
if(C.reagents.total_volume)
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/obj/effect/calldown_attack
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
unacidable = TRUE
|
||||
mouse_opacity = 0
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "drop_marker"
|
||||
|
||||
/obj/effect/calldown_attack/Initialize(mapload)
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/effect/calldown_attack/LateInitialize()
|
||||
var/delay = rand(25, 30)
|
||||
spawn(delay-7)
|
||||
new /obj/effect/falling_effect/calldown_attack(src.loc)
|
||||
spawn(delay)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/effect/falling_effect/calldown_attack
|
||||
falling_type = /obj/effect/illusionary_fall
|
||||
crushing = FALSE
|
||||
|
||||
|
||||
/obj/effect/illusionary_fall
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
mouse_opacity = 0
|
||||
icon = 'icons/effects/random_stuff_vr.dmi'
|
||||
|
||||
/obj/effect/illusionary_fall/Initialize(mapload)
|
||||
.=..()
|
||||
icon_state = "[rand(1,33)]"
|
||||
|
||||
/obj/effect/illusionary_fall/end_fall(var/crushing = FALSE)
|
||||
for(var/mob/living/L in loc)
|
||||
var/target_zone = ran_zone()
|
||||
var/blocked = L.run_armor_check(target_zone, "melee")
|
||||
var/soaked = L.get_armor_soak(target_zone, "melee")
|
||||
|
||||
if(!L.apply_damage(35, BRUTE, target_zone, blocked, soaked))
|
||||
break
|
||||
playsound(src, 'sound/effects/clang2.ogg', 50, 1)
|
||||
qdel(src)
|
||||
@@ -8,9 +8,10 @@
|
||||
var/falling_type = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita
|
||||
var/crushing = TRUE
|
||||
|
||||
/obj/effect/falling_effect/Initialize(mapload, type = /obj/item/weapon/reagent_containers/food/snacks/sliceable/pizza/margherita)
|
||||
/obj/effect/falling_effect/Initialize(mapload, type)
|
||||
..()
|
||||
falling_type = type
|
||||
if(type)
|
||||
falling_type = type
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/effect/falling_effect/LateInitialize()
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
name = T_BOARD("oven")
|
||||
desc = "The circuitboard for an oven."
|
||||
build_path = /obj/machinery/appliance/cooker/oven
|
||||
board_type = new /datum/frame/frame_types/oven
|
||||
board_type = new /datum/frame/frame_types/machine
|
||||
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/capacitor = 3,
|
||||
@@ -27,17 +27,17 @@
|
||||
name = T_BOARD("deep fryer")
|
||||
desc = "The circuitboard for a deep fryer."
|
||||
build_path = /obj/machinery/appliance/cooker/fryer
|
||||
board_type = new /datum/frame/frame_types/fryer
|
||||
board_type = new /datum/frame/frame_types/machine
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/capacitor = 3,
|
||||
/obj/item/weapon/stock_parts/scanning_module = 1,
|
||||
/obj/item/weapon/stock_parts/matter_bin = 2)
|
||||
|
||||
|
||||
/obj/item/weapon/circuitboard/grill
|
||||
name = T_BOARD("grill")
|
||||
desc = "The circuitboard for an industrial grill."
|
||||
build_path = /obj/machinery/appliance/cooker/grill
|
||||
board_type = new /datum/frame/frame_types/grill
|
||||
board_type = new /datum/frame/frame_types/machine
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/capacitor = 3,
|
||||
/obj/item/weapon/stock_parts/scanning_module = 1,
|
||||
@@ -47,7 +47,7 @@
|
||||
name = T_BOARD("cereal maker")
|
||||
desc = "The circuitboard for a cereal maker."
|
||||
build_path = /obj/machinery/appliance/mixer/cereal
|
||||
board_type = new /datum/frame/frame_types/cerealmaker
|
||||
board_type = new /datum/frame/frame_types/machine
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/capacitor = 3,
|
||||
/obj/item/weapon/stock_parts/scanning_module = 1,
|
||||
@@ -57,7 +57,7 @@
|
||||
name = T_BOARD("candy machine")
|
||||
desc = "The circuitboard for a candy machine."
|
||||
build_path = /obj/machinery/appliance/mixer/candy
|
||||
board_type = new /datum/frame/frame_types/candymachine
|
||||
board_type = new /datum/frame/frame_types/machine
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/capacitor = 3,
|
||||
/obj/item/weapon/stock_parts/scanning_module = 1,
|
||||
|
||||
@@ -5,4 +5,21 @@
|
||||
icon = 'icons/obj/weapons_vr.dmi'
|
||||
item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_melee_vr.dmi', slot_r_hand_str = 'icons/mob/items/righthand_melee_vr.dmi')
|
||||
colorable = FALSE
|
||||
lcolor = "#FFFFFF"
|
||||
lcolor = "#FFFFFF"
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/altevian
|
||||
name = "plasma blade cutter"
|
||||
desc = "A device used as both defense and operational purposes to cut through most metals. This is usually seen on engineers from the altevian hegemony when working salvaging derelicts."
|
||||
icon_state = "altevian-cutter"
|
||||
item_state = "altevian-cutter"
|
||||
icon = 'icons/obj/weapons_vr.dmi'
|
||||
item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_melee_vr.dmi', slot_r_hand_str = 'icons/mob/items/righthand_melee_vr.dmi')
|
||||
colorable = FALSE
|
||||
lcolor = "#FFFFFF"
|
||||
|
||||
/obj/item/weapon/melee/energy/sword/altevian/update_icon()
|
||||
..()
|
||||
if(active)
|
||||
icon_state = "[initial(icon_state)]_active"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
@@ -13,4 +13,22 @@
|
||||
sharp = TRUE
|
||||
edge = FALSE
|
||||
attack_verb = list("stabbed", "lunged at", "dextrously struck", "sliced", "lacerated", "impaled", "diced", "charioted")
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
hitsound = 'sound/weapons/bladeslice.ogg'
|
||||
|
||||
/obj/item/weapon/melee/altevian_wrench
|
||||
name = "Hull Systems Multi-Wrench"
|
||||
desc = "A wrench designed with a method to help secure and access bolts, hatches, and airlocks on altevian designed vessels. This operates as nothing more than a massive wrench when used for other purposes."
|
||||
icon = 'icons/obj/weapons_vr.dmi'
|
||||
icon_state = "altevian-wrench"
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_melee_vr.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_melee_vr.dmi',
|
||||
)
|
||||
slot_flags = SLOT_BACK
|
||||
force = 25
|
||||
throwforce = 15
|
||||
w_class = ITEMSIZE_HUGE
|
||||
sharp = FALSE
|
||||
edge = FALSE
|
||||
attack_verb = list("whacked", "slammed", "bashed", "wrenched", "fixed", "bolted", "clonked", "bonked")
|
||||
hitsound = 'sound/weapons/smash.ogg'
|
||||
@@ -59,7 +59,7 @@
|
||||
//Please don't clutter the parent storage item with stupid hacks.
|
||||
/obj/item/weapon/storage/backpack/holding/can_be_inserted(obj/item/W as obj, stop_messages = 0)
|
||||
if(istype(W, /obj/item/weapon/storage/backpack/holding))
|
||||
return 1
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/storage/backpack/santabag
|
||||
|
||||
@@ -295,7 +295,6 @@
|
||||
|
||||
if(!inserted)
|
||||
usr.remove_from_mob(S)
|
||||
usr.update_icons() //update our overlays
|
||||
if (usr.client && usr.s_active != src)
|
||||
usr.client.screen -= S
|
||||
S.dropped(usr)
|
||||
|
||||
@@ -98,6 +98,7 @@
|
||||
prob(2);/obj/item/weapon/gun/projectile/shotgun/pump/combat,
|
||||
prob(4);/obj/item/weapon/gun/projectile/shotgun/pump/rifle,
|
||||
prob(3);/obj/item/weapon/gun/projectile/shotgun/pump/rifle/lever,
|
||||
prob(2);/obj/item/weapon/gun/projectile/shotgun/semi,
|
||||
prob(2);/obj/item/weapon/gun/projectile/silenced)
|
||||
|
||||
/obj/random/projectile/sec
|
||||
@@ -119,7 +120,8 @@
|
||||
return pick(prob(4);/obj/item/weapon/gun/projectile/shotgun/doublebarrel,
|
||||
prob(3);/obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn,
|
||||
prob(3);/obj/item/weapon/gun/projectile/shotgun/pump,
|
||||
prob(1);/obj/item/weapon/gun/projectile/shotgun/pump/combat)
|
||||
prob(1);/obj/item/weapon/gun/projectile/shotgun/pump/combat,
|
||||
prob(1);/obj/item/weapon/gun/projectile/shotgun/semi)
|
||||
|
||||
/obj/random/handgun
|
||||
name = "Random Handgun"
|
||||
@@ -494,6 +496,10 @@
|
||||
prob(1);list(
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat,
|
||||
/obj/item/ammo_magazine/ammo_box/b12g
|
||||
),
|
||||
prob(1);list(
|
||||
/obj/item/weapon/gun/projectile/shotgun/semi,
|
||||
/obj/item/ammo_magazine/ammo_box/b12g
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -77,7 +77,6 @@
|
||||
prob(3);/obj/machinery/vending/fitness,
|
||||
prob(4);/obj/machinery/vending/cigarette,
|
||||
prob(3);/obj/machinery/vending/giftvendor,
|
||||
prob(1);/obj/machinery/vending/hotfood,
|
||||
prob(5);/obj/machinery/vending/weeb,
|
||||
prob(5);/obj/machinery/vending/sol,
|
||||
prob(5);/obj/machinery/vending/snix,
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
/obj/item/clothing/under/sl_suit = 2,
|
||||
/obj/item/clothing/under/rank/bartender = 2,
|
||||
/obj/item/clothing/under/rank/bartender/skirt,
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/bar,
|
||||
/obj/item/clothing/under/dress/dress_saloon,
|
||||
/obj/item/clothing/accessory/wcoat = 2,
|
||||
/obj/item/clothing/shoes/black = 2,
|
||||
@@ -70,6 +71,7 @@
|
||||
/obj/item/clothing/under/dress/maid/janitor,
|
||||
/obj/item/device/radio/headset/headset_service,
|
||||
/obj/item/weapon/cartridge/janitor,
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/janitor,
|
||||
/obj/item/clothing/gloves/black,
|
||||
/obj/item/clothing/head/soft/purple,
|
||||
/obj/item/clothing/head/beret/purple,
|
||||
@@ -127,4 +129,4 @@
|
||||
/obj/item/weapon/storage/box/lights/mixed = 3,
|
||||
/obj/item/weapon/storage/box/mousetraps = 1,
|
||||
/obj/item/weapon/grenade/chem_grenade/cleaner = 4
|
||||
)
|
||||
)
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
/obj/item/device/radio/headset/headset_med,
|
||||
/obj/item/device/radio/headset/headset_med/alt,
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/medical,
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/medical/alt,
|
||||
/obj/item/clothing/shoes/boots/winter/medical,
|
||||
/obj/item/clothing/under/rank/nursesuit,
|
||||
/obj/item/clothing/head/nursehat,
|
||||
@@ -105,6 +106,7 @@
|
||||
/obj/item/clothing/suit/storage/toggle/fr_jacket,
|
||||
/obj/item/clothing/suit/storage/toggle/labcoat/emt,
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/medical/para,
|
||||
/obj/item/clothing/shoes/boots/winter/medical,
|
||||
/obj/item/device/radio/headset/headset_med/alt,
|
||||
/obj/item/weapon/cartridge/medical,
|
||||
/obj/item/weapon/storage/briefcase/inflatable,
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
/obj/item/clothing/suit/storage/toggle/labcoat,
|
||||
/obj/item/clothing/suit/storage/toggle/labcoat/modern,
|
||||
/obj/item/clothing/shoes/white,
|
||||
/obj/item/weapon/melee/umbrella, // vorestation addition,
|
||||
/obj/item/weapon/melee/umbrella,
|
||||
/obj/item/clothing/glasses/science,
|
||||
/obj/item/device/radio/headset/headset_sci,
|
||||
/obj/item/weapon/storage/belt/archaeology,
|
||||
@@ -85,4 +85,4 @@
|
||||
/obj/item/device/measuring_tape,
|
||||
/obj/item/weapon/pickaxe/hand,
|
||||
/obj/item/weapon/storage/bag/fossils,
|
||||
/obj/item/weapon/hand_labeler)
|
||||
/obj/item/weapon/hand_labeler)
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
/obj/item/clothing/under/suit_jacket/teal/skirt,
|
||||
/obj/item/clothing/glasses/sunglasses,
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/hop,
|
||||
/obj/item/clothing/head/caphat/hop/beret/,
|
||||
/obj/item/clothing/head/caphat/hop/beret,
|
||||
/obj/item/clothing/head/caphat/hop/beret/white)
|
||||
|
||||
|
||||
|
||||
@@ -251,6 +251,7 @@
|
||||
starts_with = list(
|
||||
/obj/item/clothing/under/rank/roboticist = 2,
|
||||
/obj/item/clothing/suit/storage/toggle/labcoat = 2,
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/science/robotics,
|
||||
/obj/item/clothing/shoes/black = 2,
|
||||
/obj/item/clothing/gloves/black = 2,
|
||||
/obj/item/weapon/storage/backpack/toxins,
|
||||
@@ -274,6 +275,7 @@
|
||||
/obj/item/clothing/under/rank/chemist/skirt = 2,
|
||||
/obj/item/clothing/shoes/white = 2,
|
||||
/obj/item/clothing/suit/storage/toggle/labcoat/chemist = 2,
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/medical/chemist,
|
||||
/obj/item/weapon/storage/backpack/chemistry = 2,
|
||||
/obj/item/weapon/storage/backpack/satchel/chem = 2,
|
||||
/obj/item/weapon/storage/bag/chemistry = 2,)
|
||||
@@ -301,6 +303,7 @@
|
||||
/obj/item/clothing/under/rank/virologist/skirt = 2,
|
||||
/obj/item/clothing/shoes/white = 2,
|
||||
/obj/item/clothing/suit/storage/toggle/labcoat/virologist = 2,
|
||||
/obj/item/clothing/suit/storage/hooded/wintercoat/medical/viro,
|
||||
/obj/item/clothing/mask/surgical = 2,
|
||||
/obj/item/weapon/storage/backpack/virology = 2,
|
||||
/obj/item/weapon/storage/backpack/satchel/vir = 2)
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
bound_height = width * world.icon_size
|
||||
|
||||
/obj/structure/door_assembly/proc/rename_door(mob/living/user)
|
||||
var/t = sanitizeSafe(tgui_input_text(user, "Enter the name for the windoor.", src.name, src.created_name, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
var/t = sanitizeSafe(tgui_input_text(user, "Enter the name for the [base_name].", src.name, src.created_name, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if(!in_range(src, user) && src.loc != user) return
|
||||
created_name = t
|
||||
update_state()
|
||||
|
||||
@@ -275,6 +275,28 @@
|
||||
desc = "Next to the extremely long list of names and job titles. Beneath the image, someone has scratched the word \"PACKETS\""
|
||||
icon_state = "kiddieplaque"
|
||||
|
||||
//CHOMP Add start
|
||||
/obj/structure/sign/kiddieplaque/poi1
|
||||
name = "expeditionary corps frame"
|
||||
desc = "An old framed photograph of four figures in retro mining gear wielding harpoons. They look ready for a fight."
|
||||
icon_state = "explorerplaque"
|
||||
|
||||
/obj/structure/sign/kiddieplaque/poi2
|
||||
name = "expeditionary corps frame"
|
||||
desc = "An old framed photograph of an oversized harpoon cannon."
|
||||
icon_state = "explorerplaque2"
|
||||
|
||||
/obj/structure/sign/kiddieplaque/poi3
|
||||
name = "expeditionary corps frame"
|
||||
desc = "An old framed photograph of a gigantic black bear. Even through print it's chilling to examine."
|
||||
icon_state = "explorerplaque3"
|
||||
|
||||
/obj/structure/sign/kiddieplaque/poi4
|
||||
name = "expeditionary corps frame"
|
||||
desc = "An old framed paper map littered with notes. Looks like the creator was marking the location of deposits."
|
||||
icon_state = "explorerplaque4"
|
||||
//CHOMP Add end
|
||||
|
||||
/obj/structure/sign/atmosplaque
|
||||
name = "\improper FEA atmospherics division plaque"
|
||||
desc = "This plaque commemorates the fall of the Atmos FEA division. For all the charred, dizzy, and brittle men who have died in its hands."
|
||||
|
||||
@@ -93,14 +93,52 @@
|
||||
color = null
|
||||
applies_material_colour = 0
|
||||
|
||||
// Leaving this in for the sake of compilation.
|
||||
/obj/structure/bed/chair/comfy
|
||||
name = "comfy chair"
|
||||
desc = "It's a chair. It looks comfy."
|
||||
icon_state = "comfychair"
|
||||
base_icon = "comfychair"
|
||||
|
||||
/obj/structure/bed/chair/comfy/brown/New(var/newloc,var/newmaterial)
|
||||
..(newloc,"steel","leather")
|
||||
/obj/structure/bed/chair/comfy/update_icon()
|
||||
..()
|
||||
var/image/I = image(icon, "[base_icon]_over")
|
||||
I.layer = ABOVE_MOB_LAYER
|
||||
I.plane = MOB_PLANE
|
||||
I.color = material.icon_colour
|
||||
add_overlay(I)
|
||||
if(padding_material)
|
||||
I = image(icon, "[base_icon]_padding_over")
|
||||
I.layer = ABOVE_MOB_LAYER
|
||||
I.plane = MOB_PLANE
|
||||
I.color = padding_material.icon_colour
|
||||
add_overlay(I)
|
||||
|
||||
/obj/structure/bed/chair/comfy/brown/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, MAT_LEATHER)
|
||||
|
||||
/obj/structure/bed/chair/comfy/red/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "carpet")
|
||||
|
||||
/obj/structure/bed/chair/comfy/teal/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "teal")
|
||||
|
||||
/obj/structure/bed/chair/comfy/black/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "black")
|
||||
|
||||
/obj/structure/bed/chair/comfy/green/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "green")
|
||||
|
||||
/obj/structure/bed/chair/comfy/purp/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "purple")
|
||||
|
||||
/obj/structure/bed/chair/comfy/blue/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "blue")
|
||||
|
||||
/obj/structure/bed/chair/comfy/beige/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "beige")
|
||||
|
||||
/obj/structure/bed/chair/comfy/lime/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "lime")
|
||||
|
||||
/obj/structure/bed/chair/comfy/red/New(var/newloc,var/newmaterial)
|
||||
..(newloc,"steel","carpet")
|
||||
@@ -108,29 +146,50 @@
|
||||
/obj/structure/bed/chair/comfy/teal/New(var/newloc,var/newmaterial)
|
||||
..(newloc,"steel","teal")
|
||||
|
||||
/obj/structure/bed/chair/comfy/black/New(var/newloc,var/newmaterial)
|
||||
..(newloc,"steel","black")
|
||||
/obj/structure/bed/chair/comfy/yellow/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "yellow")
|
||||
|
||||
/obj/structure/bed/chair/comfy/green/New(var/newloc,var/newmaterial)
|
||||
..(newloc,"steel","green")
|
||||
/obj/structure/bed/chair/comfy/orange/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "orange")
|
||||
|
||||
/obj/structure/bed/chair/comfy/purp/New(var/newloc,var/newmaterial)
|
||||
..(newloc,"steel","purple")
|
||||
/obj/structure/bed/chair/comfy/rounded
|
||||
name = "rounded chair"
|
||||
desc = "It's a rounded chair. It looks comfy."
|
||||
icon_state = "roundedchair"
|
||||
base_icon = "roundedchair"
|
||||
|
||||
/obj/structure/bed/chair/comfy/blue/New(var/newloc,var/newmaterial)
|
||||
..(newloc,"steel","blue")
|
||||
/obj/structure/bed/chair/comfy/rounded/brown/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, MAT_LEATHER)
|
||||
|
||||
/obj/structure/bed/chair/comfy/beige/New(var/newloc,var/newmaterial)
|
||||
..(newloc,"steel","beige")
|
||||
/obj/structure/bed/chair/comfy/rounded/red/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "carpet")
|
||||
|
||||
/obj/structure/bed/chair/comfy/lime/New(var/newloc,var/newmaterial)
|
||||
..(newloc,"steel","lime")
|
||||
/obj/structure/bed/chair/comfy/rounded/teal/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "teal")
|
||||
|
||||
/obj/structure/bed/chair/comfy/yellow/New(var/newloc,var/newmaterial)
|
||||
..(newloc,"steel","yellow")
|
||||
/obj/structure/bed/chair/comfy/rounded/black/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "black")
|
||||
|
||||
/obj/structure/bed/chair/comfy/orange/New(var/newloc,var/newmaterial)
|
||||
..(newloc,"steel","orange")
|
||||
/obj/structure/bed/chair/comfy/rounded/green/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "green")
|
||||
|
||||
/obj/structure/bed/chair/comfy/rounded/purple/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "purple")
|
||||
|
||||
/obj/structure/bed/chair/comfy/rounded/blue/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "blue")
|
||||
|
||||
/obj/structure/bed/chair/comfy/rounded/beige/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "beige")
|
||||
|
||||
/obj/structure/bed/chair/comfy/rounded/lime/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "lime")
|
||||
|
||||
/obj/structure/bed/chair/comfy/rounded/yellow/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "yellow")
|
||||
|
||||
/obj/structure/bed/chair/comfy/rounded/orange/Initialize(var/ml,var/newmaterial)
|
||||
. = ..(ml, MAT_STEEL, "orange")
|
||||
|
||||
/obj/structure/bed/chair/office
|
||||
anchored = FALSE
|
||||
@@ -146,7 +205,7 @@
|
||||
|
||||
/obj/structure/bed/chair/office/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
|
||||
|
||||
playsound(src, 'sound/effects/roll.ogg', 100, 1)
|
||||
|
||||
/obj/structure/bed/chair/office/handle_buckled_mob_movement(atom/new_loc, direction, movetime)
|
||||
|
||||
@@ -615,4 +615,15 @@ var/list/flooring_types
|
||||
footstep_sounds = list("human" = list(
|
||||
'sound/effects/footstep/lava1.ogg',
|
||||
'sound/effects/footstep/lava2.ogg',
|
||||
'sound/effects/footstep/lava3.ogg'))
|
||||
'sound/effects/footstep/lava3.ogg'))
|
||||
|
||||
/decl/flooring/concrete
|
||||
name = "concrete"
|
||||
desc = "A flat area of concrete flooring."
|
||||
icon = 'icons/turf/concrete.dmi'
|
||||
icon_base = "concrete"
|
||||
is_plating = FALSE //VOREStation edit. It's a lot cooler if it's actual tile.
|
||||
can_paint = 1 //VOREStation edit. Let's allow for some fun.
|
||||
can_engrave = 1 //VOREStation edit. Fun.
|
||||
flags = TURF_ACID_IMMUNE | TURF_CAN_BREAK | TURF_REMOVE_CROWBAR
|
||||
|
||||
@@ -527,3 +527,9 @@
|
||||
add_overlay(image(icon = 'icons/turf/outdoors.dmi', icon_state = "snow_footprints", dir = text2num(d)))
|
||||
|
||||
//**** Here ends snow ****
|
||||
|
||||
/turf/simulated/floor/concrete
|
||||
name = "concrete"
|
||||
icon = 'icons/turf/concrete.dmi'
|
||||
icon_state = "concrete"
|
||||
initial_flooring = /decl/flooring/concrete
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
/turf/simulated/shuttle/proc/underlay_update()
|
||||
if(!takes_underlays)
|
||||
//Basically, if it's not forced, and we don't care, don't do it.
|
||||
return //CHOMP Edit removed 0. Sarcastically quoting the above comment ^ "Basically, if it's not stupposed to store a fucking value, don't store a fucking value."
|
||||
return
|
||||
|
||||
var/turf/under //May be a path or a turf
|
||||
var/mutable_appearance/us = new(src) //We'll use this for changes later
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"dirt9" = 1
|
||||
)
|
||||
flooring_override = pickweight(possibledirts)
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
|
||||
/turf/simulated/floor/outdoors/newdirt_nograss
|
||||
@@ -62,7 +62,7 @@
|
||||
"dirt9" = 1
|
||||
)
|
||||
flooring_override = pickweight(possibledirts)
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
/turf/simulated/floor/outdoors/sidewalk
|
||||
name = "sidewalk"
|
||||
@@ -116,10 +116,10 @@
|
||||
"[initial(icon_state)]7" = 2,
|
||||
"[initial(icon_state)]8" = 2,
|
||||
"[initial(icon_state)]9" = 2,
|
||||
"[initial(icon_state)]10" = 2
|
||||
"[initial(icon_state)]10" = 2
|
||||
)
|
||||
flooring_override = pickweight(possibledirts)
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
/turf/simulated/floor/outdoors/sidewalk/side
|
||||
icon_state = "side-walk"
|
||||
@@ -141,3 +141,18 @@
|
||||
build_type = /obj/item/stack/tile/floor/sidewalk/slab
|
||||
|
||||
/obj/item/stack/tile/floor/sidewalk/slab
|
||||
|
||||
/obj/item/stack/tile/floor/concrete //Proper concrete tile.
|
||||
name = "concrete tile"
|
||||
singular_name = "floor tile"
|
||||
desc = "A concrete tile fit for covering a section of floor."
|
||||
icon_state = "tile"
|
||||
force = 6.0
|
||||
matter = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT / 4)
|
||||
throwforce = 15.0
|
||||
throw_speed = 5
|
||||
throw_range = 20
|
||||
no_variants = TRUE
|
||||
|
||||
/decl/flooring/concrete
|
||||
build_type = /obj/item/stack/tile/floor/concrete
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
if(reinf_material)
|
||||
name = "reinforced [material.display_name] wall"
|
||||
desc = "It seems to be a section of hull reinforced with [reinf_material.display_name] and plated with [material.display_name]."
|
||||
desc = "It seems to be a section of wall reinforced with [reinf_material.display_name] and plated with [material.display_name]."
|
||||
else
|
||||
name = "[material.display_name] wall"
|
||||
desc = "It seems to be a section of hull plated with [material.display_name]."
|
||||
desc = "It seems to be a section of wall plated with [material.display_name]."
|
||||
|
||||
if(material.opacity > 0.5 && !opacity)
|
||||
set_light(1)
|
||||
@@ -77,6 +77,9 @@
|
||||
I = image(wall_masks, reinf_material.icon_reinf)
|
||||
I.color = reinf_material.icon_colour
|
||||
add_overlay(I)
|
||||
var/image/texture = material.get_wall_texture()
|
||||
if(texture)
|
||||
add_overlay(texture)
|
||||
|
||||
if(damage != 0)
|
||||
var/integrity = material.integrity
|
||||
|
||||
@@ -78,6 +78,18 @@
|
||||
/turf/simulated/wall/resin/Initialize(mapload)
|
||||
. = ..(mapload, "resin",null,"resin")
|
||||
|
||||
/turf/simulated/wall/concrete
|
||||
icon_state = "brick"
|
||||
|
||||
/turf/simulated/wall/concrete/Initialize(mapload)
|
||||
. = ..(mapload, "concrete") //3strong
|
||||
|
||||
/turf/simulated/wall/r_concrete
|
||||
icon_state = "rbrick"
|
||||
|
||||
/turf/simulated/wall/r_concrete/Initialize(mapload)
|
||||
. = ..(mapload, "concrete","plasteel rebar") //3strong
|
||||
|
||||
// Kind of wondering if this is going to bite me in the butt.
|
||||
/turf/simulated/wall/skipjack/Initialize(mapload)
|
||||
. = ..(mapload, "alienalloy")
|
||||
@@ -325,10 +337,9 @@
|
||||
/obj/structure/hull_corner
|
||||
name = "hull corner"
|
||||
plane = OBJ_PLANE - 1
|
||||
|
||||
icon = 'icons/turf/wall_masks.dmi'
|
||||
icon_state = "hull_corner"
|
||||
|
||||
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
breakable = TRUE
|
||||
@@ -344,6 +355,7 @@
|
||||
return list(dir, turn(dir,90))
|
||||
|
||||
/obj/structure/hull_corner/proc/update_look()
|
||||
cut_overlays()
|
||||
var/turf/simulated/wall/T
|
||||
for(var/direction in get_dirs_to_test())
|
||||
T = get_step(src, direction)
|
||||
@@ -363,7 +375,7 @@
|
||||
I.color = R.icon_colour
|
||||
add_overlay(I)
|
||||
break
|
||||
|
||||
|
||||
if(!T)
|
||||
warning("Hull corner at [x],[y] not placed adjacent to a hull it can find.")
|
||||
|
||||
@@ -393,7 +405,7 @@
|
||||
|
||||
/turf/simulated/wall/eris/can_join_with_low_wall(var/obj/structure/low_wall/WF)
|
||||
return istype(WF, /obj/structure/low_wall/eris)
|
||||
|
||||
|
||||
/turf/simulated/wall/eris/special_wall_connections(list/dirs, list/inrange)
|
||||
..()
|
||||
for(var/direction in cardinal)
|
||||
@@ -414,7 +426,7 @@
|
||||
if(decided_to_blend)
|
||||
dirs += direction
|
||||
break blend_obj_loop // breaks outer loop
|
||||
|
||||
|
||||
/turf/simulated/wall/eris/r_wall
|
||||
icon_state = "rgeneric"
|
||||
/turf/simulated/wall/eris/r_wall/Initialize(mapload)
|
||||
@@ -427,7 +439,7 @@
|
||||
wall_masks = 'icons/turf/wall_masks_bay.dmi'
|
||||
var/list/blend_objects = list(/obj/machinery/door)
|
||||
var/list/noblend_objects = list(/obj/machinery/door/window, /obj/machinery/door/firedoor)
|
||||
|
||||
|
||||
var/stripe_color // Adds a colored stripe to the walls
|
||||
|
||||
/turf/simulated/wall/bay/can_join_with_low_wall(var/obj/structure/low_wall/WF)
|
||||
@@ -441,7 +453,7 @@
|
||||
I = image(wall_masks, "stripe[wall_connections[i]]", dir = 1<<(i-1))
|
||||
I.color = stripe_color
|
||||
add_overlay(I)
|
||||
|
||||
|
||||
/turf/simulated/wall/bay/special_wall_connections(list/dirs, list/inrange)
|
||||
..()
|
||||
for(var/direction in cardinal)
|
||||
@@ -744,4 +756,4 @@
|
||||
wall_base_state = "darkwall_rwindow"
|
||||
|
||||
#undef WINDOW_GLASS
|
||||
#undef WINDOW_RGLASS
|
||||
#undef WINDOW_RGLASS
|
||||
|
||||
@@ -154,10 +154,10 @@
|
||||
// /datum/asset/simple/fontawesome
|
||||
// )
|
||||
|
||||
// /datum/asset/simple/jquery
|
||||
// assets = list(
|
||||
// "jquery.min.js" = 'code/modules/goonchat/browserassets/js/jquery.min.js',
|
||||
// )
|
||||
/datum/asset/simple/jquery
|
||||
assets = list(
|
||||
"jquery.min.js" = 'code/modules/tooltip/jquery.min.js',
|
||||
)
|
||||
|
||||
// /datum/asset/simple/goonchat
|
||||
// assets = list(
|
||||
@@ -300,10 +300,20 @@
|
||||
name = "vore"
|
||||
|
||||
/datum/asset/spritesheet/vore/register()
|
||||
var/icon/downscaled = icon('modular_chomp/icons/mob/screen_full_vore_ch.dmi') //CHOMPedit
|
||||
var/icon/downscaled = icon('modular_chomp/icons/mob/screen_full_vore_ch.dmi') //CHOMPedit: preserving save data
|
||||
downscaled.Scale(240, 240)
|
||||
InsertAll("", downscaled)
|
||||
..()
|
||||
|
||||
/datum/asset/spritesheet/vore_fixed //This should be getting loaded in the TGUI vore panel but the game refuses to do so, for some reason. It only loads the vore spritesheet. //CHOMPedit
|
||||
name = "fixedvore" //CHOMPedit
|
||||
|
||||
/datum/asset/spritesheet/vore_fixed/register() //CHOMPedi start: preserving save data
|
||||
var/icon/downscaledVF = icon('icons/mob/screen_full_vore.dmi')
|
||||
downscaledVF.Scale(240, 240)
|
||||
InsertAll("", downscaledVF) //CHOMpedit end
|
||||
..()
|
||||
|
||||
//VOREStation Add End
|
||||
|
||||
// // Representative icons for each research design
|
||||
@@ -520,20 +530,5 @@
|
||||
"southern_cross_nanomap_z9.png" = 'icons/_nanomaps/southern_cross_nanomap_z9.png',
|
||||
"southern_cross_nanomap_z10.png" = 'icons/_nanomaps/southern_cross_nanomap_z10.png',
|
||||
"southern_cross_nanomap_z11.png" = 'icons/_nanomaps/southern_cross_nanomap_z11.png',
|
||||
//"tether_nanomap_z1.png" = 'icons/_nanomaps/tether_nanomap_z1.png',
|
||||
//"tether_nanomap_z2.png" = 'icons/_nanomaps/tether_nanomap_z2.png',
|
||||
//"tether_nanomap_z3.png" = 'icons/_nanomaps/tether_nanomap_z3.png',
|
||||
//"tether_nanomap_z4.png" = 'icons/_nanomaps/tether_nanomap_z4.png',
|
||||
//"tether_nanomap_z5.png" = 'icons/_nanomaps/tether_nanomap_z5.png',
|
||||
//"tether_nanomap_z6.png" = 'icons/_nanomaps/tether_nanomap_z6.png',
|
||||
//"tether_nanomap_z7.png" = 'icons/_nanomaps/tether_nanomap_z7.png',
|
||||
//"tether_nanomap_z8.png" = 'icons/_nanomaps/tether_nanomap_z8.png',
|
||||
//"tether_nanomap_z9.png" = 'icons/_nanomaps/tether_nanomap_z9.png',
|
||||
//"tether_nanomap_z10.png" = 'icons/_nanomaps/tether_nanomap_z10.png',
|
||||
//"tether_nanomap_z13.png" = 'icons/_nanomaps/tether_nanomap_z13.png',
|
||||
//"tether_nanomap_z14.png" = 'icons/_nanomaps/tether_nanomap_z14.png',
|
||||
//"stellardelight_nanomap_z1.png" = 'icons/_nanomaps/sd_deck1.png',
|
||||
//"stellardelight_nanomap_z2.png" = 'icons/_nanomaps/sd_deck2.png',
|
||||
//"stellardelight_nanomap_z3.png" = 'icons/_nanomaps/sd_deck3.png',
|
||||
// CHOMP Edit End
|
||||
)
|
||||
|
||||
@@ -86,6 +86,23 @@
|
||||
//whitelisted = SPECIES_TAJ
|
||||
sort_category = "Xenowear"
|
||||
|
||||
/datum/gear/mask/altevian_breath
|
||||
display_name = "spacer tuned mask (Altevian)"
|
||||
path = /obj/item/clothing/mask/altevian_breath
|
||||
sort_category = "Xenowear"
|
||||
|
||||
/datum/gear/uniform/altevian_outfit
|
||||
description = "A uniform commonly seen from altevians during their work. The material on this uniform seems to be made of durable thread that can handle the stress of most matters of labor."
|
||||
display_name = "altevian duty jumpsuit selection (Altevian)"
|
||||
sort_category = "Xenowear"
|
||||
|
||||
/datum/gear/uniform/altevian_outfit/New()
|
||||
..()
|
||||
var/list/pants = list()
|
||||
for(var/obj/item/clothing/under/altevian/uniform_type as anything in typesof(/obj/item/clothing/under/altevian))
|
||||
pants[initial(uniform_type.name)] = uniform_type
|
||||
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(pants))
|
||||
|
||||
// Taur stuff
|
||||
/datum/gear/suit/taur/drake_cloak
|
||||
display_name = "drake cloak (Drake-taur)"
|
||||
|
||||
@@ -7,9 +7,12 @@
|
||||
/datum/trait/modifier/apply_trait_post_spawn(mob/living/L)
|
||||
L.add_modifier(modifier_type)
|
||||
|
||||
/datum/trait/modifier/is_available()
|
||||
return !!modifier_type
|
||||
|
||||
/datum/trait/modifier/generate_desc()
|
||||
var/new_desc = desc
|
||||
if(!modifier_type)
|
||||
if(!is_available())
|
||||
new_desc = "[new_desc] This trait is not implemented yet."
|
||||
return new_desc
|
||||
var/datum/modifier/M = new modifier_type()
|
||||
|
||||
@@ -7,6 +7,9 @@ var/list/trait_categories = list() // The categories available for the trait men
|
||||
//create a list of trait datums
|
||||
for(var/trait_type in typesof(/datum/trait) - list(/datum/trait, /datum/trait/modifier))
|
||||
var/datum/trait/T = new trait_type
|
||||
if(!T.is_available())
|
||||
qdel(T)
|
||||
continue
|
||||
|
||||
if(!T.name)
|
||||
error("Trait Menu - Missing name: [T.type]")
|
||||
@@ -173,6 +176,9 @@ var/list/trait_categories = list() // The categories available for the trait men
|
||||
|
||||
return result
|
||||
|
||||
/datum/trait/proc/is_available()
|
||||
return TRUE
|
||||
|
||||
// Similar to above, but uses the above two procs, in one place.
|
||||
// Returns TRUE is everything is well.
|
||||
/datum/trait/proc/validate(var/list/current_traits, var/datum/category_item/player_setup_item/traits/setup)
|
||||
@@ -193,4 +199,4 @@ var/list/trait_categories = list() // The categories available for the trait men
|
||||
for(var/trait in mind.traits)
|
||||
var/datum/trait/T = trait_datums[trait]
|
||||
if(istype(T))
|
||||
T.apply_trait_post_spawn(src)
|
||||
T.apply_trait_post_spawn(src)
|
||||
|
||||
@@ -254,3 +254,5 @@
|
||||
persist_storable = FALSE
|
||||
/obj/item/weapon/spacecasinocash
|
||||
persist_storable = FALSE
|
||||
/obj/item/device/personal_shield_generator
|
||||
persist_storable = FALSE
|
||||
|
||||
@@ -2,3 +2,20 @@
|
||||
name = "transparent breath mask"
|
||||
item_state = "golem" //This is dumb and hacky but was here when I got here.
|
||||
sprite_sheets = null
|
||||
|
||||
/obj/item/clothing/mask/altevian_breath
|
||||
name = "Spacer Tuned Mask"
|
||||
desc = "A mask designed for long-term use in areas where breathing comes at a premium."
|
||||
icon_state = "altevian-mask"
|
||||
icon = 'icons/inventory/face/item_vr.dmi'
|
||||
icon_override = 'icons/inventory/face/mob_vr.dmi'
|
||||
sprite_sheets = null
|
||||
item_state_slots = list(slot_r_hand_str = "breath", slot_l_hand_str = "breath")
|
||||
item_flags = AIRTIGHT|FLEXIBLEMATERIAL
|
||||
body_parts_covered = FACE
|
||||
w_class = ITEMSIZE_SMALL
|
||||
gas_transfer_coefficient = 0.10
|
||||
permeability_coefficient = 0.50
|
||||
species_restricted = list(SPECIES_ALTEVIAN)
|
||||
pickup_sound = 'sound/items/pickup/component.ogg'
|
||||
drop_sound = 'sound/items/drop/component.ogg'
|
||||
|
||||
@@ -189,3 +189,32 @@
|
||||
)
|
||||
|
||||
//ChompEdit Ends
|
||||
|
||||
|
||||
//Chompedit Begins
|
||||
|
||||
/obj/item/weapon/rig/vox/security
|
||||
name = "sturdy alien control module"
|
||||
suit_type = "dense alien"
|
||||
icon_state = "vox_rig"
|
||||
desc = "A medium weight, alien control module. Built sturdy for security engagements."
|
||||
armor = list (melee = 60, bullet = 50, laser = 40, energy = 10, bomb = 20, bio = 100, rad = 50) //CE suit values but shuffled to a tighter focus on the job hazards
|
||||
flags = PHORONGUARD
|
||||
item_flags = THICKMATERIAL
|
||||
siemens_coefficient = 0.5
|
||||
offline_slowdown = 5
|
||||
slowdown = 0
|
||||
emp_protection = 40 //change this to 30 if too high.
|
||||
|
||||
req_one_access = list()
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage)
|
||||
offline_vision_restriction = 1
|
||||
|
||||
initial_modules = list(
|
||||
)
|
||||
|
||||
air_type = /obj/item/weapon/tank/vox
|
||||
|
||||
max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
|
||||
//ChompEdit Ends
|
||||
|
||||
@@ -88,11 +88,11 @@
|
||||
/obj/item/clothing/suit/space/void/hev
|
||||
name = "hazardous environment suit"
|
||||
desc = "Has a strange smell to it, but you feel like it might be an old friend."
|
||||
|
||||
|
||||
icon = 'icons/inventory/suit/item_vr.dmi'
|
||||
default_worn_icon = 'icons/inventory/suit/mob_vr.dmi'
|
||||
icon_state = "hev_orange"
|
||||
|
||||
|
||||
sprite_sheets = ALL_VR_SPRITE_SHEETS_SUIT_MOB
|
||||
sprite_sheets_obj = ALL_VR_SPRITE_SHEETS_SUIT_ITEM
|
||||
|
||||
@@ -103,11 +103,11 @@
|
||||
/obj/item/clothing/head/helmet/space/void/hev
|
||||
name = "hazardous environment helmet"
|
||||
desc = "Has a strange smell to it, but you feel like it might be an old friend."
|
||||
|
||||
|
||||
icon = 'icons/inventory/head/item_vr.dmi'
|
||||
default_worn_icon = 'icons/inventory/head/mob_vr.dmi'
|
||||
icon_state = "hev_orange"
|
||||
|
||||
|
||||
sprite_sheets = ALL_VR_SPRITE_SHEETS_HEAD_MOB
|
||||
sprite_sheets_obj = ALL_VR_SPRITE_SHEETS_HEAD_ITEM
|
||||
|
||||
@@ -119,11 +119,11 @@
|
||||
/obj/item/clothing/suit/space/void/makeshift
|
||||
name = "makeshift voidsuit"
|
||||
desc = "This is not something you should use if you have other options, but it's better than nothing!"
|
||||
|
||||
|
||||
icon = 'icons/inventory/suit/item_vr.dmi'
|
||||
default_worn_icon = 'icons/inventory/suit/mob_vr.dmi'
|
||||
icon_state = "makeshift_void"
|
||||
|
||||
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0)
|
||||
|
||||
sprite_sheets = ALL_VR_SPRITE_SHEETS_SUIT_MOB
|
||||
@@ -132,7 +132,7 @@
|
||||
/obj/item/clothing/head/helmet/space/void/makeshift
|
||||
name = "makeshift voidsuit helmet"
|
||||
desc = "This is not something you should use if you have other options, but it's better than nothing!"
|
||||
|
||||
|
||||
icon = 'icons/inventory/head/item_vr.dmi'
|
||||
default_worn_icon = 'icons/inventory/head/mob_vr.dmi'
|
||||
icon_state = "makeshift_void"
|
||||
@@ -146,26 +146,26 @@
|
||||
/obj/item/clothing/suit/space/void/custodian
|
||||
name = "custodian suit"
|
||||
desc = "Vacuum-capable armor for a Custodian to do their duty."
|
||||
|
||||
|
||||
icon = 'icons/inventory/suit/item_vr.dmi'
|
||||
default_worn_icon = 'icons/inventory/suit/mob_vr.dmi'
|
||||
icon_state = "custodian"
|
||||
|
||||
armor = list("melee" = 70, "bullet" = 70, "laser" = 70, "energy" = 50, "bomb" = 40, "bio" = 0, "rad" = 20)
|
||||
|
||||
|
||||
sprite_sheets = ALL_VR_SPRITE_SHEETS_SUIT_MOB
|
||||
sprite_sheets_obj = ALL_VR_SPRITE_SHEETS_SUIT_ITEM
|
||||
|
||||
/obj/item/clothing/head/helmet/space/void/custodian
|
||||
name = "custodian helmet"
|
||||
desc = "Vacuum-capable helmet for a Custodian to do their duty."
|
||||
|
||||
|
||||
icon = 'icons/inventory/head/item_vr.dmi'
|
||||
default_worn_icon = 'icons/inventory/head/mob_vr.dmi'
|
||||
icon_state = "custodian"
|
||||
|
||||
armor = list("melee" = 70, "bullet" = 70, "laser" = 70, "energy" = 50, "bomb" = 40, "bio" = 0, "rad" = 20)
|
||||
|
||||
|
||||
sprite_sheets = ALL_VR_SPRITE_SHEETS_HEAD_MOB
|
||||
sprite_sheets_obj = ALL_VR_SPRITE_SHEETS_HEAD_ITEM
|
||||
|
||||
@@ -173,7 +173,7 @@
|
||||
/obj/item/clothing/suit/space/void/aether
|
||||
name = "\improper Aether voidsuit"
|
||||
desc = "This suit seems rather high-end for a standard voidsuit. The air in it has a hint of 'new car smell', courtesy of Aether Atmospherics."
|
||||
|
||||
|
||||
icon = 'icons/inventory/suit/item_vr.dmi'
|
||||
default_worn_icon = 'icons/inventory/suit/mob_vr.dmi'
|
||||
icon_state = "moebiussuit"
|
||||
@@ -186,7 +186,7 @@
|
||||
/obj/item/clothing/head/helmet/space/void/aether
|
||||
name = "\improper Aether voidsuit helmet"
|
||||
desc = "Aether Atmospherics thought that giving this helmet selectable colored lighting would improve market penetration. Very comfortable, regardless."
|
||||
|
||||
|
||||
icon = 'icons/inventory/head/item_vr.dmi'
|
||||
default_worn_icon = 'icons/inventory/head/mob_vr.dmi'
|
||||
icon_state = "moebiushelm_White"
|
||||
@@ -212,21 +212,49 @@
|
||||
/obj/item/clothing/suit/space/void/excelsior
|
||||
name = "\improper Excelsior voidsuit"
|
||||
desc = "A space suit from a particular spaceship: Excelsior."
|
||||
|
||||
|
||||
icon = 'icons/inventory/suit/item_vr.dmi'
|
||||
default_worn_icon = 'icons/inventory/suit/mob_vr.dmi'
|
||||
icon_state = "excelsior"
|
||||
|
||||
|
||||
sprite_sheets = ALL_VR_SPRITE_SHEETS_SUIT_MOB
|
||||
sprite_sheets_obj = ALL_VR_SPRITE_SHEETS_SUIT_ITEM
|
||||
|
||||
/obj/item/clothing/head/helmet/space/void/excelsior
|
||||
name = "\improper Excelsior voidsuit helmet"
|
||||
desc = "A space helmet from a particular spaceship: Excelsior."
|
||||
|
||||
|
||||
icon = 'icons/inventory/head/item_vr.dmi'
|
||||
default_worn_icon = 'icons/inventory/head/mob_vr.dmi'
|
||||
icon_state = "excelsior"
|
||||
|
||||
|
||||
sprite_sheets = ALL_VR_SPRITE_SHEETS_HEAD_MOB
|
||||
sprite_sheets_obj = ALL_VR_SPRITE_SHEETS_HEAD_ITEM
|
||||
|
||||
|
||||
/obj/item/clothing/suit/space/void/altevian_heartbreaker
|
||||
name = "\improper heartbreaker voidsuit"
|
||||
desc = "The altevians' newest iteration of their armored suits. This one is tailored for zero-g environments, and while it can function in an area with gravity, it'll put a strain on even the most athletic of individuals."
|
||||
|
||||
icon = 'icons/inventory/suit/item_vr_altevian.dmi'
|
||||
default_worn_icon = 'icons/inventory/suit/mob_vr_altevian.dmi'
|
||||
icon_state = "rig-heartbreaker"
|
||||
|
||||
armor = list("melee" = 90, "bullet" = 90, "laser" = 90, "energy" = 90, "bomb" = 90, "bio" = 100, "rad" = 80)
|
||||
|
||||
species_restricted = list(SPECIES_ALTEVIAN)
|
||||
no_cycle = TRUE
|
||||
slowdown = 2.5
|
||||
|
||||
/obj/item/clothing/head/helmet/space/void/altevian_heartbreaker
|
||||
name = "\improper heartbreaker helmet"
|
||||
desc = "The altevians' newest iteration of their armored suits. This one is tailored for zero-g environments, and while it can function in an area with gravity, it'll put a strain on even the most athletic of individuals."
|
||||
|
||||
icon = 'icons/inventory/head/item_vr_altevian.dmi'
|
||||
default_worn_icon = 'icons/inventory/head/mob_vr_altevian.dmi'
|
||||
icon_state = "rig0-heartbreaker"
|
||||
|
||||
armor = list("melee" = 90, "bullet" = 90, "laser" = 90, "energy" = 90, "bomb" = 90, "bio" = 100, "rad" = 80)
|
||||
|
||||
species_restricted = list(SPECIES_ALTEVIAN)
|
||||
no_cycle = TRUE
|
||||
|
||||
@@ -44,3 +44,32 @@
|
||||
icon_state = "altevian-pants-cargo"
|
||||
worn_state = "altevian-pants-cargo"
|
||||
starting_accessories = list(/obj/item/clothing/accessory/jacket/altevian/cargo)
|
||||
|
||||
/obj/item/clothing/under/altevian
|
||||
name = "Altevian Duty Jumpsuit"
|
||||
desc = "A uniform commonly seen from altevians during their work. The material on this uniform seems to be made of durable thread that can handle the stress of most matters of labor."
|
||||
icon = 'icons/inventory/uniform/item_vr.dmi'
|
||||
icon_override = 'icons/inventory/uniform/mob_vr.dmi'
|
||||
icon_state = "altevian-specialist"
|
||||
worn_state = "altevian-specialist"
|
||||
species_restricted = list(SPECIES_ALTEVIAN)
|
||||
|
||||
/obj/item/clothing/under/altevian/sci
|
||||
name = "Altevian Science Duty Jumpsuit"
|
||||
icon_state = "altevian-specialist-sci"
|
||||
worn_state = "altevian-specialist-sci"
|
||||
|
||||
/obj/item/clothing/under/altevian/med
|
||||
name = "Altevian Medical Duty Jumpsuit"
|
||||
icon_state = "altevian-specialist-med"
|
||||
worn_state = "altevian-specialist-med"
|
||||
|
||||
/obj/item/clothing/under/altevian/sec
|
||||
name = "Altevian Security Duty Jumpsuit"
|
||||
icon_state = "altevian-specialist-sec"
|
||||
worn_state = "altevian-specialist-sec"
|
||||
|
||||
/obj/item/clothing/under/altevian/eng
|
||||
name = "Altevian Engineering Duty Jumpsuit"
|
||||
icon_state = "altevian-specialist-eng"
|
||||
worn_state = "altevian-specialist-eng"
|
||||
@@ -47,17 +47,21 @@
|
||||
/obj/item/weapon/reagent_containers/food/drinks/glass2/shot = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/glass2/pint = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/glass2/mug = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/glass2/wine = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/glass2/carafe = 2, //VOREStation Add - Carafes and Pitchers
|
||||
/obj/item/weapon/reagent_containers/food/drinks/glass2/pitcher = 2, //VOREStation Add - Carafes and Pitchers
|
||||
/obj/item/weapon/reagent_containers/food/drinks/glass2/wine = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/whitewine = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/grapejuice = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/metaglass = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/metaglass/metapint = 10,
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/stopperedbottle = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/gin = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/cognac = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/grenadine = 5,
|
||||
/obj/item/weapon/reagent_containers/food/condiment/cookingoil = 5,
|
||||
/obj/item/weapon/reagent_containers/food/condiment/cornoil = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/melonliquor = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/peppermintschnapps = 5,
|
||||
@@ -70,8 +74,6 @@
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/wine = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/whitewine = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/grapejuice = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/jager = 5,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale = 15,
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
icon_state = "rc_food"
|
||||
refill_type = list(/obj/machinery/vending/snack,
|
||||
/obj/machinery/vending/fitness,
|
||||
/obj/machinery/vending/hotfood,
|
||||
/obj/machinery/vending/weeb,
|
||||
/obj/machinery/vending/sol,
|
||||
/obj/machinery/vending/snix,
|
||||
@@ -104,9 +103,6 @@
|
||||
/obj/item/weapon/refill_cartridge/autoname/food/fitness
|
||||
refill_type = /obj/machinery/vending/fitness
|
||||
|
||||
/obj/item/weapon/refill_cartridge/autoname/food/hotfood
|
||||
refill_type = /obj/machinery/vending/hotfood
|
||||
|
||||
/obj/item/weapon/refill_cartridge/autoname/food/weeb
|
||||
refill_type = /obj/machinery/vending/weeb
|
||||
|
||||
|
||||
@@ -29,4 +29,18 @@
|
||||
|
||||
/obj/item/device/assembly/electronic_assembly
|
||||
description_info = "This is the casing for the 'device' type of electronic assembly. It behaves like any other 'assembly' type device such as an igniter or signaler \
|
||||
and can be attached to others in the same way. Use the 'toggle-open' verb (right click) or a crowbar to pop the electronic device open to add components and close when finished."
|
||||
and can be attached to others in the same way. Use the 'toggle-open' verb (right click) or a crowbar to pop the electronic device open to add components and close when finished."
|
||||
|
||||
/obj/item/device/personal_shield_generator
|
||||
description_info = "This is a personal shield generator. Depending on the type, it can either be worn on your backpack slot, your belt slot, or in a rigsuit \
|
||||
storage slot. It runs on an internal battery, which is usually self-charging. Some versions come with a gun. To active the shield, click the button in the upper \
|
||||
right of the screen, use the 'Toggle Shield' command under your objects tab, or click the device itself while it is on you. Some units come with an active weapon \
|
||||
which can be taken out at any time by Alt-clicking the device. If the device requires a cell, a screwdriver can be used. The shield slowly drains charge while \
|
||||
active and becomes weaker with each individual strike taken. Additonally, the device can be colored via use of a multitool."
|
||||
|
||||
description_fluff = "A relatively new invention, made in a collaboration between Hephaestus Industries and a startup known as Kuznetsova Enterprise in the year \
|
||||
2322. Numerous variants of the device have been made for specific tasks, ranging from riot control, mining, biohazard containment, and search and rescue, among \
|
||||
others. Most of the devices share the flaw that electrical attacks can easily overload the device and cause a shield failure, encouraging combatants to swap to \
|
||||
the use of stun-based electric weaponry when shield generators are in use. Most shield devices are self-charging, running off a micro-nuclear reactor built into \
|
||||
the chassis itself, although some variants exist without this capability and can have normal cells inserted into them. Larger units boast the capability of \
|
||||
storing a weapon, although without upgraded batteries the usage of said weapon is ill-advised."
|
||||
@@ -773,7 +773,7 @@
|
||||
/obj/item/weapon/reagent_containers/food/snacks/donkpocket/ascended/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("uranium", 3)
|
||||
reagents.add_reagent("pyrotoxin", 3)
|
||||
reagents.add_reagent("thermite_v", 3)
|
||||
|
||||
// Altevian Foobs
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Holographic racks are in code/modules/tables/rack.dm
|
||||
|
||||
/turf/simulated/floor/holofloor
|
||||
desc = "A convincing simulation."
|
||||
thermal_conductivity = 0
|
||||
flags = TURF_ACID_IMMUNE
|
||||
|
||||
@@ -281,6 +282,7 @@
|
||||
no_random_knockdown = TRUE
|
||||
|
||||
/obj/item/weapon/holo/esword
|
||||
name = "holographic energy sword"
|
||||
desc = "May the force be within you. Sorta."
|
||||
icon_state = "esword"
|
||||
var/lcolor
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
name = "stack of marble"
|
||||
type_to_spawn = /obj/item/stack/material/marble
|
||||
|
||||
/obj/fiftyspawner/concrete
|
||||
name = "stack of concrete"
|
||||
type_to_spawn = /obj/item/stack/material/concrete
|
||||
|
||||
/obj/fiftyspawner/diamond
|
||||
name = "stack of diamond"
|
||||
type_to_spawn = /obj/item/stack/material/diamond
|
||||
@@ -72,6 +76,10 @@
|
||||
name = "stack of plasteel"
|
||||
type_to_spawn = /obj/item/stack/material/plasteel
|
||||
|
||||
/obj/fiftyspawner/plasteel/rebar
|
||||
name = "stack of plasteel rebars"
|
||||
type_to_spawn = /obj/item/stack/material/plasteel/rebar
|
||||
|
||||
/obj/fiftyspawner/plasteel/hull
|
||||
name = "stack of plasteel hull"
|
||||
type_to_spawn = /obj/item/stack/material/plasteel/hull
|
||||
|
||||
@@ -373,4 +373,7 @@ var/list/name_to_material
|
||||
new /datum/stack_recipe("[display_name] knife", /obj/item/weapon/material/knife/plastic, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE),
|
||||
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),
|
||||
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/proc/get_wall_texture()
|
||||
return
|
||||
|
||||
@@ -24,8 +24,17 @@
|
||||
new /datum/stack_recipe("dark floor tile", /obj/item/stack/tile/floor/dark, 1, 4, 20, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("roller bed", /obj/item/roller, 5, time = 30, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("whetstone", /obj/item/weapon/whetstone, 2, time = 10, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("plasteel rebar", /obj/item/stack/material/plasteel/rebar, 1, time = 5, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe_list("reinforced low walls",list(
|
||||
new /datum/stack_recipe("reinforced low wall (bay style)", /obj/structure/low_wall/bay/reinforced, 3, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("reinforced low wall (eris style)", /obj/structure/low_wall/eris/reinforced, 3, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", recycle_material = "[name]")
|
||||
)),
|
||||
)
|
||||
)
|
||||
|
||||
/datum/material/plasteel/rebar //to give a different reinforced overlay
|
||||
name = MAT_PLASTEELREBAR
|
||||
icon_reinf = "reinf_metal"
|
||||
icon_colour = "#6A6A6A"
|
||||
stack_type = /obj/item/stack/material/plasteel/rebar
|
||||
sheet_singular_name = "rod"
|
||||
sheet_plural_name = "rods"
|
||||
|
||||
@@ -15,19 +15,19 @@
|
||||
new /datum/stack_recipe("dark office chair", /obj/structure/bed/chair/office/dark, 5, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("light office chair", /obj/structure/bed/chair/office/light, 5, one_per_turf = 1, on_floor = 1, recycle_material = "[name]")
|
||||
)),
|
||||
new /datum/stack_recipe_list("comfy chairs", list(
|
||||
new /datum/stack_recipe("beige comfy chair", /obj/structure/bed/chair/comfy/beige, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("black comfy chair", /obj/structure/bed/chair/comfy/black, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("brown comfy chair", /obj/structure/bed/chair/comfy/brown, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("lime comfy chair", /obj/structure/bed/chair/comfy/lime, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("teal comfy chair", /obj/structure/bed/chair/comfy/teal, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("red comfy chair", /obj/structure/bed/chair/comfy/red, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("blue comfy chair", /obj/structure/bed/chair/comfy/blue, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("purple comfy chair", /obj/structure/bed/chair/comfy/purp, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("green comfy chair", /obj/structure/bed/chair/comfy/green, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("yellow comfy chair", /obj/structure/bed/chair/comfy/yellow, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("orange comfy chair", /obj/structure/bed/chair/comfy/orange, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
)),
|
||||
new /datum/stack_recipe_list("rounded chairs", list(
|
||||
new /datum/stack_recipe("beige rounded chair", /obj/structure/bed/chair/comfy/rounded/beige, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("black rounded chair", /obj/structure/bed/chair/comfy/rounded/black, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("brown rounded chair", /obj/structure/bed/chair/comfy/rounded/brown, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("lime rounded chair", /obj/structure/bed/chair/comfy/rounded/lime, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("teal rounded chair", /obj/structure/bed/chair/comfy/rounded/teal, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("red rounded chair", /obj/structure/bed/chair/comfy/rounded/red, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("blue rounded chair", /obj/structure/bed/chair/comfy/rounded/blue, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("purple rounded chair", /obj/structure/bed/chair/comfy/rounded/purple, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("green rounded chair", /obj/structure/bed/chair/comfy/rounded/green, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("yellow rounded chair", /obj/structure/bed/chair/comfy/rounded/yellow, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("orange rounded chair", /obj/structure/bed/chair/comfy/rounded/orange, 2, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
)),
|
||||
new /datum/stack_recipe_list("airlock assemblies", list(
|
||||
new /datum/stack_recipe("standard airlock assembly", /obj/structure/door_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("command airlock assembly", /obj/structure/door_assembly/door_assembly_com, 4, time = 50, one_per_turf = 1, on_floor = 1, recycle_material = "[name]"),
|
||||
@@ -86,4 +86,4 @@
|
||||
new /datum/stack_recipe("apc frame", /obj/item/frame/apc, 2, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("desk bell", /obj/item/weapon/deskbell, 1, on_floor = 1, supplied_material = "[name]"),
|
||||
new /datum/stack_recipe("tanning rack", /obj/structure/tanning_rack, 3, one_per_turf = TRUE, time = 20, on_floor = TRUE, supplied_material = "[name]")
|
||||
)
|
||||
)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
icon_colour = "#9e9c99"
|
||||
weight = 20
|
||||
hardness = 30
|
||||
integrity = 100
|
||||
integrity = 100
|
||||
stack_type = /obj/item/stack/material/flint
|
||||
supply_conversion_value = 2
|
||||
sheet_singular_name = "piece"
|
||||
@@ -47,4 +47,35 @@
|
||||
|
||||
/datum/material/stone/flint/generate_recipes()
|
||||
return
|
||||
//VOREStation Addition End
|
||||
//VOREStation Addition End
|
||||
|
||||
/datum/material/stone/concrete
|
||||
name = MAT_CONCRETE
|
||||
stack_type = /obj/item/stack/material/concrete
|
||||
icon_base = "brick"
|
||||
icon_colour = COLOR_GRAY
|
||||
integrity = 150
|
||||
melting_point = 1550
|
||||
protectiveness = 10
|
||||
weight = 27
|
||||
hardness = 60
|
||||
var/image/texture
|
||||
|
||||
/datum/material/stone/concrete/generate_recipes()
|
||||
..()
|
||||
recipes += list(
|
||||
new /datum/stack_recipe_list("Concrete Pathing",list(
|
||||
new /datum/stack_recipe("Concrete Flooring", /obj/item/stack/tile/floor/concrete, 1, 4, 20, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("Concrete Sidewalk", /obj/item/stack/tile/floor/sidewalk, 1, 4, 20, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("Concrete Sidewalk (Side)", /obj/item/stack/tile/floor/sidewalk/side, 1, 4, 20, recycle_material = "[name]"),
|
||||
new /datum/stack_recipe("Concrete Sidewalk (Slab)", /obj/item/stack/tile/floor/sidewalk/slab, 1, 4, 20, recycle_material = "[name]")
|
||||
)),
|
||||
)
|
||||
|
||||
/datum/material/stone/concrete/New()
|
||||
. = ..()
|
||||
texture = image('icons/turf/wall_texture.dmi', "concrete")
|
||||
texture.blend_mode = BLEND_MULTIPLY
|
||||
|
||||
/datum/material/stone/concrete/get_wall_texture()
|
||||
return texture
|
||||
|
||||
@@ -12,6 +12,19 @@
|
||||
no_variants = FALSE
|
||||
apply_colour = TRUE
|
||||
|
||||
/obj/item/stack/material/plasteel/rebar
|
||||
name = MAT_PLASTEELREBAR
|
||||
icon_state = "rods"
|
||||
default_type = MAT_PLASTEELREBAR
|
||||
apply_colour = 1
|
||||
|
||||
/obj/item/stack/material/plasteel/rebar/update_icon()
|
||||
var/amount = get_amount()
|
||||
if((amount <= 5) && (amount > 0))
|
||||
icon_state = "rods-[amount]"
|
||||
else
|
||||
icon_state = "rods"
|
||||
|
||||
/obj/item/stack/material/durasteel
|
||||
name = "durasteel"
|
||||
icon_state = "sheet-durasteel" //CHOMPedit - replace materials update
|
||||
|
||||
@@ -22,4 +22,11 @@
|
||||
drop_sound = 'sound/items/drop/boots.ogg'
|
||||
pickup_sound = 'sound/items/pickup/boots.ogg'
|
||||
pass_color = TRUE
|
||||
apply_colour = TRUE
|
||||
apply_colour = TRUE
|
||||
|
||||
/obj/item/stack/material/concrete
|
||||
name = "concrete brick"
|
||||
icon_state = "brick"
|
||||
default_type = "concrete"
|
||||
no_variants = FALSE
|
||||
apply_colour = 1
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
generate_loot()
|
||||
|
||||
/obj/structure/closet/crate/secure/loot/proc/generate_loot()
|
||||
var/loot = rand(1, 99)
|
||||
var/loot = rand(1, 100)
|
||||
switch(loot)
|
||||
if(1 to 5) // Common things go, 5%
|
||||
new/obj/item/weapon/reagent_containers/food/drinks/bottle/rum(src)
|
||||
@@ -140,6 +140,8 @@
|
||||
if(99)
|
||||
new/obj/item/weapon/storage/belt/champion(src)
|
||||
new/obj/item/clothing/mask/luchador(src)
|
||||
if(100)
|
||||
new/obj/item/device/personal_shield_generator/belt/mining/loaded(src)
|
||||
|
||||
/obj/structure/closet/crate/secure/loot/togglelock(mob/user as mob)
|
||||
if(!locked)
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
EQUIPMENT("Thalers - 1000", /obj/item/weapon/spacecash/c1000, 10000),
|
||||
EQUIPMENT("Umbrella", /obj/item/weapon/melee/umbrella/random, 200),
|
||||
EQUIPMENT("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 125),
|
||||
EQUIPMENT("Mining PSG Upgrade Disk", /obj/item/borg/upgrade/shield_upgrade, 2500),
|
||||
)
|
||||
prize_list["Extra"] = list() // Used in child vendors
|
||||
//VOREStation Edit End
|
||||
|
||||
@@ -1,3 +1,51 @@
|
||||
/datum/modifier
|
||||
var/effect_color // Allows for coloring of modifiers.
|
||||
var/coloration_applied = 0 // Tells the game is coloration has been applied already or not.
|
||||
var/icon_override = 0 // Tells the game if it should use modifer_effects_vr.dmi or not.
|
||||
// ENERGY CODE. Variables to allow for energy based modifiers.
|
||||
var/energy_based // Sees if the modifier is based on something electronic based.
|
||||
var/energy_cost // How much the modifier uses per action/special effect blocked. For base values.
|
||||
var/damage_cost // How much energy is used when numbers are involed. For values, such as taking damage. Ex: (Damage*damage_cost)
|
||||
var/obj/item/weapon/cell/energy_source = null // The source of the above.
|
||||
|
||||
// RESISTANCES CODE. Variable to enable external damage resistance modifiers. This is not unlike armor.
|
||||
// 0 = immune || < 0 = heals || 1 = full damage || >1 = increased damage.
|
||||
// It should never be below zero as it is not intended to do such, but you are free to experiment!
|
||||
// Ex: Max_brute_resistance = 0. Min_brute resistance = 1. When started, provides 100% resistance to brute. When cell is dying, goes down to 0% resistance.
|
||||
// Max is the MAXIMUM % multiplier that will be taken at a MAX charge. Min is the MINIMUM % multiplier that will be taken at a MINIMUM charge.
|
||||
// Think of it like this: Minimum = what happens at minimum charge. Max = what happens at maximum charge.
|
||||
// Why do I mention this so much? Because even /I/ got confused, and I wrote this thing!
|
||||
var/min_damage_resistance
|
||||
var/max_damage_resistance
|
||||
var/effective_damage_resistance
|
||||
|
||||
var/min_brute_resistance
|
||||
var/max_brute_resistance
|
||||
var/effective_brute_resistance
|
||||
|
||||
var/min_fire_resistance
|
||||
var/max_fire_resistance
|
||||
var/effective_fire_resistance
|
||||
|
||||
var/min_tox_resistance
|
||||
var/max_tox_resistance
|
||||
var/effective_tox_resistance
|
||||
|
||||
var/min_oxy_resistance
|
||||
var/max_oxy_resistance
|
||||
var/effective_oxy_resistance
|
||||
|
||||
var/min_clone_resistance
|
||||
var/max_clone_resistance
|
||||
var/effective_clone_resistance
|
||||
|
||||
var/min_hal_resistance
|
||||
var/max_hal_resistance
|
||||
var/effective_hal_resistance
|
||||
// Resistances end
|
||||
|
||||
|
||||
|
||||
/datum/modifier/underwater_stealth
|
||||
name = "underwater stealth"
|
||||
desc = "You are currently underwater, rendering it more difficult to see you and enabling you to move quicker, thanks to your aquatic nature."
|
||||
@@ -30,4 +78,258 @@
|
||||
if(water_floor.depth < 1) //You're not in deep enough water anymore.
|
||||
expire(silent = FALSE)
|
||||
else
|
||||
expire(silent = FALSE)
|
||||
expire(silent = FALSE)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/datum/modifier/shield_projection
|
||||
name = "Shield Projection"
|
||||
desc = "You are currently protected by a shield, rendering nigh impossible to hit you through conventional means."
|
||||
|
||||
on_created_text = "<span class='notice'>Your shield generator buzzes on.</span>"
|
||||
on_expired_text = "<span class='warning'>Your shield generator buzzes off.</span>"
|
||||
stacks = MODIFIER_STACK_FORBID //No stacking shields. If you put one one your belt and backpack it won't work.
|
||||
|
||||
icon_override = 1
|
||||
mob_overlay_state = "deflect"
|
||||
siemens_coefficient = 2 //Stun weapons drain 100% charge per point of damage. They're good at blocking lasers and bullets but not good at blocking stun beams!
|
||||
energy_based = 1
|
||||
energy_cost = 99999 //This is changed to the shield_generator's energy_cost.
|
||||
damage_cost = 50 //This is how much battery is used per damage unit absorbed. Higher damage means higher charge use per damage absorbed. Changed below!
|
||||
|
||||
//Not actually in use until effective resistances are set. Just here so it doesn't have to be placed down for all the variants. Less lines.
|
||||
max_damage_resistance = 1
|
||||
max_brute_resistance = 1
|
||||
max_fire_resistance = 1
|
||||
max_tox_resistance = 1
|
||||
max_oxy_resistance = 1
|
||||
max_clone_resistance = 1
|
||||
max_hal_resistance = 1
|
||||
min_damage_resistance = 1
|
||||
min_brute_resistance = 1
|
||||
min_fire_resistance = 1
|
||||
min_tox_resistance = 1
|
||||
min_oxy_resistance = 1
|
||||
min_clone_resistance = 1
|
||||
min_hal_resistance = 1
|
||||
|
||||
/* // These are not set, but left here as an example. All three (min,max,effective) must be set or BAD THINGS will happen.
|
||||
min_brute_resistance = 1 // Min = WHAT HAPPENS AT MINIMUM CHARGE
|
||||
max_brute_resistance = 0 // MAX = WHAT HAPPENS AT MAXIMUM CHARGE
|
||||
effective_brute_resistance = 1 //Just tells the game that it has vars. Done to use less checks.
|
||||
|
||||
min_fire_resistance = 1
|
||||
max_fire_resistance = 0
|
||||
effective_fire_resistance = 1
|
||||
disable_duration_percent = 1 //THIS CAN ALSO BE USED! Don't be too afraid to use this one, but use it sparingly!
|
||||
*/
|
||||
var/obj/item/device/personal_shield_generator/shield_generator //This is the shield generator you're wearing!
|
||||
|
||||
|
||||
/datum/modifier/shield_projection/on_applied()
|
||||
return
|
||||
|
||||
/datum/modifier/shield_projection/on_expire() //Don't need to modify this!
|
||||
return
|
||||
|
||||
/datum/modifier/shield_projection/check_if_valid() //Let's check to make sure you got the stuff and set the vars. Don't need to modify this for any subtypes!
|
||||
if(ishuman(holder)) //Only humans can use this! Other things later down the line might use the same stuff this does, but the shield generator is human only!
|
||||
var/mob/living/carbon/human/H = holder
|
||||
if(istype(H.get_equipped_item(slot_back), /obj/item/device/personal_shield_generator))
|
||||
shield_generator = H.get_equipped_item(slot_back) //Sets the var on the modifier that the shield gen is their back shield gen.
|
||||
else if(istype(H.get_equipped_item(slot_belt), /obj/item/device/personal_shield_generator))
|
||||
shield_generator = H.get_equipped_item(slot_belt) //No need for other checks. If they got hit by this, they just turned it on.
|
||||
else if(istype(H.get_equipped_item(slot_s_store), /obj/item/device/personal_shield_generator) ) //Rigsuits.
|
||||
shield_generator = H.get_equipped_item(slot_s_store)
|
||||
else
|
||||
expire(silent = TRUE)
|
||||
if(shield_generator) //Sanity.
|
||||
energy_source = shield_generator.bcell
|
||||
energy_cost = shield_generator.generator_hit_cost
|
||||
damage_cost = shield_generator.damage_cost
|
||||
effect_color = shield_generator.effect_color
|
||||
if(!coloration_applied) //Does a check if colors have been applied. If not, updates the color.
|
||||
H.update_modifier_visuals() //This can only happen on the next tick, unfortunately, not the same tick the modifier is applied. Thus, must be done here.
|
||||
coloration_applied = 1
|
||||
else
|
||||
expire(silent = TRUE)
|
||||
|
||||
|
||||
/datum/modifier/shield_projection/tick() //When the shield generator runs out of charge, it'll remove this naturally.
|
||||
if(holder.stat == DEAD)
|
||||
expire(silent = TRUE) //If you're dead the generator stops protecting you but keeps running.
|
||||
if(!shield_generator || !shield_generator.slot_check()) //No shield to begin with/shield is not on them any longer.
|
||||
expire(silent = FALSE)
|
||||
|
||||
var/shield_efficiency = (energy_source.charge/energy_source.maxcharge) //1 = complete resistance. 0 = no resistance. Must be adjusted for subtypes!
|
||||
if(!isnull(effective_damage_resistance))
|
||||
effective_damage_resistance = min_damage_resistance + (max_damage_resistance - min_damage_resistance) * shield_efficiency
|
||||
|
||||
if(!isnull(effective_brute_resistance))
|
||||
effective_brute_resistance = min_brute_resistance + (max_brute_resistance - min_brute_resistance) * shield_efficiency
|
||||
|
||||
if(!isnull(effective_fire_resistance))
|
||||
effective_fire_resistance = min_fire_resistance + (max_fire_resistance - min_fire_resistance) * shield_efficiency
|
||||
|
||||
if(!isnull(effective_tox_resistance))
|
||||
effective_tox_resistance = min_tox_resistance + (max_tox_resistance - min_tox_resistance) * shield_efficiency
|
||||
|
||||
if(!isnull(effective_oxy_resistance))
|
||||
effective_oxy_resistance = min_oxy_resistance + (max_oxy_resistance - min_oxy_resistance) * shield_efficiency
|
||||
|
||||
if(!isnull(effective_clone_resistance))
|
||||
effective_clone_resistance = min_clone_resistance + (max_clone_resistance - min_clone_resistance) * shield_efficiency
|
||||
|
||||
if(!isnull(effective_hal_resistance))
|
||||
effective_hal_resistance = min_hal_resistance + (max_hal_resistance - min_hal_resistance) * shield_efficiency
|
||||
|
||||
//Shield variants.
|
||||
|
||||
//Simple. Goes from 100% resistance to 0% resistance depending on charge. This is mostly an example of a shield variant.
|
||||
/datum/modifier/shield_projection/bruteburn
|
||||
max_brute_resistance = 0
|
||||
effective_brute_resistance = 1
|
||||
|
||||
max_fire_resistance = 0
|
||||
effective_fire_resistance = 1
|
||||
|
||||
/datum/modifier/shield_projection/bruteburn/weak
|
||||
max_brute_resistance = 0.5
|
||||
max_fire_resistance = 0.5
|
||||
|
||||
//SECURITY VARIANTS
|
||||
/datum/modifier/shield_projection/security // Security backpack. 50% resistance at full charge. 10% resistance for the last shot taken.
|
||||
max_brute_resistance = 0.50
|
||||
min_brute_resistance = 0.9
|
||||
effective_brute_resistance = 1
|
||||
|
||||
max_fire_resistance = 0.5
|
||||
min_fire_resistance = 0.9
|
||||
effective_fire_resistance = 1
|
||||
|
||||
max_hal_resistance = 0.5
|
||||
min_hal_resistance = 0.9
|
||||
effective_hal_resistance = 1
|
||||
|
||||
disable_duration_percent = 0.75
|
||||
|
||||
/datum/modifier/shield_projection/security/weak // Security belt.
|
||||
max_brute_resistance = 0.75
|
||||
min_brute_resistance = 0.95
|
||||
max_fire_resistance = 0.75
|
||||
min_fire_resistance = 0.95
|
||||
max_hal_resistance = 0.75
|
||||
min_hal_resistance = 0.95
|
||||
|
||||
/datum/modifier/shield_projection/security/strong // Dunno. Upgraded variant of security backpack?
|
||||
max_brute_resistance = 0.25
|
||||
max_fire_resistance = 0.25
|
||||
max_hal_resistance = 0.25
|
||||
siemens_coefficient = 1.5 //Not as weak as normal, but still weak.
|
||||
disable_duration_percent = 0.5
|
||||
|
||||
|
||||
//MINING VARIANTS
|
||||
/datum/modifier/shield_projection/mining //Base mining belt. 30% resistance that fades to 15% resistance
|
||||
max_brute_resistance = 0.70
|
||||
min_brute_resistance = 0.85
|
||||
effective_brute_resistance = 1
|
||||
|
||||
max_fire_resistance = 0.70
|
||||
min_brute_resistance = 0.85
|
||||
effective_fire_resistance = 1
|
||||
|
||||
max_hal_resistance = 1.5 // No mobs should be shooting you with halloss. If this happens, it means you're using it wrong!!!
|
||||
min_hal_resistance = 1.5
|
||||
effective_hal_resistance = 1
|
||||
|
||||
disable_duration_percent = 0.75 //Miners often come into contact with things that can stun them.
|
||||
|
||||
/datum/modifier/shield_projection/mining/strong // Mining belt, but upgraded. Even weaker to halloss!
|
||||
max_brute_resistance = 0.55
|
||||
min_brute_resistance = 0.75
|
||||
max_fire_resistance = 0.55
|
||||
min_fire_resistance = 0.75
|
||||
disable_duration_percent = 0.5
|
||||
|
||||
max_hal_resistance = 2
|
||||
min_hal_resistance = 2
|
||||
|
||||
//MISC VARIANTS
|
||||
|
||||
/datum/modifier/shield_projection/biohazard //The odd-ball damage types. Provides near-complete immunity while it's up.
|
||||
min_tox_resistance = 0.25
|
||||
max_tox_resistance = 0
|
||||
effective_tox_resistance = 1
|
||||
|
||||
min_oxy_resistance = 0.25
|
||||
max_oxy_resistance = 0
|
||||
effective_oxy_resistance = 1
|
||||
|
||||
min_clone_resistance = 0.25
|
||||
max_clone_resistance = 0
|
||||
effective_clone_resistance = 1
|
||||
|
||||
/datum/modifier/shield_projection/admin // Adminbus.
|
||||
on_created_text = "<span class='notice'>Your shield generator activates and you feel the power of the tesla buzzing around you.</span>"
|
||||
on_expired_text = "<span class='warning'>Your shield generator deactivates, leaving you feeling weak and vulnerable.</span>"
|
||||
siemens_coefficient = 0
|
||||
disable_duration_percent = 0
|
||||
min_damage_resistance = 0
|
||||
max_damage_resistance = 0
|
||||
effective_damage_resistance = 0
|
||||
min_brute_resistance = 0
|
||||
max_brute_resistance = 0
|
||||
effective_brute_resistance = 0
|
||||
min_fire_resistance = 0
|
||||
max_fire_resistance = 0
|
||||
effective_fire_resistance = 0
|
||||
min_tox_resistance = 0
|
||||
max_tox_resistance = 0
|
||||
effective_tox_resistance = 0
|
||||
min_oxy_resistance = 0
|
||||
max_oxy_resistance = 0
|
||||
effective_oxy_resistance = 0
|
||||
min_clone_resistance = 0
|
||||
max_clone_resistance = 0
|
||||
effective_clone_resistance = 0
|
||||
min_hal_resistance = 0
|
||||
max_hal_resistance = 0
|
||||
effective_hal_resistance = 0
|
||||
|
||||
/datum/modifier/shield_projection/broken //For broken variants. Good if possible randomization is included for packs spawned on PoIs.
|
||||
max_brute_resistance = 2
|
||||
min_brute_resistance = 2
|
||||
effective_brute_resistance = 1
|
||||
|
||||
max_fire_resistance = 2
|
||||
min_fire_resistance = 2
|
||||
effective_fire_resistance = 1
|
||||
|
||||
/datum/modifier/shield_projection/inverted //Becomes stronger the weaker the cell is. Means the last shot taken will be the weakest. Example just to show it can be done.
|
||||
max_brute_resistance = 1
|
||||
min_brute_resistance = 0
|
||||
effective_brute_resistance = 1
|
||||
|
||||
max_fire_resistance = 1
|
||||
min_fire_resistance = 0
|
||||
effective_fire_resistance = 1
|
||||
|
||||
/datum/modifier/shield_projection/parry //Intended for 'parry' shields, which only last for a single second before running out of charge
|
||||
max_brute_resistance = 0
|
||||
min_brute_resistance = 0
|
||||
effective_brute_resistance = 1
|
||||
|
||||
max_fire_resistance = 0
|
||||
min_fire_resistance = 0
|
||||
effective_fire_resistance = 1
|
||||
|
||||
max_hal_resistance = 0
|
||||
min_hal_resistance = 0
|
||||
effective_hal_resistance = 1
|
||||
@@ -18,7 +18,7 @@ var/global/list/prevent_respawns = list()
|
||||
|
||||
//Why are you clicking this button?
|
||||
if(!mind || !mind.assigned_role)
|
||||
to_chat(src,"<span class='warning'>Either you haven't played this round, or you already used this verb.</span>")
|
||||
to_chat(src,"<span class='warning'>Either you haven't played this round, you already used this verb or you left round properly already.</span>")
|
||||
return
|
||||
|
||||
//Add them to the nope list
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
add_overlay(H.overlays_standing)
|
||||
default_pixel_x = body.default_pixel_x
|
||||
default_pixel_y = body.default_pixel_y
|
||||
if(!T)
|
||||
if(!T && length(latejoin))
|
||||
T = pick(latejoin) //Safety in case we cannot find the body's position
|
||||
if(T)
|
||||
forceMove(T)
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
//Technically allows metagaming by allowing buddies to turn on digestion for like 2 seconds
|
||||
// to finish off critically wounded friends to avoid resleeving sickness, but like
|
||||
// *kill those people* ok?
|
||||
if(B.digest_mode == DM_DIGEST)
|
||||
if(B.digest_mode == DM_DIGEST || B.digest_mode == DM_SELECT)
|
||||
H.mind?.vore_death = TRUE
|
||||
|
||||
//Hooks need to return true otherwise they're considered having failed
|
||||
|
||||
@@ -115,8 +115,12 @@
|
||||
if(amount > 0)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.incoming_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_damage_percent
|
||||
if(!isnull(M.incoming_brute_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_brute_damage_percent
|
||||
if(nif && nif.flag_check(NIF_C_BRUTEARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
|
||||
take_overall_damage(amount, 0)
|
||||
@@ -133,8 +137,12 @@
|
||||
if(amount > 0)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.incoming_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_damage_percent
|
||||
if(!isnull(M.incoming_fire_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_fire_damage_percent
|
||||
if(nif && nif.flag_check(NIF_C_BURNARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
|
||||
take_overall_damage(0, amount)
|
||||
@@ -153,8 +161,12 @@
|
||||
if(amount > 0)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.incoming_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_damage_percent
|
||||
if(!isnull(M.incoming_brute_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_brute_damage_percent
|
||||
if(nif && nif.flag_check(NIF_C_BRUTEARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
|
||||
O.take_damage(amount, 0, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
|
||||
@@ -175,8 +187,12 @@
|
||||
if(amount > 0)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.incoming_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_damage_percent
|
||||
if(!isnull(M.incoming_fire_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_fire_damage_percent
|
||||
if(nif && nif.flag_check(NIF_C_BURNARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
|
||||
O.take_damage(0, amount, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
|
||||
@@ -485,6 +501,53 @@ This function restores all organs.
|
||||
if(!def_zone) def_zone = ran_zone(def_zone)
|
||||
organ = get_organ(check_zone(def_zone))
|
||||
|
||||
for(var/datum/modifier/M in modifiers) //MODIFIER STUFF. It's best to do this RIGHT before armor is calculated, so it's done here! This is the 'forcefield' defence.
|
||||
if(damagetype == BRUTE && (!isnull(M.effective_brute_resistance)))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost * damage)
|
||||
damage = damage * M.effective_brute_resistance
|
||||
continue
|
||||
if((damagetype == BURN || damagetype == ELECTROCUTE) && (!isnull(M.effective_fire_resistance)))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost * damage)
|
||||
damage = damage * M.effective_fire_resistance
|
||||
continue
|
||||
if(damagetype == TOX && (!isnull(M.effective_tox_resistance)))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost * damage)
|
||||
damage = damage * M.effective_tox_resistance
|
||||
continue
|
||||
if(damagetype == OXY && (!isnull(M.effective_oxy_resistance)))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost * damage)
|
||||
damage = damage * M.effective_oxy_resistance
|
||||
continue
|
||||
if(damagetype == CLONE && (!isnull(M.effective_clone_resistance)))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost * damage)
|
||||
damage = damage * M.effective_clone_resistance
|
||||
continue
|
||||
if(damagetype == HALLOSS && (!isnull(M.effective_hal_resistance)))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost * damage)
|
||||
damage = damage * M.effective_hal_resistance
|
||||
continue
|
||||
if(damagetype == SEARING && (!isnull(M.effective_fire_resistance) || !isnull(M.effective_brute_resistance)))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost * damage)
|
||||
var/damage_mitigation = 0//Used for dual calculations.
|
||||
if(!isnull(M.effective_fire_resistance))
|
||||
damage_mitigation += round((1/3)*damage * M.effective_fire_resistance)
|
||||
if(!isnull(M.effective_brute_resistance))
|
||||
damage_mitigation += round((2/3)*damage * M.effective_brute_resistance)
|
||||
damage -= damage_mitigation
|
||||
continue
|
||||
if(damagetype == BIOACID && (isSynthetic() && (!isnull(M.effective_fire_resistance))) || (!isSynthetic() && M.effective_tox_resistance))
|
||||
if(isSynthetic())
|
||||
damage = damage * M.effective_fire_resistance
|
||||
else
|
||||
damage = damage * M.effective_tox_resistance
|
||||
continue
|
||||
//Handle other types of damage
|
||||
if((damagetype != BRUTE) && (damagetype != BURN))
|
||||
if(damagetype == HALLOSS)
|
||||
@@ -523,8 +586,12 @@ This function restores all organs.
|
||||
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.incoming_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*damage)
|
||||
damage *= M.incoming_damage_percent
|
||||
if(!isnull(M.incoming_brute_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*damage)
|
||||
damage *= M.incoming_brute_damage_percent
|
||||
|
||||
if(organ.take_damage(damage, 0, sharp, edge, used_weapon))
|
||||
@@ -536,8 +603,12 @@ This function restores all organs.
|
||||
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.incoming_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*damage)
|
||||
damage *= M.incoming_damage_percent
|
||||
if(!isnull(M.incoming_brute_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*damage)
|
||||
damage *= M.incoming_fire_damage_percent
|
||||
|
||||
if(organ.take_damage(0, damage, sharp, edge, used_weapon))
|
||||
|
||||
@@ -37,6 +37,18 @@ emp_act
|
||||
var/armor = getarmor_organ(organ, "bullet")
|
||||
if(!prob(armor/2)) //Even if the armor doesn't stop the bullet from hurting you, it might stop it from embedding.
|
||||
var/hit_embed_chance = P.embed_chance + (P.damage - armor) //More damage equals more chance to embed
|
||||
|
||||
//Modifiers can make bullets less likely to embed! These are the normal modifiers and shouldn't be related to energy stuff, but they can be anyways!
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.incoming_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.energy_cost) //We use energy_cost here for special effects, such as embedding.
|
||||
hit_embed_chance = hit_embed_chance*M.incoming_damage_percent
|
||||
if(P.damage_type == BRUTE && (!isnull(M.incoming_brute_damage_percent)))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.energy_cost)
|
||||
hit_embed_chance = hit_embed_chance*M.incoming_brute_damage_percent
|
||||
|
||||
if(prob(max(hit_embed_chance, 0)))
|
||||
var/obj/item/weapon/material/shard/shrapnel/SP = new()
|
||||
SP.name = (P.name != "shrapnel")? "[P.name] shrapnel" : "shrapnel"
|
||||
@@ -381,9 +393,28 @@ emp_act
|
||||
// if(buckled && buckled == AM)
|
||||
// return // Don't get hit by the thing we're buckled to.
|
||||
|
||||
//VORESTATION EDIT START - Allows for thrown vore!
|
||||
//Throwing a prey into a pred takes priority. After that it checks to see if the person being thrown is a pred.
|
||||
if(istype(AM, /mob/living))
|
||||
var/mob/living/thrown_mob = AM
|
||||
if((can_be_drop_pred && throw_vore) && (thrown_mob.devourable && thrown_mob.throw_vore && thrown_mob.can_be_drop_prey)) //Prey thrown into pred.
|
||||
vore_selected.nom_mob(thrown_mob) //Eat them!!!
|
||||
visible_message("<span class='warning'>[thrown_mob] is thrown right into [src]'s [lowertext(vore_selected.name)]!</span>")
|
||||
if(thrown_mob.loc != vore_selected)
|
||||
thrown_mob.forceMove(vore_selected) //Double check. Should never happen but...Weirder things have happened!
|
||||
add_attack_logs(thrown_mob.thrower,src,"Devoured [thrown_mob.name] via throw vore.")
|
||||
return //We can stop here. We don't need to calculate damage or anything else. They're eaten.
|
||||
else if((can_be_drop_prey && throw_vore && devourable) && (thrown_mob.can_be_drop_pred && thrown_mob.throw_vore)) //Pred thrown into prey.
|
||||
visible_message("<span class='warning'>[src] suddenly slips inside of [thrown_mob]'s [lowertext(thrown_mob.vore_selected.name)] as [thrown_mob] flies into them!</span>")
|
||||
thrown_mob.vore_selected.nom_mob(src) //Eat them!!!
|
||||
if(src.loc != thrown_mob.vore_selected)
|
||||
src.forceMove(thrown_mob.vore_selected) //Double check. Should never happen but...Weirder things have happened!
|
||||
add_attack_logs(thrown_mob.LAssailant,src,"Was Devoured by [thrown_mob.name] via throw vore.")
|
||||
return
|
||||
//VORESTATION EDIT END - Allows for thrown vore!
|
||||
|
||||
if(istype(AM,/obj/))
|
||||
var/obj/O = AM
|
||||
|
||||
if(in_throw_mode && speed <= THROWFORCE_SPEED_DIVISOR) //empty active hand and we're in throw mode
|
||||
if(canmove && !restrained())
|
||||
if(isturf(O.loc))
|
||||
|
||||
@@ -27,4 +27,7 @@
|
||||
..(new_loc, "Alraune")
|
||||
|
||||
/mob/living/carbon/human/shadekin/New(var/new_loc)
|
||||
..(new_loc, SPECIES_SHADEKIN)
|
||||
..(new_loc, SPECIES_SHADEKIN)
|
||||
|
||||
/mob/living/carbon/human/altevian/New(var/new_loc)
|
||||
..(new_loc, SPECIES_ALTEVIAN)
|
||||
|
||||
@@ -248,9 +248,28 @@
|
||||
to_chat(src, "<span class='danger'>Your legs won't respond properly, you fall down!</span>")
|
||||
Weaken(10)
|
||||
|
||||
// RADIATION! Everyone's favorite thing in the world! So let's get some numbers down off the bat.
|
||||
// 50 rads = 1Bq. This means 1 rad = 0.02Bq.
|
||||
// However, unless I am a smoothbrained dumbo, absorbed rads are in Gy. Not Bq.
|
||||
// So let's just assume that 50 rads = 1Gy. Make life easier!
|
||||
|
||||
// ACUTE RADIATION (The stuff that the 'radiation' variable takes care of. Remember, 50radiation=1Gy.):
|
||||
// Without care: 1-2Gy has a (0-5%) mortality chance. 2-6 (5-95%) 6-8 (95-100)% 8-30 (100%) >30 (100%)
|
||||
// With care: 1-2Gy (0-5%), 2-6 (5-50%), 6-8 (50-100%), 8-30 (99-100%) >30 (100%)
|
||||
// So let's make our thresholds based on this! 50-100, 100-300, 300-400, 400-1500, and anything above 1500!
|
||||
// In reality, however, nobody should ever go above 300 radiation, which is why the cutoff before the really bad effects start to happen being
|
||||
// 300 radiation is good. For reference: Breaking an artifact deals ~300 rads with no resistance. Getting shot with a lvl 3 PA deals 300 rads with no resistance.
|
||||
// Nobody outside of engineering should ever have to worry about being irradiated over 300 and start getting organ damage..
|
||||
|
||||
|
||||
/mob/living/carbon/human/handle_mutations_and_radiation()
|
||||
// CHRONIC RADIATION (The stuff that 'accumulated_rads' takes care of):
|
||||
// This is more or less for if someone was exposed for a long time to radiation or just finished being treated for extreme ARS.
|
||||
// These are meant to be annoying effects to nudge someone towards medical, but not lethal or deadly.
|
||||
// Things such as loss of taste, eye damage, dropping items in your hand, being temporaily weakened, etc. Stuff to annoy them and get them to fix their rads.
|
||||
|
||||
// Additionally, RADIATION_SPEED_COEFFICIENT = 0.1
|
||||
|
||||
/mob/living/carbon/human/handle_mutations_and_radiation() //Radiation rework! Now with 'accumulated_rads'
|
||||
if(inStasisNow())
|
||||
return
|
||||
|
||||
@@ -267,12 +286,15 @@
|
||||
if(gene.is_active(src))
|
||||
gene.OnMobLife(src)
|
||||
|
||||
radiation = CLAMP(radiation,0,250)
|
||||
|
||||
radiation = CLAMP(radiation,0,2500) //Max of 50Gy. If you reach that...You're going to wish you were dead. You probably will be dead.
|
||||
accumulated_rads = CLAMP(accumulated_rads,0,2500) //Max of 50Gy as well. You should never get higher than this. You will be dead before you can reach this.
|
||||
var/obj/item/organ/internal/I = null //Used for further down below when an organ is picked.
|
||||
if(!radiation)
|
||||
if(species.appearance_flags & RADIATION_GLOWS)
|
||||
set_light(0)
|
||||
else
|
||||
if(accumulated_rads)
|
||||
accumulated_rads -= RADIATION_SPEED_COEFFICIENT //Accumulated rads slowly dissipate very slowly. Get to medical to get it treated!
|
||||
else if(((life_tick % 5 == 0) && radiation) || (radiation > 600)) //Radiation is a slow, insidious killer. Unless you get a massive dose, then the onset is sudden!
|
||||
if(species.appearance_flags & RADIATION_GLOWS)
|
||||
set_light(max(1,min(5,radiation/15)), max(1,min(10,radiation/25)), species.get_flesh_colour(src))
|
||||
// END DOGSHIT SNOWFLAKE
|
||||
@@ -299,42 +321,139 @@
|
||||
return
|
||||
//VOREStation Addition end: shadekin
|
||||
|
||||
var/damage = 0
|
||||
radiation -= 1 * RADIATION_SPEED_COEFFICIENT
|
||||
if(radiation > 2.5 && prob(25)) // Safe for a little over 2m at the recommended maximum safe dosage of 0.05Bq
|
||||
damage = 1
|
||||
if(reagents.has_reagent("prussian_blue")) //Prussian Blue temporarily stops radiation effects.
|
||||
return
|
||||
|
||||
if (radiation > 50)
|
||||
var/damage = 0
|
||||
|
||||
|
||||
if (radiation < 50) //Less than 1.0 Gy. No side effects.
|
||||
radiation -= 10 * RADIATION_SPEED_COEFFICIENT
|
||||
accumulated_rads += 10 * RADIATION_SPEED_COEFFICIENT //No escape from accumulated rads.
|
||||
|
||||
else if (radiation >= 50 && radiation < 100) //Equivalent of 1.0-2.0 Gy. Minimum stage you start seeing effects.
|
||||
damage = 1
|
||||
radiation -= 1 * RADIATION_SPEED_COEFFICIENT
|
||||
radiation -= 10 * RADIATION_SPEED_COEFFICIENT
|
||||
accumulated_rads += 10 * RADIATION_SPEED_COEFFICIENT
|
||||
if(!isSynthetic())
|
||||
if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT))
|
||||
radiation -= 5 * RADIATION_SPEED_COEFFICIENT
|
||||
to_chat(src, "<span class='warning'>You feel weak.</span>")
|
||||
Weaken(3)
|
||||
if(!lying)
|
||||
emote("collapse")
|
||||
if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT) && !weakened)
|
||||
to_chat(src, "<span class='warning'>You feel exhausted.</span>")
|
||||
AdjustWeakened(3)
|
||||
if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT) && species.get_bodytype() == SPECIES_HUMAN) //apes go bald
|
||||
if((h_style != "Bald" || f_style != "Shaved" ))
|
||||
to_chat(src, "<span class='warning'>Your hair falls out.</span>")
|
||||
h_style = "Bald"
|
||||
f_style = "Shaved"
|
||||
update_hair()
|
||||
if(prob(1) && prob(100 * RADIATION_SPEED_COEFFICIENT)) //Rare chance of vomiting.
|
||||
spawn vomit()
|
||||
|
||||
if (radiation > 75)
|
||||
else if (radiation >= 100 && radiation < 300) //Equivalent of 2.0 to 6.0 Gy. Nobody should ever be above this without extreme negligence.
|
||||
damage = 3
|
||||
radiation -= 1 * RADIATION_SPEED_COEFFICIENT
|
||||
radiation -= 30 * RADIATION_SPEED_COEFFICIENT
|
||||
accumulated_rads += 30 * RADIATION_SPEED_COEFFICIENT
|
||||
if(!isSynthetic())
|
||||
if(prob(5))
|
||||
take_overall_damage(0, 5 * RADIATION_SPEED_COEFFICIENT, used_weapon = "Radiation Burns")
|
||||
if(prob(1))
|
||||
to_chat(src, "<span class='warning'>You feel strange!</span>")
|
||||
adjustCloneLoss(5 * RADIATION_SPEED_COEFFICIENT)
|
||||
emote("gasp")
|
||||
if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT))
|
||||
spawn vomit()
|
||||
if(prob(10) && !weakened)
|
||||
to_chat(src, "<span class='warning'>You feel sick.</span>")
|
||||
AdjustWeakened(3)
|
||||
|
||||
if (radiation > 150)
|
||||
damage = 6
|
||||
radiation -= 4 * RADIATION_SPEED_COEFFICIENT
|
||||
else if (radiation >= 300 && radiation < 400) //Equivalent of 6.0 to 8.0 Gy.
|
||||
damage = 5
|
||||
radiation -= 50 * RADIATION_SPEED_COEFFICIENT
|
||||
accumulated_rads += 50 * RADIATION_SPEED_COEFFICIENT
|
||||
if(!isSynthetic())
|
||||
if(prob(15))
|
||||
take_overall_damage(0, 10 * RADIATION_SPEED_COEFFICIENT, used_weapon = "Radiation Burns")
|
||||
if(prob(2))
|
||||
adjustCloneLoss(5 * RADIATION_SPEED_COEFFICIENT)
|
||||
emote("gasp")
|
||||
if(prob(10) && prob(100 * RADIATION_SPEED_COEFFICIENT))
|
||||
spawn vomit()
|
||||
if(prob(15) && !weakened)
|
||||
to_chat(src, "<span class='warning'>You feel horribly ill.</span>")
|
||||
AdjustWeakened(3)
|
||||
if(prob(5) && internal_organs.len)
|
||||
I = pick(internal_organs) //Internal organ damage...Not good. Not good at all.
|
||||
if(istype(I)) I.add_autopsy_data("Radiation Induced Cancerous Growth", damage)
|
||||
I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
|
||||
|
||||
|
||||
else if (radiation >= 400 && radiation < 1500) //Equivalent of 8.0 to 30 Gy.
|
||||
damage = 10
|
||||
radiation -= 100 * RADIATION_SPEED_COEFFICIENT
|
||||
accumulated_rads += 100 * RADIATION_SPEED_COEFFICIENT
|
||||
if(!isSynthetic())
|
||||
if(prob(25))
|
||||
take_overall_damage(0, 15 * RADIATION_SPEED_COEFFICIENT, used_weapon = "Radiation Burns")
|
||||
if(prob(5))
|
||||
I = internal_organs_by_name[O_EYES]
|
||||
if(I)
|
||||
if(istype(I)) I.add_autopsy_data("Radiation Burns", damage)
|
||||
I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
|
||||
to_chat(src, "<span class='warning'>Your eyes burn!</span>")
|
||||
eye_blurry += 10
|
||||
if(prob(4))
|
||||
adjustCloneLoss(5 * RADIATION_SPEED_COEFFICIENT)
|
||||
emote("gasp")
|
||||
if(prob(25) && prob(100 * RADIATION_SPEED_COEFFICIENT))
|
||||
spawn vomit()
|
||||
if(prob(20) && !weakened)
|
||||
to_chat(src, "<span class='critical'>You feel like your insides are burning!</span>")
|
||||
AdjustWeakened(5)
|
||||
if(prob(5))
|
||||
to_chat(src, "<span class='critical'>Your entire body feels like it's on fire!</span>")
|
||||
adjustHalLoss(5)
|
||||
if(prob(10) && internal_organs.len)
|
||||
I = pick(internal_organs) //Internal organ damage...Not good. Not good at all.
|
||||
if(istype(I)) I.add_autopsy_data("Radiation Induced Cancerous Growth", damage)
|
||||
I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
|
||||
|
||||
else if (radiation >= 1500) //Above 30Gy. You had to get absolutely blasted with rads for this.
|
||||
damage = 30
|
||||
radiation -= 300 * RADIATION_SPEED_COEFFICIENT
|
||||
accumulated_rads += 300 * RADIATION_SPEED_COEFFICIENT
|
||||
|
||||
if(!isSynthetic())
|
||||
take_overall_damage(0, damage * RADIATION_SPEED_COEFFICIENT, used_weapon = "Radiation Burns") //3 burn damage a tick as your body melts.
|
||||
adjustCloneLoss(15 * RADIATION_SPEED_COEFFICIENT) //1.5 cloneloss a tick as your cells mutate and break down.
|
||||
|
||||
I = internal_organs_by_name[O_EYES]
|
||||
if(I)
|
||||
I.add_autopsy_data("Radiation Burns", damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
|
||||
I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT) //3 eye damage a tick as your eyes melt down.
|
||||
eye_blurry += 10
|
||||
|
||||
if(prob(50) && prob(100 * RADIATION_SPEED_COEFFICIENT))
|
||||
spawn vomit()
|
||||
if(!paralysis && prob(30) && prob(100 * RADIATION_SPEED_COEFFICIENT)) //CNS is shutting down.
|
||||
to_chat(src, "<font color='Critical'>You have a seizure!</font>")
|
||||
Paralyse(10)
|
||||
make_jittery(1000)
|
||||
if(!lying)
|
||||
emote("collapse")
|
||||
if(get_active_hand() && prob(15)) //CNS is shutting down.
|
||||
to_chat(src, "<span class='danger'>Your hand won't respond properly, you drop what you're holding!</span>")
|
||||
drop_item()
|
||||
if(internal_organs.len)
|
||||
I = pick(internal_organs) //Internal organ damage...Not good. Not good at all.
|
||||
if(istype(I)) I.add_autopsy_data("Radiation Induced Cancerous Growth", damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
|
||||
I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
|
||||
|
||||
/* //Not-so-sparkledog code. TODO: Make a pref for 'special game interactions' that allows interactions that align with prefs to occur.
|
||||
if(radiation >= 250) //Special effect stuff that occurs at certain rad levels.
|
||||
if(prob(1) && prob(radiation/2 * RADIATION_SPEED_COEFFICIENT) && allow_spontaneous_tf) //If you've got spontaneous TF...well...
|
||||
scramble(1, src, 3) //I tried to base this on how many rads you took and it was...Hilarious. Sparkledogs everywhere.
|
||||
//For the most part, 3 strength will simply change colors. If you get really unlucky, it can do more TF's.
|
||||
//Math: 250 rads = 1/800 chance
|
||||
//500 rads = 1/400 chance chance. Etc.
|
||||
*/
|
||||
|
||||
if(damage)
|
||||
damage *= species.radiation_mod
|
||||
@@ -344,6 +463,47 @@
|
||||
var/obj/item/organ/external/O = pick(organs)
|
||||
if(istype(O)) O.add_autopsy_data("Radiation Poisoning", damage)
|
||||
|
||||
// Begin long-term radiation effects
|
||||
// Loss of taste occurs at 100 (2Gy) and is handled in taste.dm
|
||||
// These are all done one after another, so duplication is not required. Someone at 400rads will have the 100&400 effects.
|
||||
if(!radiation && accumulated_rads >= 100 && !reagents.has_reagent("prussian_blue")) //Let's not hit them with long term effects when they're actively being hit with rads.
|
||||
if(!isSynthetic())
|
||||
I = internal_organs_by_name[O_EYES]
|
||||
if(I) //Eye stuff
|
||||
if(prob(5) && prob(accumulated_rads * RADIATION_SPEED_COEFFICIENT))
|
||||
to_chat(src, "<span class='warning'>Your eyes water.</span>")
|
||||
eye_blurry += 5
|
||||
if(accumulated_rads > 300) // (6Gy)
|
||||
if(prob(2) && prob(accumulated_rads * RADIATION_SPEED_COEFFICIENT))
|
||||
to_chat(src, "<span class='warning'>Your eyes burn.</span>")
|
||||
I.add_autopsy_data("Radiation Burns", 1 * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
|
||||
I.take_damage(1 * species.radiation_mod * RADIATION_SPEED_COEFFICIENT) //0.1 damage. Not a lot, but enough to tell you to get to medical.
|
||||
eye_blurry += 10
|
||||
|
||||
if(accumulated_rads > 200) // (4Gy)
|
||||
if(prob(5) && prob(accumulated_rads * RADIATION_SPEED_COEFFICIENT))
|
||||
to_chat(src, "<span class='warning'>Your feel nauseated.</span>")
|
||||
spawn vomit()
|
||||
if(!weakened && prob(2) && prob(accumulated_rads * RADIATION_SPEED_COEFFICIENT))
|
||||
to_chat(src, "<span class='warning'>Your feel exhausted.</span>")
|
||||
AdjustWeakened(3)
|
||||
if(accumulated_rads > 300) // (6Gy)
|
||||
if(get_active_hand() && prob(15) && prob(100 * RADIATION_SPEED_COEFFICIENT)) //CNS is shutting down.
|
||||
to_chat(src, "<span class='danger'>Your hand won't respond properly, you drop what you're holding!</span>")
|
||||
drop_item()
|
||||
if(accumulated_rads > 700) // (12Gy)
|
||||
if(!paralysis && prob(1) && prob(100 * RADIATION_SPEED_COEFFICIENT)) //1 in 1000 chance per tick.
|
||||
to_chat(src, "<font color='Critical'>You have a seizure!</font>")
|
||||
Paralyse(10)
|
||||
make_jittery(1000)
|
||||
if(!lying)
|
||||
emote("collapse")
|
||||
|
||||
else //The synthetic effects!
|
||||
return //Nothing for now.
|
||||
|
||||
|
||||
|
||||
/** breathing **/
|
||||
|
||||
/mob/living/carbon/human/handle_chemical_smoke(var/datum/gas_mixture/environment)
|
||||
@@ -1419,7 +1579,9 @@
|
||||
else
|
||||
clear_alert("high")
|
||||
|
||||
if(!isbelly(loc)) clear_fullscreen("belly") //VOREStation Add - Belly fullscreens safety
|
||||
if(!isbelly(loc)) //VOREStation Add - Belly fullscreens safety
|
||||
clear_fullscreen("belly")
|
||||
//clear_fullscreen("belly2") //For multilayered stomachs. Not currently implemented.
|
||||
|
||||
if(config.welder_vision)
|
||||
var/found_welder
|
||||
|
||||
+212
-1
@@ -1154,7 +1154,6 @@
|
||||
to_chat(src, "<span class='notice'>You successfully drag \the [target] into the water, slipping them into your [vore_selected].</span>")
|
||||
target.forceMove(src.vore_selected)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/toggle_pain_module()
|
||||
set name = "Toggle pain simulation."
|
||||
set desc = "Turn on your pain simulation for that organic experience! Or turn it off for repairs, or if it's too much."
|
||||
@@ -1166,3 +1165,215 @@
|
||||
to_chat(src, "<span class='danger'> You turn on your pain simulators </span>")
|
||||
|
||||
synth_cosmetic_pain = !synth_cosmetic_pain
|
||||
|
||||
//This is the 'long vore' ability. Also known as "Grab Prey with appendage" or "Long Predatorial Reach". Or simply "Tongue Vore"
|
||||
//It involves projectiles (which means it can be VV'd onto a gun for shenanigans)
|
||||
//It can also be recolored via the proc, which persists between rounds.
|
||||
|
||||
/mob/living/proc/long_vore() // Allows the user to tongue grab a creature in range. Made a /living proc so frogs can frog you.
|
||||
set name = "Grab Prey With Appendage"
|
||||
set category = "Abilities"
|
||||
set desc = "Grab a target with any of your appendages!"
|
||||
|
||||
if(stat || paralysis || weakened || stunned || world.time < last_special) //No tongue flicking while stunned.
|
||||
to_chat(src, "<span class='warning'>You can't do that in your current state.</span>")
|
||||
return
|
||||
|
||||
last_special = world.time + 10 //Anti-spam.
|
||||
|
||||
if (!istype(src, /mob/living))
|
||||
to_chat(src, "<span class='warning'>It doesn't work that way.</span>")
|
||||
return
|
||||
|
||||
var/choice = tgui_alert(src, "Do you wish to change the color of your appendage, use it, or change its functionality?", "Selection List", list("Use it", "Color", "Functionality"))
|
||||
|
||||
if(choice == "Color") //Easy way to set color so we don't bloat up the menu with even more buttons.
|
||||
var/new_color = input(usr, "Choose a color to set your appendage to!", "", appendage_color) as color|null
|
||||
if(new_color)
|
||||
appendage_color = new_color
|
||||
|
||||
if(choice == "Functionality") //Easy way to set color so we don't bloat up the menu with even more buttons.
|
||||
var/choice2 = tgui_alert(usr, "Choose if you want to be pulled to the target or pull them to you!", "Functionality Setting", list("Pull target to self", "Pull self to target"))
|
||||
if(choice2 == "Pull target to self")
|
||||
appendage_alt_setting = 0
|
||||
else
|
||||
appendage_alt_setting = 1
|
||||
else
|
||||
var/list/targets = list() //IF IT IS NOT BROKEN. DO NOT FIX IT.
|
||||
|
||||
for(var/mob/living/L in range(5, src))
|
||||
if(!istype(L, /mob/living)) //Don't eat anything that isn't mob/living. Failsafe.
|
||||
continue
|
||||
if(L == src) //no eating yourself. 1984.
|
||||
continue
|
||||
if(L.devourable && L.throw_vore && (L.can_be_drop_pred || L.can_be_drop_prey))
|
||||
targets += L
|
||||
|
||||
if(!(targets.len))
|
||||
to_chat(src, "<span class='notice'>No eligible targets found.</span>")
|
||||
return
|
||||
|
||||
var/mob/living/target = tgui_input_list(src, "Please select a target.", "Victim", targets)
|
||||
|
||||
if(!target)
|
||||
return
|
||||
|
||||
if(!istype(target, /mob/living)) //Safety.
|
||||
to_chat(src, "<span class='warning'>You need to select a living target!</span>")
|
||||
return
|
||||
|
||||
if (get_dist(src,target) >= 6)
|
||||
to_chat(src, "<span class='warning'>You need to be closer to do that.</span>")
|
||||
return
|
||||
|
||||
visible_message("<span class='notice'>\The [src] attempts to snatch up [target]!</span>", \
|
||||
"<span class='notice'>You attempt to snatch up [target]!</span>" )
|
||||
playsound(src, 'sound/vore/sunesound/pred/schlorp.ogg', 25)
|
||||
|
||||
//Code to shoot the beam here.
|
||||
var/obj/item/projectile/beam/appendage/appendage_attack = new /obj/item/projectile/beam/appendage(get_turf(loc))
|
||||
appendage_attack.launch_projectile(target, BP_TORSO, src) //Send it.
|
||||
last_special = world.time + 100 //Cooldown for successful strike.
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/projectile/beam/appendage //The tongue projecitle.
|
||||
name = "appendage"
|
||||
icon_state = "laser"
|
||||
nodamage = 1
|
||||
damage = 0
|
||||
eyeblur = 0
|
||||
check_armour = "bullet" //Not really needed, but whatever.
|
||||
can_miss = FALSE //Let's not miss our tongue!
|
||||
hitsound = 'sound/vore/sunesound/pred/schlorp.ogg'
|
||||
hitsound_wall = 'sound/vore/sunesound/pred/schlorp.ogg'
|
||||
excavation_amount = 0
|
||||
hitscan_light_intensity = 0
|
||||
hitscan_light_range = 0
|
||||
muzzle_flash_intensity = 0
|
||||
muzzle_flash_range = 0
|
||||
impact_light_intensity = 0
|
||||
impact_light_range = 0
|
||||
light_range = 0 //No your tongue can not glow...For now.
|
||||
light_power = 0
|
||||
light_on = 0 //NO LIGHT
|
||||
combustion = FALSE //No, your tongue can't set the room on fire.
|
||||
pass_flags = PASSTABLE
|
||||
|
||||
muzzle_type = /obj/effect/projectile/muzzle/appendage
|
||||
tracer_type = /obj/effect/projectile/tracer/appendage
|
||||
impact_type = /obj/effect/projectile/impact/appendage
|
||||
|
||||
/obj/item/projectile/beam/appendage/generate_hitscan_tracers()
|
||||
if(firer) //This neat little code block allows for C O L O R A B L E tongues! Correction: 'Appendages'
|
||||
if(istype(firer,/mob/living))
|
||||
var/mob/living/originator = firer
|
||||
color = originator.appendage_color
|
||||
..()
|
||||
|
||||
/obj/item/projectile/beam/appendage/on_hit(var/atom/target)
|
||||
if(target == firer) //NO EATING YOURSELF
|
||||
return
|
||||
if(istype(target, /mob/living))
|
||||
var/mob/living/M = target
|
||||
var/throw_range = get_dist(firer,M)
|
||||
if(istype(firer, /mob/living)) //Let's check for any alt settings. Such as: User selected to be thrown at target.
|
||||
var/mob/living/F = firer
|
||||
if(F.appendage_alt_setting == 1)
|
||||
F.throw_at(M, throw_range, firer.throw_speed, F) //Firer thrown at target.
|
||||
F.updateicon()
|
||||
return
|
||||
if(istype(M))
|
||||
M.throw_at(firer, throw_range, M.throw_speed, firer) //Fun fact: living things have a throw_speed of 2.
|
||||
M.updateicon()
|
||||
return
|
||||
else //Anything that isn't a /living
|
||||
return
|
||||
if(istype(target, /obj/item/)) //We hit an object? Pull it. This can only happen via admin shenanigans such as a gun being VV'd with this projectile.
|
||||
var/obj/item/hit_object = target
|
||||
if(hit_object.density || hit_object.anchored)
|
||||
if(istype(firer, /mob/living))
|
||||
var/mob/living/originator = firer
|
||||
originator.Weaken(2) //If you hit something dense or anchored, fall flat on your face.
|
||||
originator.visible_message("<span class='warning'>\The [originator] trips over their self and falls flat on their face!</span>", \
|
||||
"<span class='warning'>You trip over yourself and fall flat on your face!</span>" )
|
||||
playsound(originator, "punch", 25, 1, -1)
|
||||
return
|
||||
else
|
||||
hit_object.throw_at(firer, throw_range, hit_object.throw_speed, firer)
|
||||
if(istype(target, /turf/simulated/wall) || istype(target, /obj/machinery/door) || istype(target, /obj/structure/window)) //This can happen normally due to odd terrain. For some reason, it seems to not actually interact with walls.
|
||||
if(istype(firer, /mob/living))
|
||||
var/mob/living/originator = firer
|
||||
originator.Weaken(2) //Hit a wall? Whoops!
|
||||
originator.visible_message("<span class='warning'>\The [originator] trips over their self and falls flat on their face!</span>", \
|
||||
"<span class='warning'>You trip over yourself and fall flat on your face!</span>" )
|
||||
playsound(originator, "punch", 25, 1, -1)
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/effect/projectile/muzzle/appendage
|
||||
icon = 'icons/obj/projectiles_vr.dmi'
|
||||
icon_state = "muzzle_appendage"
|
||||
light_range = 0
|
||||
light_power = 0
|
||||
light_color = "#FF0D00"
|
||||
|
||||
/obj/effect/projectile/tracer/appendage
|
||||
icon = 'icons/obj/projectiles_vr.dmi'
|
||||
icon_state = "appendage_beam"
|
||||
light_range = 0
|
||||
light_power = 0
|
||||
light_color = "#FF0D00" //Doesn't matter. Not used.
|
||||
|
||||
/obj/effect/projectile/impact/appendage
|
||||
icon = 'icons/obj/projectiles_vr.dmi'
|
||||
icon_state = "impact_appendage_combined"
|
||||
light_range = 0
|
||||
light_power = 0
|
||||
light_color = "#FF0D00"
|
||||
//LONG VORE ABILITY END
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/tongue //This is the 'tongue' gun for admin memery.
|
||||
name = "tongue"
|
||||
desc = "A tongue that can be used to grab things."
|
||||
icon = 'icons/mob/dogborg_vr.dmi'
|
||||
icon_state = "synthtongue"
|
||||
item_state = "gun"
|
||||
fire_delay = null
|
||||
force = 0
|
||||
fire_delay = 1 //Adminspawn. No delay.
|
||||
charge_cost = 0 //This is an adminspawn gun...No reason to force it to have a charge state.
|
||||
|
||||
projectile_type = /obj/item/projectile/beam/appendage
|
||||
cell_type = /obj/item/weapon/cell/device/weapon/recharge
|
||||
battery_lock = 1
|
||||
modifystate = null
|
||||
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="vore", projectile_type=/obj/item/projectile/beam/appendage, modifystate=null, fire_sound='sound/vore/sunesound/pred/schlorp.ogg', charge_cost = 0),)
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/tongue/update_icon() //No updating the icon.
|
||||
icon_state = "synthtongue"
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/energy/bfgtaser/tongue
|
||||
name = "9000-series Ball Tongue Taser"
|
||||
desc = "A banned riot control device."
|
||||
slot_flags = SLOT_BELT|SLOT_BACK
|
||||
projectile_type = /obj/item/projectile/bullet/BFGtaser/tongue
|
||||
fire_delay = 20
|
||||
w_class = ITEMSIZE_LARGE
|
||||
one_handed_penalty = 90 // The thing's heavy and huge.
|
||||
accuracy = 45
|
||||
charge_cost = 2400 //yes, this bad boy empties an entire weapon cell in one shot. What of it?
|
||||
|
||||
/obj/item/projectile/bullet/BFGtaser/tongue
|
||||
name = "tongue ball"
|
||||
hitsound = 'sound/vore/sunesound/pred/schlorp.ogg'
|
||||
hitsound_wall = 'sound/vore/sunesound/pred/schlorp.ogg'
|
||||
zaptype = /obj/item/projectile/beam/appendage
|
||||
|
||||
@@ -122,6 +122,16 @@
|
||||
H.verbs |= /mob/living/carbon/human/proc/succubus_drain_finalize
|
||||
H.verbs |= /mob/living/carbon/human/proc/succubus_drain_lethal
|
||||
|
||||
/datum/trait/neutral/long_vore
|
||||
name = "Long Predatorial Reach"
|
||||
desc = "Makes you able to use your tongue to grab creatures."
|
||||
cost = 0
|
||||
custom_only = FALSE
|
||||
|
||||
/datum/trait/neutral/long_vore/apply(var/datum/species/S,var/mob/living/carbon/human/H)
|
||||
..(S,H)
|
||||
H.verbs |= /mob/living/proc/long_vore
|
||||
|
||||
/datum/trait/neutral/feeder
|
||||
name = "Feeder"
|
||||
desc = "Allows you to feed your prey using your own body."
|
||||
|
||||
@@ -144,3 +144,13 @@
|
||||
),
|
||||
autohiss_exempt = list("Vespinae"))
|
||||
excludes = list(/datum/trait/neutral/autohiss_tajaran, /datum/trait/neutral/autohiss_unathi)
|
||||
//End YW edit
|
||||
|
||||
/datum/trait/positive/cocoon_tf/xenochimera
|
||||
sort = TRAIT_SORT_SPECIES
|
||||
allowed_species = list(SPECIES_XENOCHIMERA)
|
||||
custom_only = FALSE
|
||||
name = "Xenochimera: Cocoon Spinner"
|
||||
desc = "Allows you to build a cocoon around yourself, using it to transform your body if you desire."
|
||||
cost = 0
|
||||
category = 0
|
||||
|
||||
@@ -1137,8 +1137,14 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
|
||||
var/image/effects = new()
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(M.mob_overlay_state)
|
||||
var/image/I = image(icon = 'icons/mob/modifier_effects.dmi', icon_state = M.mob_overlay_state)
|
||||
effects.overlays += I // Leaving this as overlays +=
|
||||
if(M.icon_override) //VOREStation Edit. Override for the modifer icon.
|
||||
var/image/I = image(icon = 'icons/mob/modifier_effects_vr.dmi', icon_state = M.mob_overlay_state)
|
||||
I.color = M.effect_color
|
||||
effects.overlays += I // Leaving this as overlays +=
|
||||
else
|
||||
var/image/I = image(icon = 'icons/mob/modifier_effects.dmi', icon_state = M.mob_overlay_state)
|
||||
I.color = M.effect_color
|
||||
effects.overlays += I // Leaving this as overlays +=
|
||||
|
||||
overlays_standing[MODIFIER_EFFECTS_LAYER] = effects
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
from.trans_to_holder(temp, amount, multiplier, 1)
|
||||
|
||||
var/text_output = temp.generate_taste_message(src)
|
||||
if(accumulated_rads >= 100) //If you're irradiated, you can't taste!
|
||||
text_output = "nothing"
|
||||
|
||||
if(text_output != last_taste_text || last_taste_time + 100 < world.time) //We dont want to spam the same message over and over again at the person. Give it a bit of a buffer.
|
||||
to_chat(src, "<span class='notice'>You can taste [text_output].</span>")//no taste means there are too many tastes and not enough flavor.
|
||||
|
||||
|
||||
@@ -13,6 +13,53 @@
|
||||
to_world_log("## DEBUG: apply_damage() was called on [src], with [damage] damage, and an armor value of [blocked].")
|
||||
if(!damage || (blocked >= 100))
|
||||
return 0
|
||||
for(var/datum/modifier/M in modifiers) //MODIFIER STUFF. It's best to do this RIGHT before armor is calculated, so it's done here! This is the 'forcefield' defence.
|
||||
if(damagetype == BRUTE && (!isnull(M.effective_brute_resistance)))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost * damage)
|
||||
damage = damage * M.effective_brute_resistance
|
||||
continue
|
||||
if((damagetype == BURN || damagetype == ELECTROCUTE)&& (!isnull(M.effective_fire_resistance)))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost * damage)
|
||||
damage = damage * M.effective_fire_resistance
|
||||
continue
|
||||
if(damagetype == TOX && (!isnull(M.effective_tox_resistance)))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost * damage)
|
||||
damage = damage * M.effective_tox_resistance
|
||||
continue
|
||||
if(damagetype == OXY && (!isnull(M.effective_oxy_resistance)))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost * damage)
|
||||
damage = damage * M.effective_oxy_resistance
|
||||
continue
|
||||
if(damagetype == CLONE && (!isnull(M.effective_clone_resistance)))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost * damage)
|
||||
damage = damage * M.effective_clone_resistance
|
||||
continue
|
||||
if(damagetype == HALLOSS && (!isnull(M.effective_hal_resistance)))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost * damage)
|
||||
damage = damage * M.effective_hal_resistance
|
||||
continue
|
||||
if(damagetype == SEARING && (!isnull(M.effective_fire_resistance) || !isnull(M.effective_brute_resistance)))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost * damage)
|
||||
var/damage_mitigation = 0//Used for dual calculations.
|
||||
if(!isnull(M.effective_fire_resistance))
|
||||
damage_mitigation += round((1/3)*damage * M.effective_fire_resistance)
|
||||
if(!isnull(M.effective_brute_resistance))
|
||||
damage_mitigation += round((2/3)*damage * M.effective_brute_resistance)
|
||||
damage -= damage_mitigation
|
||||
continue
|
||||
if(damagetype == BIOACID && (isSynthetic() && (!isnull(M.effective_fire_resistance))) || (!isSynthetic() && M.effective_tox_resistance))
|
||||
if(isSynthetic())
|
||||
damage = damage * M.effective_fire_resistance
|
||||
else
|
||||
damage = damage * M.effective_tox_resistance
|
||||
continue
|
||||
if(soaked)
|
||||
if(soaked >= round(damage*0.8))
|
||||
damage -= round(damage*0.8)
|
||||
@@ -55,6 +102,7 @@
|
||||
/mob/living/proc/apply_damages(var/brute = 0, var/burn = 0, var/tox = 0, var/oxy = 0, var/clone = 0, var/halloss = 0, var/def_zone = null, var/blocked = 0)
|
||||
if(blocked >= 100)
|
||||
return 0
|
||||
// INSERT MODIFIER CODE HERE... But no, really, only two things in the game use it, quad and viruses. The former is admin-only and the latter wouldn't be affected logically, but would if shield code was inerted here. If you really want, you can copy&paste the above and modify it to adjust brute/burn/etc. I do not advise this however.
|
||||
if(brute) apply_damage(brute, BRUTE, def_zone, blocked)
|
||||
if(burn) apply_damage(burn, BURN, def_zone, blocked)
|
||||
if(tox) apply_damage(tox, TOX, def_zone, blocked)
|
||||
|
||||
@@ -192,8 +192,12 @@
|
||||
if(amount > 0)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.incoming_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_damage_percent
|
||||
if(!isnull(M.incoming_brute_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_brute_damage_percent
|
||||
else if(amount < 0)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
@@ -219,8 +223,12 @@
|
||||
if(amount > 0)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.incoming_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_damage_percent
|
||||
if(!isnull(M.incoming_oxy_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_oxy_damage_percent
|
||||
else if(amount < 0)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
@@ -243,8 +251,12 @@
|
||||
if(amount > 0)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.incoming_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_damage_percent
|
||||
if(!isnull(M.incoming_tox_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_tox_damage_percent
|
||||
else if(amount < 0)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
@@ -273,8 +285,12 @@
|
||||
if(amount > 0)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.incoming_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_damage_percent
|
||||
if(!isnull(M.incoming_fire_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_fire_damage_percent
|
||||
else if(amount < 0)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
@@ -298,8 +314,12 @@
|
||||
if(amount > 0)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(!isnull(M.incoming_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_damage_percent
|
||||
if(!isnull(M.incoming_clone_damage_percent))
|
||||
if(M.energy_based)
|
||||
M.energy_source.use(M.damage_cost*amount)
|
||||
amount *= M.incoming_clone_damage_percent
|
||||
else if(amount < 0)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
@@ -331,6 +351,9 @@
|
||||
if(status_flags & GODMODE) return 0 //godmode
|
||||
if(amount > 0)
|
||||
for(var/datum/modifier/M in modifiers)
|
||||
if(M.energy_based && (!isnull(M.incoming_hal_damage_percent) || !isnull(M.disable_duration_percent)))
|
||||
M.energy_source.use(M.damage_cost*amount) // Cost of the Damage absorbed.
|
||||
M.energy_source.use(M.energy_cost) // Cost of the Effect absorbed.
|
||||
if(!isnull(M.incoming_damage_percent))
|
||||
amount *= M.incoming_damage_percent
|
||||
if(!isnull(M.incoming_hal_damage_percent))
|
||||
@@ -1088,6 +1111,7 @@
|
||||
src.inertia_dir = get_dir(target, src)
|
||||
step(src, inertia_dir)
|
||||
item.throw_at(target, throw_range, item.throw_speed, src)
|
||||
item.throwing = 1 //Small edit so thrown interactions actually work!
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
@@ -324,6 +324,28 @@
|
||||
src.anchored = TRUE
|
||||
src.pinned += O
|
||||
|
||||
//VORESTATION EDIT START - Allows for thrown vore!
|
||||
//Throwing a prey into a pred takes priority. After that it checks to see if the person being thrown is a pred.
|
||||
if(istype(AM, /mob/living))
|
||||
var/mob/living/thrown_mob = AM
|
||||
if(!client && !thrown_mob.allowmobvore)
|
||||
return //The mob is AI controlled and the prey doesn't allow for mob vore allowed, don't even bother.
|
||||
if((can_be_drop_pred && throw_vore) && (thrown_mob.devourable && thrown_mob.throw_vore && thrown_mob.can_be_drop_prey)) //Prey thrown into pred.
|
||||
vore_selected.nom_mob(thrown_mob) //Eat them!!!
|
||||
visible_message("<span class='warning'>[thrown_mob] is thrown right into [src]'s [lowertext(vore_selected.name)]!</span>")
|
||||
if(thrown_mob.loc != vore_selected)
|
||||
thrown_mob.forceMove(vore_selected) //Double check. Should never happen but...Weirder things have happened!
|
||||
add_attack_logs(thrown_mob.thrower,src,"Devoured [thrown_mob.name] via throw vore.")
|
||||
return //We can stop here. We don't need to calculate damage or anything else. They're eaten.
|
||||
else if((can_be_drop_prey && throw_vore && devourable) && (thrown_mob.can_be_drop_pred && thrown_mob.throw_vore)) //Pred thrown into prey.
|
||||
visible_message("<span class='warning'>[src] suddenly slips inside of [thrown_mob]'s [lowertext(thrown_mob.vore_selected.name)] as [thrown_mob] flies into them!</span>")
|
||||
thrown_mob.vore_selected.nom_mob(src) //Eat them!!!
|
||||
if(src.loc != thrown_mob.vore_selected)
|
||||
src.forceMove(thrown_mob.vore_selected) //Double check. Should never happen but...Weirder things have happened!
|
||||
add_attack_logs(thrown_mob.LAssailant,src,"Was Devoured by [thrown_mob.name] via throw vore.")
|
||||
return
|
||||
//VORESTATION EDIT END - Allows for thrown vore!
|
||||
|
||||
/mob/living/proc/embed(var/obj/O, var/def_zone=null)
|
||||
O.loc = src
|
||||
src.embedded += O
|
||||
|
||||
@@ -598,9 +598,12 @@
|
||||
volume = T.reagents.total_volume
|
||||
if(water)
|
||||
water.add_charge(volume)
|
||||
if(T.ckey)
|
||||
GLOB.prey_digested_roundstat++
|
||||
if(patient == T)
|
||||
patient_laststat = null
|
||||
patient = null
|
||||
T.mind?.vore_death = TRUE
|
||||
qdel(T)
|
||||
|
||||
//Pick a random item to deal with (if there are any)
|
||||
|
||||
@@ -680,7 +680,8 @@ var/global/list/robot_modules = list(
|
||||
src.emag.reagents = R
|
||||
R.my_atom = src.emag
|
||||
R.add_reagent("beer2", 50)
|
||||
src.emag.name = "Mickey Finn's Special Brew"
|
||||
src.emag.name = "Auntie Hong's Final Sip"
|
||||
src.emag.desc = "A bottle of very special mix of alcohol and poison. Some may argue that there's alcohol to die for, but Auntie Hong took it to next level."
|
||||
|
||||
/obj/item/weapon/robot_module/robot/clerical/general
|
||||
name = "clerical robot module"
|
||||
|
||||
@@ -1084,13 +1084,7 @@
|
||||
|
||||
src.modules += new /obj/item/weapon/tray/robotray(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/borghypo/service(src)
|
||||
src.emag = new /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer(src)
|
||||
|
||||
var/datum/reagents/N = new/datum/reagents(50)
|
||||
src.emag.reagents = N
|
||||
N.my_atom = src.emag
|
||||
N.add_reagent("beer2", 50)
|
||||
src.emag.name = "Mickey Finn's Special Brew"
|
||||
R.icon = 'icons/mob/widerobot_colors_vr.dmi'
|
||||
R.wideborg_dept = 'icons/mob/widerobot_colors_vr.dmi'
|
||||
R.hands.icon = 'icons/mob/screen1_robot_vr.dmi'
|
||||
@@ -1110,9 +1104,6 @@
|
||||
/obj/item/weapon/robot_module/robot/booze/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
|
||||
var/obj/item/weapon/reagent_containers/food/condiment/enzyme/E = locate() in src.modules
|
||||
E.reagents.add_reagent("enzyme", 2 * amount)
|
||||
if(src.emag)
|
||||
var/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer/B = src.emag
|
||||
B.reagents.add_reagent("beer2", 2 * amount)
|
||||
|
||||
//CHOMP addition start BORGHYPO
|
||||
/obj/item/weapon/reagent_containers/borghypo/service/booze
|
||||
@@ -1206,4 +1197,3 @@
|
||||
R.verbs -= /mob/living/proc/shred_limb
|
||||
R.verbs -= /mob/living/silicon/robot/proc/rest_style
|
||||
..()
|
||||
// CH changes - Unity Hound end
|
||||
|
||||
@@ -64,6 +64,8 @@
|
||||
/mob/living/simple_mob/proc/add_eyes()
|
||||
if(!eye_layer)
|
||||
eye_layer = image(icon, "[icon_state]-eyes")
|
||||
if(custom_eye_color)
|
||||
eye_layer.color = custom_eye_color
|
||||
eye_layer.plane = PLANE_LIGHTING_ABOVE
|
||||
eye_layer.appearance_flags = appearance_flags //VOREStation Edit. Make eye overlays respect the mob's scaling settings.
|
||||
add_overlay(eye_layer)
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
var/image/modifier_overlay = null // Holds overlays from modifiers.
|
||||
var/image/eye_layer = null // Holds the eye overlay.
|
||||
var/has_eye_glow = FALSE // If true, adds an overlay over the lighting plane for [icon_state]-eyes.
|
||||
var/custom_eye_color = null
|
||||
attack_icon = 'icons/effects/effects.dmi' //Just the default, played like the weapon attack anim
|
||||
attack_icon_state = "slash" //Just the default
|
||||
|
||||
|
||||
@@ -265,6 +265,7 @@
|
||||
"The juices pooling beneath you sizzle against your sore skin.",
|
||||
"The churning walls slowly pulverize you into meaty nutrients.",
|
||||
"The stomach glorps and gurgles as it tries to work you into slop.")
|
||||
can_be_drop_pred = TRUE // Mobs will eat anyone that decides to drop/slip into them by default.
|
||||
|
||||
/mob/living/simple_mob/Bumped(var/atom/movable/AM, yes)
|
||||
if(tryBumpNom(AM))
|
||||
|
||||
@@ -85,7 +85,9 @@ GLOBAL_VAR_INIT(jellyfish_count, 0)
|
||||
|
||||
|
||||
/mob/living/simple_mob/vore/alienanimals/space_jellyfish/init_vore()
|
||||
..()
|
||||
if(!voremob_loaded)
|
||||
return
|
||||
.=..()
|
||||
var/obj/belly/B = vore_selected
|
||||
B.name = "internal chamber"
|
||||
B.desc = "It's smooth and translucent. You can see the world around you distort and wobble with the movement of the space jellyfish. It floats casually, while the delicate flesh seems to form to you. It's surprisingly cool, and flickers with its own light. You're on display for all to see, trapped within the confines of this strange space alien!"
|
||||
|
||||
@@ -110,12 +110,13 @@
|
||||
violent_breakthrough = TRUE
|
||||
|
||||
/mob/living/simple_mob/vore/alienanimals/startreader/apply_melee_effects(mob/living/L)
|
||||
if(!isliving(L))
|
||||
return
|
||||
if(L.weakened) //Don't stun people while they're already stunned! That's SILLY!
|
||||
return
|
||||
if(prob(15))
|
||||
if(isliving(L))
|
||||
visible_message("<span class='danger'>\The [src] trips \the [L]!</span>!")
|
||||
L.weakened += rand(1,10)
|
||||
visible_message("<span class='danger'>\The [src] trips \the [L]!</span>!")
|
||||
L.weakened += rand(1,10)
|
||||
|
||||
/mob/living/simple_mob/vore/alienanimals/startreader/Life()
|
||||
. = ..()
|
||||
|
||||
@@ -13,10 +13,10 @@ GLOBAL_VAR_INIT(queen_amount, 0) //We only gonna want 1 queen in the world.
|
||||
faction = "notmetroid"
|
||||
maxHealth = 400
|
||||
health = 400
|
||||
melee_damage_lower = 2
|
||||
melee_damage_upper = 6
|
||||
melee_damage_lower = 0
|
||||
melee_damage_upper = 0
|
||||
movement_cooldown = 6
|
||||
harm_intent_damage = 3
|
||||
harm_intent_damage = 2
|
||||
armor = list(
|
||||
"melee" = 50,
|
||||
"bullet" = -90,
|
||||
|
||||
@@ -0,0 +1,347 @@
|
||||
#define GA_ADS 0
|
||||
#define GA_CALLDOWN 1
|
||||
#define GA_SPEEDUP 2
|
||||
#define GA_ILLUSION 3
|
||||
#define GA_BULLETHELL 4
|
||||
#define GA_LINES 5
|
||||
#define GA_CONFUSION 6
|
||||
|
||||
/mob/living/simple_mob/glitch_boss
|
||||
name = "CLICK ME!!!"
|
||||
desc = "WELCOME TO %location_data% THIS IS YOUR HOME NOW PLEASE INPUT CREDIT CARD CREDENTIALS BELOW"
|
||||
tt_desc = "BEST TOOLBAR PROVIDER SINCE 2098"
|
||||
icon = 'icons/mob/unknown_boss.dmi'
|
||||
icon_state = "glitch_boss"
|
||||
icon_living = "glitch_boss"
|
||||
icon_dead = "glitch_boss_dead"
|
||||
|
||||
faction = "MATH"
|
||||
|
||||
maxHealth = 2000
|
||||
health = 2000
|
||||
evasion = -75 // Its hitbox is broken ;_;
|
||||
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 40
|
||||
attack_armor_pen = 20
|
||||
|
||||
base_attack_cooldown = 2.5 SECONDS
|
||||
|
||||
projectiletype = /obj/item/projectile/energy/slow_orb
|
||||
projectilesound = 'sound/effects/uncloak.ogg'
|
||||
|
||||
special_attack_min_range = 0
|
||||
special_attack_max_range = 10
|
||||
special_attack_cooldown = 20 SECONDS
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/ranged/aggressive/bossmob_glitch
|
||||
|
||||
var/next_special_attack = GA_ADS
|
||||
var/recently_used_attack = GA_SPEEDUP
|
||||
var/all_special_attacks = list(GA_ADS, GA_CALLDOWN, GA_LINES, GA_BULLETHELL, GA_ILLUSION, GA_CONFUSION, GA_SPEEDUP)
|
||||
|
||||
loot_list = list(/obj/item/device/nif/glitch = 100)
|
||||
|
||||
/obj/item/projectile/energy/slow_orb
|
||||
name = "TROJAN"
|
||||
icon_state = "glitch"
|
||||
damage = 50
|
||||
speed = 6
|
||||
damage_type = ELECTROCUTE
|
||||
agony = 15
|
||||
check_armour = "energy"
|
||||
armor_penetration = 40
|
||||
|
||||
fire_sound = 'sound/effects/uncloak.ogg'
|
||||
combustion = TRUE
|
||||
|
||||
/mob/living/simple_mob/glitch_boss/death(gibbed, deathmessage="suddenly %runtime error in unknown.dm, line 56%")
|
||||
. = ..()
|
||||
new /obj/effect/temp_visual/glitch(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_mob/glitch_boss/updatehealth()
|
||||
. = ..()
|
||||
|
||||
if(health < maxHealth*0.25)
|
||||
special_attack_cooldown = 5 SECONDS
|
||||
icon_state = "glitch_boss_25"
|
||||
icon_living = "glitch_boss_25"
|
||||
else if(health < maxHealth*0.5)
|
||||
special_attack_cooldown = 10 SECONDS
|
||||
icon_state = "glitch_boss_50"
|
||||
icon_living = "glitch_boss_50"
|
||||
else if (health < maxHealth*0.75)
|
||||
special_attack_cooldown = 15 SECONDS
|
||||
icon_state = "glitch_boss_75"
|
||||
icon_living = "glitch_boss_75"
|
||||
|
||||
/mob/living/simple_mob/glitch_boss/proc/create_illusions(atom/A)
|
||||
var/list/possible_turfs = list()
|
||||
for(var/turf/T in view(4, src))
|
||||
if(T.density || T == get_turf(src)) // Our turf is always eligible
|
||||
continue
|
||||
var/blocked = FALSE
|
||||
for(var/atom/movable/AM in T)
|
||||
if(AM.density)
|
||||
blocked = TRUE
|
||||
break
|
||||
if(!blocked)
|
||||
possible_turfs += T
|
||||
|
||||
if(possible_turfs.len <= 1)
|
||||
return
|
||||
|
||||
var/illusion_amount = min(possible_turfs.len, 4) // Not including our spot
|
||||
var/list/actual_turfs = list()
|
||||
actual_turfs += get_turf(src)
|
||||
for(var/i = 0, i < illusion_amount, i++)
|
||||
var/turf_to_add = pick(possible_turfs)
|
||||
actual_turfs += turf_to_add
|
||||
possible_turfs -= turf_to_add
|
||||
|
||||
for(var/i = 0, i < illusion_amount, i++)
|
||||
var/chosen_turf = pick(actual_turfs)
|
||||
var/type_to_spawn = prob(15) ? /mob/living/simple_mob/glitch_boss_fake/strong : /mob/living/simple_mob/glitch_boss_fake
|
||||
var/mob/living/simple_mob/newmob = new type_to_spawn(chosen_turf)
|
||||
newmob.icon_living = src.icon_living
|
||||
newmob.icon_state = src.icon_state
|
||||
new /obj/effect/temp_visual/glitch(chosen_turf)
|
||||
actual_turfs -= chosen_turf
|
||||
|
||||
var/move_turf = pick(actual_turfs)
|
||||
src.forceMove(move_turf)
|
||||
new /obj/effect/temp_visual/glitch(move_turf)
|
||||
|
||||
/mob/living/simple_mob/glitch_boss/proc/make_ads(atom/A)
|
||||
var/list/potential_targets = list()
|
||||
for(var/mob/living/mob in view(7, src))
|
||||
if(mob.client && mob.faction != faction)
|
||||
potential_targets += mob
|
||||
if(potential_targets.len)
|
||||
var/iteration = clamp(potential_targets.len, 1, 4)
|
||||
for(var/i = 0, i < iteration, i++)
|
||||
if(!(potential_targets.len))
|
||||
break
|
||||
var/mob/target = pick(potential_targets)
|
||||
potential_targets -= target
|
||||
if(target.client)
|
||||
target.client.create_fake_ad_popup_multiple(/obj/screen/popup/default, 5)
|
||||
|
||||
/mob/living/simple_mob/glitch_boss/proc/bombardment(atom/A)
|
||||
var/list/potential_targets = ai_holder.list_targets()
|
||||
for(var/atom/entry in potential_targets)
|
||||
if(istype(entry, /mob/living/simple_mob/glitch_boss_fake))
|
||||
potential_targets -= entry
|
||||
if(potential_targets.len)
|
||||
var/iteration = clamp(potential_targets.len, 1, 3)
|
||||
for(var/i = 0, i < iteration, i++)
|
||||
if(!(potential_targets.len))
|
||||
break
|
||||
var/mob/target = pick(potential_targets)
|
||||
potential_targets -= target
|
||||
spawn_bombardments(target)
|
||||
|
||||
/mob/living/simple_mob/glitch_boss/proc/spawn_bombardments(atom/target)
|
||||
var/list/bomb_range = block(locate(target.x-1, target.y-1, target.z), locate(target.x+1, target.y+1, target.z))
|
||||
new /obj/effect/calldown_attack(get_turf(target))
|
||||
bomb_range -= get_turf(target)
|
||||
for(var/i = 0, i < 4, i++)
|
||||
var/turf/T = pick(bomb_range)
|
||||
new /obj/effect/calldown_attack(T)
|
||||
bomb_range -= T
|
||||
|
||||
/mob/living/simple_mob/glitch_boss/proc/bomb_lines(atom/A)
|
||||
var/list/potential_targets = ai_holder.list_targets()
|
||||
for(var/atom/entry in potential_targets)
|
||||
if(istype(entry, /mob/living/simple_mob/glitch_boss_fake))
|
||||
potential_targets -= entry
|
||||
if(potential_targets.len)
|
||||
var/iteration = clamp(potential_targets.len, 1, 3)
|
||||
for(var/i = 0, i < iteration, i++)
|
||||
if(!(potential_targets.len))
|
||||
break
|
||||
var/mob/target = pick(potential_targets)
|
||||
potential_targets -= target
|
||||
spawn_lines(target)
|
||||
|
||||
/mob/living/simple_mob/glitch_boss/proc/spawn_lines(atom/target)
|
||||
var/alignment = rand(1,2) // 1 for vertical, 2 for horizontal
|
||||
var/list/line_range = list()
|
||||
var/turf/T = get_turf(target)
|
||||
line_range += T
|
||||
for(var/i = 1, i <= 7, i++)
|
||||
switch(alignment)
|
||||
if(1)
|
||||
if(T.x-i > 0)
|
||||
line_range += locate(T.x-i, T.y, T.z)
|
||||
if(T.x+i <= world.maxx)
|
||||
line_range += locate(T.x+i, T.y, T.z)
|
||||
if(2)
|
||||
if(T.y-i > 0)
|
||||
line_range += locate(T.x, T.y-i, T.z)
|
||||
if(T.y+i <= world.maxy)
|
||||
line_range += locate(T.x, T.y+i, T.z)
|
||||
for(var/turf/dropspot in line_range)
|
||||
new /obj/effect/calldown_attack(dropspot)
|
||||
|
||||
/mob/living/simple_mob/glitch_boss/proc/confuse_inflict(atom/A)
|
||||
var/list/potential_targets = ai_holder.list_targets()
|
||||
for(var/atom/entry in potential_targets)
|
||||
if(istype(entry, /mob/living/simple_mob/glitch_boss_fake))
|
||||
potential_targets -= entry
|
||||
if(potential_targets.len < 2)
|
||||
return
|
||||
potential_targets -= A
|
||||
var/mob/living/target
|
||||
while(!target && potential_targets.len)
|
||||
var/candidate = pick(potential_targets)
|
||||
if(isliving(candidate))
|
||||
target = candidate
|
||||
break
|
||||
else
|
||||
potential_targets -= candidate
|
||||
|
||||
if(target && istype(target))
|
||||
if(target.client)
|
||||
to_chat(target, "<span class='critical'>You feel as though you are losing your sense of direction! Brace yourself!</span>")
|
||||
new /obj/effect/temp_visual/pre_confuse(get_turf(target))
|
||||
spawn(5 SECONDS)
|
||||
if(target)
|
||||
target.Confuse(3)
|
||||
if(target.client)
|
||||
to_chat(target, "<span class='critical'>You feel confused!</span>")
|
||||
new /obj/effect/temp_visual/confuse(get_turf(target))
|
||||
|
||||
/mob/living/simple_mob/glitch_boss/proc/bullethell(atom/A)
|
||||
set waitfor = FALSE
|
||||
|
||||
var/sd = dir2angle(dir)
|
||||
var/list/offsets = list(45, 45, 20, 10)
|
||||
|
||||
for(var/i = 0, i<4, i++)
|
||||
for(var/j = 0, j <4, j++)
|
||||
var/obj/item/projectile/energy/slow_orb/shot = new(get_turf(src))
|
||||
shot.firer = src
|
||||
shot.fire(sd)
|
||||
sd += 90
|
||||
sd += pick(offsets)
|
||||
sleep(20)
|
||||
|
||||
/mob/living/simple_mob/glitch_boss/proc/speed_up_boost(atom/A)
|
||||
if(base_attack_cooldown == initial(base_attack_cooldown))
|
||||
base_attack_cooldown = 1 SECOND
|
||||
var/duration = (special_attack_cooldown == 5 SECONDS) ? 5 SECONDS : 10 SECONDS
|
||||
spawn(duration)
|
||||
base_attack_cooldown = initial(base_attack_cooldown)
|
||||
|
||||
/mob/living/simple_mob/glitch_boss/do_special_attack(atom/A)
|
||||
. = TRUE
|
||||
recently_used_attack = next_special_attack
|
||||
switch(next_special_attack)
|
||||
if(GA_ADS)
|
||||
make_ads(A)
|
||||
if(GA_CALLDOWN)
|
||||
bombardment(A)
|
||||
if(GA_LINES)
|
||||
bomb_lines(A)
|
||||
if(GA_BULLETHELL)
|
||||
bullethell(A)
|
||||
if(GA_ILLUSION)
|
||||
create_illusions(A)
|
||||
if(GA_CONFUSION)
|
||||
confuse_inflict(A)
|
||||
if(GA_SPEEDUP)
|
||||
speed_up_boost(A)
|
||||
|
||||
/datum/ai_holder/simple_mob/ranged/aggressive/bossmob_glitch
|
||||
wander = TRUE
|
||||
pointblank = TRUE
|
||||
intelligence_level = AI_SMART
|
||||
vision_range = 10
|
||||
closest_distance = 4
|
||||
|
||||
/datum/ai_holder/simple_mob/ranged/bossmob_glitch/pre_special_attack(atom/A)
|
||||
var/mob/living/simple_mob/glitch_boss/GB
|
||||
if(istype(holder, /mob/living/simple_mob/glitch_boss))
|
||||
GB = holder
|
||||
if(GB)
|
||||
if(isliving(A) || ismecha(A))
|
||||
var/list/possible_attacks = list()
|
||||
possible_attacks += GB.all_special_attacks - GB.recently_used_attack
|
||||
var/illusion_count = 0
|
||||
var/list/potential_targets = list_targets()
|
||||
for(var/atom/illusion_maybe in potential_targets)
|
||||
if(istype(illusion_maybe, /mob/living/simple_mob/glitch_boss_fake))
|
||||
illusion_count++
|
||||
potential_targets -= illusion_maybe
|
||||
if(potential_targets.len < 2)
|
||||
possible_attacks -= GA_CONFUSION
|
||||
possible_attacks += GA_SPEEDUP // Double chance when fighting single target
|
||||
if(illusion_count > 4)
|
||||
possible_attacks -= GA_ILLUSION
|
||||
if(!(possible_attacks.len))
|
||||
GB.next_special_attack = GA_BULLETHELL
|
||||
else
|
||||
GB.next_special_attack = pick(possible_attacks)
|
||||
else
|
||||
GB.next_special_attack = GA_BULLETHELL
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_mob/glitch_boss_fake
|
||||
name = "CLICK ME!!!"
|
||||
desc = "WELCOME TO %location_data% THIS IS YOUR HOME NOW PLEASE INPUT CREDIT CARD CREDENTIALS BELOW"
|
||||
tt_desc = "BEST TOOLBAR PROVIDER SINCE 2098"
|
||||
icon = 'icons/mob/unknown_boss.dmi'
|
||||
icon_state = "glitch_boss"
|
||||
icon_living = "glitch_boss"
|
||||
icon_dead = "glitch_boss_dead"
|
||||
faction = "MATH"
|
||||
|
||||
maxHealth = 20
|
||||
health = 20
|
||||
evasion = -75
|
||||
|
||||
melee_damage_lower = 0
|
||||
melee_damage_upper = 0
|
||||
attack_armor_pen = 0
|
||||
|
||||
base_attack_cooldown = 2.5 SECONDS
|
||||
|
||||
projectiletype = /obj/item/projectile/energy/slow_orb_fake
|
||||
projectilesound = 'sound/effects/uncloak.ogg'
|
||||
|
||||
var/prob_respawn = 15
|
||||
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/ranged/aggressive/bossmob_glitch_fake
|
||||
|
||||
/mob/living/simple_mob/glitch_boss_fake/strong
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
prob_respawn = 60
|
||||
|
||||
/mob/living/simple_mob/glitch_boss_fake/death(gibbed, deathmessage="disappears in cloud of static.")
|
||||
new /obj/effect/temp_visual/glitch(get_turf(src))
|
||||
if(prob(prob_respawn))
|
||||
new /mob/living/simple_mob/glitch_boss_fake(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/projectile/energy/slow_orb_fake
|
||||
name = "TROJAN"
|
||||
icon_state = "glitch"
|
||||
damage = 0
|
||||
speed = 6
|
||||
damage_type = ELECTROCUTE
|
||||
agony = 0
|
||||
check_armour = "energy"
|
||||
armor_penetration = 0
|
||||
|
||||
fire_sound = 'sound/effects/uncloak.ogg'
|
||||
combustion = TRUE
|
||||
|
||||
/datum/ai_holder/simple_mob/ranged/aggressive/bossmob_glitch_fake //Same AI, but without special attack calculation stuff
|
||||
wander = TRUE
|
||||
pointblank = TRUE
|
||||
intelligence_level = AI_SMART
|
||||
vision_range = 9
|
||||
closest_distance = 4
|
||||
@@ -29,6 +29,7 @@
|
||||
icon = 'icons/mob/vore.dmi'
|
||||
|
||||
movement_cooldown = 4 //fast as fucc boie.
|
||||
can_be_drop_pred = 1 //They can tongue vore.
|
||||
|
||||
meat_amount = 4
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
|
||||
@@ -39,6 +40,10 @@
|
||||
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/melee
|
||||
|
||||
special_attack_min_range = 1
|
||||
special_attack_max_range = 5
|
||||
special_attack_cooldown = 100
|
||||
|
||||
// Pepe is love, not hate.
|
||||
/mob/living/simple_mob/vore/aggressive/frog/New()
|
||||
if(rand(1,1000000) == 1)
|
||||
@@ -46,6 +51,21 @@
|
||||
desc = "You found a rare Pepe. Screenshot for good luck."
|
||||
..()
|
||||
|
||||
/mob/living/simple_mob/vore/aggressive/frog/do_special_attack(atom/A)
|
||||
set_AI_busy(TRUE)
|
||||
do_windup_animation(A, 20)
|
||||
addtimer(CALLBACK(src, .proc/chargeend, A), 20)
|
||||
|
||||
/mob/living/simple_mob/vore/aggressive/frog/proc/chargeend(atom/A)
|
||||
if(stat) //you are dead
|
||||
set_AI_busy(FALSE)
|
||||
return
|
||||
playsound(src, 'sound/vore/sunesound/pred/schlorp.ogg', 25)
|
||||
var/obj/item/projectile/beam/appendage/appendage_attack = new /obj/item/projectile/beam/appendage(get_turf(loc))
|
||||
appendage_attack.old_style_target(A, src)
|
||||
appendage_attack.launch_projectile(A, BP_TORSO, src)
|
||||
set_AI_busy(FALSE)
|
||||
|
||||
// Activate Noms!
|
||||
/mob/living/simple_mob/vore/aggressive/frog
|
||||
vore_active = 1
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user