mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Merge remote-tracking branch 'upstream/dev-freeze' into dev
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
icon_state = "motion0"
|
||||
layer = 3
|
||||
anchored = 1.0
|
||||
use_power = 1
|
||||
idle_power_usage = 10
|
||||
var/uses = 20
|
||||
var/disabled = 1
|
||||
var/lethal = 0
|
||||
@@ -13,6 +15,7 @@
|
||||
var/cooldown_on = 0
|
||||
req_access = list(access_ai_upload)
|
||||
|
||||
|
||||
/obj/machinery/ai_slipper/New()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 100
|
||||
active_power_usage = 2000
|
||||
|
||||
var/list/machine_recipes
|
||||
var/list/stored_material = list("metal" = 0, "glass" = 0)
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
var/datum/wires/autolathe/wires = null
|
||||
|
||||
|
||||
/obj/machinery/autolathe/New()
|
||||
|
||||
..()
|
||||
@@ -233,8 +234,7 @@
|
||||
return
|
||||
|
||||
busy = 1
|
||||
//This needs some work.
|
||||
use_power(max(2000, (making.power_use*multiplier)))
|
||||
update_use_power(2)
|
||||
|
||||
//Check if we still have the materials.
|
||||
for(var/material in making.resources)
|
||||
@@ -253,6 +253,7 @@
|
||||
sleep(build_time)
|
||||
|
||||
busy = 0
|
||||
update_use_power(1)
|
||||
|
||||
//Sanity check.
|
||||
if(!making || !src) return
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
var/build_eff = 1
|
||||
var/eat_eff = 1
|
||||
|
||||
|
||||
/obj/machinery/biogenerator/New()
|
||||
..()
|
||||
var/datum/reagents/R = new/datum/reagents(1000)
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
//These machines are mostly just here for debugging/spawning. Skeletons of the feature to come.
|
||||
|
||||
/obj/machinery/bioprinter
|
||||
name = "bioprinter"
|
||||
name = "organ bioprinter"
|
||||
desc = "It's a machine that grows replacement organs."
|
||||
icon = 'icons/obj/surgery.dmi'
|
||||
|
||||
anchored = 1
|
||||
density = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 40
|
||||
|
||||
icon_state = "bioprinter"
|
||||
|
||||
@@ -41,33 +43,45 @@
|
||||
if(prints_prosthetics)
|
||||
O.robotic = 2
|
||||
else if(loaded_dna)
|
||||
visible_message("The printer would be using the DNA sample if it was coded.")
|
||||
//TODO: Copy DNA hash or donor reference over to new organ.
|
||||
visible_message("<span class='notice'>The printer injects stored DNA in used biomass.</span>.")
|
||||
var/datum/organ/internal/I = new O.organ_type
|
||||
I.transplant_data = list()
|
||||
var/mob/living/carbon/C = loaded_dna["donor"]
|
||||
I.transplant_data["species"] = C.species.name
|
||||
I.transplant_data["blood_type"] = loaded_dna["blood_type"]
|
||||
I.transplant_data["blood_DNA"] = loaded_dna["blood_DNA"]
|
||||
O.organ_data = I
|
||||
I.organ_holder = O
|
||||
|
||||
visible_message("The bioprinter spits out a new organ.")
|
||||
|
||||
visible_message("<span class='info'>The bioprinter spits out a new organ.")
|
||||
|
||||
else
|
||||
user << "There is not enough matter in the printer."
|
||||
user << "<span class='warning'>There is not enough matter in the printer.</span>"
|
||||
|
||||
/obj/machinery/bioprinter/attackby(obj/item/weapon/W, mob/user)
|
||||
|
||||
// DNA sample from syringe.
|
||||
if(!prints_prosthetics && istype(W,/obj/item/weapon/reagent_containers/syringe))
|
||||
user << "You inject the blood sample into the bioprinter, but it isn't coded yet."
|
||||
var/obj/item/weapon/reagent_containers/syringe/S = W
|
||||
var/datum/reagent/blood/injected = locate() in S.reagents.reagent_list //Grab some blood
|
||||
if(injected && injected.data)
|
||||
loaded_dna = injected.data
|
||||
user << "<span class='info'>You inject the blood sample into the bioprinter.</span>"
|
||||
return
|
||||
// Meat for biomass.
|
||||
else if(!prints_prosthetics && istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat))
|
||||
user << "\blue \The [src] processes \the [W]."
|
||||
stored_matter += 50
|
||||
user.drop_item()
|
||||
user << "<span class='info'>\The [src] processes \the [W]. Levels of stored biomass now: [stored_matter]</span>"
|
||||
del(W)
|
||||
return
|
||||
// Steel for matter.
|
||||
else if(prints_prosthetics && istype(W, /obj/item/stack/sheet/metal))
|
||||
var/obj/item/stack/sheet/metal/M = W
|
||||
user << "\blue \The [src] processes \the [W]."
|
||||
stored_matter += M.amount * 10
|
||||
user.drop_item()
|
||||
user << "<span class='info'>\The [src] processes \the [W]. Levels of stored matter now: [stored_matter]</span>"
|
||||
del(W)
|
||||
return
|
||||
else
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
idle_power_usage = 2
|
||||
active_power_usage = 4
|
||||
|
||||
|
||||
/obj/machinery/button/attack_ai(mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
idle_power_usage = 2
|
||||
active_power_usage = 4
|
||||
|
||||
|
||||
/obj/machinery/door_control/attack_ai(mob/user as mob)
|
||||
if(wires & 2)
|
||||
return src.attack_hand(user)
|
||||
|
||||
@@ -13,9 +13,6 @@ var/list/doppler_arrays = list()
|
||||
doppler_arrays -= src
|
||||
..()
|
||||
|
||||
/obj/machinery/doppler_array/process()
|
||||
return PROCESS_KILL
|
||||
|
||||
/obj/machinery/doppler_array/proc/sense_explosion(var/x0,var/y0,var/z0,var/devastation_range,var/heavy_impact_range,var/light_impact_range,var/took)
|
||||
if(stat & NOPOWER) return
|
||||
if(z != z0) return
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
var/strength = 10 //How weakened targets are when flashed.
|
||||
var/base_state = "mflash"
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 2
|
||||
|
||||
/obj/machinery/flasher/portable //Portable version of the flasher. Only flashes when anchored
|
||||
name = "portable flasher"
|
||||
@@ -133,7 +135,7 @@
|
||||
active = 1
|
||||
icon_state = "launcheract"
|
||||
|
||||
for(var/obj/machinery/flasher/M in world)
|
||||
for(var/obj/machinery/flasher/M in machines)
|
||||
if(M.id == src.id)
|
||||
spawn()
|
||||
M.flash()
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
icon = 'icons/obj/holosign.dmi'
|
||||
icon_state = "sign_off"
|
||||
layer = 4
|
||||
use_power = 1
|
||||
idle_power_usage = 2
|
||||
active_power_usage = 4
|
||||
var/lit = 0
|
||||
var/id = null
|
||||
var/on_icon = "sign_on"
|
||||
@@ -14,12 +16,9 @@
|
||||
if (stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
lit = !lit
|
||||
use_power = lit ? 1 : 0
|
||||
use_power = lit ? 2 : 1
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/holosign/process()
|
||||
return
|
||||
|
||||
/obj/machinery/holosign/update_icon()
|
||||
if (!lit)
|
||||
icon_state = "sign_off"
|
||||
|
||||
@@ -53,6 +53,10 @@
|
||||
var/last_spark = 0
|
||||
var/base_state = "migniter"
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 2
|
||||
active_power_usage = 4
|
||||
|
||||
|
||||
/obj/machinery/sparker/New()
|
||||
..()
|
||||
@@ -129,12 +133,12 @@
|
||||
active = 1
|
||||
icon_state = "launcheract"
|
||||
|
||||
for(var/obj/machinery/sparker/M in world)
|
||||
for(var/obj/machinery/sparker/M in machines)
|
||||
if (M.id == src.id)
|
||||
spawn( 0 )
|
||||
M.ignite()
|
||||
|
||||
for(var/obj/machinery/igniter/M in world)
|
||||
for(var/obj/machinery/igniter/M in machines)
|
||||
if(M.id == src.id)
|
||||
use_power(50)
|
||||
M.on = !( M.on )
|
||||
|
||||
@@ -16,6 +16,9 @@ datum/track/New(var/title_name, var/audio)
|
||||
anchored = 1
|
||||
density = 1
|
||||
power_channel = EQUIP
|
||||
use_power = 1
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 100
|
||||
|
||||
var/playing = 0
|
||||
|
||||
@@ -32,6 +35,7 @@ datum/track/New(var/title_name, var/audio)
|
||||
new/datum/track("Trai`Tor", 'sound/music/traitor.ogg'),
|
||||
)
|
||||
|
||||
|
||||
/obj/machinery/media/jukebox/Del()
|
||||
StopPlaying()
|
||||
..()
|
||||
@@ -190,6 +194,7 @@ datum/track/New(var/title_name, var/audio)
|
||||
|
||||
related_area.forced_ambience = null
|
||||
playing = 0
|
||||
update_use_power(1)
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -207,4 +212,5 @@ datum/track/New(var/title_name, var/audio)
|
||||
related_area.play_ambience(related_area)
|
||||
|
||||
playing = 1
|
||||
update_use_power(2)
|
||||
update_icon()
|
||||
|
||||
@@ -126,7 +126,10 @@ Class Procs:
|
||||
..()
|
||||
|
||||
/obj/machinery/process()//If you dont use process or power why are you here
|
||||
return PROCESS_KILL
|
||||
if(!(use_power || idle_power_usage || active_power_usage))
|
||||
return PROCESS_KILL
|
||||
|
||||
return
|
||||
|
||||
/obj/machinery/emp_act(severity)
|
||||
if(use_power && stat == 0)
|
||||
|
||||
@@ -39,7 +39,4 @@
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
drive()
|
||||
..(severity)
|
||||
|
||||
/obj/machinery/mass_driver/process()
|
||||
return
|
||||
..(severity)
|
||||
@@ -86,7 +86,7 @@
|
||||
|
||||
/obj/machinery/computer/teleporter/attack_hand(user as mob)
|
||||
if(..()) return
|
||||
|
||||
|
||||
/* Ghosts can't use this one because it's a direct selection */
|
||||
if(istype(user, /mob/dead/observer)) return
|
||||
|
||||
@@ -175,6 +175,7 @@
|
||||
active_power_usage = 2000
|
||||
var/obj/machinery/computer/teleporter/com
|
||||
|
||||
|
||||
/obj/machinery/teleport/hub/New()
|
||||
..()
|
||||
underlays.Cut()
|
||||
@@ -335,6 +336,8 @@
|
||||
if (com)
|
||||
com.icon_state = "tele1"
|
||||
use_power(5000)
|
||||
update_use_power(2)
|
||||
com.update_use_power(2)
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message("\blue Teleporter engaged!", 2)
|
||||
src.add_fingerprint(usr)
|
||||
@@ -348,6 +351,8 @@
|
||||
if (com)
|
||||
com.icon_state = "tele0"
|
||||
com.accurate = 0
|
||||
com.update_use_power(1)
|
||||
update_use_power(1)
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message("\blue Teleporter disengaged!", 2)
|
||||
src.add_fingerprint(usr)
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
/client/Stat()
|
||||
. = ..()
|
||||
if(statpanel("Examine"))
|
||||
if(usr && statpanel("Examine"))
|
||||
stat(null,"[description_holders["icon"]] <font size='5'>[description_holders["name"]]</font>") //The name, written in big letters.
|
||||
stat(null,"[description_holders["desc"]]") //the default examine text.
|
||||
if(description_holders["info"])
|
||||
|
||||
@@ -319,7 +319,7 @@ emp_act
|
||||
if (O.throw_source)
|
||||
var/distance = get_dist(O.throw_source, loc)
|
||||
miss_chance = max(15*(distance-2), 0)
|
||||
zone = get_zone_with_miss_chance(zone, src, miss_chance)
|
||||
zone = get_zone_with_miss_chance(zone, src, miss_chance, ranged_attack=1)
|
||||
|
||||
if(!zone)
|
||||
visible_message("\blue \The [O] misses [src] narrowly!")
|
||||
|
||||
@@ -532,7 +532,7 @@
|
||||
del(G)
|
||||
if(GRAB_NECK)
|
||||
//If the you move when grabbing someone then it's easier for them to break free. Same if the affected mob is immune to stun.
|
||||
if (((world.time - G.assailant.l_move_time < 20 || !L.stunned) && prob(15)) || prob(3))
|
||||
if (((world.time - G.assailant.l_move_time < 30 || !L.stunned) && prob(15)) || prob(3))
|
||||
L.visible_message("<span class='warning'>[L] has broken free of [G.assailant]'s headlock!</span>")
|
||||
del(G)
|
||||
if(resisting)
|
||||
|
||||
@@ -236,20 +236,26 @@ var/list/global/organ_rel_size = list(
|
||||
// Emulates targetting a specific body part, and miss chances
|
||||
// May return null if missed
|
||||
// miss_chance_mod may be negative.
|
||||
/proc/get_zone_with_miss_chance(zone, var/mob/target, var/miss_chance_mod = 0)
|
||||
/proc/get_zone_with_miss_chance(zone, var/mob/target, var/miss_chance_mod = 0, var/ranged_attack=0)
|
||||
zone = check_zone(zone)
|
||||
|
||||
// you can only miss if your target is standing and not restrained
|
||||
if(!target.buckled && !target.lying)
|
||||
var/miss_chance = 10
|
||||
if (zone in base_miss_chance)
|
||||
miss_chance = base_miss_chance[zone]
|
||||
miss_chance = max(miss_chance + miss_chance_mod, 0)
|
||||
if(prob(miss_chance))
|
||||
if(prob(70))
|
||||
return null
|
||||
return pick(base_miss_chance)
|
||||
|
||||
// you cannot miss if your target is prone or restrained
|
||||
if(target.buckled || target.lying)
|
||||
return zone
|
||||
// if your target is being grabbed aggressively by someone you cannot miss either
|
||||
if(!ranged_attack)
|
||||
for(var/obj/item/weapon/grab/G in target.grabbed_by)
|
||||
if(G.state >= GRAB_AGGRESSIVE)
|
||||
return zone
|
||||
|
||||
var/miss_chance = 10
|
||||
if (zone in base_miss_chance)
|
||||
miss_chance = base_miss_chance[zone]
|
||||
miss_chance = max(miss_chance + miss_chance_mod, 0)
|
||||
if(prob(miss_chance))
|
||||
if(prob(70))
|
||||
return null
|
||||
return pick(base_miss_chance)
|
||||
return zone
|
||||
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
/obj/item/organ/proc/update()
|
||||
|
||||
if(!organ_data)
|
||||
organ_data = new /datum/organ/internal()
|
||||
organ_data = new organ_type()
|
||||
|
||||
if(robotic)
|
||||
organ_data.robotic = robotic
|
||||
@@ -93,6 +93,7 @@
|
||||
organ_tag = "heart"
|
||||
fresh = 6 // Juicy.
|
||||
dead_icon = "heart-off"
|
||||
organ_type = /datum/organ/internal/heart
|
||||
|
||||
/obj/item/organ/lungs
|
||||
name = "lungs"
|
||||
@@ -101,6 +102,7 @@
|
||||
prosthetic_name = "gas exchange system"
|
||||
prosthetic_icon = "lungs-prosthetic"
|
||||
organ_tag = "lungs"
|
||||
organ_type = /datum/organ/internal/lungs
|
||||
|
||||
/obj/item/organ/kidneys
|
||||
name = "kidneys"
|
||||
@@ -109,6 +111,7 @@
|
||||
prosthetic_name = "prosthetic kidneys"
|
||||
prosthetic_icon = "kidneys-prosthetic"
|
||||
organ_tag = "kidneys"
|
||||
organ_type = /datum/organ/internal/kidney
|
||||
|
||||
/obj/item/organ/eyes
|
||||
name = "eyeballs"
|
||||
@@ -117,7 +120,7 @@
|
||||
prosthetic_name = "visual prosthesis"
|
||||
prosthetic_icon = "eyes-prosthetic"
|
||||
organ_tag = "eyes"
|
||||
|
||||
organ_type = /datum/organ/internal/eyes
|
||||
var/eye_colour
|
||||
|
||||
/obj/item/organ/liver
|
||||
@@ -126,11 +129,13 @@
|
||||
prosthetic_name = "toxin filter"
|
||||
prosthetic_icon = "liver-prosthetic"
|
||||
organ_tag = "liver"
|
||||
organ_type = /datum/organ/internal/liver
|
||||
|
||||
/obj/item/organ/appendix
|
||||
name = "appendix"
|
||||
icon_state = "appendix"
|
||||
organ_tag = "appendix"
|
||||
organ_type = /datum/organ/internal/appendix
|
||||
|
||||
//These are here so they can be printed out via the fabricator.
|
||||
/obj/item/organ/heart/prosthetic
|
||||
|
||||
@@ -197,9 +197,22 @@
|
||||
x_offset = rand(-1,1)
|
||||
|
||||
//Point blank bonus
|
||||
if(pointblank) P.damage *= 1.3
|
||||
|
||||
//TODO: accuracy modifiers
|
||||
if(pointblank)
|
||||
var/damage_mult = 1.3 //default point blank multiplier
|
||||
|
||||
//determine multiplier due to the target being grabbed
|
||||
if(ismob(target))
|
||||
var/mob/M = target
|
||||
if(M.grabbed_by.len)
|
||||
var/grabstate = 0
|
||||
for(var/obj/item/weapon/grab/G in M.grabbed_by)
|
||||
grabstate = max(grabstate, G.state)
|
||||
if(grabstate >= GRAB_NECK)
|
||||
damage_mult = 3.0
|
||||
else if (grabstate >= GRAB_AGGRESSIVE)
|
||||
damage_mult = 1.5
|
||||
|
||||
P.damage *= damage_mult
|
||||
|
||||
if(params)
|
||||
P.set_clickpoint(params)
|
||||
|
||||
@@ -148,16 +148,21 @@
|
||||
xo = new_x - starting_loc.x
|
||||
|
||||
//Called when the projectile intercepts a mob. Returns 1 if the projectile hit the mob, 0 if it missed and should keep flying.
|
||||
/obj/item/projectile/proc/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier)
|
||||
/obj/item/projectile/proc/attack_mob(var/mob/living/target_mob, var/distance, var/miss_modifier=0)
|
||||
//accuracy bonus from aiming
|
||||
if (istype(shot_from, /obj/item/weapon/gun)) //If you aim at someone beforehead, it'll hit more often.
|
||||
var/obj/item/weapon/gun/daddy = shot_from //Kinda balanced by fact you need like 2 seconds to aim
|
||||
if (istype(shot_from, /obj/item/weapon/gun))
|
||||
var/obj/item/weapon/gun/daddy = shot_from
|
||||
miss_modifier -= round(15*daddy.accuracy)
|
||||
if (daddy.aim_targets && original in daddy.aim_targets) //As opposed to no-delay pew pew
|
||||
|
||||
//If you aim at someone beforehead, it'll hit more often.
|
||||
//Kinda balanced by fact you need like 2 seconds to aim
|
||||
//As opposed to no-delay pew pew
|
||||
if (daddy.aim_targets && original in daddy.aim_targets)
|
||||
miss_modifier += -30
|
||||
|
||||
//roll to-hit
|
||||
var/hit_zone = get_zone_with_miss_chance(def_zone, target_mob, max(miss_modifier + 15*(distance-2), 0))
|
||||
miss_modifier = max(miss_modifier + 15*(distance-2), 0)
|
||||
var/hit_zone = get_zone_with_miss_chance(def_zone, target_mob, miss_modifier, ranged_attack=(distance > 1))
|
||||
if(!hit_zone)
|
||||
visible_message("<span class='notice'>\The [src] misses [target_mob] narrowly!</span>")
|
||||
return 0
|
||||
@@ -189,7 +194,7 @@
|
||||
|
||||
return 1
|
||||
|
||||
/obj/item/projectile/Bump(atom/A as mob|obj|turf|area)
|
||||
/obj/item/projectile/Bump(atom/A as mob|obj|turf|area, forced=0)
|
||||
if(A == src)
|
||||
return 0 //no
|
||||
|
||||
@@ -197,7 +202,7 @@
|
||||
loc = A.loc
|
||||
return 0 //cannot shoot yourself
|
||||
|
||||
if(bumped || (A in permutated))
|
||||
if((bumped && !forced) || (A in permutated))
|
||||
return 0
|
||||
|
||||
var/passthrough = 0 //if the projectile should continue flying
|
||||
@@ -207,6 +212,13 @@
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
if(istype(A, /mob/living))
|
||||
//if they have a neck grab on someone, that person gets hit instead
|
||||
var/obj/item/weapon/grab/G = locate() in M
|
||||
if(G && G.state >= GRAB_NECK)
|
||||
visible_message("<span class='danger'>\The [M] uses [G.affecting] as a shield!</span>")
|
||||
if(Bump(G.affecting, forced=1))
|
||||
return //If Bump() returns 0 (keep going) then we continue on to attack M.
|
||||
|
||||
passthrough = !attack_mob(M, distance)
|
||||
else
|
||||
passthrough = 1 //so ghosts don't stop bullets
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 158 KiB After Width: | Height: | Size: 149 KiB |
1420
maps/exodus-1.dmm
1420
maps/exodus-1.dmm
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user