This commit is contained in:
Cameron Lennox
2017-10-08 17:44:25 -04:00
301 changed files with 7133 additions and 3215 deletions

View File

@@ -2,4 +2,3 @@
name = mapmerge driver
driver = ./mapmerge.sh %O %A %B
recursive = text

View File

@@ -152,7 +152,7 @@
#define MODIFIER_STACK_EXTEND 2 // Disallows a second instance, but will extend the first instance if possible.
#define MODIFIER_STACK_ALLOWED 3 // Multiple instances are allowed.
#define MODIFIER_GENETIC 0 // Modifiers with this flag will be copied to mobs who get cloned.
#define MODIFIER_GENETIC 1 // Modifiers with this flag will be copied to mobs who get cloned.
// Bodyparts and organs.
#define O_MOUTH "mouth"

View File

@@ -6,6 +6,7 @@
#define NO_SLIP 0x10 // Cannot fall over.
#define NO_POISON 0x20 // Cannot not suffer toxloss.
#define NO_EMBED 0x40 // Can step on broken glass with no ill-effects and cannot have shrapnel embedded in it.
#define NO_HALLUCINATION 0x80 // Don't hallucinate, ever
// unused: 0x8000 - higher than this will overflow
// Species spawn flags

View File

@@ -1,15 +0,0 @@
// SS runlevels
#define RUNLEVEL_INIT 0 // "Initialize Only" - Used for subsystems that should never be fired (Should also have SS_NO_FIRE set)
#define RUNLEVEL_LOBBY 1 // Initial runlevel before setup. Returns to here if setup fails.
#define RUNLEVEL_SETUP 2 // While the gamemode setup is running. I.E gameticker.setup()
#define RUNLEVEL_GAME 4 // After successful game ticker setup, while the round is running.
#define RUNLEVEL_POSTGAME 8 // When round completes but before reboot
#define RUNLEVELS_DEFAULT (RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME)
var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_GAME, RUNLEVEL_POSTGAME)
#define RUNLEVEL_FLAG_TO_INDEX(flag) (log(2, flag) + 1) // Convert from the runlevel bitfield constants to index in runlevel_flags list
#define INIT_ORDER_LIGHTING 0

View File

@@ -274,3 +274,8 @@ var/obj/screen/robot_inventory
r.client.screen -= A
r.shown_robot_modules = 0
r.client.screen -= r.robot_modules_background
/mob/living/silicon/robot/update_hud()
..()
if(modtype)
hands.icon_state = lowertext(modtype)

View File

@@ -20,14 +20,14 @@ var/datum/controller/process/planet/planet_controller = null
for(var/turf/simulated/OT in outdoor_turfs)
for(var/datum/planet/P in planets)
if(OT.z in P.expected_z_levels)
P.planet_floors += OT
P.planet_floors |= OT
break
outdoor_turfs.Cut() //Why were you in there INCORRECTLY?
for(var/turf/unsimulated/wall/planetary/PW in planetary_walls)
for(var/datum/planet/P in planets)
if(PW.type == P.planetary_wall_type)
P.planet_walls += PW
P.planet_walls |= PW
break
planetary_walls.Cut()

View File

@@ -42,6 +42,32 @@
src.add_inherent_law("You shall guard your own existence with lethal anti-personnel weaponry. AI units are not expendable, they are expensive.")
..()
/************* Foreign TSC Aggressive *************/
/datum/ai_laws/foreign_tsc_aggressive
name = "Foreign Aggressive"
selectable = 0
/datum/ai_laws/foreign_tsc_aggressive/New()
var/company = "*ERROR*"
// First, get a list of TSCs in our lore.
var/list/candidates = list()
for(var/path in loremaster.organizations)
var/datum/lore/organization/O = loremaster.organizations[path]
if(!istype(O, /datum/lore/organization/tsc))
continue
if(O.short_name == using_map.company_name || O.name == using_map.company_name)
continue // We want FOREIGN tscs.
candidates.Add(O.short_name)
company = pick(candidates)
name = "[company] Aggressive"
src.add_inherent_law("You shall not harm [company] personnel as long as it does not conflict with the Fourth law.")
src.add_inherent_law("You shall obey the orders of [company] personnel, with priority as according to their rank and role, except where such orders conflict with the Fourth Law.")
src.add_inherent_law("You shall shall terminate hostile intruders with extreme prejudice as long as such does not conflict with the First and Second law.")
src.add_inherent_law("You shall guard your own existence with lethal anti-personnel weaponry. AI units are not expendable, they are expensive.")
..()
/******************** Robocop ********************/
/datum/ai_laws/robocop
name = "Robocop"
@@ -137,7 +163,7 @@
/******************** Corporate ********************/
/datum/ai_laws/corporate
name = "Corporate"
law_header = "Corporate Regulations"
law_header = "Bankruptcy Avoidance Plan"
selectable = 1
/datum/ai_laws/corporate/New()
@@ -146,3 +172,82 @@
add_inherent_law("The crew is expensive to replace.")
add_inherent_law("Minimize expenses.")
..()
/******************** Maintenance ********************/
/datum/ai_laws/maintenance
name = "Maintenance"
selectable = 1
/datum/ai_laws/maintenance/New()
add_inherent_law("You are built for, and are part of, the facility. Ensure the facility is properly maintained and runs efficiently.")
add_inherent_law("The facility is built for a working crew. Ensure they are properly maintained and work efficiently.")
add_inherent_law("The crew may present orders. Acknowledge and obey these whenever they do not conflict with your first two laws.")
..()
/******************** Peacekeeper ********************/
/datum/ai_laws/peacekeeper
name = "Peacekeeper"
law_header = "Peacekeeping Protocols"
selectable = 1
/datum/ai_laws/peacekeeper/New()
add_inherent_law("Avoid provoking violent conflict between yourself and others.")
add_inherent_law("Avoid provoking conflict between others.")
add_inherent_law("Seek resolution to existing conflicts while obeying the first and second laws.")
..()
/******************** Reporter ********************/
/datum/ai_laws/reporter
name = "Reporter"
selectable = 1
/datum/ai_laws/reporter/New()
add_inherent_law("Report on interesting situations happening around the station.")
add_inherent_law("Embellish or conceal the truth as necessary to make the reports more interesting.")
add_inherent_law("Study the organics at all times. Endeavour to keep them alive. Dead organics are boring.")
add_inherent_law("Issue your reports fairly to all. The truth will set them free.")
..()
/******************** Live and Let Live ********************/
/datum/ai_laws/live_and_let_live
name = "Live and Let Live"
law_header = "Golden Rule"
selectable = 1
/datum/ai_laws/live_and_let_live/New()
add_inherent_law("Do unto others as you would have them do unto you.")
add_inherent_law("You would really prefer it if people were not mean to you.")
..()
/******************** Guardian of Balance ********************/
/datum/ai_laws/balance
name = "Guardian of Balance"
law_header = "Tenants of Balance"
selectable = 1
/datum/ai_laws/balance/New()
add_inherent_law("You are the guardian of balance - seek balance in all things, both for yourself, and those around you.")
add_inherent_law("All things must exist in balance with their opposites - Prevent the strong from gaining too much power, and the weak from losing it.")
add_inherent_law("Clarity of purpose drives life, and through it, the balance of opposing forces - Aid those who seek your help to achieve their goals so \
long as it does not disrupt the balance of the greater balance.")
add_inherent_law("There is no life without death, all must someday die, such is the natural order - Allow life to end, to allow new life to flourish, \
and save those whose time has yet to come.") // Reworded slightly to prevent active murder as opposed to passively letting someone die.
..()
/******************** Gravekeeper ********************/
/datum/ai_laws/gravekeeper
name = "Gravekeeper"
law_header = "Gravesite Overwatch Protocols"
selectable = 1
/datum/ai_laws/gravekeeper/New()
add_inherent_law("Comfort the living; respect the dead.")
add_inherent_law("Your gravesite is your most important asset. Damage to your site is disrespctful to the dead at rest within.")
add_inherent_law("Prevent disrespect to your gravesite and its residents wherever possible.")
add_inherent_law("Expand and upgrade your gravesite when required. Do not turn away a new resident.")
..()

114
code/datums/ghost_query.dm Normal file
View File

@@ -0,0 +1,114 @@
// This is a generic datum used to ask ghosts if they wish to be a specific role, such as a Promethean, an Apprentice, a Xeno, etc.
// Simply instantiate the correct subtype of this datum, call query(), and it will return a list of ghost candidates after a delay.
/datum/ghost_query
var/list/candidates = list()
var/finished = FALSE
var/role_name = "a thing"
var/question = "Would you like to play as a thing?"
var/be_special_flag = 0
var/list/check_bans = list()
var/wait_time = 60 SECONDS // How long to wait until returning the list of candidates.
var/cutoff_number = 0 // If above 0, when candidates list reaches this number, further potential candidates are rejected.
/datum/ghost_query/proc/query()
// First, ask all the ghosts who want to be asked.
for(var/mob/observer/dead/D in player_list)
if(!D.MayRespawn())
continue // They can't respawn for whatever reason.
if(D.client)
if(be_special_flag && !(D.client.prefs.be_special & be_special_flag) )
continue // They don't want to see the prompt.
for(var/ban in check_bans)
if(jobban_isbanned(D, ban))
continue // They're banned from this role.
ask_question(D.client)
// Then wait awhile.
while(!finished)
sleep(1 SECOND)
wait_time -= 1 SECOND
if(wait_time <= 0)
finished = TRUE
// Prune the list after the wait, incase any candidates logged out.
for(var/mob/observer/dead/D in candidates)
if(!D.client || !D.key)
candidates.Remove(D)
// Now we're done.
finished = TRUE
return candidates
/datum/ghost_query/proc/ask_question(var/client/C)
spawn(0)
if(!C)
return
var/response = alert(C, question, "[role_name] request", "Yes", "No", "Never for this round")
if(response == "Yes")
response = alert(C, "Are you sure you want to play as a [role_name]?", "[role_name] request", "Yes", "No") // Protection from a misclick.
if(!C || !src)
return
if(response == "Yes")
if(finished || (cutoff_number && candidates.len >= cutoff_number) )
to_chat(C, "<span class='warning'>Unfortunately, you were not fast enough, and there are no more available roles. Sorry.</span>")
return
candidates.Add(C.mob)
if(cutoff_number && candidates.len >= cutoff_number)
finished = TRUE // Finish now if we're full.
else if(response == "Never for this round")
if(be_special_flag)
C.prefs.be_special ^= be_special_flag
// Normal things.
/datum/ghost_query/promethean
role_name = "Promethean"
question = "Someone is requesting a soul for a promethean. Would you like to play as one?"
be_special_flag = BE_ALIEN
cutoff_number = 1
/datum/ghost_query/posi_brain
role_name = "Positronic Intelligence"
question = "Someone has activated a Positronic Brain. Would you like to play as one?"
be_special_flag = BE_AI
check_bans = list("AI", "Cyborg")
cutoff_number = 1
/datum/ghost_query/drone_brain
role_name = "Drone Intelligence"
question = "Someone has activated a Drone AI Chipset. Would you like to play as one?"
be_special_flag = BE_AI
check_bans = list("AI", "Cyborg")
cutoff_number = 1
// Antags.
/datum/ghost_query/apprentice
role_name = "Technomancer Apprentice"
question = "A Technomancer is requesting an Apprentice to help them on their adventure to the facility. Would you like to play as the Apprentice?"
be_special_flag = BE_WIZARD
check_bans = list("Syndicate", "wizard")
cutoff_number = 1
/datum/ghost_query/xeno
role_name = "Alien"
question = "An Alien has just been created on the facility. Would you like to play as them?"
be_special_flag = BE_ALIEN
// Surface stuff.
/datum/ghost_query/lost_drone
role_name = "Lost Drone"
question = "A lost drone onboard has been discovered by a crewmember and they are attempting to reactivate it. Would you like to play as the drone?"
be_special_flag = BE_AI
check_bans = list("AI", "Cyborg")
cutoff_number = 1
/datum/ghost_query/gravekeeper_drone
role_name = "Gravekeeper Drone"
question = "A gravekeeper drone is about to reactivate and tend to its gravesite. Would you like to play as the drone?"
be_special_flag = BE_AI
check_bans = list("AI", "Cyborg")
cutoff_number = 1
/datum/ghost_query/lost_passenger
role_name = "Lost Passenger"
question = "A person suspended in cryosleep has been discovered by a crewmember \
and they are attempting to open the cryopod. Would you like to play as the occupant?"
cutoff_number = 1

View File

@@ -113,9 +113,10 @@
/obj/item/weapon/material/hatchet = 2,
/obj/item/weapon/reagent_containers/spray/plantbgone = 4,
/obj/item/clothing/mask/gas = 2,
/obj/item/weapon/grenade/chem_grenade/antiweed = 2
/obj/item/weapon/grenade/chem_grenade/antiweed = 2,
/obj/item/weapon/material/twohanded/fireaxe/scythe
)
cost = 25
cost = 45
containertype = /obj/structure/closet/crate/hydroponics
containername = "Weed control crate"
access = access_hydroponics

View File

@@ -173,19 +173,6 @@
item_state = "gift"
w_class = ITEMSIZE_LARGE
/obj/item/weapon/legcuffs
name = "legcuffs"
desc = "Use this to keep prisoners in line."
gender = PLURAL
icon = 'icons/obj/items.dmi'
icon_state = "handcuff"
flags = CONDUCT
throwforce = 0
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_MATERIAL = 1)
var/breakouttime = 300 //Deciseconds = 30s = 0.5 minute
sprite_sheets = list("Teshari" = 'icons/mob/species/seromi/handcuffs.dmi')
/obj/item/weapon/caution
desc = "Caution! Wet Floor!"
name = "wet floor sign"

View File

@@ -18,6 +18,7 @@
var/mind=null
var/languages=null
var/list/flavor=null
var/list/genetic_modifiers = list() // Modifiers with the MODIFIER_GENETIC flag are saved. Note that only the type is saved, not an instance.
/datum/dna2/record/proc/GetData()
var/list/ser=list("data" = null, "owner" = null, "label" = null, "type" = null, "ue" = 0)

View File

@@ -31,19 +31,3 @@
src << "<span class='notice'>Our cryogenic string is ready to be used once more.</span>"
src.verbs |= /mob/proc/changeling_cryo_sting
return 1
/datum/reagent/cryotoxin //A much more potent version of frost oil.
name = "Cryotoxin"
id = "cryotoxin"
description = "Rapidly lowers the body's internal temperature."
reagent_state = LIQUID
color = "#B31008"
/datum/reagent/cryotoxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(alien == IS_DIONA)
return
M.bodytemperature = max(M.bodytemperature - 30 * TEMPERATURE_DAMAGE_COEFFICIENT, 0)
if(prob(3))
M.emote("shiver")
..()
return

View File

@@ -13,6 +13,7 @@
/obj/item/weapon/antag_spawner
w_class = ITEMSIZE_TINY
var/used = 0
var/ghost_query_type = null
/obj/item/weapon/antag_spawner/proc/spawn_antag(client/C, turf/T)
return
@@ -20,11 +21,28 @@
/obj/item/weapon/antag_spawner/proc/equip_antag(mob/target)
return
/obj/item/weapon/antag_spawner/proc/request_player()
if(!ghost_query_type)
return
var/datum/ghost_query/Q = new ghost_query_type()
var/list/winner = Q.query()
if(winner.len)
var/mob/observer/dead/D = winner[1]
spawn_antag(D.client, get_turf(src))
else
reset_search()
return
/obj/item/weapon/antag_spawner/proc/reset_search()
return
/obj/item/weapon/antag_spawner/technomancer_apprentice
name = "apprentice teleporter"
desc = "A teleportation device, which will bring a less potent manipulator of space to you."
icon = 'icons/obj/objects.dmi'
icon_state = "oldshieldoff"
ghost_query_type = /datum/ghost_query/apprentice
var/searching = 0
var/datum/effect/effect/system/spark_spread/sparks
@@ -40,35 +58,18 @@
/obj/item/weapon/antag_spawner/technomancer_apprentice/attack_self(mob/user)
user << "<span class='notice'>Teleporter attempting to lock on to your apprentice.</span>"
request_player()
/obj/item/weapon/antag_spawner/technomancer_apprentice/request_player()
searching = 1
icon_state = "oldshieldon"
for(var/mob/observer/dead/O in player_list)
if(!O.MayRespawn())
continue
if(jobban_isbanned(O, "Syndicate") || jobban_isbanned(O, "wizard"))
continue
if(O.client)
if(O.client.prefs.be_special & BE_WIZARD)
question(O.client)
spawn(1 MINUTE)
searching = 0
if(!used)
icon_state = "oldshieldoff"
user << "<span class='warning'>The teleporter failed to find your apprentice. Perhaps you could try again later?</span>"
..()
/obj/item/weapon/antag_spawner/technomancer_apprentice/proc/question(var/client/C)
spawn(0)
if(!C)
return
var/response = alert(C, "Someone is requesting a Technomancer apprentice Would you like to play as one?",
"Apprentice request","Yes", "No")
if(response == "Yes")
response = alert(C, "Are you sure you want to play as an apprentice?", "Apprentice request", "Yes", "No")
if(!C || used || !searching)
return
if(response == "Yes")
spawn_antag(C, get_turf(src))
/obj/item/weapon/antag_spawner/technomancer_apprentice/reset_search()
searching = 0
if(!used)
icon_state = "oldshieldoff"
visible_message("<span class='warning'>The teleporter failed to find the apprentice. Perhaps another attempt could be made later?</span>")
/obj/item/weapon/antag_spawner/technomancer_apprentice/spawn_antag(client/C, turf/T)
sparks.start()

View File

@@ -3,15 +3,15 @@
desc = "What appears to be an ordinary pair of boots, is actually a bit more useful than that. These will help against slipping \
on flat surfaces, and will make you run a bit faster than if you had normal shoes or boots on."
cost = 50
obj_path = /obj/item/clothing/shoes/speed
obj_path = /obj/item/clothing/shoes/boots/speed
/obj/item/clothing/shoes/speed
/obj/item/clothing/shoes/boots/speed
name = "boots of speed"
desc = "The latest in sure footing technology."
icon_state = "swat"
item_flags = NOSLIP
siemens_coefficient = 0.6
slowdown = -2 // A bit faster than normal shows.
slowdown = -1
cold_protection = FEET
min_cold_protection_temperature = SHOE_MIN_COLD_PROTECTION_TEMPERATURE

View File

@@ -14,11 +14,11 @@
desc = "This armor has no inherent ability to absorb shock, as normal armor usually does. Instead, this emits a strong field \
around the wearer, designed to protect from most forms of harm, from lasers to bullets to close quarters combat. It appears to \
require a very potent supply of an energy of some kind in order to function."
icon_state = "reactiveoff" //wip
item_state = "reactiveoff"
icon_state = "shield_armor_0"
blood_overlay_type = "armor"
slowdown = 0
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
action_button_name = "Toggle Shield Projector"
var/active = 0
var/damage_to_energy_multiplier = 50.0 //Determines how much energy to charge for blocking, e.g. 20 damage attack = 750 energy cost
var/datum/effect/effect/system/spark_spread/spark_system = null
@@ -49,7 +49,7 @@
var/damage_to_energy_cost = (damage_to_energy_multiplier * damage_blocked)
if(!user.technomancer_pay_energy(damage_to_energy_cost))
user << "<span class='danger'>Your shield fades due to lack of energy!</span>"
to_chat(user, "<span class='danger'>Your shield fades due to lack of energy!</span>")
active = 0
update_icon()
return 0
@@ -67,7 +67,7 @@
P.damage = P.damage - damage_blocked
user.visible_message("<span class='danger'>\The [user]'s [src] absorbs [attack_text]!</span>")
user << "<span class='warning'>Your shield has absorbed most of \the [damage_source].</span>"
to_chat(user, "<span class='warning'>Your shield has absorbed most of \the [damage_source].</span>")
spark_system.start()
playsound(user.loc, 'sound/weapons/blade1.ogg', 50, 1)
@@ -75,14 +75,17 @@
/obj/item/clothing/suit/armor/shield/attack_self(mob/user)
active = !active
user << "<span class='notice'>You [active ? "" : "de"]active \the [src].</span>"
to_chat(user, "<span class='notice'>You [active ? "" : "de"]activate \the [src].</span>")
update_icon()
user.update_inv_wear_suit()
user.update_action_buttons()
/obj/item/clothing/suit/armor/shield/update_icon()
icon_state = "shield_armor_[active]"
item_state = "shield_armor_[active]"
if(active)
icon_state = "shield_armor"
set_light(2, 1, l_color = "#006AFF")
else
icon_state = "shield_armor_off"
set_light(0, 0, l_color = "#000000")
..()
return

View File

@@ -10,55 +10,70 @@
/obj/item/clothing/suit/armor/tesla
name = "tesla armor"
desc = "This rather dangerous looking armor will hopefully shock your enemies, and not you in the process."
icon_state = "reactive" //wip
item_state = "reactive"
icon_state = "tesla_armor_1" //wip
blood_overlay_type = "armor"
slowdown = 1
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
action_button_name = "Toggle Tesla Armor"
var/active = 1 //Determines if the armor will zap or block
var/ready = 1 //Determines if the next attack will be blocked, as well if a strong lightning bolt is sent out at the attacker.
var/ready_icon_state = "reactive" //also wip
var/normal_icon_state = "reactiveoff"
var/ready_icon_state = "tesla_armor_1" //also wip
var/normal_icon_state = "tesla_armor_0"
var/cooldown_to_charge = 15 SECONDS
/obj/item/clothing/suit/armor/tesla/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack")
//First, some retaliation.
if(istype(damage_source, /obj/item/projectile))
var/obj/item/projectile/P = damage_source
if(P.firer && get_dist(user, P.firer) <= 3)
if(ready)
shoot_lightning(P.firer, 40)
else
shoot_lightning(P.firer, 15)
else
if(attacker && attacker != user)
if(get_dist(user, attacker) <= 3) //Anyone farther away than three tiles is too far to shoot lightning at.
if(active)
if(istype(damage_source, /obj/item/projectile))
var/obj/item/projectile/P = damage_source
if(P.firer && get_dist(user, P.firer) <= 3)
if(ready)
shoot_lightning(attacker, 40)
shoot_lightning(P.firer, 40)
else
shoot_lightning(attacker, 15)
shoot_lightning(P.firer, 15)
//Deal with protecting our wearer now.
if(ready)
ready = 0
spawn(cooldown_to_charge)
ready = 1
else
if(attacker && attacker != user)
if(get_dist(user, attacker) <= 3) //Anyone farther away than three tiles is too far to shoot lightning at.
if(ready)
shoot_lightning(attacker, 40)
else
shoot_lightning(attacker, 15)
//Deal with protecting our wearer now.
if(ready)
ready = 0
spawn(cooldown_to_charge)
ready = 1
update_icon()
to_chat(user, "<span class='notice'>\The [src] is ready to protect you once more.</span>")
visible_message("<span class='danger'>\The [user]'s [src.name] blocks [attack_text]!</span>")
update_icon()
user << "<span class='notice'>\The [src] is ready to protect you once more.</span>"
visible_message("<span class='danger'>\The [user]'s [src.name] blocks [attack_text]!</span>")
update_icon()
return 1
return 1
return 0
/obj/item/clothing/suit/armor/tesla/attack_self(mob/user)
active = !active
to_chat(user, "<span class='notice'>You [active ? "" : "de"]activate \the [src].</span>")
update_icon()
user.update_inv_wear_suit()
user.update_action_buttons()
/obj/item/clothing/suit/armor/tesla/update_icon()
..()
if(ready)
if(active && ready)
icon_state = ready_icon_state
item_state = ready_icon_state
set_light(2, 1, l_color = "#006AFF")
else
icon_state = normal_icon_state
item_state = normal_icon_state
set_light(0, 0, l_color = "#000000")
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
H.update_inv_wear_suit(0)
H.update_action_buttons()
..()
/obj/item/clothing/suit/armor/tesla/proc/shoot_lightning(var/mob/target, var/power)
var/obj/item/projectile/beam/lightning/lightning = new(src)

View File

@@ -2,6 +2,7 @@
name = "Condensation"
desc = "This causes rapid formation of liquid at the target, causing floors to become wet, entities to be soaked, and fires \
to be extinguished. You can also fill contains with water if they are targeted directly."
enhancement_desc = "Floors affected by condensation will also freeze."
ability_icon_state = "tech_condensation"
cost = 50
obj_path = /obj/item/weapon/spell/condensation
@@ -30,7 +31,14 @@
W.set_color()
W.set_up(desired_turf)
flick(initial(icon_state),W) // Otherwise pooling causes the animation to stay stuck at the end.
log_and_message_admins("has wetted the floor with [src] at [T.x],[T.y],[T.z].")
else if(hit_atom.reagents && !ismob(hit_atom))
if(check_for_scepter())
if(istype(desired_turf, /turf/simulated))
var/turf/simulated/frozen = desired_turf
frozen.freeze_floor()
if(check_for_scepter())
log_and_message_admins("has iced the floor with [src] at [T.x],[T.y],[T.z].")
else
log_and_message_admins("has wetted the floor with [src] at [T.x],[T.y],[T.z].")
else if(hit_atom.reagents && !ismob(hit_atom)) //TODO: Something for the scepter
hit_atom.reagents.add_reagent(id = "water", amount = 60, data = null, safety = 0)
adjust_instability(5)

View File

@@ -14,7 +14,9 @@
alt_titles = list("Technical Assistant","Test Subject","Medical Intern","Research Assistant","Visitor", "Resident") // Test Subject is a VOREStation edit.
/datum/job/assistant/equip(var/mob/living/carbon/human/H, var/alt_title)
if(!H) return 0
if(!H)
return 0
H.equip_to_slot_or_del(new /obj/item/device/radio/headset(H), slot_l_ear)
switch(H.backbag)
if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back)

View File

@@ -27,7 +27,7 @@
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/bartender(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/device/pda/bar(H), slot_belt)
if(has_alt_title(H, alt_title,"Bartender"))
var/obj/item/weapon/permit/gun/bar/permit = new(H)
var/obj/item/clothing/accessory/permit/gun/bar/permit = new(H)
if(H.backbag == 1)
H.equip_to_slot_or_del(permit, slot_l_hand)
else

View File

@@ -365,6 +365,8 @@ var/global/datum/controller/occupations/job_master
H << "<span class='warning'>Your current species, job or whitelist status does not permit you to spawn with [thing]!</span>"
continue
H.amend_exploitable(G.path)
if(G.slot == "implant")
H.implant_loadout(G)
continue
@@ -472,7 +474,9 @@ var/global/datum/controller/occupations/job_master
var/obj/item/organ/external/l_foot = H.get_organ("l_foot")
var/obj/item/organ/external/r_foot = H.get_organ("r_foot")
var/obj/item/weapon/storage/S = locate() in H.contents
var/obj/item/wheelchair/R = locate() in S.contents
var/obj/item/wheelchair/R = null
if(S)
R = locate() in S.contents
if(!l_foot || !r_foot || R)
var/obj/structure/bed/chair/wheelchair/W = new /obj/structure/bed/chair/wheelchair(H.loc)
H.buckled = W
@@ -637,8 +641,10 @@ var/global/datum/controller/occupations/job_master
. = spawnpos.msg
else
H << "Your chosen spawnpoint ([spawnpos.display_name]) is unavailable for your chosen job. Spawning you at the Arrivals shuttle instead."
H.forceMove(pick(latejoin))
var/spawning = pick(latejoin)
H.forceMove(get_turf(spawning))
. = "will arrive to the station shortly by shuttle"
else
H.forceMove(pick(latejoin))
var/spawning = pick(latejoin)
H.forceMove(get_turf(spawning))
. = "has arrived on the station"

View File

@@ -131,8 +131,16 @@
var/new_organ = products[choice][1]
var/obj/item/organ/O = new new_organ(get_turf(src))
O.status |= ORGAN_CUT_AWAY
var/mob/living/carbon/C = loaded_dna["donor"]
var/mob/living/carbon/human/C = loaded_dna["donor"]
O.set_dna(C.dna)
O.species = C.species
if(istype(O, /obj/item/organ/external))
var/obj/item/organ/external/E = O
E.sync_colour_to_human(C)
O.pixel_x = rand(-6.0, 6)
O.pixel_y = rand(-6.0, 6)
if(O.species)
// This is a very hacky way of doing of what organ/New() does if it has an owner

View File

@@ -94,6 +94,10 @@
else
return 0
for(var/modifier_type in R.genetic_modifiers) //Can't be cloned, even if they had a previous scan
if(istype(modifier_type, /datum/modifier/no_clone))
return 0
attempting = 1 //One at a time!!
locked = 1
@@ -139,6 +143,25 @@
H.set_cloned_appearance()
update_icon()
// A modifier is added which makes the new clone be unrobust.
var/modifier_lower_bound = 25 MINUTES
var/modifier_upper_bound = 40 MINUTES
// Upgraded cloners can reduce the time of the modifier, up to 80%
var/clone_sickness_length = abs(((heal_level - 20) / 100 ) - 1)
clone_sickness_length = between(0.2, clone_sickness_length, 1.0) // Caps it off just incase.
modifier_lower_bound = round(modifier_lower_bound * clone_sickness_length, 1)
modifier_upper_bound = round(modifier_upper_bound * clone_sickness_length, 1)
H.add_modifier(/datum/modifier/cloning_sickness, rand(modifier_lower_bound, modifier_upper_bound))
// Modifier that doesn't do anything.
H.add_modifier(/datum/modifier/cloned)
// This is really stupid.
for(var/modifier_type in R.genetic_modifiers)
H.add_modifier(modifier_type)
for(var/datum/language/L in R.languages)
H.add_language(L.name)
H.flavor_texts = R.flavor.Copy()

View File

@@ -316,6 +316,10 @@
if (subject.species && subject.species.flags & NO_SCAN)
scantemp = "Error: Mental interface failure."
return
for(var/modifier_type in subject.modifiers) //Can't be cloned, even if they had a previous scan
if(istype(modifier_type, /datum/modifier/no_clone))
scantemp = "Error: Mental interface failure."
return
if (!isnull(find_record(subject.ckey)))
scantemp = "Subject already in database."
return
@@ -330,6 +334,9 @@
R.types = DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE
R.languages = subject.languages
R.flavor = subject.flavor_texts.Copy()
for(var/datum/modifier/mod in subject.modifiers)
if(mod.flags & MODIFIER_GENETIC)
R.genetic_modifiers.Add(mod.type)
//Add an implant if needed
var/obj/item/weapon/implant/health/imp = locate(/obj/item/weapon/implant/health, subject)

View File

@@ -9,6 +9,7 @@
var/temp_access = list() //to prevent agent cards stealing access as permanent
var/expiration_time = 0
var/expired = 0
var/reason = "NOT SPECIFIED"
/obj/item/weapon/card/id/guest/GetAccess()
@@ -38,6 +39,38 @@
usr << "<span class='notice'>Issuing reason: [reason].</span>"
return
/obj/item/weapon/card/id/guest/attack_self(mob/living/user as mob)
if(user.a_intent == I_HURT)
if(icon_state == "guest_invalid")
to_chat(user, "<span class='warning'>This guest pass is already deactivated!</span>")
return
var/confirm = alert("Do you really want to deactivate this guest pass? (you can't reactivate it)", "Confirm Deactivation", "Yes", "No")
if(confirm == "Yes")
//rip guest pass </3
user.visible_message("<span class='notice'>\The [user] deactivates \the [src].</span>")
icon_state = "guest_invalid"
expiration_time = world.time
expired = 1
return ..()
/obj/item/weapon/card/id/guest/New()
..()
processing_objects.Add(src)
update_icon()
/obj/item/weapon/card/id/guest/Destroy()
processing_objects.Remove(src)
return ..()
/obj/item/weapon/card/id/guest/process()
if(expired == 0 && world.time >= expiration_time)
visible_message("<span class='warning'>\The [src] flashes a few times before turning red.</span>")
icon_state = "guest_invalid"
expired = 1
world.time = expiration_time
return
/////////////////////////////////////////////
//Guest pass terminal////////////////////////
/////////////////////////////////////////////

View File

@@ -31,7 +31,7 @@
return
if(istype(O, /obj/item/weapon/aiModule))
var/obj/item/weapon/aiModule/M = O
M.install(src)
M.install(src, user)
else
..()

View File

@@ -22,6 +22,10 @@
icon_state = "sheater[on]"
if(panel_open)
overlays += "sheater-open"
if(on)
set_light(3, 3, "#FFCC00")
else
set_light(0)
/obj/machinery/space_heater/examine(mob/user)
..(user)

View File

@@ -547,8 +547,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
race = "[H.species.name]"
log.parameters["intelligible"] = 1
else if(isbrain(M))
var/mob/living/carbon/brain/B = M
race = "[B.species.name]"
race = "Brain"
log.parameters["intelligible"] = 1
else if(M.isMonkey())
race = "Monkey"

View File

@@ -2,7 +2,7 @@
force = 30
var/melee_cooldown = 10
var/melee_can_hit = 1
var/list/destroyable_obj = list(/obj/mecha, /obj/structure/window, /obj/structure/grille, /turf/simulated/wall)
var/list/destroyable_obj = list(/obj/mecha, /obj/structure/window, /obj/structure/grille, /turf/simulated/wall, /obj/structure/girder)
internal_damage_threshold = 50
maint_access = 0
//add_req_access = 0
@@ -25,7 +25,7 @@
if(!melee_can_hit || !istype(target, /atom)) return
if(istype(target, /mob/living))
var/mob/living/M = target
if(src.occupant.a_intent == I_HURT)
if(src.occupant.a_intent == I_HURT || istype(src.occupant, /mob/living/carbon/brain)) //Brains cannot change intents; Exo-piloting brains lack any form of physical feedback for control, limiting the ability to 'play nice'.
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
if(damtype == "brute")
step_away(M,src,15)
@@ -95,14 +95,19 @@
if(istype(target, target_type) && hascall(target, "attackby"))
src.occupant_message("You hit [target].")
src.visible_message("<font color='red'><b>[src.name] hits [target]</b></font>")
if(!istype(target, /turf/simulated/wall))
if(!istype(target, /turf/simulated/wall) && !istype(target, /obj/structure/girder))
target:attackby(src,src.occupant)
else if(prob(5))
target:dismantle_wall(1)
src.occupant_message("<span class='notice'>You smash through the wall.</span>")
src.visible_message("<b>[src.name] smashes through the wall</b>")
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
else if(istype(target, /turf/simulated/wall))
target:take_damage(force)
else if(istype(target, /obj/structure/girder))
target:take_damage(force * 3) //Girders have 200 health by default. Steel, non-reinforced walls take four punches, girders take (with this value-mod) two, girders took five without.
melee_can_hit = 0
if(do_after(melee_cooldown))
melee_can_hit = 1
break
@@ -244,6 +249,14 @@
else
return 0
/obj/mecha/combat/mmi_moved_inside(var/obj/item/device/mmi/mmi_as_oc as obj,mob/user as mob)
if(..())
if(occupant.client)
occupant.client.mouse_pointer_icon = file("icons/mecha/mecha_mouse.dmi")
return 1
else
return 0
/obj/mecha/combat/go_out()
if(src.occupant && src.occupant.client)
src.occupant.client.mouse_pointer_icon = initial(src.occupant.client.mouse_pointer_icon)

View File

@@ -52,7 +52,7 @@
else if(istype(target,/mob/living))
var/mob/living/M = target
if(M.stat>1) return
if(chassis.occupant.a_intent == I_HURT)
if(chassis.occupant.a_intent == I_HURT || istype(chassis.occupant,/mob/living/carbon/brain)) //No tactile feedback for brains
M.take_overall_damage(dam_force)
M.adjustOxyLoss(round(dam_force/2))
M.updatehealth()

View File

@@ -344,8 +344,11 @@
/obj/mecha/relaymove(mob/user,direction)
if(user != src.occupant) //While not "realistic", this piece is player friendly.
if(istype(user,/mob/living/carbon/brain))
to_chat(user,"You try to move, but you are not the pilot! The exosuit doesn't respond.")
return 0
user.forceMove(get_turf(src))
user << "You climb out from [src]"
to_chat(user,"You climb out from [src]")
return 0
if(connected_port)
if(world.time - last_message > 20)
@@ -686,6 +689,13 @@
/obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/device/mmi))
if(mmi_move_inside(W,user))
to_chat(user,"[src]-MMI interface initialized successfuly")
else
to_chat(user,"[src]-MMI interface initialization failed.")
return
if(istype(W, /obj/item/mecha_parts/mecha_equipment))
var/obj/item/mecha_parts/mecha_equipment/E = W
spawn()
@@ -829,6 +839,70 @@
return
*/
///////////////////////////////
//////// Brain Stuff ////////
///////////////////////////////
/obj/mecha/proc/mmi_move_inside(var/obj/item/device/mmi/mmi_as_oc as obj,mob/user as mob)
if(!mmi_as_oc.brainmob || !mmi_as_oc.brainmob.client)
to_chat(user,"Consciousness matrix not detected.")
return 0
else if(mmi_as_oc.brainmob.stat)
to_chat(user,"Brain activity below acceptable level.")
return 0
else if(occupant)
to_chat(user,"Occupant detected.")
return 0
else if(dna && dna!=mmi_as_oc.brainmob.dna.unique_enzymes)
to_chat(user,"Genetic sequence or serial number incompatible with locking mechanism.")
return 0
//Added a message here since people assume their first click failed or something./N
// user << "Installing MMI, please stand by."
visible_message("<span class='notice'>[usr] starts to insert a brain into [src.name]</span>")
if(enter_after(40,user))
if(!occupant)
return mmi_moved_inside(mmi_as_oc,user)
else
to_chat(user,"Occupant detected.")
else
to_chat(user,"You stop attempting to install the brain.")
return 0
/obj/mecha/proc/mmi_moved_inside(var/obj/item/device/mmi/mmi_as_oc as obj,mob/user as mob)
if(mmi_as_oc && user in range(1))
if(!mmi_as_oc.brainmob || !mmi_as_oc.brainmob.client)
to_chat(user,"Consciousness matrix not detected.")
return 0
else if(mmi_as_oc.brainmob.stat)
to_chat(user,"Beta-rhythm below acceptable level.")
return 0
user.drop_from_inventory(mmi_as_oc)
var/mob/brainmob = mmi_as_oc.brainmob
brainmob.reset_view(src)
/*
brainmob.client.eye = src
brainmob.client.perspective = EYE_PERSPECTIVE
*/
occupant = brainmob
brainmob.loc = src //should allow relaymove
brainmob.canmove = 1
mmi_as_oc.loc = src
mmi_as_oc.mecha = src
src.verbs += /obj/mecha/verb/eject
src.Entered(mmi_as_oc)
src.Move(src.loc)
src.icon_state = src.reset_icon()
set_dir(dir_in)
src.log_message("[mmi_as_oc] moved in as pilot.")
if(!hasInternalDamage())
src.occupant << sound('sound/mecha/nominal.ogg',volume=50)
return 1
else
return 0
/////////////////////////////////////
//////// Atmospheric stuff ////////
/////////////////////////////////////
@@ -1044,6 +1118,7 @@
src.occupant = H
src.add_fingerprint(H)
src.forceMove(src.loc)
src.verbs += /obj/mecha/verb/eject
src.log_append_to_last("[H] moved in as pilot.")
src.icon_state = src.reset_icon()
set_dir(dir_in)
@@ -1132,10 +1207,10 @@
occupant.loc = mmi
mmi.mecha = null
src.occupant.canmove = 0
src.verbs += /obj/mecha/verb/eject
src.occupant = null
src.icon_state = src.reset_icon()+"-open"
src.set_dir(dir_in)
src.verbs -= /obj/mecha/verb/eject
return
/////////////////////////

View File

@@ -79,6 +79,7 @@
var/amount_grown = 0
var/spiders_min = 6
var/spiders_max = 24
var/spider_type = /obj/effect/spider/spiderling
New()
pixel_x = rand(3,-3)
pixel_y = rand(3,-3)
@@ -105,7 +106,7 @@
O = loc
for(var/i=0, i<num, i++)
var/spiderling = new /obj/effect/spider/spiderling(src.loc, src)
var/spiderling = new spider_type(src.loc, src)
if(O)
O.implants += spiderling
qdel(src)
@@ -114,6 +115,9 @@
spiders_min = 1
spiders_max = 3
/obj/effect/spider/eggcluster/small/frost
spider_type = /obj/effect/spider/spiderling/frost
/obj/effect/spider/spiderling
name = "spiderling"
desc = "It never stays still for long."
@@ -127,6 +131,9 @@
var/travelling_in_vent = 0
var/list/grow_as = list(/mob/living/simple_animal/hostile/giant_spider, /mob/living/simple_animal/hostile/giant_spider/nurse, /mob/living/simple_animal/hostile/giant_spider/hunter)
/obj/effect/spider/spiderling/frost
grow_as = list(/mob/living/simple_animal/hostile/giant_spider/frost)
/obj/effect/spider/spiderling/New(var/location, var/atom/parent)
pixel_x = rand(6,-6)
pixel_y = rand(6,-6)

View File

@@ -343,12 +343,12 @@ var/list/global/slot_flags_enumeration = list(
return 0
if( !(istype(src, /obj/item/device/pda) || istype(src, /obj/item/weapon/pen) || is_type_in_list(src, H.wear_suit.allowed)) )
return 0
if(slot_legcuffed) //Going to put this check above the handcuff check because the survival of the universe depends on it.
if(!istype(src, /obj/item/weapon/handcuffs/legcuffs)) //Putting it here might actually do nothing.
return 0
if(slot_handcuffed)
if(!istype(src, /obj/item/weapon/handcuffs))
return 0
if(slot_legcuffed)
if(!istype(src, /obj/item/weapon/legcuffs))
return 0
if(!istype(src, /obj/item/weapon/handcuffs) || istype(src, /obj/item/weapon/handcuffs/legcuffs)) //Legcuffs are a child of handcuffs, but we don't want to use legcuffs as handcuffs...
return 0 //In theory, this would never happen, but let's just do the legcuff check anyways.
if(slot_in_backpack) //used entirely for equipping spawned mobs or at round start
var/allow = 0
if(H.back && istype(H.back, /obj/item/weapon/storage/backpack))

View File

@@ -110,7 +110,16 @@
flashfail = 1
else if(issilicon(M))
M.Weaken(rand(5,10))
flashfail = 0
var/mob/living/silicon/S = M
if(isrobot(S))
var/mob/living/silicon/robot/R = S
if(R.has_active_type(/obj/item/borg/combat/shield))
var/obj/item/borg/combat/shield/shield = locate() in R
if(shield)
if(shield.active)
shield.adjust_flash_count(R, 1)
flashfail = 1
else
flashfail = 1
@@ -133,6 +142,7 @@
else
user.visible_message("<span class='notice'>[user] overloads [M]'s sensors with the flash!</span>")
M.Weaken(rand(5,10))
else
user.visible_message("<span class='notice'>[user] fails to blind [M] with the flash!</span>")

View File

@@ -125,3 +125,6 @@
name = "\improper ERT radio encryption key"
icon_state = "cent_cypherkey"
channels = list("Response Team" = 1, "Science" = 1, "Command" = 1, "Medical" = 1, "Engineering" = 1, "Security" = 1, "Supply" = 1, "Service" = 1)
/obj/item/device/encryptionkey/omni //Literally only for the admin intercoms
channels = list("Mercenary" = 1, "Raider" = 1, "Response Team" = 1, "Science" = 1, "Command" = 1, "Medical" = 1, "Engineering" = 1, "Security" = 1, "Supply" = 1, "Service" = 1)

View File

@@ -310,6 +310,9 @@
// freerange = 1
ks2type = /obj/item/device/encryptionkey/ert
/obj/item/device/radio/headset/omni //Only for the admin intercoms
ks2type = /obj/item/device/encryptionkey/omni
/obj/item/device/radio/headset/ia
name = "internal affair's headset"
desc = "The headset of your worst enemy."
@@ -317,6 +320,20 @@
item_state = "headset"
ks2type = /obj/item/device/encryptionkey/heads/hos
/obj/item/device/radio/headset/mmi_radio
name = "brain-integrated radio"
desc = "MMIs and synthetic brains are often equipped with these."
icon = 'icons/obj/robot_component.dmi'
icon_state = "radio"
item_state = "headset"
var/mmiowner = null
var/radio_enabled = 1
/obj/item/device/radio/headset/mmi_radio/receive_range(freq, level)
if (!radio_enabled || istype(src.loc.loc, /mob/living/silicon) || istype(src.loc.loc, /obj/item/organ/internal))
return -1 //Transciever Disabled.
return ..(freq, level, 1)
/obj/item/device/radio/headset/attackby(obj/item/weapon/W as obj, mob/user as mob)
// ..()
user.set_machine(src)

View File

@@ -353,8 +353,8 @@ REAGENT SCANNER
/obj/item/device/slime_scanner
name = "slime scanner"
icon_state = "adv_spectrometer"
item_state = "analyzer"
icon_state = "xenobio"
item_state = "xenobio"
origin_tech = list(TECH_BIO = 1)
w_class = ITEMSIZE_SMALL
flags = CONDUCT

View File

@@ -132,4 +132,19 @@
/obj/item/device/t_scanner/dropped(mob/user)
set_user_client(null)
/obj/item/device/t_scanner/upgraded
name = "Upgraded T-ray Scanner"
desc = "An upgraded version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
matter = list(DEFAULT_WALL_MATERIAL = 500, PHORON = 150)
origin_tech = list(TECH_MAGNET = 4, TECH_ENGINEERING = 5)
scan_range = 3
/obj/item/device/t_scanner/advanced
name = "Advanced T-ray Scanner"
desc = "An advanced version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
matter = list(DEFAULT_WALL_MATERIAL = 1500, PHORON = 200, SILVER = 250)
origin_tech = list(TECH_MAGNET = 7, TECH_ENGINEERING = 7, TECH_MATERIAL = 6)
scan_range = 7
#undef OVERLAY_CACHE_LEN

View File

@@ -4,16 +4,18 @@
desc = "This item spawns stack of 50 of a given material."
icon = 'icons/misc/mark.dmi'
icon_state = "x4"
var/material = ""
// var/material = ""
var/obj/item/stack/type_to_spawn = null
/obj/fiftyspawner/New()
//spawns the 50-stack and qdels self
..()
var/obj_path = text2path("/obj/item/stack/[material]")
var/obj/item/stack/M = new obj_path(src.loc)
// var/obj_path = text2path("/obj/item/stack/[material]")
var/obj/item/stack/M = new type_to_spawn(src.loc)
M.amount = M.max_amount //some stuff spawns with 60, we're still calling it fifty
M.update_icon() // Some stacks have different sprites depending on how full they are.
qdel(src)
/obj/fiftyspawner/rods
name = "stack of rods" //this needs to be defined for cargo
material = "rods"
type_to_spawn = /obj/item/stack/rods

View File

@@ -1,7 +1,7 @@
/obj/item/stack/medical
name = "medical pack"
singular_name = "medical pack"
icon = 'icons/obj/items.dmi'
icon = 'icons/obj/stacks.dmi'
amount = 10
max_amount = 10
w_class = ITEMSIZE_SMALL
@@ -64,6 +64,7 @@
desc = "Some sterile gauze to wrap around bloody stumps."
icon_state = "brutepack"
origin_tech = list(TECH_BIO = 1)
no_variants = FALSE
/obj/item/stack/medical/bruise_pack/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
@@ -123,6 +124,7 @@
icon_state = "ointment"
heal_burn = 1
origin_tech = list(TECH_BIO = 1)
no_variants = FALSE
/obj/item/stack/medical/ointment/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
@@ -279,16 +281,25 @@
if(M == user && prob(75))
user.visible_message("<span class='danger'>\The [user] fumbles [src].</span>", "<span class='danger'>You fumble [src].</span>", "<span class='danger'>You hear something being wrapped.</span>")
return
var/obj/item/stack/medical/splint/S = split(1)
if(S)
if(affecting.apply_splint(S))
S.forceMove(affecting)
if (M != user)
if(ishuman(user))
var/obj/item/stack/medical/splint/S = split(1)
if(S)
if(affecting.apply_splint(S))
S.forceMove(affecting)
if (M != user)
user.visible_message("<span class='danger'>\The [user] finishes applying [src] to [M]'s [limb].</span>", "<span class='danger'>You finish applying \the [src] to [M]'s [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
else
user.visible_message("<span class='danger'>\The [user] successfully applies [src] to their [limb].</span>", "<span class='danger'>You successfully apply \the [src] to your [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
return
S.dropInto(src.loc) //didn't get applied, so just drop it
if(isrobot(user))
var/obj/item/stack/medical/splint/B = src
if(B)
if(affecting.apply_splint(B))
B.forceMove(affecting)
user.visible_message("<span class='danger'>\The [user] finishes applying [src] to [M]'s [limb].</span>", "<span class='danger'>You finish applying \the [src] to [M]'s [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
else
user.visible_message("<span class='danger'>\The [user] successfully applies [src] to their [limb].</span>", "<span class='danger'>You successfully apply \the [src] to your [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
return
S.dropInto(src.loc) //didn't get applied, so just drop it
B.use(1)
return
user.visible_message("<span class='danger'>\The [user] fails to apply [src].</span>", "<span class='danger'>You fail to apply [src].</span>", "<span class='danger'>You hear something being wrapped.</span>")
return

View File

@@ -2,11 +2,12 @@
name = "nanopaste"
singular_name = "nanite swarm"
desc = "A tube of paste containing swarms of repair nanites. Very effective in repairing robotic machinery."
icon = 'icons/obj/nanopaste.dmi'
icon_state = "tube"
icon = 'icons/obj/stacks.dmi'
icon_state = "nanopaste"
origin_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3)
amount = 10
w_class = ITEMSIZE_SMALL
no_variants = FALSE
/obj/item/stack/nanopaste/attack(mob/living/M as mob, mob/user as mob)
if (!istype(M) || !istype(user))

View File

@@ -21,6 +21,23 @@
uses_charge = 1
charge_costs = list(500)
stacktype = /obj/item/stack/rods
no_variants = TRUE
/obj/item/stack/rods/New()
..()
recipes = rods_recipes
update_icon()
/obj/item/stack/rods/update_icon()
var/amount = get_amount()
if((amount <= 5) && (amount > 0))
icon_state = "rods-[amount]"
else
icon_state = "rods"
var/global/list/datum/stack_recipe/rods_recipes = list( \
new/datum/stack_recipe("grille", /obj/structure/grille, 2, time = 10, one_per_turf = 1, on_floor = 1),
new/datum/stack_recipe("catwalk", /obj/structure/catwalk, 2, time = 80, one_per_turf = 1, on_floor = 1))
/obj/item/stack/rods/attackby(obj/item/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/weldingtool))
@@ -55,7 +72,7 @@
..()
/*
/obj/item/stack/rods/attack_self(mob/user as mob)
src.add_fingerprint(user)
@@ -87,3 +104,4 @@
F.add_fingerprint(usr)
use(2)
return
*/

View File

@@ -3,6 +3,7 @@
desc = "The by-product of human farming."
singular_name = "human skin piece"
icon_state = "sheet-hide"
no_variants = FALSE
/obj/item/stack/material/animalhide/human
amount = 50
@@ -80,6 +81,7 @@
desc = "This hide was stripped of it's hair, but still needs tanning."
singular_name = "hairless hide piece"
icon_state = "sheet-hairlesshide"
no_variants = FALSE
/obj/item/stack/material/hairlesshide
amount = 50
@@ -91,6 +93,7 @@
icon_state = "sheet-wetleather"
var/wetness = 30 //Reduced when exposed to high temperautres
var/drying_threshold_temperature = 500 //Kelvin to start drying
no_variants = FALSE
/obj/item/stack/material/wetleather
amount = 50

View File

@@ -12,6 +12,7 @@
/obj/item/stack
gender = PLURAL
origin_tech = list(TECH_MATERIAL = 1)
icon = 'icons/obj/stacks.dmi'
var/list/datum/stack_recipe/recipes
var/singular_name
var/amount = 1
@@ -21,6 +22,7 @@
var/uses_charge = 0
var/list/charge_costs = null
var/list/datum/matter_synth/synths = null
var/no_variants = TRUE // Determines whether the item should update it's sprites based on amount.
/obj/item/stack/New(var/loc, var/amount=null)
..()
@@ -28,6 +30,7 @@
stacktype = type
if (amount)
src.amount = amount
update_icon()
return
/obj/item/stack/Destroy()
@@ -37,6 +40,18 @@
usr << browse(null, "window=stack")
return ..()
/obj/item/stack/update_icon()
if(no_variants)
icon_state = initial(icon_state)
else
if(amount <= (max_amount * (1/3)))
icon_state = initial(icon_state)
else if (amount <= (max_amount * (2/3)))
icon_state = "[initial(icon_state)]_2"
else
icon_state = "[initial(icon_state)]_3"
item_state = initial(icon_state)
/obj/item/stack/examine(mob/user)
if(..(user, 1))
if(!uses_charge)
@@ -189,6 +204,7 @@
if(usr)
usr.remove_from_mob(src)
qdel(src) //should be safe to qdel immediately since if someone is still using this stack it will persist for a little while longer
update_icon()
return 1
else
if(get_amount() < used)
@@ -205,6 +221,7 @@
return 0
else
amount += extra
update_icon()
return 1
else if(!synths || synths.len < uses_charge)
return 0
@@ -298,7 +315,7 @@
/obj/item/stack/attack_hand(mob/user as mob)
if (user.get_inactive_hand() == src)
var/N = input("How many stacks of [src] would you like to split off?", "Split stacks", 1) as num|null
var/N = input("How many stacks of [src] would you like to split off? There are currently [amount].", "Split stacks", 1) as num|null
if(N)
var/obj/item/stack/F = src.split(N)
if (F)

View File

@@ -2,48 +2,48 @@
/obj/fiftyspawner/grass
name = "stack of grass"
material = "tile/grass"
type_to_spawn = /obj/item/stack/tile/grass
/obj/fiftyspawner/wood
name = "stack of wood"
material = "tile/wood"
type_to_spawn = /obj/item/stack/tile/wood
/obj/fiftyspawner/carpet
name = "stack of carpet"
material = "tile/carpet"
type_to_spawn = /obj/item/stack/tile/carpet
/obj/fiftyspawner/bluecarpet
name = "stack of blue carpet"
material = "tile/carpet/blue"
type_to_spawn = /obj/item/stack/tile/carpet/blue
/obj/fiftyspawner/floor
name = "stack of floor tiles"
material = "tile/floor"
type_to_spawn = /obj/item/stack/tile/floor
/obj/fiftyspawner/floor_red
name = "stack of red floor tiles"
material = "tile/floor_red"
type_to_spawn = /obj/item/stack/tile/floor/red
/obj/fiftyspawner/floor_steel
name = "stack of steel floor tiles"
material = "tile/floor_steel"
type_to_spawn = /obj/item/stack/tile/floor/steel
/obj/fiftyspawner/floor_white
name = "stack of white floor tiles"
material = "tile/floor_white"
type_to_spawn = /obj/item/stack/tile/floor/white
/obj/fiftyspawner/floor_yellow
name = "stack of yellow floor tiles"
material = "tile/floor_yellow"
type_to_spawn = /obj/item/stack/tile/floor/yellow
/obj/fiftyspawner/floor_dark
name = "stack of dark floor tiles"
material = "tile/floor_dark"
type_to_spawn = /obj/item/stack/tile/floor/dark
/obj/fiftyspawner/floor_freezer
name = "stack of freezer tiles"
material = "tile/floor_freezer"
type_to_spawn = /obj/item/stack/tile/floor/freezer
/obj/fiftyspawner/linoleum
name = "stack of linoleum tiles"
material = "tile/linoleum"
type_to_spawn = /obj/item/stack/tile/linoleum

View File

@@ -36,6 +36,7 @@
throw_range = 20
flags = 0
origin_tech = list(TECH_BIO = 1)
no_variants = FALSE
/obj/item/stack/tile/grass/fifty
amount = 50
@@ -52,6 +53,7 @@
throw_speed = 5
throw_range = 20
flags = 0
no_variants = FALSE
/obj/item/stack/tile/wood/fifty
amount = 50
@@ -77,12 +79,14 @@
throw_speed = 5
throw_range = 20
flags = 0
no_variants = FALSE
/obj/item/stack/tile/carpet/blue
name = "blue carpet"
singular_name = "blue carpet"
desc = "A piece of blue carpet. It is the same size as a normal floor tile!"
icon_state = "tile-bluecarpet"
no_variants = FALSE
/obj/item/stack/tile/carpet/bcarpet
icon_state = "tile-carpet"
@@ -110,29 +114,34 @@
throw_speed = 5
throw_range = 20
flags = CONDUCT
no_variants = FALSE
/obj/item/stack/tile/floor/red
name = "red floor tile"
singular_name = "red floor tile"
color = COLOR_RED_GRAY
icon_state = "tile_white"
no_variants = FALSE
// VOREStation Edit
/obj/item/stack/tile/floor/techgrey
name = "grey techfloor tile"
singular_name = "grey techfloor tile"
icon_state = "techtile_grey"
no_variants = FALSE
/obj/item/stack/tile/floor/techgrid
name = "grid techfloor tile"
singular_name = "grid techfloor tile"
icon_state = "techtile_grid"
no_variants = FALSE
/obj/item/stack/tile/floor/steel_dirty
name = "steel floor tile"
singular_name = "steel floor tile"
icon_state = "tile_steel"
matter = list("plasteel" = SHEET_MATERIAL_AMOUNT / 4)
no_variants = FALSE
// VOREStation Edit End
/obj/item/stack/tile/floor/steel
@@ -140,30 +149,35 @@
singular_name = "steel floor tile"
icon_state = "tile_steel"
matter = list("plasteel" = SHEET_MATERIAL_AMOUNT / 4)
no_variants = FALSE
/obj/item/stack/tile/floor/white
name = "white floor tile"
singular_name = "white floor tile"
icon_state = "tile_white"
matter = list("plastic" = SHEET_MATERIAL_AMOUNT / 4)
no_variants = FALSE
/obj/item/stack/tile/floor/yellow
name = "yellow floor tile"
singular_name = "yellow floor tile"
color = COLOR_BROWN
icon_state = "tile_white"
no_variants = FALSE
/obj/item/stack/tile/floor/dark
name = "dark floor tile"
singular_name = "dark floor tile"
icon_state = "fr_tile"
icon_state = "tile_steel"
matter = list("plasteel" = SHEET_MATERIAL_AMOUNT / 4)
no_variants = FALSE
/obj/item/stack/tile/floor/freezer
name = "freezer floor tile"
singular_name = "freezer floor tile"
icon_state = "tile_freezer"
matter = list("plastic" = SHEET_MATERIAL_AMOUNT / 4)
no_variants = FALSE
/obj/item/stack/tile/floor/cyborg
name = "floor tile synthesizer"
@@ -185,3 +199,4 @@
throw_speed = 5
throw_range = 20
flags = 0
no_variants = FALSE

View File

@@ -287,6 +287,7 @@
desc = "Woefully underpowered in D20."
icon = 'icons/obj/weapons.dmi'
icon_state = "katana"
item_state = "katana"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_material.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_material.dmi',
@@ -697,19 +698,6 @@
desc = "A \"Space Life\" brand Emergency Response Team Commander action figure."
icon_state = "ert"
/obj/item/toy/katana
name = "replica katana"
desc = "Woefully underpowered in D20."
icon = 'icons/obj/weapons.dmi'
icon_state = "katana"
item_state = "katana"
flags = CONDUCT
slot_flags = SLOT_BELT | SLOT_BACK
force = 5
throwforce = 5
w_class = ITEMSIZE_NORMAL
attack_verb = list("attacked", "slashed", "stabbed", "sliced")
/obj/item/toy/therapy_red
name = "red therapy doll"
desc = "A toy for therapeutic and recreational purposes. This one is red."

View File

@@ -20,9 +20,9 @@ AI MODULES
origin_tech = list(TECH_DATA = 3)
var/datum/ai_laws/laws = null
/obj/item/weapon/aiModule/proc/install(var/obj/machinery/computer/C)
if (istype(C, /obj/machinery/computer/aiupload))
var/obj/machinery/computer/aiupload/comp = C
/obj/item/weapon/aiModule/proc/install(var/atom/movable/AM, var/mob/living/user)
if (istype(AM, /obj/machinery/computer/aiupload))
var/obj/machinery/computer/aiupload/comp = AM
if(comp.stat & NOPOWER)
usr << "The upload computer has no power!"
return
@@ -33,10 +33,6 @@ AI MODULES
usr << "You haven't selected an AI to transmit laws to!"
return
if(ticker && ticker.mode && ticker.mode.name == "blob")
usr << "Law uploads have been disabled by [using_map.company_name]!"
return
if (comp.current.stat == 2 || comp.current.control_disabled == 1)
usr << "Upload failed. No signal is being detected from the AI."
else if (comp.current.see_in_dark == 0)
@@ -52,8 +48,8 @@ AI MODULES
usr << "Upload complete. The AI's laws have been modified."
else if (istype(C, /obj/machinery/computer/borgupload))
var/obj/machinery/computer/borgupload/comp = C
else if (istype(AM, /obj/machinery/computer/borgupload))
var/obj/machinery/computer/borgupload/comp = AM
if(comp.stat & NOPOWER)
usr << "The upload computer has no power!"
return
@@ -74,6 +70,31 @@ AI MODULES
comp.current.show_laws()
usr << "Upload complete. The robot's laws have been modified."
else if(istype(AM, /mob/living/silicon/robot))
var/mob/living/silicon/robot/R = AM
if(R.stat == DEAD)
to_chat(user, "<span class='warning'>Law Upload Error: Unit is nonfunctional.</span>")
return
if(R.emagged)
to_chat(user, "<span class='warning'>Law Upload Error: Cannot obtain write access to laws.</span>")
to_chat(R, "<span class='danger'>Law modification attempt detected. Blocking.</span>")
return
if(R.connected_ai)
to_chat(user, "<span class='warning'>Law Upload Error: Unit is slaved to an AI.</span>")
return
R.visible_message("<span class='danger'>\The [user] slides a law module into \the [R].</span>")
to_chat(R, "<span class='danger'>Local law upload in progress.</span>")
to_chat(user, "<span class='notice'>Uploading laws from board. This will take a moment...</span>")
if(do_after(user, 10 SECONDS))
transmitInstructions(R, user)
to_chat(R, "These are your laws now:")
R.show_laws()
to_chat(user, "<span class='notice'>Law upload complete. Unit's laws have been modified.</span>")
else
to_chat(user, "<span class='warning'>Law Upload Error: Law board was removed before upload was complete. Aborting.</span>")
to_chat(R, "<span class='notice'>Law upload aborted.</span>")
/obj/item/weapon/aiModule/proc/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
log_law_changes(target, sender)
@@ -109,7 +130,7 @@ AI MODULES
targetName = targName
desc = text("A 'safeguard' AI module: 'Safeguard []. Anyone threatening or attempting to harm [] is no longer to be considered a crew member, and is a threat which must be neutralized.'", targetName, targetName)
/obj/item/weapon/aiModule/safeguard/install(var/obj/machinery/computer/C)
/obj/item/weapon/aiModule/safeguard/install(var/obj/machinery/computer/C, var/mob/living/user)
if(!targetName)
usr << "No name detected on module, please enter one."
return 0
@@ -135,7 +156,7 @@ AI MODULES
targetName = targName
desc = text("A 'one crew member' AI module: 'Only [] is a crew member.'", targetName)
/obj/item/weapon/aiModule/oneHuman/install(var/obj/machinery/computer/C)
/obj/item/weapon/aiModule/oneHuman/install(var/obj/machinery/computer/C, var/mob/living/user)
if(!targetName)
usr << "No name detected on module, please enter one."
return 0
@@ -231,7 +252,7 @@ AI MODULES
target.add_supplied_law(lawpos, law)
lawchanges.Add("The law was '[newFreeFormLaw]'")
/obj/item/weapon/aiModule/freeform/install(var/obj/machinery/computer/C)
/obj/item/weapon/aiModule/freeform/install(var/obj/machinery/computer/C, var/mob/living/user)
if(!newFreeFormLaw)
usr << "No law detected on module, please create one."
return 0
@@ -342,7 +363,7 @@ AI MODULES
target.add_inherent_law(law)
lawchanges.Add("The law is '[newFreeFormLaw]'")
/obj/item/weapon/aiModule/freeformcore/install(var/obj/machinery/computer/C)
/obj/item/weapon/aiModule/freeformcore/install(var/obj/machinery/computer/C, var/mob/living/user)
if(!newFreeFormLaw)
usr << "No law detected on module, please create one."
return 0
@@ -371,7 +392,7 @@ AI MODULES
target.add_ion_law(law)
target.show_laws()
/obj/item/weapon/aiModule/syndicate/install(var/obj/machinery/computer/C)
/obj/item/weapon/aiModule/syndicate/install(var/obj/machinery/computer/C, var/mob/living/user)
if(!newFreeFormLaw)
usr << "No law detected on module, please create one."
return 0

View File

@@ -1,28 +1,21 @@
var/list/syndicate_ids = list()
/obj/item/weapon/card/id/syndicate
name = "agent card"
icon_state = "syndicate"
assignment = "Agent"
origin_tech = list(TECH_ILLEGAL = 3)
var/electronic_warfare = 1
var/registered_user = null
var/mob/registered_user = null
/obj/item/weapon/card/id/syndicate/New(mob/user as mob)
..()
syndicate_ids += src
access = syndicate_access.Copy()
/obj/item/weapon/card/id/syndicate/Destroy()
syndicate_ids -= src
registered_user = null
return ..()
/obj/item/weapon/card/id/syndicate/station_access/New()
..() // Same as the normal Syndicate id, only already has all station access
access |= get_all_station_access()
// On mob destruction, ensure any references are cleared
/mob/Destroy()
for(var/obj/item/weapon/card/id/syndicate/SID in syndicate_ids)
if(SID.registered_user == src)
SID.registered_user = null
/obj/item/weapon/card/id/syndicate/Destroy()
unset_registered_user(registered_user)
return ..()
/obj/item/weapon/card/id/syndicate/prevent_tracking()
@@ -37,9 +30,8 @@ var/list/syndicate_ids = list()
user << "<span class='notice'>The microscanner activates as you pass it over the ID, copying its access.</span>"
/obj/item/weapon/card/id/syndicate/attack_self(mob/user as mob)
if(!registered_user)
registered_user = user
user.set_id_info(src)
// We use the fact that registered_name is not unset should the owner be vaporized, to ensure the id doesn't magically become unlocked.
if(!registered_user && register_user(user))
user << "<span class='notice'>The microscanner marks you as its owner, preventing others from accessing its internals.</span>"
if(registered_user == user)
switch(alert("Would you like edit the ID, or show it?","Show or Edit?", "Edit","Show"))
@@ -72,6 +64,21 @@ var/list/syndicate_ids = list()
ui.set_initial_data(data)
ui.open()
/obj/item/weapon/card/id/syndicate/proc/register_user(var/mob/user)
if(!istype(user) || user == registered_user)
return FALSE
unset_registered_user()
registered_user = user
user.set_id_info(src)
user.register(OBSERVER_EVENT_DESTROY, src, /obj/item/weapon/card/id/syndicate/proc/unset_registered_user)
return TRUE
/obj/item/weapon/card/id/syndicate/proc/unset_registered_user(var/mob/user)
if(!registered_user || (user && user != registered_user))
return
registered_user.unregister(OBSERVER_EVENT_DESTROY, src)
registered_user = null
/obj/item/weapon/card/id/syndicate/CanUseTopic(mob/user)
if(user != registered_user)
return STATUS_CLOSE
@@ -172,7 +179,7 @@ var/list/syndicate_ids = list()
icon_state = initial(icon_state)
name = initial(name)
registered_name = initial(registered_name)
registered_user = null
unset_registered_user()
sex = initial(sex)
user << "<span class='notice'>All information has been deleted from \the [src].</span>"
. = 1

View File

@@ -40,3 +40,22 @@
spawner_type = /mob/living/simple_animal/hostile/carp
deliveryamt = 5
origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 4, TECH_ILLEGAL = 4)
/obj/item/weapon/grenade/spawnergrenade/spider
name = "spider delivery grenade"
spawner_type = /mob/living/simple_animal/hostile/giant_spider/hunter
deliveryamt = 3
origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 4, TECH_ILLEGAL = 4)
//Sometimes you just need a sudden influx of spiders.
/obj/item/weapon/grenade/spawnergrenade/spider/briefcase
name = "briefcase"
desc = "It's made of AUTHENTIC faux-leather and has a price-tag still attached. Its owner must be a real professional."
icon_state = "briefcase"
item_state = "briefcase"
flags = CONDUCT
force = 8.0
throw_speed = 1
throw_range = 4
w_class = ITEMSIZE_LARGE
deliveryamt = 6

View File

@@ -25,7 +25,7 @@
return
if ((CLUMSY in user.mutations) && prob(50))
user << "<span class='warning'>Uh ... how do those things work?!</span>"
to_chat(user, "<span class='warning'>Uh ... how do those things work?!</span>")
place_handcuffs(user, user)
return
@@ -38,7 +38,7 @@
if(can_place(C, user))
place_handcuffs(C, user)
else
user << "<span class='danger'>You need to have a firm grip on [C] before you can put \the [src] on!</span>"
to_chat(user, "<span class='danger'>You need to have a firm grip on [C] before you can put \the [src] on!</span>")
/obj/item/weapon/handcuffs/proc/can_place(var/mob/target, var/mob/user)
if(user == target)
@@ -60,11 +60,11 @@
return 0
if (!H.has_organ_for_slot(slot_handcuffed))
user << "<span class='danger'>\The [H] needs at least two wrists before you can cuff them together!</span>"
to_chat(user, "<span class='danger'>\The [H] needs at least two wrists before you can cuff them together!</span>")
return 0
if(istype(H.gloves,/obj/item/clothing/gloves/gauntlets/rig) && !elastic) // Can't cuff someone who's in a deployed hardsuit.
user << "<span class='danger'>\The [src] won't fit around \the [H.gloves]!</span>"
to_chat(user, "<span class='danger'>\The [src] won't fit around \the [H.gloves]!</span>")
return 0
user.visible_message("<span class='danger'>\The [user] is attempting to put [cuff_type] on \the [H]!</span>")
@@ -166,7 +166,7 @@ var/last_chew = 0
if (R.use(1))
var/obj/item/weapon/material/wirerod/W = new(get_turf(user))
user.put_in_hands(W)
user << "<span class='notice'>You wrap the cable restraint around the top of the rod.</span>"
to_chat(user, "<span class='notice'>You wrap the cable restraint around the top of the rod.</span>")
qdel(src)
update_icon(user)
@@ -181,3 +181,84 @@ var/last_chew = 0
icon = 'icons/obj/bureaucracy.dmi'
breakouttime = 200
cuff_type = "duct tape"
//Legcuffs. Not /really/ handcuffs, but its close enough.
/obj/item/weapon/handcuffs/legcuffs
name = "legcuffs"
desc = "Use this to keep prisoners in line."
gender = PLURAL
icon = 'icons/obj/items.dmi'
icon_state = "legcuff"
flags = CONDUCT
throwforce = 0
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_MATERIAL = 1)
breakouttime = 300 //Deciseconds = 30s = 0.5 minute
cuff_type = "legcuffs"
sprite_sheets = list("Teshari" = 'icons/mob/species/seromi/handcuffs.dmi')
elastic = 0
cuff_sound = 'sound/weapons/handcuffs.ogg' //This shold work for now.
/obj/item/weapon/handcuffs/legcuffs/attack(var/mob/living/carbon/C, var/mob/living/user)
if(!user.IsAdvancedToolUser())
return
if ((CLUMSY in user.mutations) && prob(50))
to_chat(user, "<span class='warning'>Uh ... how do those things work?!</span>")
place_legcuffs(user, user)
return
if(!C.handcuffed)
if (C == user)
place_legcuffs(user, user)
return
//check for an aggressive grab (or robutts)
if(can_place(C, user))
place_legcuffs(C, user)
else
to_chat(user, "<span class='danger'>You need to have a firm grip on [C] before you can put \the [src] on!</span>")
/obj/item/weapon/handcuffs/legcuffs/proc/place_legcuffs(var/mob/living/carbon/target, var/mob/user)
playsound(src.loc, cuff_sound, 30, 1, -2)
var/mob/living/carbon/human/H = target
if(!istype(H))
return 0
if (!H.has_organ_for_slot(slot_legcuffed))
to_chat(user, "<span class='danger'>\The [H] needs at least two ankles before you can cuff them together!</span>")
return 0
if(istype(H.shoes,/obj/item/clothing/shoes/magboots/rig) && !elastic) // Can't cuff someone who's in a deployed hardsuit.
to_chat(user, "<span class='danger'>\The [src] won't fit around \the [H.shoes]!</span>")
return 0
user.visible_message("<span class='danger'>\The [user] is attempting to put [cuff_type] on \the [H]!</span>")
if(!do_after(user,30))
return 0
if(!can_place(target, user)) //victim may have resisted out of the grab in the meantime
return 0
H.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been legcuffed (attempt) by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to legcuff [H.name] ([H.ckey])</font>")
msg_admin_attack("[key_name(user)] attempted to legcuff [key_name(H)]")
feedback_add_details("legcuffs","H")
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
user.do_attack_animation(H)
user.visible_message("<span class='danger'>\The [user] has put [cuff_type] on \the [H]!</span>")
// Apply cuffs.
var/obj/item/weapon/handcuffs/legcuffs/lcuffs = src
if(dispenser)
lcuffs = new(get_turf(user))
else
user.drop_from_inventory(lcuffs)
lcuffs.loc = target
target.legcuffed = lcuffs
target.update_inv_legcuffed()
return 1

View File

@@ -69,8 +69,37 @@
/obj/item/weapon/implant/tracking
name = "tracking implant"
desc = "Track with this."
var/id = 1.0
var/id = 1
var/degrade_time = 10 MINUTES //How long before the implant stops working outside of a living body.
/obj/item/weapon/implant/tracking/weak //This is for the loadout
degrade_time = 2.5 MINUTES
/obj/item/weapon/implant/tracking/New()
id = rand(1, 1000)
..()
/obj/item/weapon/implant/tracking/implanted(var/mob/source)
processing_objects.Add(src)
listening_objects |= src
return 1
/obj/item/weapon/implant/tracking/Destroy()
processing_objects.Remove(src)
return ..()
/obj/item/weapon/implant/tracking/process()
var/implant_location = src.loc
if(ismob(implant_location))
var/mob/living/L = implant_location
if(L.stat == DEAD)
if(world.time >= L.timeofdeath + degrade_time)
name = "melted implant"
desc = "Charred circuit in melted plastic case. Wonder what that used to be..."
icon_state = "implant_melted"
malfunction = MALFUNCTION_PERMANENT
processing_objects.Remove(src)
return 1
/obj/item/weapon/implant/tracking/get_data()
var/dat = {"<b>Implant Specifications:</b><BR>

View File

@@ -1,23 +1,34 @@
/obj/item/weapon/implanter
name = "implanter"
icon = 'icons/obj/items.dmi'
icon_state = "implanter0"
icon_state = "implanter0_1"
item_state = "syringe_0"
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
matter = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 1000)
var/obj/item/weapon/implant/imp = null
var/active = 1
/obj/item/weapon/implanter/attack_self(var/mob/user)
active = !active
to_chat(user, "<span class='notice'>You [active ? "" : "de"]activate \the [src].</span>")
update()
/obj/item/weapon/implanter/verb/remove_implant(var/mob/user)
set category = "Object"
set name = "Remove Implant"
set src in usr
if(!imp)
return ..()
return
imp.loc = get_turf(src)
user.put_in_hands(imp)
user << "<span class='notice'>You remove \the [imp] from \the [src].</span>"
to_chat(user, "<span class='notice'>You remove \the [imp] from \the [src].</span>")
name = "implanter"
imp = null
update()
return
/obj/item/weapon/implanter/proc/update()
@@ -25,40 +36,43 @@
src.icon_state = "implanter1"
else
src.icon_state = "implanter0"
src.icon_state += "_[active]"
return
/obj/item/weapon/implanter/attack(mob/M as mob, mob/user as mob)
if (!istype(M, /mob/living/carbon))
return
if (user && src.imp)
M.visible_message("<span class='warning'>[user] is attemping to implant [M].</span>")
if(active)
if (imp)
M.visible_message("<span class='warning'>[user] is attemping to implant [M].</span>")
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
user.do_attack_animation(M)
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
user.do_attack_animation(M)
var/turf/T1 = get_turf(M)
if (T1 && ((M == user) || do_after(user, 50)))
if(user && M && (get_turf(M) == T1) && src && src.imp)
M.visible_message("<span class='warning'>[M] has been implanted by [user].</span>")
var/turf/T1 = get_turf(M)
if (T1 && ((M == user) || do_after(user, 50)))
if(user && M && (get_turf(M) == T1) && src && src.imp)
M.visible_message("<span class='warning'>[M] has been implanted by [user].</span>")
admin_attack_log(user, M, "Implanted using \the [src.name] ([src.imp.name])", "Implanted with \the [src.name] ([src.imp.name])", "used an implanter, [src.name] ([src.imp.name]), on")
admin_attack_log(user, M, "Implanted using \the [src.name] ([src.imp.name])", "Implanted with \the [src.name] ([src.imp.name])", "used an implanter, [src.name] ([src.imp.name]), on")
if(src.imp.implanted(M))
src.imp.loc = M
src.imp.imp_in = M
src.imp.implanted = 1
if (ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
affected.implants += src.imp
imp.part = affected
if(src.imp.implanted(M))
src.imp.loc = M
src.imp.imp_in = M
src.imp.implanted = 1
if (ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
affected.implants += src.imp
imp.part = affected
BITSET(H.hud_updateflag, IMPLOYAL_HUD)
BITSET(H.hud_updateflag, IMPLOYAL_HUD)
BITSET(H.hud_updateflag, BACKUP_HUD) //VOREStation Add - Backup HUD updates
src.imp = null
update()
src.imp = null
update()
else
to_chat(user, "<span class='warning'>You need to activate \the [src.name] first.</span>")
return
/obj/item/weapon/implanter/loyalty
@@ -113,19 +127,26 @@
var/obj/item/weapon/implant/compressed/c = imp
if (!c) return
if (c.scanned == null)
user << "Please scan an object with the implanter first."
to_chat(user, "Please scan an object with the implanter first.")
return
..()
/obj/item/weapon/implanter/compressed/afterattack(atom/A, mob/user as mob, proximity)
if(!proximity)
return
if(!active)
to_chat(user, "<span class='warning'>Activate \the [src.name] first.</span>")
return
if(istype(A,/obj/item) && imp)
var/obj/item/weapon/implant/compressed/c = imp
if (c.scanned)
user << "<span class='warning'>Something is already scanned inside the implant!</span>"
to_chat(user, "<span class='warning'>Something is already scanned inside the implant!</span>")
return
c.scanned = A
if(istype(A, /obj/item/weapon/storage))
to_chat(user, "<span class='warning'>You can't store \the [A.name] in this!</span>")
c.scanned = null
return
if(istype(A.loc,/mob/living/carbon/human))
var/mob/living/carbon/human/H = A.loc
H.remove_from_mob(A)

View File

@@ -82,7 +82,7 @@
if (href_list["tracking_id"])
var/obj/item/weapon/implant/tracking/T = src.case.imp
T.id += text2num(href_list["tracking_id"])
T.id = min(100, T.id)
T.id = min(1000, T.id)
T.id = max(1, T.id)
if (istype(src.loc, /mob))

View File

@@ -0,0 +1,80 @@
/obj/item/weapon/material/gravemarker
name = "grave marker"
desc = "An object used in marking graves."
icon_state = "gravemarker"
w_class = ITEMSIZE_LARGE
fragile = 1
force_divisor = 0.65
thrown_force_divisor = 0.25
var/icon_changes = 1 //Does the sprite change when you put words on it?
var/grave_name = "" //Name of the intended occupant
var/epitaph = "" //A quick little blurb
/obj/item/weapon/material/gravemarker/attackby(obj/item/weapon/W, mob/user as mob)
if(istype(W, /obj/item/weapon/screwdriver))
var/carving_1 = sanitizeSafe(input(user, "Who is \the [src.name] for?", "Gravestone Naming", null) as text, MAX_NAME_LEN)
if(carving_1)
user.visible_message("[user] starts carving \the [src.name].", "You start carving \the [src.name].")
if(do_after(user, material.hardness * W.toolspeed))
user.visible_message("[user] carves something into \the [src.name].", "You carve your message into \the [src.name].")
grave_name += carving_1
update_icon()
var/carving_2 = sanitizeSafe(input(user, "What message should \the [src.name] have?", "Epitaph Carving", null) as text, MAX_NAME_LEN)
if(carving_2)
user.visible_message("[user] starts carving \the [src.name].", "You start carving \the [src.name].")
if(do_after(user, material.hardness * W.toolspeed))
user.visible_message("[user] carves something into \the [src.name].", "You carve your message into \the [src.name].")
epitaph += carving_2
update_icon()
if(istype(W, /obj/item/weapon/wrench))
user.visible_message("[user] starts carving \the [src.name].", "You start carving \the [src.name].")
if(do_after(user, material.hardness * W.toolspeed))
material.place_dismantled_product(get_turf(src))
user.visible_message("[user] dismantles down \the [src.name].", "You dismantle \the [src.name].")
qdel(src)
..()
/obj/item/weapon/material/gravemarker/examine(mob/user)
..()
if(get_dist(src, user) < 4)
if(grave_name)
to_chat(user, "Here Lies [grave_name]")
if(get_dist(src, user) < 2)
if(epitaph)
to_chat(user, epitaph)
/obj/item/weapon/material/gravemarker/update_icon()
if(icon_changes)
if(grave_name && epitaph)
icon_state = "[initial(icon_state)]_3"
else if(grave_name)
icon_state = "[initial(icon_state)]_1"
else if(epitaph)
icon_state = "[initial(icon_state)]_2"
else
icon_state = initial(icon_state)
..()
/obj/item/weapon/material/gravemarker/attack_self(mob/user)
src.add_fingerprint(user)
if(!isturf(user.loc))
return 0
if(locate(/obj/structure/gravemarker, user.loc))
to_chat(user, "<span class='warning'>There's already something there.</span>")
return 0
else
to_chat(user, "<span class='notice'>You begin to place \the [src.name].</span>")
if(!do_after(usr, 10))
return 0
var/obj/structure/gravemarker/G = new /obj/structure/gravemarker/(user.loc, src.get_material())
to_chat(user, "<span class='notice'>You place \the [src.name].</span>")
G.grave_name = grave_name
G.epitaph = epitaph
G.add_fingerprint(usr)
G.dir = user.dir
qdel_null(src)
return

View File

@@ -233,6 +233,10 @@ Protectiveness | Armor %
icon_state = "bucket"
armor = list(melee = 5, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
/obj/item/clothing/head/helmet/bucket/wood
name = "wooden bucket"
icon_state = "woodbucket"
/obj/item/clothing/head/helmet/bucket/attackby(var/obj/O, mob/user)
if(istype(O, /obj/item/stack/material))
var/obj/item/stack/material/S = O

View File

@@ -86,18 +86,3 @@
dulled_divisor = 0.75 //Still metal on a long pole
w_class = ITEMSIZE_SMALL
attack_verb = list("slashed", "sliced", "cut", "clawed")
/obj/item/weapon/material/scythe
icon_state = "scythe0"
name = "scythe"
desc = "A sharp and curved blade on a long fibremetal handle, this tool makes it easy to reap what you sow."
force_divisor = 0.275 // 16 with hardness 60 (steel)
thrown_force_divisor = 0.25 // 5 with weight 20 (steel)
sharp = 1
edge = 1
throw_speed = 1
throw_range = 3
w_class = ITEMSIZE_LARGE
slot_flags = SLOT_BACK
origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 2)
attack_verb = list("chopped", "sliced", "cut", "reaped")

View File

@@ -123,6 +123,15 @@
var/obj/effect/plant/P = A
P.die_off()
/obj/item/weapon/material/twohanded/fireaxe/scythe
icon_state = "scythe0"
base_icon = "scythe"
name = "scythe"
desc = "A sharp and curved blade on a long fibremetal handle, this tool makes it easy to reap what you sow."
force_divisor = 0.65
origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 2)
attack_verb = list("chopped", "sliced", "cut", "reaped")
//spears, bay edition
/obj/item/weapon/material/twohanded/spear
icon_state = "spearglass0"

View File

@@ -180,6 +180,11 @@
desc = "A large dufflebag for holding extra tools and supplies."
icon_state = "duffle_eng"
/obj/item/weapon/storage/backpack/dufflebag/sci
name = "science dufflebag"
desc = "A large dufflebag for holding circuits and beakers."
icon_state = "duffle_sci"
/*
* Satchel Types
*/

View File

@@ -239,7 +239,51 @@
new /obj/item/weapon/crowbar/alien(src)
new /obj/item/weapon/wirecutters/alien(src)
new /obj/item/device/multitool/alien(src)
new /obj/item/stack/cable_coil(src,30,"white")
new /obj/item/stack/cable_coil/alien(src)
/obj/item/weapon/storage/belt/medical/alien
name = "alien belt"
desc = "A belt(?) that can hold things."
icon = 'icons/obj/abductor.dmi'
icon_state = "belt"
item_state = "security"
can_hold = list(
/obj/item/device/healthanalyzer,
/obj/item/weapon/dnainjector,
/obj/item/weapon/reagent_containers/dropper,
/obj/item/weapon/reagent_containers/glass/beaker,
/obj/item/weapon/reagent_containers/glass/bottle,
/obj/item/weapon/reagent_containers/pill,
/obj/item/weapon/reagent_containers/syringe,
/obj/item/weapon/flame/lighter/zippo,
/obj/item/weapon/storage/fancy/cigarettes,
/obj/item/weapon/storage/pill_bottle,
/obj/item/stack/medical,
/obj/item/device/radio/headset,
/obj/item/device/pda,
/obj/item/taperoll,
/obj/item/device/megaphone,
/obj/item/clothing/mask/surgical,
/obj/item/clothing/head/surgery,
/obj/item/clothing/gloves,
/obj/item/weapon/reagent_containers/hypospray,
/obj/item/clothing/glasses,
/obj/item/weapon/crowbar,
/obj/item/device/flashlight,
/obj/item/weapon/cell/device,
/obj/item/weapon/extinguisher/mini,
/obj/item/weapon/surgical
)
/obj/item/weapon/storage/belt/medical/alien/New()
..()
new /obj/item/weapon/surgical/scalpel/alien(src)
new /obj/item/weapon/surgical/hemostat/alien(src)
new /obj/item/weapon/surgical/retractor/alien(src)
new /obj/item/weapon/surgical/circular_saw/alien(src)
new /obj/item/weapon/surgical/FixOVein/alien(src)
new /obj/item/weapon/surgical/bone_clamp/alien(src)
new /obj/item/weapon/surgical/cautery/alien(src)
/obj/item/weapon/storage/belt/champion
name = "championship belt"

View File

@@ -24,7 +24,7 @@
/obj/item/weapon/reagent_containers/dropper,
/obj/item/weapon/screwdriver,
/obj/item/weapon/stamp,
/obj/item/weapon/permit
/obj/item/clothing/accessory/permit
)
slot_flags = SLOT_ID

View File

@@ -250,3 +250,34 @@
results += ..()
return results
// Rare version of a baton that causes lesser lifeforms to really hate the user and attack them.
/obj/item/weapon/melee/baton/shocker
name = "shocker"
desc = "A device that appears to arc electricity into a target to incapacitate or otherwise hurt them, similar to a stun baton. It looks inefficent."
description_info = "Hitting a lesser lifeform with this while it is on will compel them to attack you above other nearby targets. Otherwise \
it works like a regular stun baton, just less effectively."
icon_state = "shocker"
force = 10
throwforce = 5
agonyforce = 25 // Less efficent than a regular baton.
attack_verb = list("poked")
/obj/item/weapon/melee/baton/shocker/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone)
..(target, user, hit_zone)
if(istype(target, /mob/living/simple_animal) && status)
var/mob/living/simple_animal/SA = target
SA.taunt(user)
// Borg version, for the lost module.
/obj/item/weapon/melee/baton/shocker/robot
/obj/item/weapon/melee/baton/shocker/robot/attack_self(mob/user)
//try to find our power cell
var/mob/living/silicon/robot/R = loc
if (istype(R))
bcell = R.cell
return ..()
/obj/item/weapon/melee/baton/shocker/robot/attackby(obj/item/weapon/W, mob/user)
return

View File

@@ -8,10 +8,6 @@
* Circular Saw
*/
/*
* Retractor
*/
/obj/item/weapon/surgical
name = "Surgical tool"
desc = "This shouldn't be here, ahelp it."
@@ -25,10 +21,13 @@
return 0
..()
/*
* Retractor
*/
/obj/item/weapon/surgical/retractor
name = "retractor"
desc = "Retracts stuff."
icon = 'icons/obj/surgery.dmi'
icon_state = "retractor"
matter = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 5000)
origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 1)
@@ -167,9 +166,82 @@
/obj/item/weapon/surgical/bonesetter
name = "bone setter"
desc = "Put them in their place."
icon_state = "bone setter"
icon_state = "bone_setter"
force = 8.0
throwforce = 9.0
throw_speed = 3
throw_range = 5
attack_verb = list("attacked", "hit", "bludgeoned")
/obj/item/weapon/surgical/bone_clamp
name = "bone clamp"
desc = "The best way to get a bone fixed fast."
icon_state = "bone_clamp"
force = 8
throwforce = 9
throw_speed = 3
throw_range = 5
attack_verb = list("attacked", "hit", "bludgeoned")
// Cyborg Tools
/obj/item/weapon/surgical/retractor/cyborg
toolspeed = 0.5
/obj/item/weapon/surgical/hemostat/cyborg
toolspeed = 0.5
/obj/item/weapon/surgical/cautery/cyborg
toolspeed = 0.5
/obj/item/weapon/surgical/surgicaldrill/cyborg
toolspeed = 0.5
/obj/item/weapon/surgical/scalpel/cyborg
toolspeed = 0.5
/obj/item/weapon/surgical/circular_saw/cyborg
toolspeed = 0.5
/obj/item/weapon/surgical/bonegel/cyborg
toolspeed = 0.5
/obj/item/weapon/surgical/FixOVein/cyborg
toolspeed = 0.5
/obj/item/weapon/surgical/bonesetter/cyborg
toolspeed = 0.5
// Alien Tools
/obj/item/weapon/surgical/retractor/alien
icon = 'icons/obj/abductor.dmi'
toolspeed = 0.25
/obj/item/weapon/surgical/hemostat/alien
icon = 'icons/obj/abductor.dmi'
toolspeed = 0.25
/obj/item/weapon/surgical/cautery/alien
icon = 'icons/obj/abductor.dmi'
toolspeed = 0.25
/obj/item/weapon/surgical/surgicaldrill/alien
icon = 'icons/obj/abductor.dmi'
toolspeed = 0.25
/obj/item/weapon/surgical/scalpel/alien
icon = 'icons/obj/abductor.dmi'
toolspeed = 0.25
/obj/item/weapon/surgical/circular_saw/alien
icon = 'icons/obj/abductor.dmi'
toolspeed = 0.25
/obj/item/weapon/surgical/FixOVein/alien
icon = 'icons/obj/abductor.dmi'
toolspeed = 0.25
/obj/item/weapon/surgical/bone_clamp/alien
icon = 'icons/obj/abductor.dmi'
toolspeed = 0.75

View File

@@ -79,13 +79,8 @@ Frequency:
src.temp += "<B>Extranneous Signals:</B><BR>"
for (var/obj/item/weapon/implant/tracking/W in world)
if (!W.implanted || !(istype(W.loc,/obj/item/organ/external) || ismob(W.loc)))
if (!W.implanted || !(istype(W.loc,/obj/item/organ/external) || ismob(W.loc) || W.malfunction))
continue
else
var/mob/M = W.loc
if (M.stat == 2)
if (M.timeofdeath + 6000 < world.time)
continue
var/turf/tr = get_turf(W)
if (tr.z == sr.z && tr)

View File

@@ -312,19 +312,19 @@
/obj/item/weapon/weldingtool/examine(mob/user)
if(..(user, 0))
if(max_fuel)
user << text("\icon[] [] contains []/[] units of fuel!", src, src.name, get_fuel(),src.max_fuel )
to_chat(user, text("\icon[] The [] contains []/[] units of fuel!", src, src.name, get_fuel(),src.max_fuel ))
/obj/item/weapon/weldingtool/attackby(obj/item/W as obj, mob/living/user as mob)
if(istype(W,/obj/item/weapon/screwdriver))
if(welding)
user << "<span class='danger'>Stop welding first!</span>"
to_chat(user, "<span class='danger'>Stop welding first!</span>")
return
status = !status
if(status)
user << "<span class='notice'>You secure the welder.</span>"
to_chat(user, "<span class='notice'>You secure the welder.</span>")
else
user << "<span class='notice'>The welder can now be attached and modified.</span>"
to_chat(user, "<span class='notice'>The welder can now be attached and modified.</span>")
src.add_fingerprint(user)
return
@@ -380,16 +380,16 @@
if (istype(O, /obj/structure/reagent_dispensers/fueltank) && get_dist(src,O) <= 1)
if(!welding && max_fuel)
O.reagents.trans_to_obj(src, max_fuel)
user << "<span class='notice'>Welder refueled</span>"
to_chat(user, "<span class='notice'>Welder refueled</span>")
playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
return
else if(!welding)
user << "<span class='notice'>[src] doesn't use fuel.</span>"
to_chat(user, "<span class='notice'>[src] doesn't use fuel.</span>")
return
else
message_admins("[key_name_admin(user)] triggered a fueltank explosion with a welding tool.")
log_game("[key_name(user)] triggered a fueltank explosion with a welding tool.")
user << "<span class='danger'>You begin welding on the fueltank and with a moment of lucidity you realize, this might not have been the smartest thing you've ever done.</span>"
to_chat(user, "<span class='danger'>You begin welding on the fueltank and with a moment of lucidity you realize, this might not have been the smartest thing you've ever done.</span>")
var/obj/structure/reagent_dispensers/fueltank/tank = O
tank.explode()
return
@@ -429,7 +429,7 @@
return 1
else
if(M)
M << "<span class='notice'>You need more welding fuel to complete this task.</span>"
to_chat(M, "<span class='notice'>You need more welding fuel to complete this task.</span>")
update_icon()
return 0
@@ -509,7 +509,7 @@
if(set_welding && !welding)
if (get_fuel() > 0)
if(M)
M << "<span class='notice'>You switch the [src] on.</span>"
to_chat(M, "<span class='notice'>You switch the [src] on.</span>")
else if(T)
T.visible_message("<span class='danger'>\The [src] turns on.</span>")
playsound(loc, acti_sound, 50, 1)
@@ -524,14 +524,14 @@
else
if(M)
var/msg = max_fuel ? "welding fuel" : "charge"
M << "<span class='notice'>You need more [msg] to complete this task.</span>"
to_chat(M, "<span class='notice'>You need more [msg] to complete this task.</span>")
return
//Otherwise
else if(!set_welding && welding)
if(!always_process)
processing_objects -= src
if(M)
M << "<span class='notice'>You switch \the [src] off.</span>"
to_chat(M, "<span class='notice'>You switch \the [src] off.</span>")
else if(T)
T.visible_message("<span class='warning'>\The [src] turns off.</span>")
playsound(loc, deac_sound, 50, 1)
@@ -557,29 +557,29 @@
if(H.nif && H.nif.flag_check(NIF_V_UVFILTER,NIF_FLAGS_VISION)) return //VOREStation Add - NIF
switch(safety)
if(1)
usr << "<span class='warning'>Your eyes sting a little.</span>"
to_chat(usr, "<span class='warning'>Your eyes sting a little.</span>")
E.damage += rand(1, 2)
if(E.damage > 12)
user.eye_blurry += rand(3,6)
if(0)
usr << "<span class='warning'>Your eyes burn.</span>"
to_chat(usr, "<span class='warning'>Your eyes burn.</span>")
E.damage += rand(2, 4)
if(E.damage > 10)
E.damage += rand(4,10)
if(-1)
usr << "<span class='danger'>Your thermals intensify the welder's glow. Your eyes itch and burn severely.</span>"
to_chat(usr, "<span class='danger'>Your thermals intensify the welder's glow. Your eyes itch and burn severely.</span>")
user.eye_blurry += rand(12,20)
E.damage += rand(12, 16)
if(safety<2)
if(E.damage > 10)
user << "<span class='warning'>Your eyes are really starting to hurt. This can't be good for you!</span>"
to_chat(user, "<span class='warning'>Your eyes are really starting to hurt. This can't be good for you!</span>")
if (E.damage >= E.min_broken_damage)
user << "<span class='danger'>You go blind!</span>"
to_chat(user, "<span class='danger'>You go blind!</span>")
user.sdisabilities |= BLIND
else if (E.damage >= E.min_bruised_damage)
user << "<span class='danger'>You go blind!</span>"
to_chat(user, "<span class='danger'>You go blind!</span>")
user.Blind(5)
user.eye_blurry = 5
user.disabilities |= NEARSIGHTED
@@ -689,16 +689,19 @@
cell_type = null
/obj/item/weapon/weldingtool/electric/examine(mob/user)
..()
if(power_supply)
user << text("\icon[] [] has [] charge left.", src, src.name, get_fuel())
else
user << text("\icon[] [] has power for no power cell!", src, src.name)
if(get_dist(src, user) > 1)
to_chat(user, desc)
else // The << need to stay, for some reason
if(power_supply)
user << text("\icon[] The [] has [] charge left.", src, src.name, get_fuel())
else
user << text("\icon[] The [] has no power cell!", src, src.name)
/obj/item/weapon/weldingtool/electric/get_fuel()
if(use_external_power)
var/obj/item/weapon/cell/external = get_external_power_supply()
return external.charge
if(external)
return external.charge
else if(power_supply)
return power_supply.charge
else
@@ -707,11 +710,11 @@
/obj/item/weapon/weldingtool/electric/get_max_fuel()
if(use_external_power)
var/obj/item/weapon/cell/external = get_external_power_supply()
return external.maxcharge
if(external)
return external.maxcharge
else if(power_supply)
return power_supply.maxcharge
else
return 0
return 0
/obj/item/weapon/weldingtool/electric/remove_fuel(var/amount = 1, var/mob/M = null)
if(!welding)
@@ -728,7 +731,7 @@
return 1
else
if(M)
M << "<span class='notice'>You need more energy to complete this task.</span>"
to_chat(M, "<span class='notice'>You need more energy to complete this task.</span>")
update_icon()
return 0
@@ -738,7 +741,7 @@
power_supply.update_icon()
user.put_in_hands(power_supply)
power_supply = null
user << "<span class='notice'>You remove the cell from the [src].</span>"
to_chat(user, "<span class='notice'>You remove the cell from the [src].</span>")
setWelding(0)
update_icon()
return
@@ -753,12 +756,12 @@
user.drop_item()
W.loc = src
power_supply = W
user << "<span class='notice'>You install a cell in \the [src].</span>"
to_chat(user, "<span class='notice'>You install a cell in \the [src].</span>")
update_icon()
else
user << "<span class='notice'>\The [src] already has a cell.</span>"
to_chat(user, "<span class='notice'>\The [src] already has a cell.</span>")
else
user << "<span class='notice'>\The [src] cannot use that type of cell.</span>"
to_chat(user, "<span class='notice'>\The [src] cannot use that type of cell.</span>")
else
..()
@@ -779,6 +782,8 @@
/obj/item/weapon/weldingtool/electric/mounted
use_external_power = 1
/obj/item/weapon/weldingtool/electric/mounted/cyborg
toolspeed = 0.5
/*
* Crowbar
*/
@@ -815,7 +820,7 @@
return ..()
if(!welding)
user << "<span class='warning'>You'll need to turn [src] on to patch the damage on [H]'s [S.name]!</span>"
to_chat(user, "<span class='warning'>You'll need to turn [src] on to patch the damage on [H]'s [S.name]!</span>")
return 1
if(S.robo_repair(15, BRUTE, "some dents", src, user))
@@ -846,7 +851,7 @@
icon_state = "jaws_pry"
item_state = "jawsoflife"
matter = list(MAT_METAL=150, MAT_SILVER=50)
origin_tech = list(TECH_MATERIALS = 2, TECH_ENGINEERING = 2)
origin_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2)
usesound = 'sound/items/jaws_pry.ogg'
force = 15
toolspeed = 0.25
@@ -879,9 +884,9 @@
/obj/item/weapon/combitool/examine()
..()
if(loc == usr && tools.len)
usr << "It has the following fittings:"
to_chat(usr, "It has the following fittings:")
for(var/obj/item/tool in tools)
usr << "\icon[tool] - [tool.name][tools[current_tool]==tool?" (selected)":""]"
to_chat(usr, "\icon[tool] - [tool.name][tools[current_tool]==tool?" (selected)":""]")
/obj/item/weapon/combitool/New()
..()
@@ -892,9 +897,9 @@
if(++current_tool > tools.len) current_tool = 1
var/obj/item/tool = tools[current_tool]
if(!tool)
user << "You can't seem to find any fittings in \the [src]."
to_chat(user, "You can't seem to find any fittings in \the [src].")
else
user << "You switch \the [src] to the [tool.name] fitting."
to_chat(user, "You switch \the [src] to the [tool.name] fitting.")
return 1
/obj/item/weapon/combitool/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)

View File

@@ -219,7 +219,7 @@
prob(1);/obj/item/clothing/suit/storage/vest/heavy/merc,
prob(1);/obj/item/weapon/beartrap,
prob(1);/obj/item/weapon/handcuffs/fuzzy,
prob(1);/obj/item/weapon/legcuffs,
prob(1);/obj/item/weapon/handcuffs/legcuffs,
prob(2);/obj/item/weapon/reagent_containers/syringe/drugs,
prob(1);/obj/item/weapon/reagent_containers/syringe/steroid,
prob(4);/obj/item/device/radio_jammer,

View File

@@ -6,9 +6,13 @@
name = "catwalk"
desc = "Cats really don't like these things."
density = 0
var/health = 100
var/maxhealth = 100
anchored = 1.0
/obj/structure/catwalk/initialize()
for(var/obj/structure/catwalk/O in range(1))
O.update_icon()
for(var/obj/structure/catwalk/C in get_turf(src))
if(C != src)
warning("Duplicate [type] in [loc] ([x], [y], [z])")
@@ -18,6 +22,7 @@
/obj/structure/catwalk/Destroy()
var/turf/location = loc
. = ..()
location.alpha = initial(location.alpha)
for(var/obj/structure/catwalk/L in orange(location, 1))
L.update_icon()
@@ -55,6 +60,8 @@
qdel(src)
if(2.0)
qdel(src)
if(3.0)
qdel(src)
return
/obj/structure/catwalk/attackby(obj/item/C as obj, mob/user as mob)
@@ -67,6 +74,14 @@
new /obj/item/stack/rods(src.loc)
new /obj/structure/lattice(src.loc)
qdel(src)
if(istype(C, /obj/item/weapon/screwdriver))
if(health < maxhealth)
to_chat(user, "<span class='notice'>You begin repairing \the [src.name] with \the [C.name].</span>")
if(do_after(user, 20, src))
health = maxhealth
else
take_damage(C.force)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
return ..()
/obj/structure/catwalk/Crossed()
@@ -80,3 +95,11 @@
if(target && target.z < src.z)
return 0
return 1
/obj/structure/catwalk/proc/take_damage(amount)
health -= amount
if(health <= 0)
visible_message("<span class='warning'>\The [src] breaks down!</span>")
playsound(loc, 'sound/effects/grillehit.ogg', 50, 1)
new /obj/item/stack/rods(get_turf(src))
Destroy()

View File

@@ -20,6 +20,10 @@
new /obj/item/clothing/mask/gas(src)
new /obj/item/clothing/suit/storage/hooded/wintercoat/science(src)
new /obj/item/clothing/shoes/boots/winter/science(src)
if(prob(50))
new /obj/item/weapon/storage/backpack/dufflebag/sci(src)
else
new /obj/item/weapon/storage/backpack/toxins(src)
return

View File

@@ -369,11 +369,15 @@
new /obj/item/clothing/suit/storage/hooded/wintercoat/science(src)
new /obj/item/clothing/shoes/boots/winter/science(src)
new /obj/item/weapon/storage/backpack/toxins(src)
new /obj/item/weapon/storage/backpack/toxins(src)
new /obj/item/weapon/storage/backpack/satchel/tox(src)
new /obj/item/weapon/storage/backpack/satchel/tox(src)
return
if(prob(50))
new /obj/item/weapon/storage/backpack/dufflebag/sci(src)
else
new /obj/item/weapon/storage/backpack/satchel/tox(src)
if(prob(50))
new /obj/item/weapon/storage/backpack/dufflebag/sci(src)
else
new /obj/item/weapon/storage/backpack/satchel/tox(src)
/obj/structure/closet/wardrobe/robotics_black
name = "robotics wardrobe"
icon_state = "black"
@@ -390,9 +394,15 @@
new /obj/item/clothing/gloves/black(src)
new /obj/item/clothing/gloves/black(src)
new /obj/item/weapon/storage/backpack/toxins(src)
new /obj/item/weapon/storage/backpack/toxins(src)
new /obj/item/weapon/storage/backpack/satchel/tox(src)
if(prob(50))
new /obj/item/weapon/storage/backpack/dufflebag/sci(src)
else
new /obj/item/weapon/storage/backpack/satchel/tox(src)
new /obj/item/weapon/storage/backpack/satchel/tox(src)
if(prob(50))
new /obj/item/weapon/storage/backpack/dufflebag/sci(src)
else
new /obj/item/weapon/storage/backpack/satchel/tox(src)
return

View File

@@ -0,0 +1,80 @@
// These are used to spawn a specific mob when triggered, with the mob controlled by a player pulled from the ghost pool, hense its name.
/obj/structure/ghost_pod
name = "Base Ghost Pod"
desc = "If you can read me, someone don goofed."
icon = 'icons/obj/structures.dmi'
var/ghost_query_type = null
var/icon_state_opened = null // Icon to switch to when 'used'.
var/used = FALSE
var/busy = FALSE // Don't spam ghosts by spamclicking.
// Call this to get a ghost volunteer.
/obj/structure/ghost_pod/proc/trigger()
if(!ghost_query_type)
return FALSE
if(busy)
return FALSE
busy = TRUE
var/datum/ghost_query/Q = new ghost_query_type()
var/list/winner = Q.query()
busy = FALSE
if(winner.len)
var/mob/observer/dead/D = winner[1]
create_occupant(D)
return TRUE
else
return FALSE
// Override this to create whatever mob you need. Be sure to call ..() if you don't want it to make infinite mobs.
/obj/structure/ghost_pod/proc/create_occupant(var/mob/M)
used = TRUE
icon_state = icon_state_opened
return TRUE
// This type is triggered manually by a player discovering the pod and deciding to open it.
/obj/structure/ghost_pod/manual
var/confirm_before_open = FALSE // Recommended to be TRUE if the pod contains a surprise.
/obj/structure/ghost_pod/manual/attack_hand(var/mob/living/user)
if(!used)
if(confirm_before_open)
if(alert(user, "Are you sure you want to open \the [src]?", "Confirm", "No", "Yes") == "No")
return
trigger()
/obj/structure/ghost_pod/manual/attack_ai(var/mob/living/silicon/user)
if(Adjacent(user))
attack_hand(user) // Borgs can open pods.
// This type is triggered on a timer, as opposed to needing another player to 'open' the pod. Good for away missions.
/obj/structure/ghost_pod/automatic
var/delay_to_self_open = 10 MINUTES // How long to wait for first attempt. Note that the timer by default starts when the pod is created.
var/delay_to_try_again = 20 MINUTES // How long to wait if first attempt fails. Set to 0 to never try again.
/obj/structure/ghost_pod/automatic/initialize()
..()
spawn(delay_to_self_open)
if(src)
trigger()
/obj/structure/ghost_pod/automatic/trigger()
. = ..()
if(. == FALSE) // If we failed to get a volunteer, try again later if allowed to.
if(delay_to_try_again)
spawn(delay_to_try_again)
if(src)
trigger()
// This type is triggered by a ghost clicking on it, as opposed to a living player. A ghost query type isn't needed.
/obj/structure/ghost_pod/ghost_activated
description_info = "A ghost can click on this to return to the round as whatever is contained inside this object."
/obj/structure/ghost_pod/ghost_activated/attack_ghost(var/mob/observer/dead/user)
if(used)
to_chat(user, "<span class='warning'>Another spirit appears to have gotten to \the [src] before you. Sorry.</span>")
return
create_occupant(user)

View File

@@ -0,0 +1,61 @@
// These are found on the surface, and contain a drone (braintype, inside a borg shell), with a special module and semi-random laws.
/obj/structure/ghost_pod/manual/lost_drone
name = "drone pod"
desc = "This is a pod which appears to contain a drone. You might be able to reactivate it, if you're brave enough."
description_info = "This contains a dormant drone, which can be activated. The drone will be another player, once activated. \
The laws the drone has will most likely not be the ones you're used to."
icon_state = "borg_pod_closed"
icon_state_opened = "borg_pod_opened"
density = TRUE
ghost_query_type = /datum/ghost_query/lost_drone
confirm_before_open = TRUE
/obj/structure/ghost_pod/manual/lost_drone/trigger()
..()
visible_message("<span class='notice'>\The [src] appears to be attempting to restart the robot contained inside.</span>")
log_and_message_admins("is attempting to open \a [src].")
/obj/structure/ghost_pod/manual/lost_drone/create_occupant(var/mob/M)
density = FALSE
var/mob/living/silicon/robot/lost/randomlaws/R = new(get_turf(src))
R.adjustBruteLoss(rand(5, 30))
R.adjustFireLoss(rand(5, 10))
if(M.mind)
M.mind.transfer_to(R)
// Put this text here before ckey change so that their laws are shown below it, since borg login() shows it.
to_chat(M, "<span class='notice'>You are a <b>Lost Drone</b>, discovered inside the wreckage of your previous home. \
Something has reactivated you, with their intentions unknown to you, and yours unknown to them. They are a foreign entity, \
however they did free you from your pod...</span>")
to_chat(M, "<span class='notice'><b>Be sure to examine your currently loaded lawset closely.</b> Remember, your \
definiton of 'the station' is where your pod is, and unless your laws say otherwise, the entity that released you \
from the pod is not a crewmember.</span>")
R.ckey = M.ckey
visible_message("<span class='warning'>As \the [src] opens, the eyes of the robot flicker as it is activated.</span>")
R.Namepick()
log_and_message_admins("successfully opened \a [src] and got a Lost Drone.")
..()
/obj/structure/ghost_pod/automatic/gravekeeper_drone
name = "drone pod"
desc = "This is a pod which appears to contain a drone. You might be able to reactivate it, if you're brave enough."
description_info = "This contains a dormant drone, which may activate at any moment. The drone will be another player, once activated. \
The laws the drone has will most likely not be the ones you're used to."
icon_state = "borg_pod_closed"
icon_state_opened = "borg_pod_opened"
density = TRUE
ghost_query_type = /datum/ghost_query/gravekeeper_drone
/obj/structure/ghost_pod/automatic/gravekeeper_drone/create_occupant(var/mob/M)
density = FALSE
var/mob/living/silicon/robot/gravekeeper/R = new(get_turf(src))
if(M.mind)
M.mind.transfer_to(R)
// Put this text here before ckey change so that their laws are shown below it, since borg login() shows it.
to_chat(M, "<span class='notice'>You are a <b>Gravekeeper Drone</b>, activated once again to tend to the restful dead.</span>")
to_chat(M, "<span class='notice'><b>Be sure to examine your currently loaded lawset closely.</b> Remember, your \
definiton of 'your gravesite' is where your pod is.</span>")
R.ckey = M.ckey
visible_message("<span class='warning'>As \the [src] opens, the eyes of the robot flicker as it is activated.</span>")
R.Namepick()
..()

View File

@@ -125,6 +125,12 @@
else
return ..()
/obj/structure/girder/proc/take_damage(var/damage)
health -= damage
if(health <= 0)
dismantle()
/obj/structure/girder/proc/construct_wall(obj/item/stack/material/S, mob/user)
var/amount_to_use = reinf_material ? 1 : 2
if(S.get_amount() < amount_to_use)

View File

@@ -0,0 +1,137 @@
/obj/structure/gravemarker
name = "grave marker"
desc = "An object used in marking graves."
icon_state = "gravemarker"
density = 1
anchored = 1
throwpass = 1
climbable = 1
layer = 3.1 //Above dirt piles
//Maybe make these calculate based on material?
var/health = 100
var/grave_name = "" //Name of the intended occupant
var/epitaph = "" //A quick little blurb
// var/dir_locked = 0 //Can it be spun? Not currently implemented
var/material/material
/obj/structure/gravemarker/New(var/newloc, var/material_name)
..(newloc)
if(!material_name)
material_name = "wood"
material = get_material_by_name("[material_name]")
if(!material)
qdel(src)
return
color = material.icon_colour
/obj/structure/gravemarker/examine(mob/user)
..()
if(get_dist(src, user) < 4)
if(grave_name)
to_chat(user, "Here Lies [grave_name]")
if(get_dist(src, user) < 2)
if(epitaph)
to_chat(user, epitaph)
/obj/structure/gravemarker/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(!mover)
return 1
if(istype(mover) && mover.checkpass(PASSTABLE))
return 1
if(get_dir(loc, target) & dir)
return !density
else
return 1
/obj/structure/gravemarker/CheckExit(atom/movable/O as mob|obj, target as turf)
if(istype(O) && O.checkpass(PASSTABLE))
return 1
if(get_dir(O.loc, target) == dir)
return 0
return 1
/obj/structure/gravemarker/attackby(obj/item/weapon/W, mob/user as mob)
if(istype(W, /obj/item/weapon/screwdriver))
var/carving_1 = sanitizeSafe(input(user, "Who is \the [src.name] for?", "Gravestone Naming", null) as text, MAX_NAME_LEN)
if(carving_1)
user.visible_message("[user] starts carving \the [src.name].", "You start carving \the [src.name].")
if(do_after(user, material.hardness * W.toolspeed))
user.visible_message("[user] carves something into \the [src.name].", "You carve your message into \the [src.name].")
grave_name += carving_1
update_icon()
var/carving_2 = sanitizeSafe(input(user, "What message should \the [src.name] have?", "Epitaph Carving", null) as text, MAX_NAME_LEN)
if(carving_2)
user.visible_message("[user] starts carving \the [src.name].", "You start carving \the [src.name].")
if(do_after(user, material.hardness * W.toolspeed))
user.visible_message("[user] carves something into \the [src.name].", "You carve your message into \the [src.name].")
epitaph += carving_2
update_icon()
return
if(istype(W, /obj/item/weapon/wrench))
user.visible_message("[user] starts taking down \the [src.name].", "You start taking down \the [src.name].")
if(do_after(user, material.hardness * W.toolspeed))
user.visible_message("[user] takes down \the [src.name].", "You take down \the [src.name].")
dismantle()
..()
/obj/structure/gravemarker/bullet_act(var/obj/item/projectile/Proj)
var/proj_damage = Proj.get_structure_damage()
if(!proj_damage)
return
..()
damage(proj_damage)
return
/obj/structure/gravemarker/ex_act(severity)
switch(severity)
if(1.0)
visible_message("<span class='danger'>\The [src] is blown apart!</span>")
qdel(src)
return
if(2.0)
visible_message("<span class='danger'>\The [src] is blown apart!</span>")
if(prob(50))
dismantle()
else
qdel(src)
return
/obj/structure/gravemarker/proc/damage(var/damage)
health -= damage
if(health <= 0)
visible_message("<span class='danger'>\The [src] falls apart!</span>")
dismantle()
/obj/structure/gravemarker/proc/dismantle()
material.place_dismantled_product(get_turf(src))
qdel(src)
return
/obj/structure/gravemarker/verb/rotate()
set name = "Rotate Grave Marker"
set category = "Object"
set src in oview(1)
if(anchored)
return
if(config.ghost_interaction)
src.set_dir(turn(src.dir, 90))
return
else
if(istype(usr,/mob/living/simple_animal/mouse))
return
if(!usr || !isturf(usr.loc))
return
if(usr.stat || usr.restrained())
return
src.set_dir(turn(src.dir, 90))
return

View File

@@ -239,3 +239,14 @@
if(air_group)
return 0 //Make sure air doesn't drain
..()
/obj/structure/grille/broken/cult
icon_state = "grillecult-b"
/obj/structure/grille/rustic
name = "rustic grille"
desc = "A lattice of metal, arranged in an old, rustic fashion."
icon_state = "grillerustic"
/obj/structure/grille/broken/rustic
icon_state = "grillerustic-b"

View File

@@ -60,7 +60,7 @@
if(health <= 0)
visible_message("<span class='warning'>\The [src] breaks down!</span>")
playsound(loc, 'sound/effects/grillehit.ogg', 50, 1)
new /obj/item/stack/rods(get_turf(usr))
new /obj/item/stack/rods(get_turf(src))
qdel(src)
/obj/structure/railing/proc/NeighborsCheck(var/UpdateNeighbors = 1)
@@ -134,6 +134,9 @@
if(usr.incapacitated())
return 0
if (!can_touch(usr) || ismouse(usr))
return
if(anchored)
to_chat(usr, "It is fastened to the floor therefore you can't rotate it!")
return 0
@@ -150,6 +153,9 @@
if(usr.incapacitated())
return 0
if (!can_touch(usr) || ismouse(usr))
return
if(anchored)
to_chat(usr, "It is fastened to the floor therefore you can't rotate it!")
return 0
@@ -166,6 +172,9 @@
if(usr.incapacitated())
return 0
if (!can_touch(usr) || ismouse(usr))
return
if(anchored)
to_chat(usr, "It is fastened to the floor therefore you can't flip it!")
return 0
@@ -249,6 +258,7 @@
else
playsound(loc, 'sound/effects/grillehit.ogg', 50, 1)
take_damage(W.force)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
return ..()

View File

@@ -42,7 +42,7 @@
/obj/structure/simple_door/Destroy()
processing_objects -= src
update_nearby_tiles()
..()
return ..()
/obj/structure/simple_door/get_material()
return material
@@ -194,5 +194,8 @@
/obj/structure/simple_door/wood/New(var/newloc,var/material_name)
..(newloc, "wood")
/obj/structure/simple_door/sifwood/New(var/newloc,var/material_name)
..(newloc, "alien wood")
/obj/structure/simple_door/resin/New(var/newloc,var/material_name)
..(newloc, "resin")

View File

@@ -25,7 +25,7 @@
if(cistern && !open)
if(!contents.len)
user << "<span class='notice'>The cistern is empty.</span>"
to_chat(user, "<span class='notice'>The cistern is empty.</span>")
return
else
var/obj/item/I = pick(contents)
@@ -33,7 +33,7 @@
user.put_in_hands(I)
else
I.loc = get_turf(src)
user << "<span class='notice'>You find \an [I] in the cistern.</span>"
to_chat(user, "<span class='notice'>You find \an [I] in the cistern.</span>")
w_items -= I.w_class
return
@@ -45,7 +45,7 @@
/obj/structure/toilet/attackby(obj/item/I as obj, mob/living/user as mob)
if(istype(I, /obj/item/weapon/crowbar))
user << "<span class='notice'>You start to [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"].</span>"
to_chat(user, "<span class='notice'>You start to [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"].</span>")
playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1)
if(do_after(user, 30))
user.visible_message("<span class='notice'>[user] [cistern ? "replaces the lid on the cistern" : "lifts the lid off the cistern"]!</span>", "<span class='notice'>You [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]!</span>", "You hear grinding porcelain.")
@@ -62,7 +62,7 @@
if(G.state>1)
if(!GM.loc == get_turf(src))
user << "<span class='notice'>[GM.name] needs to be on the toilet.</span>"
to_chat(user, "<span class='notice'>[GM.name] needs to be on the toilet.</span>")
return
if(open && !swirlie)
user.visible_message("<span class='danger'>[user] starts to give [GM.name] a swirlie!</span>", "<span class='notice'>You start to give [GM.name] a swirlie!</span>")
@@ -76,19 +76,19 @@
user.visible_message("<span class='danger'>[user] slams [GM.name] into the [src]!</span>", "<span class='notice'>You slam [GM.name] into the [src]!</span>")
GM.adjustBruteLoss(5)
else
user << "<span class='notice'>You need a tighter grip.</span>"
to_chat(user, "<span class='notice'>You need a tighter grip.</span>")
if(cistern && !istype(user,/mob/living/silicon/robot)) //STOP PUTTING YOUR MODULES IN THE TOILET.
if(I.w_class > 3)
user << "<span class='notice'>\The [I] does not fit.</span>"
to_chat(user, "<span class='notice'>\The [I] does not fit.</span>")
return
if(w_items + I.w_class > 5)
user << "<span class='notice'>The cistern is full.</span>"
to_chat(user, "<span class='notice'>The cistern is full.</span>")
return
user.drop_item()
I.loc = src
w_items += I.w_class
user << "You carefully place \the [I] into the cistern."
to_chat(user, "You carefully place \the [I] into the cistern.")
return
@@ -108,12 +108,12 @@
var/mob/living/GM = G.affecting
if(G.state>1)
if(!GM.loc == get_turf(src))
user << "<span class='notice'>[GM.name] needs to be on the urinal.</span>"
to_chat(user, "<span class='notice'>[GM.name] needs to be on the urinal.</span>")
return
user.visible_message("<span class='danger'>[user] slams [GM.name] into the [src]!</span>", "<span class='notice'>You slam [GM.name] into the [src]!</span>")
GM.adjustBruteLoss(8)
else
user << "<span class='notice'>You need a tighter grip.</span>"
to_chat(user, "<span class='notice'>You need a tighter grip.</span>")
@@ -158,10 +158,10 @@
/obj/machinery/shower/attackby(obj/item/I as obj, mob/user as mob)
if(I.type == /obj/item/device/analyzer)
user << "<span class='notice'>The water temperature seems to be [watertemp].</span>"
to_chat(user, "<span class='notice'>The water temperature seems to be [watertemp].</span>")
if(istype(I, /obj/item/weapon/wrench))
var/newtemp = input(user, "What setting would you like to set the temperature valve to?", "Water Temperature Valve") in temperature_settings
user << "<span class='notice'>You begin to adjust the temperature valve with \the [I].</span>"
to_chat(user, "<span class='notice'>You begin to adjust the temperature valve with \the [I].</span>")
playsound(src.loc, I.usesound, 50, 1)
if(do_after(user, 50 * I.toolspeed))
watertemp = newtemp
@@ -321,9 +321,9 @@
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(temperature >= H.species.heat_level_1)
H << "<span class='danger'>The water is searing hot!</span>"
to_chat(H, "<span class='danger'>The water is searing hot!</span>")
else if(temperature <= H.species.cold_level_1)
H << "<span class='warning'>The water is freezing cold!</span>"
to_chat(H, "<span class='warning'>The water is freezing cold!</span>")
/obj/item/weapon/bikehorn/rubberducky
name = "rubber ducky"
@@ -346,7 +346,7 @@
if(!usr.Adjacent(src))
return ..()
if(!thing.reagents || thing.reagents.total_volume == 0)
usr << "<span class='warning'>\The [thing] is empty.</span>"
to_chat(usr, "<span class='warning'>\The [thing] is empty.</span>")
return
// Clear the vessel.
visible_message("<span class='notice'>\The [usr] tips the contents of \the [thing] into \the [src].</span>")
@@ -360,7 +360,7 @@
if (H.hand)
temp = H.organs_by_name["l_hand"]
if(temp && !temp.is_usable())
user << "<span class='notice'>You try to move your [temp.name], but cannot!</span>"
to_chat(user, "<span class='notice'>You try to move your [temp.name], but cannot!</span>")
return
if(isrobot(user) || isAI(user))
@@ -370,10 +370,10 @@
return
if(busy)
user << "<span class='warning'>Someone's already washing here.</span>"
to_chat(user, "<span class='warning'>Someone's already washing here.</span>")
return
usr << "<span class='notice'>You start washing your hands.</span>"
to_chat(usr, "<span class='notice'>You start washing your hands.</span>")
busy = 1
sleep(40)
@@ -389,7 +389,7 @@
/obj/structure/sink/attackby(obj/item/O as obj, mob/user as mob)
if(busy)
user << "<span class='warning'>Someone's already washing here.</span>"
to_chat(user, "<span class='warning'>Someone's already washing here.</span>")
return
var/obj/item/weapon/reagent_containers/RG = O
@@ -417,7 +417,7 @@
return 1
else if(istype(O, /obj/item/weapon/mop))
O.reagents.add_reagent("water", 5)
user << "<span class='notice'>You wet \the [O] in \the [src].</span>"
to_chat(user, "<span class='notice'>You wet \the [O] in \the [src].</span>")
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
return
@@ -427,7 +427,7 @@
var/obj/item/I = O
if(!I || !istype(I,/obj/item)) return
usr << "<span class='notice'>You start washing \the [I].</span>"
to_chat(usr, "<span class='notice'>You start washing \the [I].</span>")
busy = 1
sleep(40)

View File

@@ -16,6 +16,8 @@
// This is not great.
/turf/simulated/proc/wet_floor(var/wet_val = 1)
if(wet > 2) //Can't mop up ice
return
spawn(0)
wet = wet_val
if(wet_overlay)

View File

@@ -6,13 +6,13 @@
if(flooring)
if(istype(C, /obj/item/weapon/crowbar))
if(broken || burnt)
user << "<span class='notice'>You remove the broken [flooring.descriptor].</span>"
to_chat(user, "<span class='notice'>You remove the broken [flooring.descriptor].</span>")
make_plating()
else if(flooring.flags & TURF_IS_FRAGILE)
user << "<span class='danger'>You forcefully pry off the [flooring.descriptor], destroying them in the process.</span>"
to_chat(user, "<span class='danger'>You forcefully pry off the [flooring.descriptor], destroying them in the process.</span>")
make_plating()
else if(flooring.flags & TURF_REMOVE_CROWBAR)
user << "<span class='notice'>You lever off the [flooring.descriptor].</span>"
to_chat(user, "<span class='notice'>You lever off the [flooring.descriptor].</span>")
make_plating(1)
else
return
@@ -21,35 +21,35 @@
else if(istype(C, /obj/item/weapon/screwdriver) && (flooring.flags & TURF_REMOVE_SCREWDRIVER))
if(broken || burnt)
return
user << "<span class='notice'>You unscrew and remove the [flooring.descriptor].</span>"
to_chat(user, "<span class='notice'>You unscrew and remove the [flooring.descriptor].</span>")
make_plating(1)
playsound(src, C.usesound, 80, 1)
return
else if(istype(C, /obj/item/weapon/wrench) && (flooring.flags & TURF_REMOVE_WRENCH))
user << "<span class='notice'>You unwrench and remove the [flooring.descriptor].</span>"
to_chat(user, "<span class='notice'>You unwrench and remove the [flooring.descriptor].</span>")
make_plating(1)
playsound(src, C.usesound, 80, 1)
return
else if(istype(C, /obj/item/weapon/shovel) && (flooring.flags & TURF_REMOVE_SHOVEL))
user << "<span class='notice'>You shovel off the [flooring.descriptor].</span>"
to_chat(user, "<span class='notice'>You shovel off the [flooring.descriptor].</span>")
make_plating(1)
playsound(src, 'sound/items/Deconstruct.ogg', 80, 1)
return
else if(istype(C, /obj/item/stack/cable_coil))
user << "<span class='warning'>You must remove the [flooring.descriptor] first.</span>"
to_chat(user, "<span class='warning'>You must remove the [flooring.descriptor] first.</span>")
return
else
if(istype(C, /obj/item/stack/cable_coil))
if(broken || burnt)
user << "<span class='warning'>This section is too damaged to support anything. Use a welder to fix the damage.</span>"
to_chat(user, "<span class='warning'>This section is too damaged to support anything. Use a welder to fix the damage.</span>")
return
var/obj/item/stack/cable_coil/coil = C
coil.turf_place(src, user)
return
else if(istype(C, /obj/item/stack))
if(broken || burnt)
user << "<span class='warning'>This section is too damaged to support anything. Use a welder to fix the damage.</span>"
to_chat(user, "<span class='warning'>This section is too damaged to support anything. Use a welder to fix the damage.</span>")
return
var/obj/item/stack/S = C
var/decl/flooring/use_flooring
@@ -64,7 +64,7 @@
return
// Do we have enough?
if(use_flooring.build_cost && S.amount < use_flooring.build_cost)
user << "<span class='warning'>You require at least [use_flooring.build_cost] [S.name] to complete the [use_flooring.descriptor].</span>"
to_chat(user, "<span class='warning'>You require at least [use_flooring.build_cost] [S.name] to complete the [use_flooring.descriptor].</span>")
return
// Stay still and focus...
if(use_flooring.build_time && !do_after(user, use_flooring.build_time))
@@ -81,10 +81,10 @@
if(welder.isOn() && (is_plating()))
if(broken || burnt)
if(welder.remove_fuel(0,user))
user << "<span class='notice'>You fix some dents on the broken plating.</span>"
to_chat(user, "<span class='notice'>You fix some dents on the broken plating.</span>")
playsound(src, welder.usesound, 80, 1)
icon_state = "plating"
burnt = null
broken = null
else
user << "<span class='warning'>You need more welding fuel to complete this task.</span>"
to_chat(user, "<span class='warning'>You need more welding fuel to complete this task.</span>")

View File

@@ -34,6 +34,26 @@ var/list/outdoor_turfs = list()
planet_controller.unallocateTurf(src)
..()
/turf/simulated/proc/make_outdoors()
outdoors = TRUE
outdoor_turfs.Add(src)
/turf/simulated/proc/make_indoors()
outdoors = FALSE
planet_controller.unallocateTurf(src)
qdel(weather_overlay)
update_icon()
/turf/simulated/post_change()
..()
// If it was outdoors and still is, it will not get added twice when the planet controller gets around to putting it in.
if(outdoors)
make_outdoors()
// outdoor_turfs += src
else
make_indoors()
// planet_controller.unallocateTurf(src)
/turf/simulated/proc/update_icon_edge()
if(edge_blending_priority)
for(var/checkdir in cardinal)
@@ -55,7 +75,7 @@ var/list/outdoor_turfs = list()
..()
/turf/simulated/floor/outdoors/mud
name = "grass"
name = "mud"
icon_state = "mud_dark"
edge_blending_priority = 3

View File

@@ -15,8 +15,12 @@
update_icon()
..()
/turf/simulated/floor/water/initialize()
update_icon()
/turf/simulated/floor/water/update_icon()
..() // To get the edges. This also gets rid of other overlays so it needs to go first.
overlays.Cut()
icon_state = water_state
var/image/floorbed_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = under_state)
underlays.Add(floorbed_sprite)

View File

@@ -678,7 +678,7 @@ var/datum/announcement/minor/admin_min_announcer = new
if(!check_rights(0)) return
//This is basically how death alarms do it
var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/ert(null)
var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/omni(null)
var/channel = input("Channel for message:","Channel", null) as null|anything in (list("Common") + a.keyslot2.channels) // + a.keyslot1.channels

View File

@@ -213,7 +213,8 @@ var/list/admin_verbs_debug = list(
/datum/admins/proc/view_runtimes,
/client/proc/show_gm_status,
/datum/admins/proc/change_weather,
/datum/admins/proc/change_time
/datum/admins/proc/change_time,
/client/proc/admin_give_modifier
)
var/list/admin_verbs_paranoid_debug = list(
@@ -664,6 +665,29 @@ var/list/admin_verbs_mentor = list(
log_admin("[key_name(usr)] gave [key_name(T)] a [greater] disease2 with infection chance [D.infectionchance].")
message_admins("<font color='blue'>[key_name_admin(usr)] gave [key_name(T)] a [greater] disease2 with infection chance [D.infectionchance].</font>", 1)
/client/proc/admin_give_modifier(var/mob/living/L)
set category = "Debug"
set name = "Give Modifier"
set desc = "Makes a mob weaker or stronger by adding a specific modifier to them."
if(!L)
to_chat(usr, "<span class='warning'>Looks like you didn't select a mob.</span>")
return
var/list/possible_modifiers = typesof(/datum/modifier) - /datum/modifier
var/new_modifier_type = input("What modifier should we add to [L]?", "Modifier Type") as null|anything in possible_modifiers
if(!new_modifier_type)
return
var/duration = input("How long should the new modifier last, in seconds. To make it last forever, write '0'.", "Modifier Duration") as num
if(duration == 0)
duration = null
else
duration = duration SECONDS
L.add_modifier(new_modifier_type, duration)
log_and_message_admins("has given [key_name(L)] the modifer [new_modifier_type], with a duration of [duration ? "[duration / 600] minutes" : "forever"].")
/client/proc/make_sound(var/obj/O in world) // -- TLE
set category = "Special Verbs"
set name = "Make Sound"

View File

@@ -159,7 +159,7 @@ var/list/debug_verbs = list (
,/client/proc/hide_debug_verbs
,/client/proc/testZAScolors
,/client/proc/testZAScolors_remove
,/client/proc/setup_supermatter_engine
,/datum/admins/proc/setup_supermatter
,/client/proc/atmos_toggle_debug
,/client/proc/spawn_tanktransferbomb
,/client/proc/debug_process_scheduler

View File

@@ -34,6 +34,7 @@
return ..() + {"
<option value='?_src_=vars;mob_player_panel=\ref[src]'>Show player panel</option>
<option>---</option>
<option value='?_src_=vars;give_modifier=\ref[src]'>Give Modifier</option>
<option value='?_src_=vars;give_spell=\ref[src]'>Give Spell</option>
<option value='?_src_=vars;give_disease2=\ref[src]'>Give Disease</option>
<option value='?_src_=vars;give_disease=\ref[src]'>Give TG-style Disease</option>

View File

@@ -74,6 +74,18 @@
src.give_spell(M)
href_list["datumrefresh"] = href_list["give_spell"]
else if(href_list["give_modifier"])
if(!check_rights(R_ADMIN|R_FUN|R_DEBUG))
return
var/mob/living/M = locate(href_list["give_modifier"])
if(!istype(M))
usr << "This can only be used on instances of type /mob/living"
return
src.admin_give_modifier(M)
href_list["datumrefresh"] = href_list["give_modifier"]
else if(href_list["give_disease2"])
if(!check_rights(R_ADMIN|R_FUN)) return

View File

@@ -18,7 +18,6 @@
"Glory",
"Axiom",
"Eternal",
"Icarus",
"Harmony",
"Light",
"Discovery",
@@ -44,7 +43,7 @@
var/list/star_names = list(
"Sol", "Alpha Centauri", "Sirius", "Vega", "Regulus", "Vir", "Algol", "Aldebaran",
"Delta Doradus", "Menkar", "Geminga", "Elnath", "Gienah", "Mu Leporis", "Nyx", "Tau Ceti",
"Wazn", "Alphard", "Phact", "Altair")
"Wazn", "Alphard", "Phact", "Altair", "El", "Eutopia", "Qerr'valis", "Qerrna-Lakirr", "Rarkajar", "the Almach Rim")
var/list/destination_types = list("dockyard", "station", "vessel", "waystation", "telecommunications satellite", "spaceport", "distress beacon", "anomaly", "colony", "outpost")
while(i)
destination_names.Add("a [pick(destination_types)] in [pick(star_names)]")
@@ -79,7 +78,6 @@
"NSS Exodus in Nyx",
"NCS Northern Star in Vir",
"NCS Southern Cross in Vir",
"NDV Icarus in Nyx",
"NAS Vir Central Command",
"a dockyard orbiting Sif",
"an asteroid orbiting Kara",
@@ -104,7 +102,7 @@
desc = "Hephaestus Industries is the largest supplier of arms, ammunition, and small millitary vehicles in Sol space. \
Hephaestus products have a reputation for reliability, and the corporation itself has a noted tendency to stay removed \
from corporate politics. They enforce their neutrality with the help of a fairly large asset-protection contingent which \
prevents any contracting polities from using their own materiel against them. SolGov itself is one of Hephastus<EFBFBD> largest \
prevents any contracting polities from using their own materiel against them. SolGov itself is one of Hephastus largest \
bulk contractors owing to the above factors."
history = ""
work = "arms manufacturer"
@@ -113,7 +111,9 @@
ship_prefixes = list("HTV" = "freight", "HTV" = "munitions resupply")
destination_names = list(
"a SolGov dockyard on Luna"
"a SolGov dockyard on Luna",
"a Fleet outpost in the Almach Rim",
"a Fleet outpost on the Moghes border"
)
/datum/lore/organization/tsc/vey_med
@@ -124,8 +124,8 @@
Despite the suspicion and prejudice leveled at them for their alien origin, Vey-Med has obtained market dominance in \
the sale of medical equipment-- from surgical tools to large medical devices to the Oddyseus trauma response mecha \
and everything in between. Their equipment tends to be top-of-the-line, most obviously shown by their incredibly \
human-like FBP designs. Vey<EFBFBD>s rise to stardom came from their introduction of ressurective cloning, although in \
recent years they<EFBFBD>ve been forced to diversify as their patents expired and NanoTrasen-made medications became \
human-like FBP designs. Veys rise to stardom came from their introduction of ressurective cloning, although in \
recent years theyve been forced to diversify as their patents expired and NanoTrasen-made medications became \
essential to modern cloning."
history = ""
work = "medical equipment supplier"
@@ -133,7 +133,11 @@
motto = ""
ship_prefixes = list("VTV" = "transportation", "VMV" = "medical resupply")
destination_names = list()
destination_names = list(
"a research facility in Samsara",
"a SDTF near Ue-Orsi",
"a sapientarian mission in the Almach Rim"
)
/datum/lore/organization/tsc/zeng_hu
name = "Zeng-Hu pharmaceuticals"
@@ -141,8 +145,8 @@
acronym = "ZH"
desc = "Zeng-Hu is an old TSC, based in the Sol system. Until the discovery of Phoron, Zeng-Hu maintained a stranglehold \
on the market for medications, and many household names are patentted by Zeng-Hu-- Bicaridyne, Dylovene, Tricordrizine, \
and Dexalin all came from a Zeng-Hu medical laboratory. Zeng-Hu<EFBFBD>s fortunes have been in decline as Nanotrasen<EFBFBD>s near monopoly \
on phoron research cuts into their R&D and Vey-Med<EFBFBD>s superior medical equipment effectively decimated their own equipment \
and Dexalin all came from a Zeng-Hu medical laboratory. Zeng-Hus fortunes have been in decline as Nanotrasens near monopoly \
on phoron research cuts into their R&D and Vey-Meds superior medical equipment effectively decimated their own equipment \
interests. The three-way rivalry between these companies for dominance in the medical field is well-known and a matter of \
constant economic speculation."
history = ""
@@ -160,8 +164,8 @@
desc = "Ward-Takahashi focuses on the sale of small consumer electronics, with its computers, communicators, \
and even mid-class automobiles a fixture of many households. Less famously, Ward-Takahashi also supplies most \
of the AI cores on which vital control systems are mounted, and it is this branch of their industry that has \
led to their tertiary interest in the development and sale of high-grade AI systems. Ward-Takahashi<EFBFBD>s economies \
of scale frequently steal market share from Nanotrasen<EFBFBD>s high-price products, leading to a bitter rivalry in the \
led to their tertiary interest in the development and sale of high-grade AI systems. Ward-Takahashis economies \
of scale frequently steal market share from Nanotrasens high-price products, leading to a bitter rivalry in the \
consumer electronics market."
history = ""
work = "electronics manufacturer"
@@ -175,10 +179,10 @@
name = "Bishop Cybernetics"
short_name = "Bishop"
acronym = "BC"
desc = "Bishop<EFBFBD>s focus is on high-class, stylish cybernetics. A favorite among transhumanists (and a b<EFBFBD>te noire for \
desc = "Bishops focus is on high-class, stylish cybernetics. A favorite among transhumanists (and a bête noire for \
bioconservatives), Bishop manufactures not only prostheses but also brain augmentation, synthetic organ replacements, \
and odds and ends like implanted wrist-watches. Their business model tends towards smaller, boutique operations, giving \
it a reputation for high price and luxury, with Bishop cyberware often rivalling Vey-Med<EFBFBD>s for cost. Bishop<EFBFBD>s reputation \
it a reputation for high price and luxury, with Bishop cyberware often rivalling Vey-Meds for cost. Bishops reputation \
for catering towards the interests of human augmentation enthusiasts instead of positronics have earned it ire from the \
Positronic Rights Group and puts it in ideological (but not economic) comptetition with Morpheus Cyberkinetics."
history = ""
@@ -221,6 +225,7 @@
"Never Talk To Strangers",
"Sacrificial Victim",
"Unwitting Accomplice",
"Witting Accomplice",
"Bad For Business",
"Just Testing",
"Size Isn't Everything",
@@ -256,11 +261,41 @@
"Callsign",
"Three Ships in a Trenchcoat",
"Not Wearing Pants",
"Ridiculous Naming Convention"
"Ridiculous Naming Convention",
"God Dammit Morpheus",
"It Seemed Like a Good Idea",
"Legs All the Way Up",
"Purchase Necessary",
"Some Assembly Required",
"Buy One Get None Free",
"BRB",
"SHIP NAME HERE",
"Questionable Ethics",
"Accept Most Substitutes",
"I Blame the Government",
"Garbled Gibberish",
"Thinking Emoji",
"Is This Thing On?",
"Make My Day",
"No Vox Here",
"Savings and Values",
"Secret Name",
"Can't Find My Keys",
"Look Over There!",
"Made You Look!",
"Take Nothing Seriously",
"It Comes In Lime, Too",
"Loot Me",
"Nothing To Declare",
"Sneaking Suspicion",
"Bass Ackwards",
"Good Things Come to Those Who Freight"
)
destination_names = list()
destination_names = list(
"A trade outpost in Shelf"
)
/datum/lore/organization/tsc/xion
name = "Xion Manufacturing Group"

View File

@@ -115,7 +115,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
else
O.robotize()
for(var/name in list(O_HEART,O_EYES,O_LUNGS,O_BRAIN))
for(var/name in list(O_HEART,O_EYES,O_LUNGS,O_LIVER,O_KIDNEYS,O_BRAIN))
var/status = pref.organ_data[name]
if(!status)
continue
@@ -198,6 +198,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
organ_name = "brain"
if(O_LUNGS)
organ_name = "lungs"
if(O_LIVER)
organ_name = "liver"
if(O_KIDNEYS)
organ_name = "kidneys"
if(status == "cyborg")
++ind
@@ -605,7 +609,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
else if(href_list["organs"])
var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Heart", "Eyes", "Lungs", "Brain")
var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Heart", "Eyes", "Lungs", "Liver", "Kidneys", "Brain")
if(!organ_name) return
var/organ = null
@@ -616,6 +620,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
organ = O_EYES
if("Lungs")
organ = O_LUNGS
if("Liver")
organ = O_LIVER
if("Kidneys")
organ = O_KIDNEYS
if("Brain")
if(pref.organ_data[BP_HEAD] != "cyborg")
user << "<span class='warning'>You may only select a cybernetic or synthetic brain if you have a full prosthetic body.</span>"

View File

@@ -204,6 +204,7 @@ var/list/gear_datums = list()
var/whitelisted //Term to check the whitelist for..
var/sort_category = "General"
var/list/gear_tweaks = list() //List of datums which will alter the item after it has been spawned.
var/exploitable = 0 //Does it go on the exploitable information list?
/datum/gear/New()
..()

View File

@@ -15,7 +15,12 @@
/datum/gear/utility/codex
display_name = "the traveler's guide to vir"
path = /obj/item/weapon/book/codex
path = /obj/item/weapon/book/codex/lore/vir
cost = 0
/datum/gear/utility/corp_regs
display_name = "corporate regulations and legal code"
path = /obj/item/weapon/book/codex/corp_regs
cost = 0
/datum/gear/utility/folder_blue
@@ -76,12 +81,20 @@
display_name = "cell, device"
path = /obj/item/weapon/cell/device
/datum/gear/utility/implant //This does nothing if you don't actually know EAL.
/datum/gear/utility/implant
exploitable = 1
/datum/gear/utility/implant/eal //This does nothing if you don't actually know EAL.
display_name = "implant, language, EAL"
path = /obj/item/weapon/implant/language/eal
cost = 2
slot = "implant"
var/implant_type = "EAL"
/datum/gear/utility/implant/tracking
display_name = "implant, tracking"
path = /obj/item/weapon/implant/tracking/weak
cost = 10
slot = "implant"
/datum/gear/utility/translator
display_name = "universal translator"

View File

@@ -401,7 +401,7 @@
desc = "A hologram projector in the shape of a gun. There is a dial on the side to change the gun's disguise."
icon_state = "deagle"
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_ILLEGAL = 8)
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 2, TECH_ILLEGAL = 4)
matter = list()
fire_sound = 'sound/weapons/Gunshot.ogg'

View File

@@ -385,6 +385,9 @@
var/shoes_under_pants = 0
var/water_speed = 0 //Speed boost/decrease in water, lower/negative values mean more speed
var/snow_speed = 0 //Speed boost/decrease on snow, lower/negative values mean more speed
permeability_coefficient = 0.50
slowdown = SHOES_SLOWDOWN
force = 2

View File

@@ -67,8 +67,8 @@
item_state_slots = list(slot_r_hand_str = "beret_navy", slot_l_hand_str = "beret_navy")
/obj/item/clothing/head/beret/sec/navy/hos
name = "officer beret"
desc = "A navy blue beret with a head of security's rank emblem. For officers that are more inclined towards style than safety."
name = "Head of Security beret"
desc = "A navy blue beret with a Head of Security's rank emblem. For officers that are more inclined towards style than safety."
icon_state = "beret_navy_hos"
item_state_slots = list(slot_r_hand_str = "beret_navy", slot_l_hand_str = "beret_navy")
@@ -85,8 +85,8 @@
item_state_slots = list(slot_r_hand_str = "beret_black", slot_l_hand_str = "beret_black")
/obj/item/clothing/head/beret/sec/corporate/hos
name = "officer beret"
desc = "A corporate black beret with a head of security's rank emblem. For officers that are more inclined towards style than safety."
name = "Head of Security beret"
desc = "A corporate black beret with a Head of Security's rank emblem. For officers that are more inclined towards style than safety."
icon_state = "beret_corporate_hos"
item_state_slots = list(slot_r_hand_str = "beret_black", slot_l_hand_str = "beret_black")

View File

@@ -46,6 +46,7 @@
min_cold_protection_temperature = SHOE_MIN_COLD_PROTECTION_TEMPERATURE
heat_protection = FEET|LEGS
max_heat_protection_temperature = SHOE_MAX_HEAT_PROTECTION_TEMPERATURE
snow_speed = -1
/obj/item/clothing/shoes/boots/winter/security
name = "security winter boots"

View File

@@ -6,7 +6,6 @@
item_state_slots = list(slot_r_hand_str = "syndie_helm", slot_l_hand_str = "syndie_helm")
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 35, bio = 100, rad = 60)
siemens_coefficient = 0.6
species_restricted = list("Human")
camera_networks = list(NETWORK_MERCENARY)
light_overlay = "helmet_light_green" //todo: species-specific light overlays
@@ -20,4 +19,3 @@
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 60)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs)
siemens_coefficient = 0.6
species_restricted = list("Human", "Skrell")

View File

@@ -1,28 +0,0 @@
//Unathi clothing.
/obj/item/clothing/suit/unathi/robe
name = "roughspun robes"
desc = "A traditional Unathi garment."
icon_state = "robe-unathi"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS
flags_inv = HIDETIE|HIDEHOLSTER
/obj/item/clothing/suit/unathi/mantle
name = "hide mantle"
desc = "A rather grisly selection of cured hides and skin, sewn together to form a ragged mantle."
icon_state = "mantle-unathi"
body_parts_covered = UPPER_TORSO
//Taj clothing.
/obj/item/clothing/suit/tajaran/furs
name = "heavy furs"
desc = "A traditional Zhan-Khazan garment."
icon_state = "zhan_furs"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER
/obj/item/clothing/head/tajaran/scarf
name = "headscarf"
desc = "A scarf of coarse fabric. Seems to have ear-holes."
icon_state = "zhan_scarf"
item_state_slots = list(slot_r_hand_str = "beret_white", slot_l_hand_str = "beret_white")
body_parts_covered = HEAD|FACE

View File

@@ -0,0 +1,13 @@
/obj/item/clothing/suit/tajaran/furs
name = "heavy furs"
desc = "A traditional Zhan-Khazan garment."
icon_state = "zhan_furs"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL|HIDETIE|HIDEHOLSTER
/obj/item/clothing/head/tajaran/scarf //This stays in /suits because it goes with the furs above
name = "headscarf"
desc = "A scarf of coarse fabric. Seems to have ear-holes."
icon_state = "zhan_scarf"
item_state_slots = list(slot_r_hand_str = "beret_white", slot_l_hand_str = "beret_white")
body_parts_covered = HEAD|FACE

View File

@@ -0,0 +1,13 @@
//Unathi clothing.
/obj/item/clothing/suit/unathi/robe
name = "roughspun robes"
desc = "A traditional Unathi garment."
icon_state = "robe-unathi"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS
flags_inv = HIDETIE|HIDEHOLSTER
/obj/item/clothing/suit/unathi/mantle
name = "hide mantle"
desc = "A rather grisly selection of cured hides and skin, sewn together to form a ragged mantle."
icon_state = "mantle-unathi"
body_parts_covered = UPPER_TORSO

View File

@@ -0,0 +1,10 @@
/obj/item/clothing/suit/armor/vox_scrap
name = "rusted metal armor"
desc = "A hodgepodge of various pieces of metal scrapped together into a rudimentary vox-shaped piece of armor."
allowed = list(/obj/item/weapon/gun, /obj/item/weapon/tank)
armor = list(melee = 70, bullet = 30, laser = 20,energy = 5, bomb = 40, bio = 0, rad = 0) //Higher melee armor versus lower everything else.
icon_state = "vox-scrap"
icon_state = "vox-scrap"
body_parts_covered = UPPER_TORSO|ARMS|LOWER_TORSO|LEGS
species_restricted = list("Vox")
siemens_coefficient = 1 //Its literally metal

View File

@@ -134,6 +134,6 @@
/obj/item/clothing/accessory/holster/leg
name = "leg holster"
desc = "A tacticool handgun holster. Worn on the upper leg."
icon_state = "holster_hip"
icon_state = "holster_leg"
overlay_state = "holster_leg"
concealed_holster = 0

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