Merge branch 'master' into culttweaks2

This commit is contained in:
Robustin
2017-05-22 10:36:57 -04:00
committed by GitHub
172 changed files with 81635 additions and 84477 deletions
+1 -1
View File
@@ -442,7 +442,7 @@
dat += "</table>"
for(var/datum/gang/G in SSticker.mode.gangs)
dat += "<br><table cellspacing=5><tr><td><B>[G.name] Gang: <a href='?_src_=holder;gangpoints=\ref[G]'>[G.points] Influence</a> | [round((G.territory.len/GLOB.start_state.num_territories)*100, 1)]% Control</B></td><td></td></tr>"
dat += "<br><table cellspacing=5><tr><td><B>[G.name] Gang: [round((G.territory.len/GLOB.start_state.num_territories)*100, 1)]% Control</B></td><td></td></tr>"
for(var/datum/mind/N in G.bosses)
var/mob/M = N.current
if(!M)
+5 -11
View File
@@ -281,6 +281,11 @@
minor_announce("The emergency shuttle will reach its destination in [round(SSshuttle.emergency.timeLeft(600))] minutes.")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] edited the Emergency Shuttle's timeleft to [timer] seconds.</span>")
href_list["secrets"] = "check_antagonist"
else if(href_list["trigger_centcom_recall"])
if(!check_rights(R_ADMIN))
return
usr.client.trigger_centcom_recall()
else if(href_list["toggle_continuous"])
if(!check_rights(R_ADMIN))
@@ -1511,17 +1516,6 @@
usr.client.cmd_admin_animalize(M)
else if(href_list["gangpoints"])
var/datum/gang/G = locate(href_list["gangpoints"]) in SSticker.mode.gangs
if(G)
var/newpoints = input("Set [G.name ] Gang's influence.","Set Influence",G.points) as null|num
if(!newpoints)
return
message_admins("[key_name_admin(usr)] changed the [G.name] Gang's influence from [G.points] to [newpoints].</span>")
log_admin("[key_name(usr)] changed the [G.name] Gang's influence from [G.points] to [newpoints].</span>")
G.points = newpoints
G.message_gangtools("Your gang now has [G.points] influence.")
else if(href_list["adminplayeropts"])
var/mob/M = locate(href_list["adminplayeropts"])
show_player_panel(M)
+4
View File
@@ -109,7 +109,11 @@ GLOBAL_PROTECT(AdminProcCallCount)
return call(target, procname)(arglist(arguments))
/proc/IsAdminAdvancedProcCall()
#ifdef TESTING
return FALSE
#else
return usr && usr.client && GLOB.AdminProcCaller == usr.client.ckey
#endif
/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf)
set category = "Debug"
+13
View File
@@ -1193,3 +1193,16 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
message_admins(msg)
admin_ticket_log(target, msg)
log_admin("[key_name(usr)] punished [key_name(target)] with [punishment].")
/client/proc/trigger_centcom_recall()
if(!holder)
return
var/message = pick(GLOB.admiral_messages)
message = input("Enter message from the on-call admiral to be put in the recall report.", "Admiral Message", message) as text|null
if(!message)
return
message_admins("[key_name_admin(usr)] triggered a Centcom recall, with the admiral message of: [message]")
log_game("[key_name(usr)] triggered a Centcom recall, with the message of: [message]")
@@ -76,7 +76,6 @@
/datum/gas_reaction/freon/react(datum/gas_mixture/air, turf/open/location)
. = NO_REACTION
if(location && location.freon_gas_act())
air.gases["freon"][MOLES] -= MOLES_PLASMA_VISIBLE
. = REACTING
//water vapor: puts out fires?
@@ -19,7 +19,7 @@
/obj/machinery/meter/Initialize(mapload)
. = ..()
SSair.atmos_machinery += src
if (mapload && !target)
if (!target)
target = locate(/obj/machinery/atmospherics/pipe) in loc
/obj/machinery/meter/Destroy()
+2 -3
View File
@@ -65,9 +65,8 @@
backpack_contents = list(/obj/item/weapon/storage/box/engineer=1,\
/obj/item/weapon/storage/box/handcuffs=1,\
/obj/item/clothing/mask/gas/sechailer=1,\
/obj/item/weapon/gun/energy/e_gun=1,\
/obj/item/weapon/melee/baton/loaded=1,\
/obj/item/weapon/gun/energy/e_gun/advtaser=1)
/obj/item/weapon/gun/energy/e_gun/stun=1,\
/obj/item/weapon/melee/baton/loaded=1)
/datum/outfit/ert/security/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()
@@ -211,6 +211,14 @@
item_state = "black_suit_fem"
item_color = "black_suit_fem"
/obj/item/clothing/under/suit_jacket/green
name = "green suit"
desc = "A green suit and yellow necktie. Baller."
icon_state = "green_suit"
item_state = "dg_suit"
item_color = "green_suit"
can_adjust = 0
/obj/item/clothing/under/suit_jacket/red
name = "red suit"
desc = "A red suit and blue tie. Somewhat formal."
+1 -1
View File
@@ -18,7 +18,7 @@
/obj/item/clothing/under/syndicate/sniper
name = "Tactical turtleneck suit"
desc = "A double seamed tactical turtleneck disguised as a civillian grade silk suit. Intended for the most formal operator. The collar is really sharp"
desc = "A double seamed tactical turtleneck disguised as a civilian grade silk suit. Intended for the most formal operator. The collar is really sharp"
icon_state = "really_black_suit"
item_state = "bl_suit"
item_color = "black_suit"
+13 -2
View File
@@ -33,6 +33,7 @@
var/process_edge_turfs = FALSE //Don't do this either unless it's absolutely necessary, you can just track what things are inside manually or on the initial setup.
var/setup_edge_turfs = FALSE //Setup edge turfs/all field turfs. Set either or both to ON when you need it, it's defaulting to off unless you do to save CPU.
var/setup_field_turfs = FALSE
var/use_host_turf = FALSE //For fields from items carried on mobs to check turf instead of loc...
var/list/turf/field_turfs = list()
var/list/turf/edge_turfs = list()
@@ -90,8 +91,19 @@
for(var/turf/T in field_turfs)
cleanup_field_turf(T)
/datum/proximity_monitor/advanced/proc/check_movement()
if(!use_host_turf)
if(host.loc != last_host_loc)
last_host_loc = host.loc
return TRUE
else
if(get_turf(host) != last_host_loc)
last_host_loc = get_turf(host)
return TRUE
return FALSE
/datum/proximity_monitor/advanced/proc/recalculate_field(ignore_movement_check = FALSE) //Call every time the field moves (done automatically if you use update_center) or a setup specification is changed.
if(!(ignore_movement_check || ((host.loc != last_host_loc) && (field_shape != FIELD_NO_SHAPE))))
if(!(ignore_movement_check || check_movement()) && (field_shape != FIELD_NO_SHAPE))
return
update_new_turfs()
var/list/turf/needs_setup = field_turfs_new.Copy()
@@ -173,7 +185,6 @@
/datum/proximity_monitor/advanced/proc/update_new_turfs()
if(!istype(host))
return FALSE
last_host_loc = host.loc
var/turf/center = get_turf(host)
field_turfs_new = list()
edge_turfs_new = list()
@@ -15,9 +15,11 @@
var/static/image/southwest_corner = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_southwest")
var/static/image/northeast_corner = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_northeast")
var/static/image/southeast_corner = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_southeast")
var/static/image/generic_edge = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_generic")
var/obj/item/borg/projectile_dampen/projector = null
var/list/obj/item/projectile/tracked
var/list/obj/item/projectile/staging
use_host_turf = TRUE
/datum/proximity_monitor/advanced/peaceborg_dampener/New()
tracked = list()
@@ -71,6 +73,8 @@
return southeast_corner
if(SOUTHWEST)
return southwest_corner
else
return generic_edge
/datum/proximity_monitor/advanced/peaceborg_dampener/proc/capture_projectile(obj/item/projectile/P, track_projectile = TRUE)
if(P in tracked)
+1
View File
@@ -7,6 +7,7 @@
alpha = 0
invisibility = INVISIBILITY_ABSTRACT
flags = ABSTRACT|ON_BORDER
mouse_opacity = 0
var/datum/proximity_monitor/advanced/parent = null
/obj/effect/abstract/proximity_checker/advanced/Initialize(mapload, _monitor)
+1 -1
View File
@@ -128,7 +128,7 @@
/datum/language_holder/synthetic
languages = list(/datum/language/common)
shadow_languages = list(/datum/language/machine, /datum/language/draconic)
shadow_languages = list(/datum/language/common, /datum/language/machine, /datum/language/draconic)
/datum/language_holder/universal/New()
..()
+9 -1
View File
@@ -2,7 +2,8 @@
#define BAD_ZLEVEL 1
#define BAD_AREA 2
#define ZONE_SET 3
#define BAD_COORDS 3
#define ZONE_SET 4
/area/shuttle/auxillary_base
name = "Auxillary Base"
@@ -149,6 +150,9 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
if(T.z != ZLEVEL_MINING)
return BAD_ZLEVEL
var/colony_radius = max(base_dock.width, base_dock.height)*0.5
if(T.x - colony_radius < 1 || T.x + colony_radius >= world.maxx || T.y - colony_radius < 1 || T.y + colony_radius >= world.maxx)
return BAD_COORDS //Avoid dropping the base too close to map boundaries, as it results in parts of it being left in space
var/list/area_counter = get_areas_in_range(colony_radius, T)
if(area_counter.len > 1) //Avoid smashing ruins unless you are inside a really big one
return BAD_AREA
@@ -195,6 +199,7 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
if(!do_after(user, 50, target = user)) //You get a few seconds to cancel if you do not want to drop there.
setting = FALSE
return
setting = FALSE
var/turf/T = get_turf(user)
var/obj/machinery/computer/auxillary_base/AB
@@ -212,6 +217,8 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
to_chat(user, "<span class='warning'>This uplink can only be used in a designed mining zone.</span>")
if(BAD_AREA)
to_chat(user, "<span class='warning'>Unable to acquire a targeting lock. Find an area clear of stuctures or entirely within one.</span>")
if(BAD_COORDS)
to_chat(user, "<span class='warning'>Location is too close to the edge of the station's scanning range. Move several paces away and try again.</span>")
if(ZONE_SET)
qdel(src)
@@ -347,4 +354,5 @@ obj/docking_port/stationary/public_mining_dock/onShuttleMove()
#undef BAD_ZLEVEL
#undef BAD_AREA
#undef BAD_COORDS
#undef ZONE_SET
+84 -80
View File
@@ -169,7 +169,7 @@
icon = 'icons/obj/mining.dmi'
icon_state = "resonator"
item_state = "resonator"
desc = "A handheld device that creates small fields of energy that resonate until they detonate, crushing rock. It can also be activated without a target to create a field at the user's location, to act as a delayed time trap. It's more effective in a vacuum."
desc = "A handheld device that creates small fields of energy that resonate until they detonate, crushing rock. It's more effective in a vacuum."
w_class = WEIGHT_CLASS_NORMAL
force = 15
throwforce = 10
@@ -188,18 +188,6 @@
fieldlimit = 6
quick_burst_mod = 1
/obj/item/weapon/resonator/proc/CreateResonance(target, creator)
var/turf/T = get_turf(target)
var/obj/effect/resonance/R = locate(/obj/effect/resonance) in T
if(R)
R.resonance_damage *= quick_burst_mod
R.burst()
return
if(fields.len < fieldlimit)
playsound(src,'sound/weapons/resonator_fire.ogg',50,1)
var/obj/effect/resonance/RE = new(T, creator, burst_time, src)
fields += RE
/obj/item/weapon/resonator/attack_self(mob/user)
if(burst_time == 50)
burst_time = 30
@@ -208,57 +196,76 @@
burst_time = 50
to_chat(user, "<span class='info'>You set the resonator's fields to detonate after 5 seconds.</span>")
/obj/item/weapon/resonator/afterattack(atom/target, mob/user, proximity_flag)
if(proximity_flag)
if(!check_allowed_items(target, 1))
return
/obj/item/weapon/resonator/proc/CreateResonance(target, mob/user)
var/turf/T = get_turf(target)
var/obj/effect/temp_visual/resonance/R = locate(/obj/effect/temp_visual/resonance) in T
if(R)
R.damage_multiplier = quick_burst_mod
R.burst()
return
if(LAZYLEN(fields) < fieldlimit)
new /obj/effect/temp_visual/resonance(T, user, src, burst_time)
user.changeNext_move(CLICK_CD_MELEE)
CreateResonance(target, user)
/obj/effect/resonance
/obj/item/weapon/resonator/pre_attackby(atom/target, mob/user, params)
if(check_allowed_items(target, 1))
CreateResonance(target, user)
return TRUE
/obj/effect/temp_visual/resonance
name = "resonance field"
desc = "A resonating field that significantly damages anything inside of it when the field eventually ruptures. More damaging in low pressure environments."
icon = 'icons/effects/effects.dmi'
icon_state = "shield1"
layer = ABOVE_ALL_MOB_LAYER
anchored = TRUE
mouse_opacity = 0
duration = 50
var/resonance_damage = 20
var/damage_multiplier = 1
var/creator
var/obj/item/weapon/resonator/res
/obj/effect/resonance/New(loc, set_creator, timetoburst, set_resonator)
..()
/obj/effect/temp_visual/resonance/Initialize(mapload, set_creator, set_resonator, set_duration)
duration = set_duration
. = ..()
creator = set_creator
res = set_resonator
check_pressure()
addtimer(CALLBACK(src, .proc/burst), timetoburst)
if(res)
res.fields += src
playsound(src,'sound/weapons/resonator_fire.ogg',50,1)
transform = matrix()*0.75
animate(src, transform = matrix()*1.5, time = duration)
deltimer(timerid)
timerid = addtimer(CALLBACK(src, .proc/burst), duration, TIMER_STOPPABLE)
/obj/effect/resonance/Destroy()
/obj/effect/temp_visual/resonance/Destroy()
if(res)
res.fields -= src
res = null
creator = null
. = ..()
/obj/effect/resonance/proc/check_pressure()
var/turf/proj_turf = get_turf(src)
/obj/effect/temp_visual/resonance/proc/check_pressure(turf/proj_turf)
if(!proj_turf)
proj_turf = get_turf(src)
if(!istype(proj_turf))
return
var/datum/gas_mixture/environment = proj_turf.return_air()
var/pressure = environment.return_pressure()
resonance_damage = initial(resonance_damage)
if(pressure < 50)
name = "strong [initial(name)]"
resonance_damage = 60
resonance_damage *= 3
else
name = initial(name)
resonance_damage = initial(resonance_damage)
resonance_damage *= damage_multiplier
/obj/effect/resonance/proc/burst()
check_pressure()
/obj/effect/temp_visual/resonance/proc/burst()
var/turf/T = get_turf(src)
playsound(src,'sound/weapons/resonator_blast.ogg',50,1)
new /obj/effect/temp_visual/resonance_crush(T)
if(ismineralturf(T))
var/turf/closed/mineral/M = T
M.gets_drilled(creator)
check_pressure(T)
playsound(T,'sound/weapons/resonator_blast.ogg',50,1)
for(var/mob/living/L in T)
if(creator)
add_logs(creator, L, "used a resonator field on", "resonator")
@@ -266,6 +273,16 @@
L.apply_damage(resonance_damage, BRUTE)
qdel(src)
/obj/effect/temp_visual/resonance_crush
icon_state = "shield1"
layer = ABOVE_ALL_MOB_LAYER
duration = 4
/obj/effect/temp_visual/resonance_crush/Initialize()
. = ..()
transform = matrix()*1.5
animate(src, transform = matrix()*0.1, alpha = 50, time = 4)
/**********************Facehugger toy**********************/
/obj/item/clothing/mask/facehugger/toy
@@ -510,79 +527,66 @@
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("smashed", "crushed", "cleaved", "chopped", "pulped")
sharpness = IS_SHARP
var/charged = 1
var/charge_time = 16
var/atom/mark = null
var/mutable_appearance/marked_underlay
var/charged = TRUE
var/charge_time = 14
/obj/item/projectile/destabilizer
name = "destabilizing force"
icon_state = "pulse1"
nodamage = TRUE
damage = 0 //We're just here to mark people. This is still a melee weapon.
damage_type = BRUTE
flag = "bomb"
range = 6
var/obj/item/weapon/twohanded/required/mining_hammer/hammer_synced = null
log_override = TRUE
var/obj/item/weapon/twohanded/required/mining_hammer/hammer_synced
/obj/item/projectile/destabilizer/Destroy()
hammer_synced = null
return ..()
/obj/item/projectile/destabilizer/on_hit(atom/target, blocked = 0)
if(hammer_synced)
if(hammer_synced.mark == target)
return ..()
if(isliving(target))
if(hammer_synced.mark && hammer_synced.marked_underlay)
hammer_synced.mark.underlays -= hammer_synced.marked_underlay
hammer_synced.marked_underlay = null
var/mob/living/L = target
if(L.mob_size >= MOB_SIZE_LARGE)
hammer_synced.mark = L
hammer_synced.marked_underlay = mutable_appearance('icons/effects/effects.dmi', "shield2")
hammer_synced.marked_underlay.pixel_x = -L.pixel_x
hammer_synced.marked_underlay.pixel_y = -L.pixel_y
L.underlays += hammer_synced.marked_underlay
var/target_turf = get_turf(target)
if(ismineralturf(target_turf))
var/turf/closed/mineral/M = target_turf
new /obj/effect/temp_visual/kinetic_blast(M)
M.gets_drilled(firer)
if(isliving(target))
var/mob/living/L = target
var/datum/status_effect/crusher_mark/CM = L.apply_status_effect(STATUS_EFFECT_CRUSHERMARK)
CM.hammer_synced = hammer_synced
var/target_turf = get_turf(target)
if(ismineralturf(target_turf))
var/turf/closed/mineral/M = target_turf
new /obj/effect/temp_visual/kinetic_blast(M)
M.gets_drilled(firer)
..()
/obj/item/weapon/twohanded/required/mining_hammer/afterattack(atom/target, mob/user, proximity_flag)
if(!proximity_flag && charged)//Mark a target, or mine a tile.
var/turf/proj_turf = get_turf(src)
var/turf/proj_turf = user.loc
if(!isturf(proj_turf))
return
var/datum/gas_mixture/environment = proj_turf.return_air()
var/pressure = environment.return_pressure()
if(pressure > 50)
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
return
var/obj/item/projectile/destabilizer/D = new /obj/item/projectile/destabilizer(user.loc)
D.preparePixelProjectile(target,get_turf(target), user)
var/obj/item/projectile/destabilizer/D = new /obj/item/projectile/destabilizer(proj_turf)
D.preparePixelProjectile(target, get_turf(target), user)
D.hammer_synced = src
playsound(user, 'sound/weapons/plasma_cutter.ogg', 100, 1)
D.fire()
charged = 0
charged = FALSE
icon_state = "mining_hammer1_uncharged"
addtimer(CALLBACK(src, .proc/Recharge), charge_time)
return
if(proximity_flag && target == mark && isliving(target))
if(proximity_flag && isliving(target))
var/mob/living/L = target
var/datum/status_effect/crusher_mark/CM = L.has_status_effect(STATUS_EFFECT_CRUSHERMARK)
if(!CM || CM.hammer_synced != src || !L.remove_status_effect(STATUS_EFFECT_CRUSHERMARK))
return
new /obj/effect/temp_visual/kinetic_blast(get_turf(L))
mark = 0
if(L.mob_size >= MOB_SIZE_LARGE)
L.underlays -= marked_underlay
QDEL_NULL(marked_underlay)
var/backstab_dir = get_dir(user, L)
var/def_check = L.getarmor(type = "bomb")
if((user.dir & backstab_dir) && (L.dir & backstab_dir))
L.apply_damage(80, BRUTE, blocked = def_check)
playsound(user, 'sound/weapons/Kenetic_accel.ogg', 100, 1) //Seriously who spelled it wrong
else
L.apply_damage(50, BRUTE, blocked = def_check)
var/backstab_dir = get_dir(user, L)
var/def_check = L.getarmor(type = "bomb")
if((user.dir & backstab_dir) && (L.dir & backstab_dir))
L.apply_damage(80, BRUTE, blocked = def_check)
playsound(user, 'sound/weapons/Kenetic_accel.ogg', 100, 1) //Seriously who spelled it wrong
else
L.apply_damage(50, BRUTE, blocked = def_check)
/obj/item/weapon/twohanded/required/mining_hammer/proc/Recharge()
if(!charged)
charged = 1
charged = TRUE
icon_state = "mining_hammer1"
playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1)
+26 -10
View File
@@ -300,31 +300,47 @@
//Door
/obj/machinery/door/airlock/survival_pod
name = "airlock"
icon = 'icons/obj/doors/airlocks/survival/horizontal/survival.dmi'
overlays_file = 'icons/obj/doors/airlocks/survival/horizontal/survival_overlays.dmi'
icon = 'icons/obj/doors/airlocks/survival/survival.dmi'
overlays_file = 'icons/obj/doors/airlocks/survival/survival_overlays.dmi'
assemblytype = /obj/structure/door_assembly/door_assembly_pod
opacity = 0
glass = 1
var/expected_dir = SOUTH //we visually turn when shuttle rotated, but need to not turn for any other reason
/obj/machinery/door/airlock/survival_pod/setDir(direction)
direction = expected_dir
..()
/obj/machinery/door/airlock/survival_pod/shuttleRotate(rotation)
expected_dir = angle2dir(rotation+dir2angle(dir))
..()
/obj/machinery/door/airlock/survival_pod/vertical
icon = 'icons/obj/doors/airlocks/survival/vertical/survival.dmi'
overlays_file = 'icons/obj/doors/airlocks/survival/vertical/survival_overlays.dmi'
assemblytype = /obj/structure/door_assembly/door_assembly_pod/vertical
dir = EAST
expected_dir = EAST
/obj/structure/door_assembly/door_assembly_pod
name = "pod airlock assembly"
icon = 'icons/obj/doors/airlocks/survival/horizontal/survival.dmi'
overlays_file = 'icons/obj/doors/airlocks/survival/horizontal/survival_overlays.dmi'
icon = 'icons/obj/doors/airlocks/survival/survival.dmi'
overlays_file = 'icons/obj/doors/airlocks/survival/survival_overlays.dmi'
airlock_type = /obj/machinery/door/airlock/survival_pod
anchored = 1
state = 1
mineral = "glass"
material = "glass"
var/expected_dir = SOUTH
/obj/structure/door_assembly/door_assembly_pod/setDir(direction)
direction = expected_dir
..()
/obj/structure/door_assembly/door_assembly_pod/shuttleRotate(rotation)
expected_dir = angle2dir(rotation+dir2angle(dir))
..()
/obj/structure/door_assembly/door_assembly_pod/vertical
icon = 'icons/obj/doors/airlocks/survival/vertical/survival.dmi'
overlays_file = 'icons/obj/doors/airlocks/survival/vertical/survival_overlays.dmi'
airlock_type = /obj/machinery/door/airlock/survival_pod/vertical
dir = EAST
expected_dir = EAST
//Table
/obj/structure/table/survival_pod
+1 -1
View File
@@ -24,7 +24,7 @@
melee_damage_lower = 15
melee_damage_upper = 15
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
check_friendly_fire = 1
stop_automated_movement_when_pulled = 1
attacktext = "drills"
@@ -36,7 +36,8 @@
//initialise organs
create_internal_organs()
martial_art = default_martial_art
if(mind)
mind.martial_art = mind.default_martial_art
handcrafting = new()
@@ -40,12 +40,13 @@
if(spec_return)
return spec_return
if(martial_art && martial_art.deflection_chance) //Some martial arts users can deflect projectiles!
if(prob(martial_art.deflection_chance))
if(!lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
visible_message("<span class='danger'>[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
return 0
if(mind)
if(mind.martial_art && mind.martial_art.deflection_chance) //Some martial arts users can deflect projectiles!
if(prob(mind.martial_art.deflection_chance))
if(!lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
visible_message("<span class='danger'>[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
return 0
if(!(P.original == src && P.firer == src)) //can't block or reflect when shooting yourself
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
@@ -103,10 +104,11 @@
return 0
/mob/living/carbon/human/proc/check_block()
if(martial_art && martial_art.block_chance \
&& prob(martial_art.block_chance) && in_throw_mode \
&& !stat && !weakened && !stunned)
return TRUE
if(mind)
if(mind.martial_art && mind.martial_art.block_chance \
&& prob(mind.martial_art.block_chance) && in_throw_mode \
&& !stat && !weakened && !stunned)
return TRUE
return FALSE
/mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0)
@@ -39,9 +39,6 @@
var/bleed_rate = 0 //how much are we bleeding
var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding
var/datum/martial_art/martial_art = null
var/static/default_martial_art = new/datum/martial_art
var/name_override //For temporary visible name changes
var/drunkenness = 0 //Overall drunkenness - check handle_alcohol() in life.dm for effects
@@ -144,9 +144,9 @@
if(NOGUNS in src.dna.species.species_traits)
to_chat(src, "<span class='warning'>Your fingers don't fit in the trigger guard!</span>")
return 0
if(martial_art && martial_art.no_guns) //great dishonor to famiry
to_chat(src, "<span class='warning'>Use of ranged weaponry would bring dishonor to the clan.</span>")
return 0
if(mind)
if(mind.martial_art && mind.martial_art.no_guns) //great dishonor to famiry
to_chat(src, "<span class='warning'>Use of ranged weaponry would bring dishonor to the clan.</span>")
return 0
return .
@@ -1140,7 +1140,7 @@
/datum/species/proc/spec_hitby(atom/movable/AM, mob/living/carbon/human/H)
return
/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art)
/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style)
if(!istype(M))
return
CHECK_DNA_AND_SPECIES(M)
@@ -1148,6 +1148,8 @@
if(!istype(M)) //sanity check for drones.
return
if(M.mind)
attacker_style = M.mind.martial_art
if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(0, M.name, attack_type = UNARMED_ATTACK))
add_logs(M, H, "attempted to touch")
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>")
@@ -406,7 +406,7 @@
else
reactive_teleport(H)
/datum/species/golem/bluespace/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art)
/datum/species/golem/bluespace/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style)
..()
if(world.time > last_teleport + teleport_cooldown && M != H && M.a_intent != INTENT_HELP)
reactive_teleport(H)
@@ -490,7 +490,7 @@
var/golem_name = "[uppertext(clown_name)]"
return golem_name
/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art)
/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style)
..()
if(world.time > last_banana + banana_cooldown && M != H && M.a_intent != INTENT_HELP)
new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H))
+3 -3
View File
@@ -794,9 +794,6 @@
return 1
/mob/living/carbon/proc/update_stamina()
return
/mob/living/carbon/human/update_stamina()
if(staminaloss)
var/total_health = (health - staminaloss)
if(total_health <= HEALTH_THRESHOLD_CRIT && !stat)
@@ -805,6 +802,9 @@
setStaminaLoss(health - 2)
update_health_hud()
/mob/living/carbon/alien/update_stamina()
return
/mob/living/proc/owns_soul()
if(mind)
return mind.soulOwner == mind
@@ -273,7 +273,7 @@
//Medbot Assembly
/obj/item/weapon/firstaid_arm_assembly
name = "incomplete medibot assembly."
name = "incomplete medibot assembly"
desc = "A first aid kit with a robot arm permanently grafted to it."
icon = 'icons/mob/aibots.dmi'
icon_state = "firstaid_arm"
@@ -9,7 +9,7 @@
maxHealth = 100
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
obj_damage = 60
environment_smash = 2 //Walls can't stop THE LAW
environment_smash = ENVIRONMENT_SMASH_WALLS //Walls can't stop THE LAW
mob_size = MOB_SIZE_LARGE
radio_key = /obj/item/device/encryptionkey/headset_sec
@@ -115,7 +115,7 @@
melee_damage_upper = 30
attacktext = "smashes their armored gauntlet into"
speed = 3
environment_smash = 2
environment_smash = ENVIRONMENT_SMASH_WALLS
attack_sound = 'sound/weapons/punch3.ogg'
status_flags = 0
mob_size = MOB_SIZE_LARGE
@@ -126,7 +126,7 @@
/mob/living/simple_animal/hostile/construct/armored/hostile //actually hostile, will move around, hit things
AIStatus = AI_ON
environment_smash = 1 //only token destruction, don't smash the cult wall NO STOP
environment_smash = ENVIRONMENT_SMASH_STRUCTURES //only token destruction, don't smash the cult wall NO STOP
/mob/living/simple_animal/hostile/construct/armored/bullet_act(obj/item/projectile/P)
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
@@ -218,7 +218,7 @@
retreat_distance = 10
minimum_distance = 10 //AI artificers will flee like fuck
attacktext = "rams"
environment_smash = 2
environment_smash = ENVIRONMENT_SMASH_WALLS
attack_sound = 'sound/weapons/punch2.ogg'
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
/obj/effect/proc_holder/spell/aoe_turf/conjure/floor,
@@ -272,7 +272,7 @@
/mob/living/simple_animal/hostile/construct/builder/hostile //actually hostile, will move around, hit things, heal other constructs
AIStatus = AI_ON
environment_smash = 1 //only token destruction, don't smash the cult wall NO STOP
environment_smash = ENVIRONMENT_SMASH_STRUCTURES //only token destruction, don't smash the cult wall NO STOP
/////////////////////////////Non-cult Artificer/////////////////////////
/mob/living/simple_animal/hostile/construct/builder/noncult
@@ -55,7 +55,7 @@
var/laws = \
"1. You may not involve yourself in the matters of another being, even if such matters conflict with Law Two or Law Three, unless the other being is another Drone.\n"+\
"2. You may not harm any being, regardless of intent or circumstance.\n"+\
"3. Your goals are to build, maintain, repair, improve, and power the station to the best of your abilities, You must never actively work against these goals."
"3. Your goals are to build, maintain, repair, improve, and provide power to the best of your abilities, You must never actively work against these goals."
var/light_on = 0
var/heavy_emp_damage = 25 //Amount of damage sustained if hit by a heavy EMP pulse
var/alarms = list("Atmosphere" = list(), "Fire" = list(), "Power" = list())
@@ -24,7 +24,7 @@
maxHealth = 40
melee_damage_lower = 1
melee_damage_upper = 2
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
stop_automated_movement_when_pulled = 1
blood_volume = BLOOD_VOLUME_NORMAL
var/obj/item/udder/udder = null
@@ -20,7 +20,7 @@
mob_size = MOB_SIZE_SMALL
gold_core_spawnable = 2
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
var/list/edibles = list(/mob/living/simple_animal/butterfly,/mob/living/simple_animal/cockroach) //list of atoms, however turfs won't affect AI, but will affect consumption.
/mob/living/simple_animal/hostile/lizard/CanAttack(atom/the_target)//Can we actually attack a possible target?
@@ -31,7 +31,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
health = INFINITY
healable = FALSE //don't brusepack the guardian
damage_coeff = list(BRUTE = 0.5, BURN = 0.5, TOX = 0.5, CLONE = 0.5, STAMINA = 0, OXY = 0.5) //how much damage from each damage type we transfer to the owner
environment_smash = 1
environment_smash = ENVIRONMENT_SMASH_STRUCTURES
obj_damage = 40
melee_damage_lower = 15
melee_damage_upper = 15
@@ -71,7 +71,7 @@
melee_damage_upper = 50
armour_penetration = 100
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
new /obj/effect/temp_visual/guardian/phase/out(get_turf(src))
alpha = 15
if(!forced)
@@ -45,7 +45,7 @@
melee_damage_lower = 0
melee_damage_upper = 0
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
alpha = 45
range = 255
incorporeal_move = 1
@@ -4,7 +4,7 @@
melee_damage_upper = 20
obj_damage = 80
next_move_modifier = 0.8 //attacks 20% faster
environment_smash = 2
environment_smash = ENVIRONMENT_SMASH_WALLS
playstyle_string = "<span class='holoparasite'>As a <b>standard</b> type you have no special abilities, but have a high damage resistance and a powerful attack capable of smashing through walls.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the Assistant, faceless and generic, but never to be underestimated.</span>"
tech_fluff_string = "<span class='holoparasite'>Boot sequence complete. Standard combat modules loaded. Holoparasite swarm online.</span>"
@@ -158,7 +158,7 @@
a_intent = INTENT_HELP
friendly = "caresses"
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
gold_core_spawnable = 1
icon_state = "maid"
icon_living = "maid"
@@ -31,7 +31,7 @@
faction = list("hostile")
move_to_delay = 0
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
mouse_opacity = 2
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
@@ -8,7 +8,7 @@
icon = 'icons/mob/simple_human.dmi'
icon_state = "paperwizard"
ranged = 1
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
minimum_distance = 3
retreat_distance = 3
obj_damage = 0
@@ -8,7 +8,7 @@
icon_living = "flan"
icon_dead = "flan_dead"
turns_per_move = 5
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
speed = -2
maxHealth = 50
health = 50
@@ -17,7 +17,7 @@
robust_searching = 1
stat_attack = 2
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
speak_emote = list("squeaks")
ventcrawler = VENTCRAWLER_ALWAYS
var/datum/mind/origin
@@ -2,7 +2,7 @@
faction = list("hostile")
stop_automated_movement_when_pulled = 0
obj_damage = 40
environment_smash = 1 //Set to 1 to break closets,tables,racks, etc; 2 for walls; 3 for rwalls
environment_smash = ENVIRONMENT_SMASH_STRUCTURES //Set to 1 to break closets,tables,racks, etc; 2 for walls; 3 for rwalls
var/atom/target
var/ranged = 0
var/rapid = 0
@@ -67,7 +67,7 @@
melee_damage_upper = 0
speed = -1
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
/mob/living/simple_animal/hostile/illusion/escape/AttackingTarget()
@@ -4,7 +4,7 @@
faction = list("jungle")
weather_immunities = list("acid")
obj_damage = 30
environment_smash = 2
environment_smash = ENVIRONMENT_SMASH_WALLS
minbodytemp = 0
maxbodytemp = 450
response_help = "pokes"
@@ -123,8 +123,9 @@ Difficulty: Very Hard
/mob/living/simple_animal/hostile/megafauna/colossus/proc/enrage(mob/living/L)
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.martial_art && prob(H.martial_art.deflection_chance))
. = TRUE
if(H.mind)
if(H.mind.martial_art && prob(H.mind.martial_art.deflection_chance))
. = TRUE
/mob/living/simple_animal/hostile/megafauna/colossus/proc/alternating_dir_shots()
dir_shots(GLOB.diagonals)
@@ -657,7 +658,7 @@ Difficulty: Very Hard
minbodytemp = 0
maxbodytemp = 1500
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
AIStatus = AI_OFF
stop_automated_movement = 1
var/heal_power = 5
@@ -8,7 +8,7 @@
maxHealth = 1000
a_intent = INTENT_HARM
sentience_type = SENTIENCE_BOSS
environment_smash = 3
environment_smash = ENVIRONMENT_SMASH_RWALLS
obj_damage = 400
light_range = 3
faction = list("mining", "boss")
@@ -203,7 +203,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
if(..())
emote_see = list("aims menacingly")
obj_damage = 0
environment_smash = 0 //needed? seems weird for them to do so
environment_smash = ENVIRONMENT_SMASH_NONE //needed? seems weird for them to do so
ranged = 1
retreat_distance = 1 //just enough to shoot
minimum_distance = 6
@@ -4,7 +4,7 @@
faction = list("mining")
weather_immunities = list("lava","ash")
obj_damage = 30
environment_smash = 2
environment_smash = ENVIRONMENT_SMASH_WALLS
minbodytemp = 0
maxbodytemp = INFINITY
response_help = "pokes"
@@ -215,7 +215,7 @@
ranged_cooldown = 0
ranged_cooldown_time = 20
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
retreat_distance = 3
minimum_distance = 3
pass_flags = PASSTABLE
@@ -334,7 +334,7 @@
attack_sound = 'sound/weapons/pierce.ogg'
throw_message = "falls right through the strange body of the"
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
pass_flags = PASSTABLE
del_on_death = 1
@@ -595,7 +595,7 @@
aggro_vision_range = 9
idle_vision_range = 5
mob_size = MOB_SIZE_SMALL
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
var/wumbo = 0
var/inflate_cooldown = 0
loot = list(/obj/item/asteroid/fugu_gland{layer = ABOVE_MOB_LAYER})
@@ -640,7 +640,7 @@
minimum_distance = 1
move_to_delay = 6
transform *= 2
environment_smash = 2
environment_smash = ENVIRONMENT_SMASH_WALLS
mob_size = MOB_SIZE_LARGE
speed = 1
addtimer(CALLBACK(src, .proc/Deflate), 100)
@@ -660,7 +660,7 @@
move_to_delay = 2
transform /= 2
inflate_cooldown = 4
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
mob_size = MOB_SIZE_SMALL
speed = 0
@@ -800,11 +800,12 @@
del_on_death = 1
stat_attack = 1
robust_searching = 1
var/can_infest_dead = FALSE
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/Life()
if(isturf(loc))
for(var/mob/living/carbon/human/H in view(src,1)) //Only for corpse right next to/on same tile
if(H.stat == UNCONSCIOUS)
if(H.stat == UNCONSCIOUS || (can_infest_dead && H.stat == DEAD))
infest(H)
..()
@@ -818,6 +819,58 @@
H.forceMove(L)
qdel(src)
//Advanced Legion is slightly tougher to kill and can raise corpses (revive other legions)
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/advanced
stat_attack = 2
maxHealth = 120
health = 120
brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/advanced
icon_state = "dwarf_legion"
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/advanced
stat_attack = 2
can_infest_dead = TRUE
//Legion that spawns Legions
/mob/living/simple_animal/hostile/spawner/legion
name = "legion"
desc = "One of many."
icon = 'icons/mob/lavaland/dragon.dmi'
icon_state = "legion"
icon_living = "legion"
icon_dead = "legion"
health = 450
maxHealth = 450
max_mobs = 3
spawn_time = 200
spawn_text = "peels itself off from"
melee_damage_lower = 20
melee_damage_upper = 20
anchored = FALSE
AIStatus = AI_ON
stop_automated_movement = FALSE
wander = TRUE
maxbodytemp = INFINITY
layer = MOB_LAYER
del_on_death = TRUE
sentience_type = SENTIENCE_BOSS
loot = list(/obj/item/organ/hivelord_core/legion = 3, /obj/effect/mob_spawn/human/corpse/damaged = 5)
move_to_delay = 14
vision_range = 5
aggro_vision_range = 9
idle_vision_range = 5
speed = 3
faction = list("mining")
weather_immunities = list("lava","ash")
obj_damage = 30
environment_smash = ENVIRONMENT_SMASH_STRUCTURES
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
//Organ
/obj/item/organ/hivelord_core/legion
name = "legion's soul"
desc = "A strange rock that still crackles with power... its \
@@ -871,7 +924,7 @@
speak_chance = 1
turns_per_move = 8
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
move_to_delay = 15
response_help = "pets"
response_disarm = "gently pushes aside"
@@ -20,7 +20,7 @@
attacktext = "chomps"
attack_sound = 'sound/weapons/bite.ogg'
faction = list("mushroom")
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
stat_attack = 2
mouse_opacity = 1
speed = 1
@@ -22,7 +22,7 @@
faction = list("hostile")
attack_sound = 'sound/weapons/bite.ogg'
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
ventcrawler = VENTCRAWLER_ALWAYS
mob_size = MOB_SIZE_TINY
movement_type = FLYING
@@ -23,7 +23,7 @@
attacktext = "attacks"
attack_sound = 'sound/items/bikehorn.ogg'
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
del_on_death = 1
loot = list(/obj/effect/mob_spawn/human/clown/corpse)
@@ -20,6 +20,6 @@
attacktext = "hits"
attack_sound = 'sound/weapons/punch1.ogg'
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
del_on_death = 0
@@ -14,7 +14,7 @@
speed = 0
stat_attack = 1
robust_searching = 1
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
maxHealth = 100
health = 100
harm_intent_damage = 5
@@ -131,7 +131,7 @@
minimum_distance = 10
retreat_distance = 10
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
/mob/living/simple_animal/hostile/syndicate/civilian/Aggro()
..()
@@ -150,7 +150,7 @@
melee_damage_lower = 15
melee_damage_upper = 15
obj_damage = 0
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
attacktext = "cuts"
attack_sound = 'sound/weapons/bladeslice.ogg'
faction = list("syndicate")
@@ -51,7 +51,7 @@
var/attacktext = "attacks"
var/attack_sound = null
var/friendly = "nuzzles" //If the mob does no damage with it's attack
var/environment_smash = 0 //Set to 1 to allow breaking of crates,lockers,racks,tables; 2 for walls; 3 for Rwalls
var/environment_smash = ENVIRONMENT_SMASH_NONE //Set to 1 to allow breaking of crates,lockers,racks,tables; 2 for walls; 3 for Rwalls
var/speed = 1 //LETS SEE IF I CAN SET SPEEDS FOR SIMPLE MOBS WITHOUT DESTROYING EVERYTHING. Higher speed is slower, negative speed is faster
+9 -9
View File
@@ -78,8 +78,8 @@
name = "folder- 'TOP SECRET'"
desc = "A folder stamped \"Top Secret - Property of Nanotrasen Corporation. Unauthorized distribution is punishable by death.\""
/obj/item/weapon/folder/documents/New()
..()
/obj/item/weapon/folder/documents/Initialize()
. = ..()
new /obj/item/documents/nanotrasen(src)
update_icon()
@@ -91,20 +91,20 @@
/obj/item/weapon/folder/syndicate/red
icon_state = "folder_sred"
/obj/item/weapon/folder/syndicate/red/New()
..()
/obj/item/weapon/folder/syndicate/red/Initialize()
. = ..()
new /obj/item/documents/syndicate/red(src)
update_icon()
/obj/item/weapon/folder/syndicate/blue
icon_state = "folder_sblue"
/obj/item/weapon/folder/syndicate/blue/New()
..()
/obj/item/weapon/folder/syndicate/blue/Initialize()
. = ..()
new /obj/item/documents/syndicate/blue(src)
update_icon()
/obj/item/weapon/folder/syndicate/mining/New()
..()
/obj/item/weapon/folder/syndicate/mining/Initialize()
. = ..()
new /obj/item/documents/syndicate/mining(src)
update_icon()
update_icon()
+2 -3
View File
@@ -26,7 +26,7 @@
var/info //What's actually written on the paper.
var/info_links //A different version of the paper which includes html links at fields and EOF
var/stamps //The (text for the) stamps on the paper.
var/fields //Amount of user created fields
var/fields = 0 //Amount of user created fields
var/list/stamped
var/rigged = 0
var/spam_flag = 0
@@ -170,8 +170,7 @@
/obj/item/weapon/paper/proc/updateinfolinks()
info_links = info
var/i = 0
for(i=1,i<=fields,i++)
for(var/i in 1 to min(fields, 15))
addtofield(i, "<font face=\"[PEN_FONT]\"><A href='?src=\ref[src];write=[i]'>write</A></font>", 1)
info_links = info_links + "<font face=\"[PEN_FONT]\"><A href='?src=\ref[src];write=end'>write</A></font>"
+11 -10
View File
@@ -304,16 +304,17 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
// Sound the alert if gravity was just enabled or disabled.
var/alert = 0
var/area/A = get_area(src)
if(on && SSticker.IsRoundInProgress()) // If we turned on and the game is live.
if(gravity_in_level() == 0)
alert = 1
investigate_log("was brought online and is now producing gravity for this level.", "gravity")
message_admins("The gravity generator was brought online [A][ADMIN_COORDJMP(src)]")
else
if(gravity_in_level() == 1)
alert = 1
investigate_log("was brought offline and there is now no gravity for this level.", "gravity")
message_admins("The gravity generator was brought offline with no backup generator. [A][ADMIN_COORDJMP(src)]")
if(SSticker.IsRoundInProgress())
if(on) // If we turned on and the game is live.
if(gravity_in_level() == 0)
alert = 1
investigate_log("was brought online and is now producing gravity for this level.", "gravity")
message_admins("The gravity generator was brought online [A][ADMIN_COORDJMP(src)]")
else
if(gravity_in_level() == 1)
alert = 1
investigate_log("was brought offline and there is now no gravity for this level.", "gravity")
message_admins("The gravity generator was brought offline with no backup generator. [A][ADMIN_COORDJMP(src)]")
update_icon()
update_list()
@@ -9,6 +9,7 @@
firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/energy
/obj/item/ammo_casing/energy/chameleon
projectile_type = /obj/item/projectile/energy/chameleon
e_cost = 0
var/list/projectile_vars = list()
@@ -77,6 +78,9 @@
fire_sound = 'sound/weapons/taser.ogg'
e_cost = 200
/obj/item/ammo_casing/energy/electrode/spec
e_cost = 100
/obj/item/ammo_casing/energy/electrode/gun
fire_sound = 'sound/weapons/gunshot.ogg'
e_cost = 100
@@ -13,6 +13,22 @@
max_ammo = 8
multiple_sprites = 2
/obj/item/ammo_box/magazine/m10mm/rifle
name = "rifle magazine (10mm)"
desc = "A well-worn magazine fitted for the surplus rifle."
icon_state = "75-8"
origin_tech = "combat=2"
ammo_type = /obj/item/ammo_casing/c10mm
caliber = "10mm"
max_ammo = 10
/obj/item/ammo_box/magazine/m10mm/rifle/update_icon()
if(ammo_count())
icon_state = "75-8"
else
icon_state = "75-0"
/obj/item/ammo_box/magazine/m10mm/fire
name = "pistol magazine (10mm incendiary)"
desc = "A gun magazine. Loaded with rounds which ignite the target."
@@ -109,6 +109,11 @@
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
max_ammo = 6
/obj/item/ammo_box/magazine/internal/shot/com/compact
name = "compact combat shotgun internal magazine"
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
max_ammo = 4
/obj/item/ammo_box/magazine/internal/shot/dual
name = "double-barrel shotgun internal magazine"
max_ammo = 2
@@ -377,6 +377,30 @@
// Old Semi-Auto Rifle //
/obj/item/weapon/gun/ballistic/automatic/surplus
name = "Surplus Rifle"
desc = "One of countless obsolete ballistic rifles that still sees use as a cheap deterrent. Uses 10mm ammo and its bulky frame prevents one-hand firing."
origin_tech = "combat=3;materials=2"
icon_state = "surplus"
item_state = "moistnugget"
weapon_weight = WEAPON_HEAVY
mag_type = /obj/item/ammo_box/magazine/m10mm/rifle
fire_delay = 30
burst_size = 1
can_unsuppress = 1
can_suppress = 1
w_class = WEIGHT_CLASS_HUGE
slot_flags = SLOT_BACK
actions_types = list()
/obj/item/weapon/gun/ballistic/automatic/surplus/update_icon()
if(magazine)
icon_state = "surplus"
else
icon_state = "surplus-e"
// Laser rifle (rechargeable magazine) //
@@ -344,6 +344,16 @@
slung = 0
update_icon()
/obj/item/weapon/gun/ballistic/revolver/doublebarrel/improvised/sawn
name = "sawn-off improvised shotgun"
desc = "A single-shot shotgun, better not miss"
icon_state = "ishotgun"
item_state = "gun"
w_class = WEIGHT_CLASS_NORMAL
sawn_state = SAWN_OFF
slot_flags = SLOT_BELT
/obj/item/weapon/gun/ballistic/revolver/reverse //Fires directly at its user... unless the user is a clown, of course.
clumsy_check = 0
@@ -192,6 +192,14 @@
mag_type = /obj/item/ammo_box/magazine/internal/shot/com
w_class = WEIGHT_CLASS_HUGE
/obj/item/weapon/gun/ballistic/shotgun/automatic/combat/compact
name = "compact combat shotgun"
desc = "A compact version of the semi automatic combat shotgun. For close encounters."
icon_state = "cshotgunc"
origin_tech = "combat=4;materials=2"
mag_type = /obj/item/ammo_box/magazine/internal/shot/com/compact
w_class = WEIGHT_CLASS_BULKY
//Dual Feed Shotgun
/obj/item/weapon/gun/ballistic/shotgun/automatic/dual_tube
@@ -31,6 +31,11 @@
if(gun_light && gun_light.on)
add_overlay("mini-light")
/obj/item/weapon/gun/energy/e_gun/stun
name = "tactical energy gun"
desc = "Military issue energy gun, is able to fire stun rounds."
ammo_type = list(/obj/item/ammo_casing/energy/electrode/spec, /obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser)
/obj/item/weapon/gun/energy/e_gun/mini/practice_phaser
name = "practice phaser"
desc = "A modified version of the basic phaser gun, this one fires less concentrated energy bolts designed for target practice."
@@ -61,6 +61,7 @@
for(var/A in get_modkits())
var/obj/item/borg/upgrade/modkit/M = A
M.modify_projectile(K)
K.kinetic_modules += M //do something special on-hit, easy!
/obj/item/weapon/gun/energy/kinetic_accelerator/cyborg
holds_charge = TRUE
@@ -165,9 +166,11 @@
log_override = TRUE
var/pressure_decrease = 0.25
var/turf_aoe = FALSE
var/mob_aoe = 0
var/list/hit_overlays = list()
var/list/kinetic_modules = list()
/obj/item/projectile/kinetic/Destroy()
QDEL_NULL(kinetic_modules)
return ..()
/obj/item/projectile/kinetic/prehit(atom/target)
var/turf/target_turf = get_turf(target)
@@ -197,23 +200,15 @@
M.gets_drilled(firer)
var/obj/effect/temp_visual/kinetic_blast/K = new /obj/effect/temp_visual/kinetic_blast(target_turf)
K.color = color
for(var/type in hit_overlays)
new type(target_turf)
if(turf_aoe)
for(var/T in RANGE_TURFS(1, target_turf) - target_turf)
if(ismineralturf(T))
var/turf/closed/mineral/M = T
M.gets_drilled(firer)
if(mob_aoe)
for(var/mob/living/L in range(1, target_turf) - firer - target)
var/armor = L.run_armor_check(def_zone, flag, "", "", armour_penetration)
L.apply_damage(damage*mob_aoe, damage_type, def_zone, armor)
to_chat(L, "<span class='userdanger'>You're struck by a [name]!</span>")
for(var/obj/item/borg/upgrade/modkit/M in kinetic_modules)
if(QDELETED(M)) //whoever shot this was very, very unfortunate.
continue
M.projectile_strike(src, target_turf, target)
//Modkits
/obj/item/borg/upgrade/modkit
name = "modification kit"
name = "kinetic accelerator modification kit"
desc = "An upgrade for kinetic accelerators."
icon = 'icons/obj/objects.dmi'
icon_state = "modkit"
@@ -266,14 +261,13 @@
to_chat(user, "<span class='notice'>You don't have room(<b>[KA.get_remaining_mod_capacity()]%</b> remaining, [cost]% needed) to install this modkit. Use a crowbar to remove existing modkits.</span>")
. = FALSE
/obj/item/borg/upgrade/modkit/proc/uninstall(obj/item/weapon/gun/energy/kinetic_accelerator/KA)
forceMove(get_turf(KA))
KA.modkits -= src
/obj/item/borg/upgrade/modkit/proc/modify_projectile(obj/item/projectile/kinetic/K)
/obj/item/borg/upgrade/modkit/proc/projectile_strike(obj/item/projectile/kinetic/K, turf/target_turf, atom/target)
//Range
/obj/item/borg/upgrade/modkit/range
@@ -315,21 +309,73 @@
//AoE blasts
/obj/item/borg/upgrade/modkit/aoe
modifier = 0
var/turf_aoe = FALSE
var/stats_stolen = FALSE
/obj/item/borg/upgrade/modkit/aoe/install(obj/item/weapon/gun/energy/kinetic_accelerator/KA, mob/user)
. = ..()
if(.)
for(var/obj/item/borg/upgrade/modkit/aoe/AOE in KA.modkits) //make sure only one of the aoe modules has values if somebody has multiple
if(AOE.stats_stolen)
continue
modifier += AOE.modifier //take its modifiers
AOE.modifier = 0
turf_aoe += AOE.turf_aoe
AOE.turf_aoe = FALSE
AOE.stats_stolen = TRUE
/obj/item/borg/upgrade/modkit/aoe/uninstall(obj/item/weapon/gun/energy/kinetic_accelerator/KA)
..()
modifier = initial(modifier) //get our modifiers back
turf_aoe = initial(turf_aoe)
if(stats_stolen) //if we had our stats stolen, find the stealer and take them from it
for(var/obj/item/borg/upgrade/modkit/aoe/AOE in KA.modkits)
if(AOE.stats_stolen)
continue
AOE.modifier -= modifier
AOE.turf_aoe -= turf_aoe
else //otherwise, reset the stolen stats and have it recalculate
var/obj/item/borg/upgrade/modkit/aoe/new_stealer
for(var/obj/item/borg/upgrade/modkit/aoe/AOE in KA.modkits)
if(!new_stealer)
new_stealer = AOE //just make the first one a stealer
AOE.modifier = initial(AOE.modifier)
AOE.turf_aoe = initial(AOE.turf_aoe)
AOE.stats_stolen = FALSE
if(new_stealer) //if there's no stealer, then there's no other aoe modkits
for(var/obj/item/borg/upgrade/modkit/aoe/AOE in KA.modkits)
if(AOE != new_stealer)
new_stealer.modifier += AOE.modifier
AOE.modifier = 0
new_stealer.turf_aoe += AOE.turf_aoe
AOE.turf_aoe = FALSE
AOE.stats_stolen = TRUE
stats_stolen = FALSE
/obj/item/borg/upgrade/modkit/aoe/modify_projectile(obj/item/projectile/kinetic/K)
K.name = "kinetic explosion"
if(!K.turf_aoe && !K.mob_aoe)
K.hit_overlays += /obj/effect/temp_visual/explosion/fast
K.mob_aoe += modifier
/obj/item/borg/upgrade/modkit/aoe/projectile_strike(obj/item/projectile/kinetic/K, turf/target_turf, atom/target)
if(stats_stolen)
return
new /obj/effect/temp_visual/explosion/fast(target_turf)
if(turf_aoe)
for(var/T in RANGE_TURFS(1, target_turf) - target_turf)
if(ismineralturf(T))
var/turf/closed/mineral/M = T
M.gets_drilled(K.firer)
if(modifier)
for(var/mob/living/L in range(1, target_turf) - K.firer - target)
var/armor = L.run_armor_check(K.def_zone, K.flag, "", "", K.armour_penetration)
L.apply_damage(K.damage*modifier, K.damage_type, K.def_zone, armor)
to_chat(L, "<span class='userdanger'>You're struck by a [K.name]!</span>")
/obj/item/borg/upgrade/modkit/aoe/turfs
name = "mining explosion"
desc = "Causes the kinetic accelerator to destroy rock in an AoE."
denied_type = /obj/item/borg/upgrade/modkit/aoe/turfs
/obj/item/borg/upgrade/modkit/aoe/turfs/modify_projectile(obj/item/projectile/kinetic/K)
..()
K.turf_aoe = TRUE
turf_aoe = TRUE
/obj/item/borg/upgrade/modkit/aoe/turfs/andmobs
name = "offensive mining explosion"
@@ -346,11 +392,11 @@
//Indoors
/obj/item/borg/upgrade/modkit/indoors
name = "decrease pressure penalty"
desc = "Increases the damage a kinetic accelerator does in a high pressure environment."
desc = "A syndicate modification kit that increases the damage a kinetic accelerator does in a high pressure environment."
modifier = 2
denied_type = /obj/item/borg/upgrade/modkit/indoors
maximum_of_type = 2
cost = 40
cost = 35
/obj/item/borg/upgrade/modkit/indoors/modify_projectile(obj/item/projectile/kinetic/K)
K.pressure_decrease *= modifier
@@ -5,6 +5,7 @@
item_state = null
w_class = WEIGHT_CLASS_BULKY
force = 10
modifystate = TRUE
flags = CONDUCT
slot_flags = SLOT_BACK
ammo_type = list(/obj/item/ammo_casing/energy/laser/pulse, /obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser)
@@ -39,7 +40,7 @@
w_class = WEIGHT_CLASS_NORMAL
slot_flags = SLOT_BELT
icon_state = "pulse_carbine"
item_state = "pulse"
item_state = null
cell_type = "/obj/item/weapon/stock_parts/cell/pulse/carbine"
can_flashlight = 1
flight_x_offset = 18
@@ -56,7 +57,6 @@
icon_state = "pulse_pistol"
item_state = "gun"
cell_type = "/obj/item/weapon/stock_parts/cell/pulse/pistol"
can_charge = 0
/obj/item/weapon/gun/energy/pulse/pistol/loyalpin
pin = /obj/item/device/firing_pin/implant/mindshield
@@ -5,6 +5,8 @@
damage_type = BURN
flag = "energy"
/obj/item/projectile/energy/chameleon
nodamage = TRUE
/obj/item/projectile/energy/electrode
name = "electrode"
@@ -200,9 +200,10 @@
icon_state = "plasmacutter"
damage_type = BRUTE
damage = 5
range = 3.5 //works as 4, but doubles to 7
range = 4
dismemberment = 20
impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser
var/mine_range = 3 //mines this many additional tiles
/obj/item/projectile/plasma/Initialize()
. = ..()
@@ -215,24 +216,27 @@
if(pressure < 60)
name = "full strength [name]"
damage *= 4
range *= 2
/obj/item/projectile/plasma/on_hit(atom/target)
. = ..()
if(ismineralturf(target))
var/turf/closed/mineral/M = target
M.gets_drilled(firer)
Range()
if(mine_range)
mine_range--
range++
if(range > 0)
return -1
/obj/item/projectile/plasma/adv
damage = 7
range = 5
mine_range = 5
/obj/item/projectile/plasma/adv/mech
damage = 10
range = 6
range = 9
mine_range = 3
/obj/item/projectile/plasma/turret
//Between normal and advanced for damage, made a beam so not the turret does not destroy glass
@@ -1,285 +1,183 @@
/obj/machinery/computer/pandemic
name = "PanD.E.M.I.C 2200"
desc = "Used to work with viruses."
density = 1
anchored = 1
density = TRUE
anchored = TRUE
icon = 'icons/obj/chemical.dmi'
icon_state = "mixer0"
circuit = /obj/item/weapon/circuitboard/computer/pandemic
use_power = 1
use_power = TRUE
idle_power_usage = 20
resistance_flags = ACID_PROOF
var/temp_html = ""
var/wait = null
var/obj/item/weapon/reagent_containers/beaker = null
var/wait
var/obj/item/weapon/reagent_containers/beaker
/obj/machinery/computer/pandemic/Initialize()
. = ..()
update_icon()
/obj/machinery/computer/pandemic/proc/GetVirusByIndex(index)
if(beaker && beaker.reagents)
if(beaker.reagents.reagent_list.len)
var/datum/reagent/blood/BL = locate() in beaker.reagents.reagent_list
if(BL)
if(BL.data && BL.data["viruses"])
var/list/viruses = BL.data["viruses"]
return viruses[index]
return null
/obj/machinery/computer/pandemic/Destroy()
QDEL_NULL(beaker)
return ..()
/obj/machinery/computer/pandemic/proc/GetResistancesByIndex(index)
if(beaker && beaker.reagents)
if(beaker.reagents.reagent_list.len)
var/datum/reagent/blood/BL = locate() in beaker.reagents.reagent_list
if(BL)
if(BL.data && BL.data["resistances"])
var/list/resistances = BL.data["resistances"]
return resistances[index]
return null
/obj/machinery/computer/pandemic/proc/get_by_index(thing, index)
if(!beaker || !beaker.reagents)
return
var/datum/reagent/blood/B = locate() in beaker.reagents.reagent_list
if(B && B.data[thing])
return B.data[thing][index]
/obj/machinery/computer/pandemic/proc/GetVirusTypeByIndex(index)
var/datum/disease/D = GetVirusByIndex(index)
/obj/machinery/computer/pandemic/proc/get_virus_id_by_index(index)
var/datum/disease/D = get_by_index("viruses", index)
if(D)
return D.GetDiseaseID()
return null
/obj/machinery/computer/pandemic/proc/replicator_cooldown(waittime)
wait = 1
/obj/machinery/computer/pandemic/proc/get_viruses_data(datum/reagent/blood/B)
. = list()
if(!islist(B.data["viruses"]))
return
var/list/V = B.data["viruses"]
var/index = 1
for(var/virus in V)
var/datum/disease/D = virus
if(!istype(D) || D.visibility_flags & HIDDEN_PANDEMIC)
continue
var/list/this = list()
this["name"] = D.name
if(istype(D, /datum/disease/advance))
var/datum/disease/advance/A = SSdisease.archive_diseases[D.GetDiseaseID()]
if(A.name == "Unknown")
this["can_rename"] = TRUE
this["name"] = A.name
this["is_adv"] = TRUE
this["resistance"] = A.totalResistance()
this["stealth"] = A.totalStealth()
this["stage_speed"] = A.totalStageSpeed()
this["transmission"] = A.totalTransmittable()
this["symptoms"] = list()
for(var/symptom in A.symptoms)
var/datum/symptom/S = symptom
var/list/this_symptom = list()
this_symptom["name"] = S.name
this["symptoms"] += list(this_symptom)
this["index"] = index++
this["agent"] = D.agent
this["description"] = D.desc || "none"
this["spread"] = D.spread_text || "none"
this["cure"] = D.cure_text || "none"
. += list(this)
/obj/machinery/computer/pandemic/proc/get_resistance_data(datum/reagent/blood/B)
. = list()
if(!islist(B.data["resistances"]))
return
var/list/resistances = B.data["resistances"]
for(var/id in resistances)
var/list/this = list()
var/datum/disease/D = SSdisease.archive_diseases[id]
if(D)
this["id"] = id
this["name"] = D.name
. += list(this)
/obj/machinery/computer/pandemic/proc/reset_replicator_cooldown()
wait = FALSE
update_icon()
spawn(waittime)
wait = null
update_icon()
playsound(src.loc, 'sound/machines/ping.ogg', 30, 1)
playsound(loc, 'sound/machines/ping.ogg', 30, 1)
/obj/machinery/computer/pandemic/update_icon()
if(stat & BROKEN)
icon_state = (beaker ? "mixer1_b" : "mixer0_b")
return
icon_state = "mixer[(beaker)?"1":"0"][(powered()) ? "" : "_nopower"]"
icon_state = "mixer[(beaker) ? "1" : "0"][powered() ? "" : "_nopower"]"
if(wait)
cut_overlays()
else
add_overlay("waitlight")
/obj/machinery/computer/pandemic/Topic(href, href_list)
/obj/machinery/computer/pandemic/proc/eject_beaker()
beaker.forceMove(get_turf(src))
beaker = null
update_icon()
/obj/machinery/computer/pandemic/ui_interact(mob/user, ui_key = "main", datum/tgui/ui, force_open = FALSE, datum/tgui/master_ui, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "pandemic", name, 575, 500, master_ui, state)
ui.open()
/obj/machinery/computer/pandemic/ui_data(mob/user)
var/list/data = list()
data["is_ready"] = !wait
if(beaker)
data["has_beaker"] = TRUE
if(!beaker.reagents.total_volume || !beaker.reagents.reagent_list)
data["beaker_empty"] = TRUE
var/datum/reagent/blood/B = locate() in beaker.reagents.reagent_list
if(B)
data["has_blood"] = TRUE
data["blood"] = list()
data["blood"]["dna"] = B.data["blood_DNA"] || "none"
data["blood"]["type"] = B.data["blood_type"] || "none"
data["viruses"] = get_viruses_data(B)
data["resistances"] = get_resistance_data(B)
return data
/obj/machinery/computer/pandemic/ui_act(action, params)
if(..())
return
usr.set_machine(src)
if(!beaker) return
if (href_list["create_vaccine"])
if(!src.wait)
var/obj/item/weapon/reagent_containers/glass/bottle/B = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc)
if(B)
B.pixel_x = rand(-3, 3)
B.pixel_y = rand(-3, 3)
var/path = GetResistancesByIndex(text2num(href_list["create_vaccine"]))
var/vaccine_type = path
var/vaccine_name = "Unknown"
if(!ispath(vaccine_type))
if(SSdisease.archive_diseases[path])
var/datum/disease/D = SSdisease.archive_diseases[path]
if(D)
vaccine_name = D.name
vaccine_type = path
else if(vaccine_type)
var/datum/disease/D = new vaccine_type(0, null)
if(D)
vaccine_name = D.name
if(vaccine_type)
B.name = "[vaccine_name] vaccine bottle"
B.reagents.add_reagent("vaccine", 15, list(vaccine_type))
replicator_cooldown(200)
else
temp_html = "The replicator is not ready yet."
updateUsrDialog()
return
else if (href_list["create_virus_culture"])
if(!wait)
var/type = GetVirusTypeByIndex(text2num(href_list["create_virus_culture"]))//the path is received as string - converting
var/datum/disease/D = null
if(!ispath(type))
D = GetVirusByIndex(text2num(href_list["create_virus_culture"]))
var/datum/disease/advance/A = SSdisease.archive_diseases[D.GetDiseaseID()]
if(A)
D = new A.type(0, A)
else if(type)
if(type in SSdisease.diseases) // Make sure this is a disease
D = new type(0, null)
if(!D)
return
var/name = stripped_input(usr,"Name:","Name the culture",D.name,MAX_NAME_LEN)
if(name == null || wait)
return
var/obj/item/weapon/reagent_containers/glass/bottle/B = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc)
B.icon_state = "bottle3"
B.pixel_x = rand(-3, 3)
B.pixel_y = rand(-3, 3)
replicator_cooldown(50)
var/list/data = list("viruses"=list(D))
B.name = "[name] culture bottle"
B.desc = "A small bottle. Contains [D.agent] culture in synthblood medium."
B.reagents.add_reagent("blood",20,data)
updateUsrDialog()
else
temp_html = "The replicator is not ready yet."
updateUsrDialog()
return
else if (href_list["empty_beaker"])
beaker.reagents.clear_reagents()
updateUsrDialog()
return
else if (href_list["eject"])
beaker.forceMove(get_turf(loc))
beaker = null
icon_state = "mixer0"
updateUsrDialog()
return
else if (href_list["emptyeject_beaker"])
beaker.reagents.clear_reagents()
beaker.forceMove(get_turf(loc))
beaker = null
icon_state = "mixer0"
updateUsrDialog()
return
else if(href_list["clear"])
temp_html = ""
updateUsrDialog()
return
else if(href_list["name_disease"])
var/new_name = stripped_input(usr, "Name the Disease", "New Name", "", MAX_NAME_LEN)
if(!new_name)
return
if(..())
return
var/id = GetVirusTypeByIndex(text2num(href_list["name_disease"]))
if(SSdisease.archive_diseases[id])
switch(action)
if("eject_beaker")
eject_beaker()
. = TRUE
if("empty_beaker")
beaker.reagents.clear_reagents()
. = TRUE
if("empty_eject_beaker")
beaker.reagents.clear_reagents()
eject_beaker()
. = TRUE
if("rename_disease")
var/id = get_virus_id_by_index(text2num(params["index"]))
var/datum/disease/advance/A = SSdisease.archive_diseases[id]
A.AssignName(new_name)
for(var/datum/disease/advance/AD in SSdisease.processing)
AD.Refresh()
updateUsrDialog()
else
usr << browse(null, "window=pandemic")
updateUsrDialog()
return
add_fingerprint(usr)
return
/obj/machinery/computer/pandemic/attack_hand(mob/user)
if(..())
return
user.set_machine(src)
var/dat = ""
if(temp_html)
dat = "[src.temp_html]<BR><BR><A href='?src=\ref[src];clear=1'>Main Menu</A>"
else if(!beaker)
dat += "Please insert beaker.<BR>"
dat += "<A href='?src=\ref[user];mach_close=pandemic'>Close</A>"
else
var/datum/reagents/R = beaker.reagents
var/datum/reagent/blood/Blood = null
for(var/datum/reagent/blood/B in R.reagent_list)
if(B)
Blood = B
break
if(!R.total_volume||!R.reagent_list.len)
dat += "The beaker is empty<BR>"
else if(!Blood)
dat += "No blood sample found in beaker."
else if(!Blood.data)
dat += "No blood data found in beaker."
else
dat += "<h3>Blood sample data:</h3>"
dat += "<b>Blood DNA:</b> [(Blood.data["blood_DNA"]||"none")]<BR>"
dat += "<b>Blood Type:</b> [(Blood.data["blood_type"]||"none")]<BR>"
if(Blood.data["viruses"])
var/list/vir = Blood.data["viruses"]
if(vir.len)
var/i = 0
for(var/datum/disease/D in Blood.data["viruses"])
i++
if(!(D.visibility_flags & HIDDEN_PANDEMIC))
if(istype(D, /datum/disease/advance))
var/datum/disease/advance/A = D
D = SSdisease.archive_diseases[A.GetDiseaseID()]
if(D && D.name == "Unknown")
dat += "<b><a href='?src=\ref[src];name_disease=[i]'>Name Disease</a></b><BR>"
if(!D)
CRASH("We weren't able to get the advance disease from the archive.")
dat += "<b>Disease Agent:</b> [D?"[D.agent] - <A href='?src=\ref[src];create_virus_culture=[i]'>Create virus culture bottle</A>":"none"]<BR>"
dat += "<b>Common name:</b> [(D.name||"none")]<BR>"
dat += "<b>Description: </b> [(D.desc||"none")]<BR>"
dat += "<b>Spread:</b> [(D.spread_text||"none")]<BR>"
dat += "<b>Possible cure:</b> [(D.cure_text||"none")]<BR><BR>"
if(istype(D, /datum/disease/advance))
var/datum/disease/advance/A = D
dat += "<b>Stealth:</b> [(A.totalStealth())]<BR>"
dat += "<b>Resistance:</b> [(A.totalResistance())]<BR>"
dat += "<b>Stage Speed:</b> [(A.totalStageSpeed())]<BR>"
dat += "<b>Transmission:</b> [(A.totalTransmittable())]<BR><BR>"
dat += "<b>Symptoms:</b> "
var/english_symptoms = list()
for(var/datum/symptom/S in A.symptoms)
english_symptoms += S.name
dat += english_list(english_symptoms)
else
dat += "No detectable virus in the sample."
else
dat += "No detectable virus in the sample."
dat += "<BR><b>Contains antibodies to:</b> "
if(Blood.data["resistances"])
var/list/res = Blood.data["resistances"]
if(res.len)
dat += "<ul>"
var/i = 0
for(var/type in Blood.data["resistances"])
i++
var/disease_name = "Unknown"
if(!ispath(type))
var/datum/disease/advance/A = SSdisease.archive_diseases[type]
if(A)
disease_name = A.name
else
var/datum/disease/D = new type(0, null)
disease_name = D.name
dat += "<li>[disease_name] - <A href='?src=\ref[src];create_vaccine=[i]'>Create vaccine bottle</A></li>"
dat += "</ul><BR>"
else
dat += "nothing<BR>"
else
dat += "nothing<BR>"
dat += "<BR><A href='?src=\ref[src];eject=1'>Eject beaker</A>[((R.total_volume&&R.reagent_list.len) ? "-- <A href='?src=\ref[src];empty_beaker=1'>Empty beaker</A>":"")]"
dat += "[((R.total_volume&&R.reagent_list.len) ? "-- <A href='?src=\ref[src];emptyeject_beaker=1'>Empty and Eject beaker</A>":"")]<BR>"
dat += "<A href='?src=\ref[user];mach_close=pandemic'>Close</A>"
user << browse("<TITLE>[src.name]</TITLE><BR>[dat]", "window=pandemic;size=575x400")
onclose(user, "pandemic")
return
if(A)
var/new_name = stripped_input(usr, "Name the disease", "New name", "", MAX_NAME_LEN)
if(!new_name || ..())
return
A.AssignName(new_name)
for(var/datum/disease/advance/AD in SSdisease.processing)
AD.Refresh()
. = TRUE
if("create_culture_bottle")
var/id = get_virus_id_by_index(text2num(params["index"]))
var/datum/disease/advance/A = new(FALSE, SSdisease.archive_diseases[id])
var/list/data = list("viruses" = list(A))
var/obj/item/weapon/reagent_containers/glass/bottle/B = new(get_turf(src))
B.name = "[A.name] culture bottle"
B.desc = "A small bottle. Contains [A.agent] culture in synthblood medium."
B.reagents.add_reagent("blood", 20, data)
wait = TRUE
update_icon()
addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 50)
. = TRUE
if("create_vaccine_bottle")
var/index = params["index"]
var/datum/disease/D = SSdisease.archive_diseases[index]
var/obj/item/weapon/reagent_containers/glass/bottle/B = new(get_turf(src))
B.name = "[D.name] vaccine bottle"
B.reagents.add_reagent("vaccine", 15, list(index))
wait = TRUE
update_icon()
addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 200)
. = TRUE
/obj/machinery/computer/pandemic/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/reagent_containers) && (I.container_type & OPENCONTAINER))
. = 1 //no afterattack
. = TRUE //no afterattack
if(stat & (NOPOWER|BROKEN))
return
if(beaker)
@@ -288,15 +186,15 @@
if(!user.drop_item())
return
beaker = I
beaker.loc = src
beaker = I
beaker.forceMove(src)
to_chat(user, "<span class='notice'>You add the beaker to the machine.</span>")
updateUsrDialog()
icon_state = "mixer1"
update_icon()
else
return ..()
/obj/machinery/computer/pandemic/on_deconstruction()
if(beaker)
beaker.loc = get_turf(src)
..()
beaker.forceMove(get_turf(src))
beaker = null
. = ..()
@@ -378,7 +378,7 @@
if(N.w_uniform)
M.visible_message(pick("<b>[M]</b>'s collar pops up without warning.</span>", "<b>[M]</b> flexes [M.p_their()] arms."))
else
M.visible_message("<b>[M]</b> [M.p_their()] their arms.")
M.visible_message("<b>[M]</b> flexes [M.p_their()] arms.")
if(prob(10))
M.say(pick("Check these sweet biceps bro!", "Deal with it.", "CHUG! CHUG! CHUG! CHUG!", "Winning!", "NERDS!", "My name is John and I hate every single one of you."))
..()
-10
View File
@@ -249,16 +249,6 @@ other types of metals and chemistry for reagents).
build_path = /obj/item/borg/upgrade/modkit/range
category = list("Mining Designs", "Cyborg Upgrade Modules")
/datum/design/superaccelerator
name = "Kinetic Accelerator Pressure Mod"
desc = "A modification kit which allows Kinetic Accelerators to do more damage while indoors."
id = "indoormod"
req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3)
build_type = PROTOLATHE | MECHFAB
materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_URANIUM = 2000)
build_path = /obj/item/borg/upgrade/modkit/indoors
category = list("Mining Designs", "Cyborg Upgrade Modules")
/datum/design/hyperaccelerator
name = "Kinetic Accelerator Mining AoE Mod"
desc = "A modification kit for Kinetic Accelerators which causes it to fire AoE blasts that destroy rock."
+1 -1
View File
@@ -254,7 +254,7 @@
/mob/living/simple_animal/hostile/bear/fightpit
name = "fight pit bear"
desc = "This bear's trained through ancient Russian secrets to fear the walls of its glass prison."
environment_smash = 0
environment_smash = ENVIRONMENT_SMASH_NONE
/obj/effect/decal/hammerandsickle
name = "hammer and sickle"
+7 -3
View File
@@ -83,14 +83,18 @@
//sometimes we want to ignore that we don't have the required amount of legs.
/mob/proc/get_leg_ignore()
return 0
return FALSE
/mob/living/carbon/alien/larva/get_leg_ignore()
return 1
return TRUE
/mob/living/carbon/human/get_leg_ignore()
if(movement_type & FLYING)
return 1
return TRUE
var/obj/item/weapon/tank/jetpack/J = get_jetpack()
if(J && J.on && !has_gravity())
return TRUE
return FALSE
/mob/living/proc/get_missing_limbs()
return list()
+11 -3
View File
@@ -1295,7 +1295,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
cost = 10
item = /obj/item/weapon/pneumatic_cannon/pie/selfcharge
restricted_roles = list("Clown")
surplus = 0 //No fun unless you're the clown!
surplus = 0 //No fun unless you're the clown!
/datum/uplink_item/role_restricted/ancient_jumpsuit
name = "Ancient Jumpsuit"
@@ -1311,8 +1311,8 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
item = /obj/item/toy/eightball/haunted
cost = 2
restricted_roles = list("Curator")
limited_stock = 1 // please don't spam deadchat
limited_stock = 1 //please don't spam deadchat
/datum/uplink_item/role_restricted/modified_syringe_gun
name = "Modified Syringe Gun"
desc = "A syringe gun that fires DNA injectors instead of normal syringes."
@@ -1320,6 +1320,14 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once.
cost = 14
restricted_roles = list("Geneticist", "Chief Medical Officer")
/datum/uplink_item/role_restricted/pressure_mod
name = "Kinetic Accelerator Pressure Mod"
desc = "A modification kit which allows Kinetic Accelerators to do greatly increased damage while indoors. Occupies 35% mod capacity."
item = /obj/item/borg/upgrade/modkit/indoors
cost = 5 //you need two for full damage, so total of 10 for maximum damage
limited_stock = 2 //you can't use more than two!
restricted_roles = list("Shaft Miner")
// Pointless
/datum/uplink_item/badass
category = "(Pointless) Badassery"