Merge remote-tracking branch 'remotes/Baystation12/dev' into internalsBox

Conflicts:
	maps/exodus-1.dmm
This commit is contained in:
Techhead0
2015-05-13 03:10:36 -04:00
368 changed files with 5964 additions and 6769 deletions

View File

@@ -277,6 +277,13 @@ var/global/floorIsLava = 0
var/dat = "<html><head><title>Info on [key]</title></head>"
dat += "<body>"
var/p_age = "unknown"
for(var/client/C in clients)
if(C.ckey == key)
p_age = C.player_age
break
dat +="<span style='color:#000000; font-weight: bold'>Player age: [p_age]</span><br>"
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
var/list/infos
info >> infos

View File

@@ -110,7 +110,8 @@ var/list/admin_verbs_fun = list(
/client/proc/cmd_admin_add_random_ai_law,
/client/proc/make_sound,
/client/proc/toggle_random_events,
/client/proc/editappear
/client/proc/editappear,
/client/proc/roll_dices
)
var/list/admin_verbs_spawn = list(
/datum/admins/proc/spawn_fruit,
@@ -255,6 +256,7 @@ var/list/admin_verbs_hideable = list(
/client/proc/cmd_debug_tog_aliens,
/client/proc/air_report,
/client/proc/enable_debug_verbs,
/client/proc/roll_dices,
/proc/possess,
/proc/release
)

View File

@@ -13,7 +13,7 @@
display_name = holder.fakekey
for(var/mob/M in mob_list)
if((M.mind && M.mind.special_role && M.client) || (M.client && M.client.holder))
if((M.mind && M.mind.special_role && M.client) || check_rights(R_ADMIN, 0, M))
M << "<font color='#960018'><span class='ooc'>" + create_text_tag("aooc", "Antag-OOC:", M.client) + " <EM>[display_name]:</EM> <span class='message'>[msg]</span></span></font>"
log_ooc("(ANTAG) [key] : [msg]")

View File

@@ -525,6 +525,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
//log_admin("[key_name(src)] has alienized [M.key].")
var/list/dresspacks = list(
"strip",
"job",
"standard space gear",
"tournament standard red",
"tournament standard green",
@@ -555,10 +556,25 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
for (var/obj/item/I in M)
if (istype(I, /obj/item/weapon/implant))
continue
qdel(I)
M.drop_from_inventory(I)
if(I.loc != M)
qdel(I)
switch(dresscode)
if ("strip")
//do nothing
if ("job")
var/selected_job = input("Select job", "Robust quick dress shop") as null|anything in joblist
if (isnull(selected_job))
return
var/datum/job/job = job_master.GetJob(selected_job)
if(!job)
return
job.equip(M)
job.apply_fingerprints(M)
job_master.spawnId(M, selected_job)
if ("standard space gear")
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)

View File

@@ -0,0 +1,24 @@
/client/proc/roll_dices()
set category = "Fun"
set name = "Roll Dice"
if(!check_rights(R_FUN))
return
var/sum = input("How many times should we throw?") as num
var/side = input("Select the number of sides.") as num
if(!side)
side = 6
if(!sum)
sum = 2
var/dice = num2text(sum) + "d" + num2text(side)
if(alert("Do you want to inform the world about your game?",,"Yes", "No") == "Yes")
world << "<h2 style=\"color:#A50400\">The dice have been rolled by Gods!</h2>"
var/result = roll(dice)
if(alert("Do you want to inform the world about the result?",,"Yes", "No") == "Yes")
world << "<h2 style=\"color:#A50400\">Gods rolled [dice], result is [result]</h2>"
message_admins("[key_name_admin(src)] rolled dice [dice], result is [result]", 1)

View File

@@ -208,8 +208,8 @@
O.vars[variable]) as num|null
if(new_value == null) return
if(variable=="luminosity")
O.SetLuminosity(new_value)
if(variable=="light_range")
O.set_light(new_value)
else
O.vars[variable] = new_value
@@ -217,24 +217,24 @@
if(istype(O, /mob))
for(var/mob/M in mob_list)
if ( istype(M , O.type) )
if(variable=="luminosity")
M.SetLuminosity(new_value)
if(variable=="light_range")
M.set_light(new_value)
else
M.vars[variable] = O.vars[variable]
else if(istype(O, /obj))
for(var/obj/A in world)
if ( istype(A , O.type) )
if(variable=="luminosity")
A.SetLuminosity(new_value)
if(variable=="light_range")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
else if(istype(O, /turf))
for(var/turf/A in world)
if ( istype(A , O.type) )
if(variable=="luminosity")
A.SetLuminosity(new_value)
if(variable=="light_range")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
@@ -242,24 +242,24 @@
if(istype(O, /mob))
for(var/mob/M in mob_list)
if (M.type == O.type)
if(variable=="luminosity")
M.SetLuminosity(new_value)
if(variable=="light_range")
M.set_light(new_value)
else
M.vars[variable] = O.vars[variable]
else if(istype(O, /obj))
for(var/obj/A in world)
if (A.type == O.type)
if(variable=="luminosity")
A.SetLuminosity(new_value)
if(variable=="light_range")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
else if(istype(O, /turf))
for(var/turf/A in world)
if (A.type == O.type)
if(variable=="luminosity")
A.SetLuminosity(new_value)
if(variable=="light_range")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
@@ -372,4 +372,4 @@
A.vars[variable] = O.vars[variable]
log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]")
message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]", 1)
message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]", 1)

View File

@@ -455,10 +455,10 @@ var/list/forbidden_varedit_object_types = list(
O.vars[variable] = var_new
if("num")
if(variable=="luminosity")
if(variable=="light_range")
var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num
if(var_new == null) return
O.SetLuminosity(var_new)
O.set_light(var_new)
else if(variable=="stat")
var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num
if(var_new == null) return

View File

@@ -18,6 +18,7 @@
var/list/sources = new() //List of sources triggering the alarm. Used to determine when the alarm should be cleared.
var/list/sources_assoc = new() //Associative list of source triggers. Used to efficiently acquire the alarm source.
var/list/cameras //List of cameras that can be switched to, if the player has that capability.
var/cache_id //ID for camera cache, changed by invalidateCameraCache().
var/area/last_area //The last acquired area, used should origin be lost (for example a destroyed borg containing an alarming camera).
var/area/last_name //The last acquired name, used should origin be lost
var/area/last_camera_area //The last area in which cameras where fetched, used to see if the camera list should be updated.
@@ -74,8 +75,12 @@
return last_name
/datum/alarm/proc/cameras()
// reset camera cache
if(camera_cache_id != cache_id)
cameras = null
cache_id = camera_cache_id
// If the alarm origin has changed area, for example a borg containing an alarming camera, reset the list of cameras
if(cameras && (last_camera_area != alarm_area()))
else if(cameras && (last_camera_area != alarm_area()))
cameras = null
// The list of cameras is also reset by /proc/invalidateCameraCache()
@@ -96,18 +101,17 @@
* Assisting procs *
******************/
/atom/proc/get_alarm_area()
var/area/A = get_area(src)
return A.master
return get_area(src)
/area/get_alarm_area()
return src.master
return src
/atom/proc/get_alarm_name()
var/area/A = get_area(src)
return A.master.name
return A.name
/area/get_alarm_name()
return master.name
return name
/mob/get_alarm_name()
return name

View File

@@ -84,8 +84,7 @@
return src
/turf/get_alarm_origin()
var/area/area = get_area(src)
return area.master // Very important to get area.master, as dynamic lightning can and will split areas.
return get_area(src)
/datum/alarm_handler/proc/register(var/object, var/procName)
listeners[object] = procName

View File

@@ -5,7 +5,7 @@
icon_state = ""
flags = CONDUCT
w_class = 2.0
matter = list("metal" = 100)
matter = list(DEFAULT_WALL_MATERIAL = 100)
throwforce = 2
throw_speed = 3
throw_range = 10

View File

@@ -2,7 +2,7 @@
name = "igniter"
desc = "A small electronic device able to ignite combustable substances."
icon_state = "igniter"
matter = list("metal" = 500, "glass" = 50, "waste" = 10)
matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 50, "waste" = 10)
origin_tech = "magnets=1"
secured = 1

View File

@@ -4,7 +4,7 @@
name = "infrared emitter"
desc = "Emits a visible or invisible beam and is triggered when the beam is interrupted."
icon_state = "infrared"
matter = list("metal" = 1000, "glass" = 500, "waste" = 100)
matter = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 500, "waste" = 100)
origin_tech = "magnets=2"
wires = WIRE_PULSE

View File

@@ -2,7 +2,7 @@
name = "mousetrap"
desc = "A handy little spring-loaded trap for catching pesty rodents."
icon_state = "mousetrap"
matter = list("metal" = 100, "waste" = 10)
matter = list(DEFAULT_WALL_MATERIAL = 100, "waste" = 10)
origin_tech = "combat=1"
var/armed = 0

View File

@@ -2,7 +2,7 @@
name = "proximity sensor"
desc = "Used for scanning and alerting when someone enters a certain proximity."
icon_state = "prox"
matter = list("metal" = 800, "glass" = 200, "waste" = 50)
matter = list(DEFAULT_WALL_MATERIAL = 800, "glass" = 200, "waste" = 50)
origin_tech = "magnets=1"
wires = WIRE_PULSE

View File

@@ -3,7 +3,7 @@
desc = "Used to remotely activate devices."
icon_state = "signaller"
item_state = "signaler"
matter = list("metal" = 1000, "glass" = 200, "waste" = 100)
matter = list(DEFAULT_WALL_MATERIAL = 1000, "glass" = 200, "waste" = 100)
origin_tech = "magnets=1"
wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE

View File

@@ -2,7 +2,7 @@
name = "timer"
desc = "Used to time things. Works well with contraptions which has to count down. Tick tock."
icon_state = "timer"
matter = list("metal" = 500, "glass" = 50, "waste" = 10)
matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 50, "waste" = 10)
origin_tech = "magnets=1"
wires = WIRE_PULSE

View File

@@ -2,7 +2,7 @@
name = "voice analyzer"
desc = "A small electronic device able to record a voice sample, and send a signal when that sample is repeated."
icon_state = "voice"
matter = list("metal" = 500, "glass" = 50, "waste" = 10)
matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 50, "waste" = 10)
origin_tech = "magnets=1"
var/listening = 0
var/recorded //the activation message

View File

@@ -305,3 +305,14 @@
'icons/spideros_icons/sos_13.png',
'icons/spideros_icons/sos_14.png'
)
mob/proc/MayRespawn()
return 0
client/proc/MayRespawn()
if(mob)
return mob.MayRespawn()
// Something went wrong, client is usually kicked or transfered to a new mob at this point
return 0

View File

@@ -84,6 +84,7 @@ datum/preferences
var/religion = "None" //Religious association.
//Mob preview
var/mob/living/carbon/human/dummy //the mannequin
var/icon/preview_icon = null
var/icon/preview_icon_front = null
var/icon/preview_icon_side = null
@@ -1447,7 +1448,7 @@ datum/preferences
rlimb_data[limb] = choice
organ_data[limb] = "cyborg"
if(second_limb)
organ_data[second_limb] = choice
rlimb_data[second_limb] = choice
organ_data[second_limb] = "cyborg"
if(third_limb && organ_data[third_limb] == "amputated")
organ_data[third_limb] = null
@@ -1642,30 +1643,18 @@ datum/preferences
character.gen_record = gen_record
character.exploit_record = exploit_record
character.gender = gender
character.change_gender(gender)
character.age = age
character.b_type = b_type
character.r_eyes = r_eyes
character.g_eyes = g_eyes
character.b_eyes = b_eyes
character.change_eye_color(r_eyes,g_eyes,b_eyes)
character.change_hair_color(r_hair,g_hair,b_hair)
character.change_facial_hair_color(r_facial,g_facial,b_facial)
character.change_skin_color(r_skin,g_skin,b_skin)
character.change_skin_tone(s_tone)
character.r_hair = r_hair
character.g_hair = g_hair
character.b_hair = b_hair
character.r_facial = r_facial
character.g_facial = g_facial
character.b_facial = b_facial
character.r_skin = r_skin
character.g_skin = g_skin
character.b_skin = b_skin
character.s_tone = s_tone
character.h_style = h_style
character.f_style = f_style
character.change_hair(h_style)
character.change_facial_hair(f_style)
character.home_system = home_system
character.citizenship = citizenship

View File

@@ -264,37 +264,19 @@ BLIND // can't see anything
return
on = !on
user << "You [on ? "enable" : "disable"] the helmet light."
update_light(user)
update_flashlight(user)
else
return ..(user)
/obj/item/clothing/head/proc/update_light(var/mob/user = null)
/obj/item/clothing/head/proc/update_flashlight(var/mob/user = null)
if(on && !light_applied)
if(loc == user)
user.SetLuminosity(user.luminosity + brightness_on)
SetLuminosity(brightness_on)
set_light(brightness_on)
light_applied = 1
else if(!on && light_applied)
if(loc == user)
user.SetLuminosity(user.luminosity - brightness_on)
SetLuminosity(0)
set_light(0)
light_applied = 0
update_icon(user)
/obj/item/clothing/head/equipped(mob/user)
..()
spawn(1)
if(on && loc == user && !light_applied)
user.SetLuminosity(user.luminosity + brightness_on)
light_applied = 1
/obj/item/clothing/head/dropped(mob/user)
..()
spawn(1)
if(on && loc != user && light_applied)
user.SetLuminosity(user.luminosity - brightness_on)
light_applied = 0
/obj/item/clothing/head/update_icon(var/mob/user)
overlays.Cut()
@@ -308,18 +290,6 @@ BLIND // can't see anything
var/mob/living/carbon/human/H = user
H.update_inv_head()
/obj/item/clothing/head/equipped(mob/user)
..()
update_light(user)
/obj/item/clothing/head/pickup(mob/user)
..()
update_light(user)
/obj/item/clothing/head/dropped(mob/user)
..()
update_light(user)
/obj/item/clothing/head/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
@@ -357,6 +327,7 @@ BLIND // can't see anything
permeability_coefficient = 0.50
slowdown = SHOES_SLOWDOWN
force = 2
var/overshoes = 0
species_restricted = list("exclude","Unathi","Tajara")
sprite_sheets = list("Vox" = 'icons/mob/species/vox/shoes.dmi')

View File

@@ -43,7 +43,7 @@
item_state = "lgloves"
siemens_coefficient = 1.0 //thin latex gloves, much more conductive than fabric gloves (basically a capacitor for AC)
permeability_coefficient = 0.01
germ_level = 0
/obj/item/clothing/gloves/botanic_leather
desc = "These leather work gloves protect against thorns, barbs, prickles, spikes and other harmful objects of floral origin."
name = "botanist's leather gloves"

View File

@@ -17,7 +17,7 @@
icon_state = "welding"
flags = HEADCOVERSEYES | HEADCOVERSMOUTH
item_state = "welding"
matter = list("metal" = 3000, "glass" = 1000)
matter = list(DEFAULT_WALL_MATERIAL = 3000, "glass" = 1000)
var/up = 0
armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
flags_inv = (HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE)

View File

@@ -1,31 +1,72 @@
/obj/item/clothing/shoes/magboots
desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle."
desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle. They're large enough to be worn over other footwear."
name = "magboots"
icon_state = "magboots0"
species_restricted = null
force = 3
overshoes = 1
var/magpulse = 0
var/icon_base = "magboots"
icon_action_button = "action_blank"
action_button_name = "Toggle the magboots"
var/obj/item/clothing/shoes/shoes = null //Undershoes
var/mob/living/carbon/human/wearer = null //For shoe procs
/obj/item/clothing/shoes/magboots/proc/set_slowdown()
slowdown = shoes? max(SHOES_SLOWDOWN, shoes.slowdown): SHOES_SLOWDOWN //So you can't put on magboots to make you walk faster.
if (magpulse)
slowdown += 3
/obj/item/clothing/shoes/magboots/attack_self(mob/user)
if(magpulse)
flags &= ~NOSLIP
slowdown = SHOES_SLOWDOWN
magpulse = 0
set_slowdown()
force = 3
if(icon_base) icon_state = "[icon_base]0"
user << "You disable the mag-pulse traction system."
else
flags |= NOSLIP
slowdown = 2
magpulse = 1
set_slowdown()
force = 5
if(icon_base) icon_state = "[icon_base]1"
user << "You enable the mag-pulse traction system."
user.update_inv_shoes() //so our mob-overlays update
/obj/item/clothing/shoes/magboots/mob_can_equip(mob/user)
var/mob/living/carbon/human/H = user
if(H.shoes)
shoes = H.shoes
if(shoes.overshoes)
user << "You are unable to wear \the [src] as \the [H.shoes] are in the way."
shoes = null
return 0
H.drop_from_inventory(shoes) //Remove the old shoes so you can put on the magboots.
shoes.loc = src
if(!..())
if(shoes) //Put the old shoes back on if the check fails.
if(H.equip_to_slot_if_possible(shoes, slot_shoes))
src.shoes = null
return 0
if (shoes)
user << "You slip \the [src] on over \the [shoes]."
set_slowdown()
wearer = H
return 1
/obj/item/clothing/shoes/magboots/dropped()
..()
var/mob/living/carbon/human/H = wearer
if(shoes)
if(!H.equip_to_slot_if_possible(shoes, slot_shoes))
shoes.loc = get_turf(src)
src.shoes = null
wearer = null
/obj/item/clothing/shoes/magboots/examine(mob/user)
..(user)
var/state = "disabled"

View File

@@ -13,7 +13,7 @@
desc = "It looks pretty sciency."
icon = 'icons/obj/rig_modules.dmi'
icon_state = "module"
matter = list("metal" = 20000, "plastic" = 30000, "glass" = 5000)
matter = list(DEFAULT_WALL_MATERIAL = 20000, "plastic" = 30000, "glass" = 5000)
var/damage = 0
var/obj/item/weapon/rig/holder

View File

@@ -59,15 +59,10 @@
/obj/item/clothing/suit/space/void/examine(user)
..(user)
if(boots || helmet || tank)
var/D = "Installed equipment: "
var/first = 1
for(var/obj/item/I in list(helmet,boots,tank))
if (I)
D += "[first?"":", "]\the [I]\icon[I]"
first = 0
D += "."
user << D
var/list/part_list = new
for(var/obj/item/I in list(helmet,boots,tank))
part_list += "\a [I]"
user << "\The [src] has [english_list(part_list)] installed."
if(tank && in_range(src,user))
user << "<span class='notice'>The wrist-mounted pressure gauge reads [max(round(tank.air_contents.return_pressure()),0)] kPa remaining in \the [tank].</span>"
@@ -96,10 +91,7 @@
helmet.canremove = 0
if(boots)
if(H.shoes)
M << "You are unable to deploy your suit's magboots as \the [H.shoes] are in the way."
else if (H.equip_to_slot_if_possible(boots, slot_shoes))
M << "Your suit's boots deploy with a hiss."
if (H.equip_to_slot_if_possible(boots, slot_shoes))
boots.canremove = 0
if(tank)
@@ -115,18 +107,18 @@
var/mob/living/carbon/human/H
if(helmet)
helmet.canremove = 1
H = helmet.loc
if(istype(H))
if(helmet && H.head == helmet)
helmet.canremove = 1
H.drop_from_inventory(helmet)
helmet.loc = src
if(boots)
boots.canremove = 1
H = boots.loc
if(istype(H))
if(boots && H.shoes == boots)
boots.canremove = 1
H.drop_from_inventory(boots)
boots.loc = src

View File

@@ -141,10 +141,11 @@
if("finalise_create_account")
var/account_name = href_list["holder_name"]
var/starting_funds = max(text2num(href_list["starting_funds"]), 0)
create_account(account_name, starting_funds, src)
starting_funds = Clamp(starting_funds, 0, station_account.money) // Not authorized to put the station in debt.
starting_funds = min(starting_funds, fund_cap) // Not authrorized to give more than the fund cap.
starting_funds = min(starting_funds, fund_cap) // Not authorized to give more than the fund cap.
create_account(account_name, starting_funds, src)
if(starting_funds > 0)
//subtract the money
station_account.money -= starting_funds

View File

@@ -63,11 +63,10 @@
//world << " checking [areapath]"
var/area/A = locate(areapath)
//world << " A: [A], contents.len: [A.contents.len]"
for(var/area/B in A.related)
//world << " B: [B], contents.len: [B.contents.len]"
for(var/turf/simulated/floor/F in B.contents)
if(!F.contents.len)
turfs += F
for(var/turf/simulated/floor/F in A.contents)
if(!F.contents.len)
turfs += F
var/list/spawn_types = list()
var/max_number
@@ -116,4 +115,4 @@
#undef VERM_MICE
#undef VERM_LIZARDS
#undef VERM_SPIDERS
#undef VERM_SPIDERS

View File

@@ -1,5 +1,11 @@
/var/global/spacevines_spawned = 0
/datum/event/spacevine
announceWhen = 10
/datum/event/spacevine/start()
spacevine_infestation()
spacevines_spawned = 1
/datum/event/spacevine/announce()
command_announcement.Announce("Confirmed outbreak of level 7 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", new_sound = 'sound/AI/outbreak7.ogg')

View File

@@ -192,6 +192,7 @@
/obj/item/weapon/holo
damtype = HALLOSS
no_attack_log = 1
/obj/item/weapon/holo/esword
desc = "May the force be within you. Sorta."
@@ -400,7 +401,7 @@
/mob/living/simple_animal/hostile/carp/holodeck/New()
..()
SetLuminosity(2) //hologram lighting
set_light(2) //hologram lighting
/mob/living/simple_animal/hostile/carp/holodeck/proc/set_safety(var/safe)
if (safe)

View File

@@ -341,9 +341,6 @@
..()
if(!seed)
return
if(seed.get_trait(TRAIT_BIOLUM))
user.SetLuminosity(user.luminosity + seed.get_trait(TRAIT_BIOLUM))
SetLuminosity(0)
if(seed.get_trait(TRAIT_STINGS))
var/mob/living/carbon/human/H = user
if(istype(H) && H.gloves)
@@ -354,12 +351,6 @@
seed.do_thorns(H,src)
seed.do_sting(H,src,pick("r_hand","l_hand"))
/obj/item/weapon/reagent_containers/food/snacks/grown/dropped(mob/user)
..()
if(seed && seed.get_trait(TRAIT_BIOLUM))
user.SetLuminosity(user.luminosity - seed.get_trait(TRAIT_BIOLUM))
SetLuminosity(seed.get_trait(TRAIT_BIOLUM))
// Predefined types for placing on the map.
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap

View File

@@ -165,9 +165,10 @@
if(!istype(splat)) // Plants handle their own stuff.
splat.name = "[thrown.name] [pick("smear","smudge","splatter")]"
if(get_trait(TRAIT_BIOLUM))
var/clr
if(get_trait(TRAIT_BIOLUM_COLOUR))
splat.l_color = get_trait(TRAIT_BIOLUM_COLOUR)
splat.SetLuminosity(get_trait(TRAIT_BIOLUM))
clr = get_trait(TRAIT_BIOLUM_COLOUR)
splat.set_light(get_trait(TRAIT_BIOLUM), l_color = clr)
if(get_trait(TRAIT_PRODUCT_COLOUR))
splat.color = get_trait(TRAIT_PRODUCT_COLOUR)
@@ -276,12 +277,11 @@
// Handle light requirements.
if(!light_supplied)
var/area/A = get_area(current_turf)
if(A)
if(A.lighting_use_dynamic)
light_supplied = max(0,min(10,current_turf.lighting_lumcount)-5)
else
light_supplied = 5
var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in current_turf
if(L)
light_supplied = max(0,min(10,L.lum_r + L.lum_g + L.lum_b)-5)
else
light_supplied = 5
if(light_supplied)
if(abs(light_supplied - get_trait(TRAIT_IDEAL_LIGHT)) > get_trait(TRAIT_LIGHT_TOLERANCE))
health_change += rand(1,3) * HYDRO_SPEED_MULTIPLIER
@@ -696,9 +696,10 @@
product.desc += " On second thought, something about this one looks strange."
if(get_trait(TRAIT_BIOLUM))
var/clr
if(get_trait(TRAIT_BIOLUM_COLOUR))
product.l_color = get_trait(TRAIT_BIOLUM_COLOUR)
product.SetLuminosity(get_trait(TRAIT_BIOLUM))
clr = get_trait(TRAIT_BIOLUM_COLOUR)
product.set_light(get_trait(TRAIT_BIOLUM), l_color = clr)
//Handle spawning in living, mobile products (like dionaea).
if(istype(product,/mob/living))

View File

@@ -13,7 +13,7 @@
spawn(75)
if(!host.ckey && !host.client)
host.death() // This seems redundant, but a lot of mobs don't
host.stat = 2 // handle death() properly. Better safe than etc.
host.stat = DEAD // handle death() properly. Better safe than etc.
host.visible_message("<span class='danger'>[host] is malformed and unable to survive. It expires pitifully, leaving behind some seeds.</span>")
var/total_yield = rand(1,3)
@@ -27,7 +27,7 @@
for(var/mob/dead/observer/O in player_list)
if(jobban_isbanned(O, "Dionaea"))
continue
if(O.client)
if(O.client && O.MayRespawn())
if(O.client.prefs.be_special & BE_PLANT && !(O.client in currently_querying))
currently_querying |= O.client
question(O.client,host)

View File

@@ -1,22 +1,28 @@
#define DEFAULT_SEED "glowshroom"
#define VINE_GROWTH_STAGES 5
/proc/spacevine_infestation()
/proc/spacevine_infestation(var/potency_min=70, var/potency_max=100, var/maturation_min=5, var/maturation_max=15)
spawn() //to stop the secrets panel hanging
var/list/turf/simulated/floor/turfs = list() //list of all the empty floor turfs in the hallway areas
for(var/areapath in typesof(/area/hallway))
var/area/A = locate(areapath)
for(var/area/B in A.related)
for(var/turf/simulated/floor/F in B.contents)
if(!F.contents.len)
turfs += F
for(var/turf/simulated/floor/F in A.contents)
if(!F.contents.len)
turfs += F
if(turfs.len) //Pick a turf to spawn at if we can
var/turf/simulated/floor/T = pick(turfs)
var/datum/seed/seed = plant_controller.create_random_seed(1)
seed.set_trait(TRAIT_SPREAD,2) // So it will function properly as vines.
seed.set_trait(TRAIT_POTENCY,rand(70,100)) // Guarantee a wide spread and powerful effects.
new /obj/effect/plant(T,seed)
seed.set_trait(TRAIT_POTENCY,rand(potency_min, potency_max)) // 70-100 potency will help guarantee a wide spread and powerful effects.
seed.set_trait(TRAIT_MATURATION,rand(maturation_min, maturation_max))
//make vine zero start off fully matured
var/obj/effect/plant/vine = new(T,seed)
vine.health = vine.max_health
vine.mature_time = 0
vine.process()
message_admins("<span class='notice'>Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])</span>")
/obj/effect/dead_plant
@@ -57,6 +63,7 @@
var/spread_chance = 40
var/spread_distance = 3
var/evolve_chance = 2
var/mature_time //minimum maturation time
var/last_tick = 0
var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/plant
@@ -112,6 +119,7 @@
if(max_growth > 2 && prob(50))
max_growth-- //Ensure some variation in final sprite, makes the carpet of crap look less wonky.
mature_time = world.time + seed.get_trait(TRAIT_MATURATION) + 15 //prevent vines from maturing until at least a few seconds after they've been created.
spread_chance = seed.get_trait(TRAIT_POTENCY)
spread_distance = ((growth_type>0) ? round(spread_chance*0.6) : round(spread_chance*0.3))
update_icon()
@@ -146,14 +154,13 @@
color = icon_colour
// Apply colour and light from seed datum.
if(seed.get_trait(TRAIT_BIOLUM))
SetLuminosity(1+round(seed.get_trait(TRAIT_POTENCY)/20))
var/clr
if(seed.get_trait(TRAIT_BIOLUM_COLOUR))
l_color = seed.get_trait(TRAIT_BIOLUM_COLOUR)
else
l_color = null
clr = seed.get_trait(TRAIT_BIOLUM_COLOUR)
set_light(1+round(seed.get_trait(TRAIT_POTENCY)/20), l_color = clr)
return
else
SetLuminosity(0)
set_light(0)
/obj/effect/plant/proc/refresh_icon()
var/growth = min(max_growth,round(health/growth_threshold))
@@ -256,4 +263,4 @@
die_off()
/obj/effect/plant/proc/is_mature()
return (health >= (max_health/3))
return (health >= (max_health/3) && world.time > mature_time)

View File

@@ -70,7 +70,10 @@
update_neighbors()
if(is_mature() && neighbors.len && prob(spread_chance))
for(var/i=1,i<=seed.get_trait(TRAIT_YIELD),i++)
//spread to 1-3 adjacent turfs depending on yield trait.
var/max_spread = between(1, round(seed.get_trait(TRAIT_YIELD)*3/14), 3)
for(var/i in 1 to max_spread)
if(prob(spread_chance))
sleep(rand(3,5))
if(!neighbors.len)

View File

@@ -7,8 +7,11 @@
if(!istype(M))
return
if(!buckled_mob && !M.buckled && !M.anchored && (M.small || prob(round(seed.get_trait(TRAIT_POTENCY)/2))))
entangle(M)
if(!buckled_mob && !M.buckled && !M.anchored && (M.small || prob(round(seed.get_trait(TRAIT_POTENCY)/6))))
//wait a tick for the Entered() proc that called HasProximity() to finish (and thus the moving animation),
//so we don't appear to teleport from two tiles away when moving into a turf adjacent to vines.
spawn(1)
entangle(M)
/obj/effect/plant/attack_hand(mob/user as mob)
// Todo, cause damage.
@@ -60,13 +63,11 @@
if(buckled_mob)
return
if(!Adjacent(victim))
if(victim.buckled)
return
victim.buckled = src
victim.update_canmove()
buckled_mob = victim
if(!victim.anchored && !victim.buckled && victim.loc != get_turf(src))
//grabbing people
if(!victim.anchored && Adjacent(victim) && victim.loc != get_turf(src))
var/can_grab = 1
if(istype(victim, /mob/living/carbon/human))
var/mob/living/carbon/human/H = victim
@@ -75,4 +76,9 @@
if(can_grab)
src.visible_message("<span class='danger'>Tendrils lash out from \the [src] and drag \the [victim] in!</span>")
victim.loc = src.loc
victim << "<span class='danger'>Tendrils [pick("wind", "tangle", "tighten")] around you!</span>"
//entangling people
if(victim.loc == src.loc)
buckle_mob(victim)
victim.set_dir(pick(cardinal))
victim << "<span class='danger'>Tendrils [pick("wind", "tangle", "tighten")] around you!</span>"

View File

@@ -350,7 +350,7 @@
usr << "There is no label to remove."
return
/obj/machinery/portable_atmospherics/hydroponics/verb/set_light()
/obj/machinery/portable_atmospherics/hydroponics/verb/setlight()
set name = "Set Light"
set category = "Object"
set src in view(1)
@@ -596,13 +596,12 @@
if(closed_system && mechanical)
light_string = "that the internal lights are set to [tray_light] lumens"
else
var/area/A = T.loc
var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T
var/light_available
if(A)
if(A.lighting_use_dynamic)
light_available = max(0,min(10,T.lighting_lumcount)-5)
else
light_available = 5
if(L)
light_available = max(0,min(10,L.lum_r + L.lum_g + L.lum_b)-5)
else
light_available = 5
light_string = "a light level of [light_available] lumens"
usr << "The tray's sensor suite is reporting [light_string] and a temperature of [environment.temperature]K."

View File

@@ -120,6 +120,14 @@
harvest = 1
lastproduce = age
// If we're a vine which is not in a closed tray and is at least half mature, and there's no vine currently on our turf: make one (maybe)
if(!closed_system && \
seed.get_trait(TRAIT_SPREAD) == 2 && \
2 * age >= seed.get_trait(TRAIT_MATURATION) && \
!(locate(/obj/effect/plant) in get_turf(src)) && \
prob(2 * seed.get_trait(TRAIT_POTENCY)))
new /obj/effect/plant(get_turf(src), seed)
if(prob(3)) // On each tick, there's a chance the pest population will increase
pestlevel += 0.1 * HYDRO_SPEED_MULTIPLIER

View File

@@ -58,7 +58,7 @@
force = 5.0
throwforce = 7.0
w_class = 2.0
matter = list("metal" = 50)
matter = list(DEFAULT_WALL_MATERIAL = 50)
attack_verb = list("slashed", "sliced", "cut", "clawed")

View File

@@ -16,7 +16,7 @@
..()
verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/close_lid_verb
verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/remove_label
verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/set_light
verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/setlight
/obj/machinery/portable_atmospherics/hydroponics/soil/CanPass()
return 1

View File

@@ -215,7 +215,7 @@
force = 5.0
throwforce = 7.0
w_class = 2.0
matter = list("metal" = 50)
matter = list(DEFAULT_WALL_MATERIAL = 50)
attack_verb = list("slashed", "sliced", "cut", "clawed")
//Hatchets and things to kill kudzu
@@ -232,7 +232,7 @@
throw_range = 4
sharp = 1
edge = 1
matter = list("metal" = 15000)
matter = list(DEFAULT_WALL_MATERIAL = 15000)
origin_tech = "materials=2;combat=1"
attack_verb = list("chopped", "torn", "cut")
@@ -277,4 +277,4 @@
for(var/obj/effect/plant/B in orange(A,1))
if(prob(80))
B.die_off(1)
qdel(A)
qdel(A)

View File

@@ -73,12 +73,11 @@
// Update bioluminescence.
if(seed)
if(seed.get_trait(TRAIT_BIOLUM))
SetLuminosity(round(seed.get_trait(TRAIT_POTENCY)/10))
var/clr
if(seed.get_trait(TRAIT_BIOLUM_COLOUR))
l_color = seed.get_trait(TRAIT_BIOLUM_COLOUR)
else
l_color = null
clr = seed.get_trait(TRAIT_BIOLUM_COLOUR)
set_light(round(seed.get_trait(TRAIT_POTENCY)/10), l_color = clr)
return
SetLuminosity(0)
return
set_light(0)
return

View File

@@ -0,0 +1,67 @@
/*
BS12 object based lighting system
*/
/*
Changes from tg DAL:
- Lighting is done using objects instead of subareas.
- Animated transitions. (newer tg DAL has this)
- Full colours with mixing.
- Support for lights on shuttles.
- Code:
- Instead of one flat luminosity var, light is represented by 3 atom vars:
- light_range; range in tiles of the light, used for calculating falloff,
- light_power; multiplier for the brightness of lights,
- light_color; hex string representing the RGB colour of the light.
- SetLuminosity() is now set_light() and takes the three variables above.
- Variables can be left as null to not update them.
- SetOpacity() is now set_opacity().
- Areas have luminosity set to 1 permanently, no hard-lighting.
- Objects inside other objects can have lights and they properly affect the turf. (flashlights)
- area/master and area/list/related have been eviscerated since subareas aren't needed.
*/
/*
Relevant vars/procs:
atom: (lighting_atom.dm)
- var/light_range; range in tiles of the light, used for calculating falloff
- var/light_power; multiplier for the brightness of lights
- var/light_color; hex string representing the RGB colour of the light
- var/datum/light_source/light; light source datum for this atom, only present if light_range && light_power
- var/list/light_sources; light sources in contents that are shining through this object, including this object
- proc/set_light(l_range, l_power, l_color):
- Sets light_range/power/color to non-null args and calls update_light()
- proc/set_opacity(new_opacity):
- Sets opacity to new_opacity.
- If opacity has changed, call turf.reconsider_lights() to fix light occlusion
- proc/update_light():
- Updates the light var on this atom, deleting or creating as needed and calling .update()
turf: (lighting_turf.dm)
- var/list/affecting_lights; list of light sources that are shining onto this turf
- proc/reconsider_lights():
- Force all light sources shining onto this turf to update
- proc/lighting_clear_overlays():
- Delete (manual GC) all light overlays on this turf, used when changing turf to space
- proc/lighting_build_overlays():
- Create lighting overlays for this turf
atom/movable/lighting_overlay: (lighting_overlay.dm)
- var/lum_r, var/lum_g, var/lum_b; lumcounts of each colour
- var/needs_update; set on update_lumcount, checked by lighting process
- var/xoffset, var/yoffset; (only present when using sub-tile overlays) fractional offset of this overlay in the tile
- proc/update_lumcount(delta_r, delta_g, delta_b):
- Change the lumcount vars and queue the overlay for update
- proc/update_overlay()
- Called by the lighting process to update the color of the overlay
*/

View File

@@ -0,0 +1,10 @@
#define LIGHTING_INTERVAL 5 // frequency, in 1/10ths of a second, of the lighting process
#define LIGHTING_FALLOFF 1 // type of falloff to use for lighting; 1 for circular, 2 for square
#define LIGHTING_LAMBERTIAN 1 // use lambertian shading for light sources
#define LIGHTING_HEIGHT 1 // height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone
#define LIGHTING_TRANSITIONS 1 // smooth, animated transitions, similar to /tg/station
#define LIGHTING_RESOLUTION 1 // resolution of the lighting overlays, powers of 2 only, max of 32
#define LIGHTING_LAYER 10 // drawing layer for lighting overlays
#define LIGHTING_ICON 'icons/effects/lighting_overlay.dmi' // icon used for lighting shading effects

View File

@@ -0,0 +1,169 @@
/datum/light_source
var/atom/top_atom
var/atom/source_atom
var/turf/source_turf
var/light_power
var/light_range
var/light_color // string, decomposed by parse_light_color()
var/lum_r
var/lum_g
var/lum_b
var/list/effect_r
var/list/effect_g
var/list/effect_b
var/list/effect_turf
var/applied
var/needs_update
var/destroyed
var/force_update
/datum/light_source/New(atom/owner, atom/top)
source_atom = owner
if(!source_atom.light_sources) source_atom.light_sources = list()
source_atom.light_sources += src
top_atom = top
if(top_atom != source_atom)
if(!top.light_sources) top.light_sources = list()
top_atom.light_sources += src
source_turf = top_atom
light_power = source_atom.light_power
light_range = source_atom.light_range
light_color = source_atom.light_color
parse_light_color()
effect_r = list()
effect_g = list()
effect_b = list()
effect_turf = list()
update()
return ..()
/datum/light_source/proc/destroy()
destroyed = 1
force_update()
if(source_atom) source_atom.light_sources -= src
if(top_atom) top_atom.light_sources -= src
/datum/light_source/proc/update(atom/new_top_atom)
if(new_top_atom && new_top_atom != top_atom)
if(top_atom != source_atom) top_atom.light_sources -= src
top_atom = new_top_atom
if(top_atom != source_atom)
if(!top_atom.light_sources) top_atom.light_sources = list()
top_atom.light_sources += src
lighting_update_lights += src
needs_update = 1
/datum/light_source/proc/force_update()
needs_update = 1
force_update = 1
lighting_update_lights += src
/datum/light_source/proc/check()
if(!source_atom)
destroy()
return 1
if(!top_atom)
top_atom = source_atom
. = 1
if(istype(top_atom, /turf))
if(source_turf != top_atom)
source_turf = top_atom
. = 1
else if(top_atom.loc != source_turf)
source_turf = top_atom.loc
. = 1
if(source_atom.light_power != light_power)
light_power = source_atom.light_power
. = 1
if(source_atom.light_range != light_range)
light_range = source_atom.light_range
. = 1
if(source_atom.light_color != light_color)
light_color = source_atom.light_color
parse_light_color()
. = 1
if(light_range && light_power && !applied)
. = 1
/datum/light_source/proc/parse_light_color()
if(light_color)
lum_r = GetRedPart(light_color) / 255
lum_g = GetGreenPart(light_color) / 255
lum_b = GetBluePart(light_color) / 255
else
lum_r = 1
lum_g = 1
lum_b = 1
/datum/light_source/proc/falloff(atom/movable/lighting_overlay/O)
#if LIGHTING_FALLOFF == 1 // circular
#if LIGHTING_RESOLUTION == 1
. = (O.x - source_turf.x)**2 + (O.y - source_turf.y)**2 + LIGHTING_HEIGHT
#else
. = (O.x - source_turf.x + O.xoffset)**2 + (O.y - source_turf.y + O.yoffset)**2 + LIGHTING_HEIGHT
#endif
#if LIGHTING_LAMBERTIAN == 1
. = CLAMP01((1 - CLAMP01(sqrt(.) / light_range)) * (1 / (sqrt(. + 1))))
#else
. = 1 - CLAMP01(sqrt(.) / light_range)
#endif
#elif LIGHTING_FALLOFF == 2 // square
#if LIGHTING_RESOLUTION == 1
. = abs(O.x - source_turf.x) + abs(O.y - source_turf.y) + LIGHTING_HEIGHT
#else
. = abs(O.x - source_turf.x + O.xoffset) + abs(O.y - source_turf.y + O.yoffset) + LIGHTING_HEIGHT
#endif
#if LIGHTING_LAMBERTIAN == 1
. = CLAMP01((1 - CLAMP01(. / light_range)) * (1 / (sqrt(.)**2 + )))
#else
. = 1 - CLAMP01(. / light_range)
#endif
#endif
/datum/light_source/proc/apply_lum()
applied = 1
if(istype(source_turf))
for(var/atom/movable/lighting_overlay/O in view(light_range, source_turf))
var/strength = light_power * falloff(O)
effect_r[O] = lum_r * strength
effect_g[O] = lum_g * strength
effect_b[O] = lum_b * strength
O.update_lumcount(lum_r * strength, lum_g * strength, lum_b * strength)
for(var/turf/T in view(light_range, source_turf))
if(!T.affecting_lights) T.affecting_lights = list()
T.affecting_lights += src
effect_turf += T
/datum/light_source/proc/remove_lum()
applied = 0
for(var/atom/movable/lighting_overlay/O in effect_r)
O.update_lumcount(-effect_r[O], -effect_g[O], -effect_b[O])
for(var/turf/T in effect_turf)
if(T.affecting_lights) T.affecting_lights -= src
effect_r.Cut()
effect_g.Cut()
effect_b.Cut()
effect_turf.Cut()

View File

@@ -0,0 +1,81 @@
/atom
var/light_power = 1 // intensity of the light
var/light_range = 0 // range in tiles of the light
var/light_color // RGB string representing the colour of the light
var/datum/light_source/light
var/list/light_sources
/atom/proc/set_light(l_range, l_power, l_color)
if(l_power != null) light_power = l_power
if(l_range != null) light_range = l_range
if(l_color != null) light_color = l_color
update_light()
/atom/proc/update_light()
if(!light_power || !light_range)
if(light)
light.destroy()
light = null
else
if(!istype(loc, /atom/movable))
. = src
else
. = loc
if(light)
light.update(.)
else
light = new /datum/light_source(src, .)
/atom/New()
. = ..()
if(light_power && light_range)
update_light()
/atom/Destroy()
if(light)
light.destroy()
light = null
return ..()
/atom/movable/Destroy()
var/turf/T = loc
if(opacity && istype(T))
T.reconsider_lights()
return ..()
/atom/movable/Move()
var/turf/old_loc = loc
. = ..()
if(loc != old_loc)
for(var/datum/light_source/L in light_sources)
L.source_atom.update_light()
var/turf/new_loc = loc
if(istype(old_loc) && opacity)
old_loc.reconsider_lights()
if(istype(new_loc) && opacity)
new_loc.reconsider_lights()
/atom/proc/set_opacity(new_opacity)
var/old_opacity = opacity
opacity = new_opacity
var/turf/T = loc
if(old_opacity != new_opacity && istype(T))
T.reconsider_lights()
/obj/item/equipped()
. = ..()
update_light()
/obj/item/pickup()
. = ..()
update_light()
/obj/item/dropped()
. = ..()
update_light()

View File

@@ -0,0 +1,48 @@
/atom/movable/lighting_overlay
name = ""
mouse_opacity = 0
simulated = 0
anchored = 1
icon = LIGHTING_ICON
layer = LIGHTING_LAYER
invisibility = INVISIBILITY_LIGHTING
blend_mode = BLEND_MULTIPLY
color = "#000000"
var/lum_r
var/lum_g
var/lum_b
#if LIGHTING_RESOLUTION != 1
var/xoffset
var/yoffset
#endif
var/needs_update
/atom/movable/lighting_overlay/New()
. = ..()
verbs.Cut()
/atom/movable/lighting_overlay/proc/update_lumcount(delta_r, delta_g, delta_b)
lum_r += delta_r
lum_g += delta_g
lum_b += delta_b
needs_update = 1
lighting_update_overlays += src
/atom/movable/lighting_overlay/proc/update_overlay()
var/mx = max(lum_r, lum_g, lum_b)
. = 1 // factor
if(mx > 1)
. = 1/mx
#if LIGHTING_TRANSITIONS == 1
animate(src,
color = rgb(lum_r * 255 * ., lum_g * 255 * ., lum_b * 255 * .),
LIGHTING_INTERVAL - 1
)
#else
color = rgb(lum_r * 255 * ., lum_g * 255 * ., lum_b * 255 * .)
#endif

View File

@@ -0,0 +1,29 @@
/datum/controller/process/lighting/setup()
name = "lighting"
schedule_interval = LIGHTING_INTERVAL
create_lighting_overlays()
/datum/controller/process/lighting/doWork()
for(var/datum/light_source/L in lighting_update_lights)
if(L.needs_update)
if(L.destroyed)
L.remove_lum()
else if(L.check() || L.force_update)
L.remove_lum()
L.apply_lum()
L.force_update = 0
L.needs_update = 0
scheck()
lighting_update_lights.Cut()
for(var/atom/movable/lighting_overlay/O in lighting_update_overlays)
if(O.needs_update)
O.update_overlay()
O.needs_update = 0
scheck()
lighting_update_overlays.Cut()

View File

@@ -0,0 +1,47 @@
/var/list/lighting_update_lights = list()
/var/list/lighting_update_overlays = list()
/area/var/lighting_use_dynamic = 1
// duplicates lots of code, but this proc needs to be as fast as possible.
/proc/create_lighting_overlays(zlevel = 0)
var/state = "light[LIGHTING_RESOLUTION]"
var/area/A
if(zlevel == 0) // populate all zlevels
for(var/turf/T in world)
if(T.dynamic_lighting)
A = T.loc
if(A.lighting_use_dynamic)
#if LIGHTING_RESOLUTION == 1
var/atom/movable/lighting_overlay/O = new(T)
O.icon_state = state
#else
for(var/i = 0; i < LIGHTING_RESOLUTION; i++)
for(var/j = 0; j < LIGHTING_RESOLUTION; j++)
var/atom/movable/lighting_overlay/O = new(T)
O.pixel_x = i * (32 / LIGHTING_RESOLUTION)
O.pixel_y = j * (32 / LIGHTING_RESOLUTION)
O.xoffset = (((2*i + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.yoffset = (((2*j + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.icon_state = state
#endif
else
for(var/x = 1; x <= world.maxx; x++)
for(var/y = 1; y <= world.maxy; y++)
var/turf/T = locate(x, y, zlevel)
if(T.dynamic_lighting)
A = T.loc
if(A.lighting_use_dynamic)
#if LIGHTING_RESOLUTION == 1
var/atom/movable/lighting_overlay/O = new(T)
O.icon_state = state
#else
for(var/i = 0; i < LIGHTING_RESOLUTION; i++)
for(var/j = 0; j < LIGHTING_RESOLUTION; j++)
var/atom/movable/lighting_overlay/O = new(T)
O.pixel_x = i * (32 / LIGHTING_RESOLUTION)
O.pixel_y = j * (32 / LIGHTING_RESOLUTION)
O.xoffset = (((2*i + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.yoffset = (((2*j + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.icon_state = state
#endif

View File

@@ -0,0 +1,29 @@
/turf
var/list/affecting_lights
/turf/proc/reconsider_lights()
for(var/datum/light_source/L in affecting_lights)
L.force_update()
/turf/proc/lighting_clear_overlays()
for(var/atom/movable/lighting_overlay/L in src)
L.loc = null
/turf/proc/lighting_build_overlays()
if(!locate(/atom/movable/lighting_overlay) in src)
var/state = "light[LIGHTING_RESOLUTION]"
var/area/A = loc
if(A.lighting_use_dynamic)
#if LIGHTING_RESOLUTION == 1
var/atom/movable/lighting_overlay/O = new(src)
O.icon_state = state
#else
for(var/i = 0; i < LIGHTING_RESOLUTION; i++)
for(var/j = 0; j < LIGHTING_RESOLUTION; j++)
var/atom/movable/lighting_overlay/O = new(src)
O.pixel_x = i * (32 / LIGHTING_RESOLUTION)
O.pixel_y = j * (32 / LIGHTING_RESOLUTION)
O.xoffset = (((2*i + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.yoffset = (((2*j + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.icon_state = state
#endif

View File

@@ -0,0 +1,10 @@
#undef LIGHTING_INTERVAL
#undef LIGHTING_FALLOFF
#undef LIGHTING_LAMBERTIAN
#undef LIGHTING_HEIGHT
#undef LIGHTING_TRANSITIONS
#undef LIGHTING_RESOLUTION
#undef LIGHTING_LAYER
#undef LIGHTING_ICON

View File

@@ -0,0 +1,170 @@
var/list/name_to_material
/proc/populate_material_list()
name_to_material = list()
for(var/type in typesof(/material) - /material)
var/material/new_mineral = new type
if(!new_mineral.name)
continue
name_to_material[lowertext(new_mineral.name)] = new_mineral
return 1
/*
Valid sprite masks:
stone
metal
solid
cult
*/
/material
var/name // Tag for use in overlay generation/list population .
var/display_name
var/icon_base = "metal"
var/icon_colour
var/icon_reinf = "reinf_metal"
var/stack_type
var/unmeltable
var/cut_delay = 0
var/radioactivity
var/ignition_point
var/melting_point = 1800 // K, walls will take damage if they're next to a fire hotter than this
var/integrity = 150 // Damage before wall falls apart, essentially.
var/hardness = 60 // Used to determine if a hulk can punch through this wall.
var/rotting_touch_message = "crumbles under your touch"
var/opacity = 1
var/explosion_resistance = 5
/material/New()
..()
if(!display_name)
display_name = name
/material/proc/place_dismantled_girder(var/turf/target, var/material/reinf_material)
var/obj/structure/girder/G = new(target)
if(reinf_material)
G.reinf_material = reinf_material
G.reinforce_girder()
/material/proc/place_dismantled_product(var/turf/target,var/is_devastated)
for(var/x=1;x<(is_devastated?2:3);x++)
place_sheet(target)
/material/proc/place_sheet(var/turf/target)
if(stack_type)
new stack_type(target)
/material/uranium
name = "uranium"
stack_type = /obj/item/stack/sheet/mineral/uranium
radioactivity = 12
icon_base = "stone"
icon_reinf = "reinf_stone"
icon_colour = "#007A00"
/material/diamond
name = "diamond"
stack_type = /obj/item/stack/sheet/mineral/diamond
unmeltable = 1
cut_delay = 60
icon_colour = "#00FFE1"
opacity = 0.4
/material/gold
name = "gold"
stack_type = /obj/item/stack/sheet/mineral/gold
icon_colour = "#EDD12F"
/material/silver
name = "silver"
stack_type = /obj/item/stack/sheet/mineral/silver
icon_colour = "#D1E6E3"
/material/phoron
name = "phoron"
stack_type = /obj/item/stack/sheet/mineral/phoron
ignition_point = 300
icon_base = "stone"
icon_colour = "#FC2BC5"
/material/sandstone
name = "sandstone"
stack_type = /obj/item/stack/sheet/mineral/sandstone
icon_base = "stone"
icon_reinf = "reinf_stone"
icon_colour = "#D9C179"
/material/steel
name = DEFAULT_WALL_MATERIAL
stack_type = /obj/item/stack/sheet/metal
icon_base = "solid"
icon_reinf = "reinf_over"
icon_colour = "#666666"
/material/plasteel
name = "plasteel"
stack_type = /obj/item/stack/sheet/plasteel
integrity = 800
melting_point = 6000
icon_base = "solid"
icon_reinf = "reinf_over"
icon_colour = "#777777"
explosion_resistance = 25
/material/glass
name = "glass"
stack_type = /obj/item/stack/sheet/glass
icon_colour = "#00E1FF"
opacity = 0.3
/material/plastic
name = "plastic"
stack_type = /obj/item/stack/sheet/mineral/plastic
icon_base = "solid"
icon_reinf = "reinf_over"
icon_colour = "#CCCCCC"
/material/osmium
name = "osmium"
stack_type = /obj/item/stack/sheet/mineral/osmium
icon_colour = "#9999FF"
/material/tritium
name = "tritium"
stack_type = /obj/item/stack/sheet/mineral/tritium
icon_colour = "#777777"
/material/mhydrogen
name = "mhydrogen"
stack_type = /obj/item/stack/sheet/mineral/mhydrogen
icon_colour = "#E6C5DE"
/material/platinum
name = "platinum"
stack_type = /obj/item/stack/sheet/mineral/platinum
icon_colour = "#9999FF"
/material/iron
name = "iron"
stack_type = /obj/item/stack/sheet/mineral/iron
icon_colour = "#5C5454"
/material/cult
name = "cult"
display_name = "disturbing stone"
icon_base = "cult"
icon_colour = "#402821"
icon_reinf = "reinf_cult"
/material/cult/place_dismantled_girder(var/turf/target)
new /obj/structure/girder/cult(target)
/material/cult/place_dismantled_product(var/turf/target)
new /obj/effect/decal/cleanable/blood(target)
/material/cult/reinf
name = "cult2"
display_name = "human remains"
/material/cult/reinf/place_dismantled_product(var/turf/target)
new /obj/effect/decal/remains/human(target)

View File

@@ -19,7 +19,7 @@
product = /obj/item/stack/sheet/plasteel
/datum/alloy/steel
metaltag = "steel"
metaltag = DEFAULT_WALL_MATERIAL
requires = list(
"coal" = 1,
"hematite" = 1

View File

@@ -4,7 +4,7 @@
icon = 'icons/obj/device.dmi'
icon_state = "forensic0-old" //GET A BETTER SPRITE.
item_state = "electronic"
matter = list("metal" = 150)
matter = list(DEFAULT_WALL_MATERIAL = 150)
origin_tech = "magnets=1;engineering=1"
/obj/item/weapon/mining_scanner/attack_self(mob/user as mob)

View File

@@ -42,8 +42,9 @@
for(var/ore in machine.ores_processing)
if(!machine.ores_stored[ore] && !show_all_ores) continue
dat += "<tr><td width = 40><b>[capitalize(ore)]</b></td><td width = 30>[machine.ores_stored[ore]]</td><td width = 100><font color='"
var/ore/O = ore_data[ore]
if(!O) continue
dat += "<tr><td width = 40><b>[capitalize(O.display_name)]</b></td><td width = 30>[machine.ores_stored[ore]]</td><td width = 100><font color='"
if(machine.ores_processing[ore])
switch(machine.ores_processing[ore])
if(0)
@@ -104,14 +105,13 @@
icon_state = "furnace"
density = 1
anchored = 1
luminosity = 3
light_range = 3
var/obj/machinery/mineral/input = null
var/obj/machinery/mineral/output = null
var/obj/machinery/mineral/console = null
var/sheets_per_tick = 10
var/list/ores_processing[0]
var/list/ores_stored[0]
var/list/ore_data[0]
var/list/alloy_data[0]
var/active = 0
@@ -123,11 +123,12 @@
for(var/alloytype in typesof(/datum/alloy)-/datum/alloy)
alloy_data += new alloytype()
for(var/oretype in typesof(/datum/ore)-/datum/ore)
var/datum/ore/OD = new oretype()
ore_data[OD.oretag] = OD
ores_processing[OD.oretag] = 0
ores_stored[OD.oretag] = 0
if(!ore_data || !ore_data.len)
for(var/oretype in typesof(/ore)-/ore)
var/ore/OD = new oretype()
ore_data[OD.name] = OD
ores_processing[OD.name] = 0
ores_stored[OD.name] = 0
//Locate our output and input machinery.
spawn(5)
@@ -150,8 +151,10 @@
for(var/i = 0,i<sheets_per_tick,i++)
var/obj/item/weapon/ore/O = locate() in input.loc
if(!O) break
if(!isnull(ores_stored[O.oretag])) ores_stored[O.oretag]++
O.loc = null
if(!isnull(ores_stored[O.material]))
ores_stored[O.material]++
qdel(O)
if(!active)
return
@@ -164,7 +167,7 @@
if(ores_stored[metal] > 0 && ores_processing[metal] != 0)
var/datum/ore/O = ore_data[metal]
var/ore/O = ore_data[metal]
if(!O) continue
@@ -206,24 +209,28 @@
var/can_make = Clamp(ores_stored[metal],0,sheets_per_tick-sheets)
if(can_make%2>0) can_make--
if(!can_make || ores_stored[metal] < 1)
var/material/M = name_to_material[O.compresses_to]
if(!istype(M) || !can_make || ores_stored[metal] < 1)
continue
for(var/i=0,i<can_make,i+=2)
ores_stored[metal]-=2
sheets+=2
new O.compresses_to(output.loc)
new M.stack_type(output.loc)
else if(ores_processing[metal] == 1 && O.smelts_to) //Smelting.
var/can_make = Clamp(ores_stored[metal],0,sheets_per_tick-sheets)
if(!can_make || ores_stored[metal] < 1)
var/material/M = name_to_material[O.smelts_to]
if(!istype(M) || !can_make || ores_stored[metal] < 1)
continue
for(var/i=0,i<can_make,i++)
ores_stored[metal]--
sheets++
new O.smelts_to(output.loc)
new M.stack_type(output.loc)
else
ores_stored[metal]--
sheets++
@@ -231,4 +238,4 @@
else
continue
console.updateUsrDialog()
console.updateUsrDialog()

View File

@@ -89,8 +89,8 @@
stack_storage["glass"] = 0
stack_paths["glass"] = /obj/item/stack/sheet/glass
stack_storage["metal"] = 0
stack_paths["metal"] = /obj/item/stack/sheet/metal
stack_storage[DEFAULT_WALL_MATERIAL] = 0
stack_paths[DEFAULT_WALL_MATERIAL] = /obj/item/stack/sheet/metal
stack_storage["plasteel"] = 0
stack_paths["plasteel"] = /obj/item/stack/sheet/plasteel

View File

@@ -1,12 +1,3 @@
/**********************Light************************/
//this item is intended to give the effect of entering the mine, so that light gradually fades
/obj/effect/light_emitter
name = "Light-emtter"
anchored = 1
unacidable = 1
luminosity = 8
/**********************Miner Lockers**************************/
/obj/structure/closet/secure_closet/miner
@@ -35,8 +26,7 @@
new /obj/item/device/flashlight/lantern(src)
new /obj/item/weapon/shovel(src)
new /obj/item/weapon/pickaxe(src)
new /obj/item/clothing/glasses/meson(src)
new /obj/item/clothing/glasses/material(src)
/******************************Lantern*******************************/
@@ -59,7 +49,7 @@
icon_state = "pickaxe"
item_state = "jackhammer"
w_class = 4.0
matter = list("metal" = 3750)
matter = list(DEFAULT_WALL_MATERIAL = 3750)
var/digspeed = 40 //moving the delay to an item var so R&D can make improved picks. --NEO
origin_tech = "materials=1;engineering=1"
attack_verb = list("hit", "pierced", "sliced", "attacked")
@@ -119,6 +109,7 @@
origin_tech = "materials=4;phorontech=3;engineering=3"
desc = "A rock cutter that uses bursts of hot plasma. You could use it to cut limbs off of xenos! Or, you know, mine stuff."
drill_verb = "cutting"
drill_sound = 'sound/items/Welder.ogg'
sharp = 1
edge = 1
@@ -161,7 +152,7 @@
throwforce = 4.0
item_state = "shovel"
w_class = 3.0
matter = list("metal" = 50)
matter = list(DEFAULT_WALL_MATERIAL = 50)
origin_tech = "materials=1;engineering=1"
attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked")
sharp = 0

View File

@@ -11,7 +11,7 @@
density = 1
blocks_air = 1
temperature = T0C
var/mineral/mineral
var/ore/mineral
var/mined_ore = 0
var/last_act = 0
var/emitter_blasts_taken = 0 // EMITTER MINING! Muhehe.
@@ -95,13 +95,13 @@
/turf/simulated/mineral/proc/UpdateMineral()
clear_ore_effects()
if(!mineral)
name = "\improper Rock"
icon_state = "rock"
return
name = "\improper [mineral.display_name] deposit"
overlays.Cut()
overlays += "rock_[mineral.name]"
new /obj/effect/mineral(src, mineral)
//Not even going to touch this pile of spaghetti
/turf/simulated/mineral/attackby(obj/item/weapon/W as obj, mob/user as mob)
@@ -234,10 +234,15 @@
else
return attack_hand(user)
/turf/simulated/mineral/proc/clear_ore_effects()
for(var/obj/effect/mineral/M in contents)
qdel(M)
/turf/simulated/mineral/proc/DropMineral()
if(!mineral)
return
clear_ore_effects()
var/obj/item/weapon/ore/O = new mineral.ore (src)
if(istype(O))
geologic_data.UpdateNearbyArtifactInfo(src)
@@ -274,6 +279,7 @@
var/list/step_overlays = list("n" = NORTH, "s" = SOUTH, "e" = EAST, "w" = WEST)
//Add some rubble, you did just clear out a big chunk of rock.
var/turf/simulated/floor/plating/airless/asteroid/N = ChangeTurf(/turf/simulated/floor/plating/airless/asteroid)
N.overlay_detail = "asteroid[rand(0,9)]"
@@ -369,12 +375,9 @@
/turf/simulated/mineral/random/New()
if (prob(mineralChance) && !mineral)
var/mineral_name = pickweight(mineralSpawnChanceList) //temp mineral name
if(!name_to_mineral)
SetupMinerals()
if (mineral_name && mineral_name in name_to_mineral)
mineral = name_to_mineral[mineral_name]
mineral_name = lowertext(mineral_name)
if (mineral_name && (mineral_name in ore_data))
mineral = ore_data[mineral_name]
UpdateMineral()
. = ..()

View File

@@ -0,0 +1,26 @@
/obj/effect/mineral
name = "mineral vein"
icon = 'icons/obj/mining.dmi'
desc = "Shiny."
mouse_opacity = 0
density = 0
anchored = 1
var/ore_key
var/image/scanner_image
/obj/effect/mineral/New(var/newloc, var/ore/M)
..(newloc)
name = "[M.display_name] deposit"
ore_key = M.name
icon_state = "rock_[ore_key]"
var/turf/T = get_turf(src)
layer = T.layer+0.1
/obj/effect/mineral/proc/get_scan_overlay()
if(!scanner_image)
var/ore/O = ore_data[ore_key]
if(O)
scanner_image = image(icon, loc = get_turf(src), icon_state = (O.scan_icon ? O.scan_icon : icon_state))
else
world << "No ore data for [src]!"
return scanner_image

View File

@@ -1,72 +0,0 @@
var/list/name_to_mineral
/proc/SetupMinerals()
name_to_mineral = list()
for(var/type in typesof(/mineral) - /mineral)
var/mineral/new_mineral = new type
if(!new_mineral.name)
continue
name_to_mineral[new_mineral.name] = new_mineral
return 1
/mineral
var/name // Tag for use in overlay generation/list population .
var/display_name // What am I called?
var/result_amount // How much ore?
var/spread = 1 // Does this type of deposit spread?
var/spread_chance // Chance of spreading in any direction
var/ore // Path to the ore produced when tile is mined.
/mineral/New()
. = ..()
if(!display_name)
display_name = name
/mineral/uranium
name = "Uranium"
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/uranium
/mineral/platinum
name = "Platinum"
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/osmium
/mineral/iron
name = "Iron"
result_amount = 5
spread_chance = 25
ore = /obj/item/weapon/ore/iron
/mineral/coal
name = "Coal"
result_amount = 5
spread_chance = 25
ore = /obj/item/weapon/ore/coal
/mineral/diamond
name = "Diamond"
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/diamond
/mineral/gold
name = "Gold"
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/gold
/mineral/silver
name = "Silver"
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/silver
/mineral/phoron
name = "Phoron"
result_amount = 5
spread_chance = 25
ore = /obj/item/weapon/ore/phoron

View File

@@ -17,7 +17,7 @@
var/amt_uranium = 0
var/newCoins = 0 //how many coins the machine made in it's last load
var/processing = 0
var/chosen = "metal" //which material will be used to make coins
var/chosen = DEFAULT_WALL_MATERIAL //which material will be used to make coins
var/coinsToProduce = 10
@@ -81,7 +81,7 @@
else
dat += text("<A href='?src=\ref[src];choose=silver'>Choose</A>")
dat += text("<br><font color='#555555'><b>Iron inserted: </b>[amt_iron]</font> ")
if (chosen == "metal")
if (chosen == DEFAULT_WALL_MATERIAL)
dat += text("chosen")
else
dat += text("<A href='?src=\ref[src];choose=metal'>Choose</A>")
@@ -133,7 +133,7 @@
icon_state = "coinpress1"
var/obj/item/weapon/moneybag/M
switch(chosen)
if("metal")
if(DEFAULT_WALL_MATERIAL)
while(amt_iron > 0 && coinsToProduce > 0)
if (locate(/obj/item/weapon/moneybag,output.loc))
M = locate(/obj/item/weapon/moneybag,output.loc)

View File

@@ -4,71 +4,71 @@
icon_state = "ore2"
w_class = 2
var/datum/geosample/geologic_data
var/oretag
var/material
/obj/item/weapon/ore/uranium
name = "pitchblende"
icon_state = "Uranium ore"
icon_state = "ore_uranium"
origin_tech = "materials=5"
oretag = "uranium"
material = "uranium"
/obj/item/weapon/ore/iron
name = "hematite"
icon_state = "Iron ore"
icon_state = "ore_iron"
origin_tech = "materials=1"
oretag = "hematite"
material = "hematite"
/obj/item/weapon/ore/coal
name = "carbonaceous rock"
icon_state = "Coal ore"
name = "raw carbon"
icon_state = "ore_coal"
origin_tech = "materials=1"
oretag = "coal"
material = "carbon"
/obj/item/weapon/ore/glass
name = "impure silicates"
icon_state = "Glass ore"
icon_state = "ore_glass"
origin_tech = "materials=1"
oretag = "sand"
material = "sand"
/obj/item/weapon/ore/phoron
name = "phoron crystals"
icon_state = "Phoron ore"
icon_state = "ore_phoron"
origin_tech = "materials=2"
oretag = "phoron"
material = "phoron"
/obj/item/weapon/ore/silver
name = "native silver ore"
icon_state = "Silver ore"
icon_state = "ore_silver"
origin_tech = "materials=3"
oretag = "silver"
material = "silver"
/obj/item/weapon/ore/gold
name = "native gold ore"
icon_state = "Gold ore"
icon_state = "ore_gold"
origin_tech = "materials=4"
oretag = "gold"
material = "gold"
/obj/item/weapon/ore/diamond
name = "diamonds"
icon_state = "Diamond ore"
icon_state = "ore_diamond"
origin_tech = "materials=6"
oretag = "diamond"
material = "diamond"
/obj/item/weapon/ore/osmium
name = "raw platinum"
icon_state = "Platinum ore"
oretag = "platinum"
icon_state = "ore_platinum"
material = "platinum"
/obj/item/weapon/ore/hydrogen
name = "raw hydrogen"
icon_state = "Phazon"
oretag = "hydrogen"
icon_state = "ore_hydrogen"
material = "mhydrogen"
/obj/item/weapon/ore/slag
name = "Slag"
desc = "Completely useless"
desc = "Someone screwed up..."
icon_state = "slag"
oretag = "slag"
material = null
/obj/item/weapon/ore/New()
pixel_x = rand(0,16)-8

View File

@@ -1,52 +1,133 @@
/datum/ore
var/oretag
var/global/list/ore_data = list()
/ore
var/name
var/display_name
var/alloy
var/smelts_to
var/compresses_to
var/result_amount // How much ore?
var/spread = 1 // Does this type of deposit spread?
var/spread_chance // Chance of spreading in any direction
var/ore // Path to the ore produced when tile is mined.
var/scan_icon // Overlay for ore scanners.
// Xenoarch stuff. No idea what it's for, just refactored it to be less awful.
var/list/xarch_ages = list(
"thousand" = 999,
"million" = 999
)
var/xarch_source_mineral = "iron"
/datum/ore/uranium
smelts_to = /obj/item/stack/sheet/mineral/uranium
oretag = "uranium"
/ore/New()
. = ..()
if(!display_name)
display_name = name
/datum/ore/iron
smelts_to = /obj/item/stack/sheet/mineral/iron
/ore/uranium
name = "uranium"
display_name = "pitchblende"
smelts_to = "uranium"
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/uranium
scan_icon = "mineral_uncommon"
xarch_ages = list(
"thousand" = 999,
"million" = 704
)
xarch_source_mineral = "potassium"
/ore/hematite
name = "hematite"
display_name = "hematite"
smelts_to = "iron"
alloy = 1
oretag = "hematite"
result_amount = 5
spread_chance = 25
ore = /obj/item/weapon/ore/iron
scan_icon = "mineral_common"
/datum/ore/coal
smelts_to = /obj/item/stack/sheet/mineral/plastic
/ore/coal
name = "carbon"
display_name = "raw carbon"
smelts_to = "plastic"
alloy = 1
oretag = "coal"
result_amount = 5
spread_chance = 25
ore = /obj/item/weapon/ore/coal
scan_icon = "mineral_common"
/datum/ore/glass
smelts_to = /obj/item/stack/sheet/glass
compresses_to = /obj/item/stack/sheet/mineral/sandstone
oretag = "sand"
/ore/glass
name = "sand"
display_name = "impure silicates"
smelts_to = "glass"
compresses_to = "sandstone"
/datum/ore/phoron
/ore/phoron
name = "phoron"
display_name = "phoron crystals"
compresses_to = "phoron"
//smelts_to = something that explodes violently on the conveyor, huhuhuhu
compresses_to = /obj/item/stack/sheet/mineral/phoron
oretag = "phoron"
result_amount = 5
spread_chance = 25
ore = /obj/item/weapon/ore/phoron
scan_icon = "mineral_uncommon"
xarch_ages = list(
"thousand" = 999,
"million" = 999,
"billion" = 13,
"billion_lower" = 10
)
xarch_source_mineral = "phoron"
/datum/ore/silver
smelts_to = /obj/item/stack/sheet/mineral/silver
oretag = "silver"
/ore/silver
name = "silver"
display_name = "native silver"
smelts_to = "silver"
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/silver
scan_icon = "mineral_uncommon"
/datum/ore/gold
smelts_to = /obj/item/stack/sheet/mineral/gold
oretag = "gold"
/ore/gold
smelts_to = "gold"
name = "gold"
display_name = "native gold"
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/gold
scan_icon = "mineral_uncommon"
xarch_ages = list(
"thousand" = 999,
"million" = 999,
"billion" = 4,
"billion_lower" = 3
)
/datum/ore/diamond
compresses_to = /obj/item/stack/sheet/mineral/diamond
oretag = "diamond"
/ore/diamond
name = "diamond"
display_name = "diamond"
compresses_to = "diamond"
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/diamond
scan_icon = "mineral_rare"
xarch_source_mineral = "nitrogen"
/datum/ore/osmium
smelts_to = /obj/item/stack/sheet/mineral/platinum
compresses_to = /obj/item/stack/sheet/mineral/osmium
/ore/platinum
name = "platinum"
display_name = "raw platinum"
smelts_to = "platinum"
compresses_to = "osmium"
alloy = 1
oretag = "platinum"
result_amount = 5
spread_chance = 10
ore = /obj/item/weapon/ore/osmium
scan_icon = "mineral_rare"
/datum/ore/hydrogen
smelts_to = /obj/item/stack/sheet/mineral/tritium
compresses_to = /obj/item/stack/sheet/mineral/mhydrogen
oretag = "hydrogen"
/ore/hydrogen
name = "mhydrogen"
display_name = "metallic hydrogen"
smelts_to = "tritium"
compresses_to = "mhydrogen"
scan_icon = "mineral_rare"

View File

@@ -436,9 +436,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
src << "<span class='warning'>Spawning as a mouse is currently disabled.</span>"
return
var/mob/dead/observer/M = usr
if(config.antag_hud_restricted && M.has_enabled_antagHUD == 1)
src << "<span class='warning'>antagHUD restrictions prevent you from spawning in as a mouse.</span>"
if(!MayRespawn(1))
return
var/timedifference = world.time - client.time_died_as_mouse
@@ -677,3 +675,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
client.images |= ghost_darkness_images
if (ghostimage)
client.images -= ghostimage //remove ourself
mob/dead/observer/MayRespawn(var/feedback = 0)
if(config.antag_hud_restricted && has_enabled_antagHUD == 1)
if(feedback)
src << "<span class='warning'>antagHUD restrictions prevent you from respawning.</span>"
return 0
return 1

View File

@@ -28,7 +28,7 @@
if(src.can_use())
cameranet.addCamera(src)
else
src.SetLuminosity(0)
src.set_light(0)
cameranet.removeCamera(src)
/obj/machinery/camera/New()

View File

@@ -155,7 +155,7 @@ var/list/slot_equipment_priority = list( \
Target = loc
remove_from_mob(W)
if(!W) return 1 // self destroying objects (tk, grabs)
if(!(W && W.loc)) return 1 // self destroying objects (tk, grabs)
W.forceMove(Target)
update_icons()

View File

@@ -110,14 +110,14 @@
if(stat)
return 0
on = 1
SetLuminosity(light_strength)
set_light(light_strength)
update_icons()
return 1
/mob/living/bot/proc/turn_off()
on = 0
SetLuminosity(0)
set_light(0)
update_icons()
/mob/living/bot/proc/explode()
qdel(src)
qdel(src)

View File

@@ -226,7 +226,7 @@
beacon_freq = freq
if("screw")
screwloose = !screwloose
usr << "<span class='notice>You twiddle the screw.</span>"
usr << "<span class='notice'>You twiddle the screw.</span>"
if("oddbutton")
oddbutton = !oddbutton
usr << "<span class='notice'>You press the weird button.</span>"

View File

@@ -334,53 +334,13 @@
path = list()
/mob/living/bot/secbot/proc/check_threat(var/mob/living/M)
if(M.stat == DEAD)
if(!M || !istype(M) || M.stat)
return 0
if(emagged)
return 10
var/threatcount = 0
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.handcuffed)
return 0
var/obj/item/weapon/card/id/id = GetIdCard(H) //Agent cards lower threatlevel.
if(id && istype(id, /obj/item/weapon/card/id/syndicate))
threatcount -= 2
if(idcheck && !access_scanner.allowed(H))
if(istype(H.l_hand, /obj/item/weapon/gun) || istype(H.l_hand, /obj/item/weapon/melee))
threatcount += 4
if(istype(H.r_hand, /obj/item/weapon/gun) || istype(H.r_hand, /obj/item/weapon/melee))
threatcount += 4
if(istype(H.belt, /obj/item/weapon/gun) || istype(H.belt, /obj/item/weapon/melee))
threatcount += 2
if(H.species.name != "Human") //beepsky so racist.
threatcount += 2
if(check_records || check_arrest)
var/perpname = H.name
if(id)
perpname = id.registered_name
var/datum/data/record/R = find_security_record("name", perpname)
if(check_records && !R)
threatcount += 4
if(check_arrest && R && (R.fields["criminal"] == "*Arrest*"))
threatcount += 4
else if(isanimal(M))
if(istype(M, /mob/living/simple_animal/hostile) && !istype(M, /mob/living/simple_animal/hostile/retaliate/goat))
threatcount += 4
return threatcount
return M.assess_perp(access_scanner, idcheck, check_records, check_arrest)
/mob/living/bot/secbot/proc/patrol_step()
if(loc == patrol_target)

View File

@@ -31,4 +31,4 @@
/mob/living/carbon/alien/diona/put_in_hands(var/obj/item/W) // No hands.
W.loc = get_turf(src)
return 1
return 1

View File

@@ -4,10 +4,12 @@
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
if(isturf(loc)) //else, there's considered to be no light
var/turf/T = loc
var/area/A = T.loc
if(A)
if(A.lighting_use_dynamic) light_amount = min(10,T.lighting_lumcount) - 5 //hardcapped so it's not abused by having a ton of flashlights
else light_amount = 5
var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T
if(L)
light_amount = min(10,L.lum_r + L.lum_g + L.lum_b) - 5 //hardcapped so it's not abused by having a ton of flashlights
else
light_amount = 5
nutrition += light_amount

View File

@@ -25,7 +25,7 @@
w_class = 3
origin_tech = "biotech=3"
var/list/construction_cost = list("metal"=1000,"glass"=500)
var/list/construction_cost = list(DEFAULT_WALL_MATERIAL=1000,"glass"=500)
var/construction_time = 75
//these vars are so the mecha fabricator doesn't shit itself anymore. --NEO

View File

@@ -6,7 +6,7 @@
w_class = 3
origin_tech = "engineering=4;materials=4;bluespace=2;programming=4"
construction_cost = list("metal"=500,"glass"=500,"silver"=200,"gold"=200,"phoron"=100,"diamond"=10)
construction_cost = list(DEFAULT_WALL_MATERIAL=500,"glass"=500,"silver"=200,"gold"=200,"phoron"=100,"diamond"=10)
construction_time = 75
var/searching = 0
var/askDelay = 10 * 60 * 1
@@ -26,7 +26,7 @@
/obj/item/device/mmi/digital/posibrain/proc/request_player()
for(var/mob/dead/observer/O in player_list)
if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
if(!O.MayRespawn())
continue
if(jobban_isbanned(O, "AI") && jobban_isbanned(O, "Cyborg"))
continue

View File

@@ -1,7 +1,7 @@
mob/living/carbon/verb/give(var/mob/living/carbon/target in view(1)-usr)
set category = "IC"
set name = "Give"
if(target.stat == 2 || usr.stat == 2|| target.client == null)
if(!istype(target) || target.stat == 2 || usr.stat == 2|| target.client == null)
return
var/obj/item/I
if(!usr.hand && usr.r_hand == null)

View File

@@ -72,6 +72,10 @@
if(I_GRAB)
if(M == src || anchored)
return 0
for(var/obj/item/weapon/grab/G in src.grabbed_by)
if(G.assailant == M)
M << "<span class='notice'>You already grabbed [src].</span>"
return
if(w_uniform)
w_uniform.add_fingerprint(M)
@@ -218,7 +222,7 @@
//See if they have any guns that might go off
for(var/obj/item/weapon/gun/W in holding)
if(W && prob(holding[W]))
if(W && prob(holding[W]))
var/list/turfs = list()
for(var/turf/T in view())
turfs += T
@@ -251,11 +255,6 @@
visible_message("<span class='danger'>[M] has disarmed [src]!</span>")
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
//if M (and only M) has a grab on src, start dislocating limbs
if(grab_joint(M))
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("\red <B>[M] attempted to disarm [src]!</B>")
@@ -304,10 +303,10 @@
if(G.affecting == src && G.state == GRAB_NECK)
has_grab = 1
break
if(!has_grab)
return 0
if(!def_zone) def_zone = user.zone_sel.selecting
var/target_zone = check_zone(def_zone)
if(!target_zone)
@@ -315,7 +314,7 @@
var/obj/item/organ/external/organ = get_organ(check_zone(target_zone))
if(!organ || organ.is_dislocated() || organ.dislocated == -1)
return 0
user.visible_message("<span class='warning'>[user] begins to dislocate [src]'s [organ.joint]!</span>")
if(do_after(user, 100))
organ.dislocate()

View File

@@ -138,6 +138,14 @@ emp_act
return 1
return 0
//Used to check if they can be fed food/drinks/pills
/mob/living/carbon/human/proc/check_mouth_coverage()
var/list/protective_gear = list(head, wear_mask, wear_suit, w_uniform)
for(var/obj/item/gear in protective_gear)
if(istype(gear) && (gear.body_parts_covered & FACE) && (gear.flags & (MASKCOVERSMOUTH|HEADCOVERSMOUTH)))
return gear
return null
/mob/living/carbon/human/proc/check_shields(var/damage = 0, var/attack_text = "the attack")
if(l_hand && istype(l_hand, /obj/item/weapon))//Current base is the prob(50-d/3)
var/obj/item/weapon/I = l_hand
@@ -281,7 +289,7 @@ emp_act
forcesay(hit_appends) //forcesay checks stat already
//Melee weapon embedded object code.
if (I && I.damtype == BRUTE && !I.anchored && !I.is_robot_module())
if (I && I.damtype == BRUTE && !I.anchored && !is_robot_module(I))
var/damage = effective_force
if (armor)
damage /= armor+1
@@ -355,7 +363,7 @@ emp_act
//thrown weapon embedded object code.
if(dtype == BRUTE && istype(O,/obj/item))
var/obj/item/I = O
if (!I.is_robot_module())
if (!is_robot_module(I))
var/sharp = is_sharp(I)
var/damage = throw_damage
if (armor)

View File

@@ -32,6 +32,7 @@
var/temperature_alert = 0
var/in_stasis = 0
var/heartbeat = 0
var/global/list/overlays_cache = null
/mob/living/carbon/human/Life()
@@ -876,10 +877,11 @@
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
if(isturf(loc)) //else, there's considered to be no light
var/turf/T = loc
var/area/A = T.loc
if(A)
if(A.lighting_use_dynamic) light_amount = min(10,T.lighting_lumcount) - 5 //hardcapped so it's not abused by having a ton of flashlights
else light_amount = 5
var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T
if(L)
light_amount = min(10,L.lum_r + L.lum_g + L.lum_b) - 5 //hardcapped so it's not abused by having a ton of flashlights
else
light_amount = 5
nutrition += light_amount
traumatic_shock -= light_amount
@@ -897,10 +899,11 @@
var/light_amount = 0
if(isturf(loc))
var/turf/T = loc
var/area/A = T.loc
if(A)
if(A.lighting_use_dynamic) light_amount = T.lighting_lumcount
else light_amount = 10
var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T
if(L)
light_amount = L.lum_r + L.lum_g + L.lum_b //hardcapped so it's not abused by having a ton of flashlights
else
light_amount = 10
if(light_amount > species.light_dam) //if there's enough light, start dying
take_overall_damage(1,1)
else //heal in the dark
@@ -1082,6 +1085,33 @@
return 1
proc/handle_regular_hud_updates()
if(!overlays_cache)
overlays_cache = list()
overlays_cache.len = 23
overlays_cache[1] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage1")
overlays_cache[2] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage2")
overlays_cache[3] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage3")
overlays_cache[4] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage4")
overlays_cache[5] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage5")
overlays_cache[6] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage6")
overlays_cache[7] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage7")
overlays_cache[8] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage8")
overlays_cache[9] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage9")
overlays_cache[10] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage10")
overlays_cache[11] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay1")
overlays_cache[12] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay2")
overlays_cache[13] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay3")
overlays_cache[14] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay4")
overlays_cache[15] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay5")
overlays_cache[16] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay6")
overlays_cache[17] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay7")
overlays_cache[18] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay1")
overlays_cache[19] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay2")
overlays_cache[20] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay3")
overlays_cache[21] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay4")
overlays_cache[22] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay5")
overlays_cache[23] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay6")
if(hud_updateflag) // update our mob's hud overlays, AKA what others see flaoting above our head
handle_hud_list()
@@ -1100,32 +1130,32 @@
if(damageoverlay.overlays)
damageoverlay.overlays = list()
if(stat == UNCONSCIOUS)
//Critical damage passage overlay
if(health <= 0)
var/image/I
switch(health)
if(-20 to -10)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage1")
I = overlays_cache[1]
if(-30 to -20)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage2")
I = overlays_cache[2]
if(-40 to -30)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage3")
I = overlays_cache[3]
if(-50 to -40)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage4")
I = overlays_cache[4]
if(-60 to -50)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage5")
I = overlays_cache[5]
if(-70 to -60)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage6")
I = overlays_cache[6]
if(-80 to -70)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage7")
I = overlays_cache[7]
if(-90 to -80)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage8")
I = overlays_cache[8]
if(-95 to -90)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage9")
I = overlays_cache[9]
if(-INFINITY to -95)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage10")
I = overlays_cache[10]
damageoverlay.overlays += I
else
//Oxygen damage overlay
@@ -1133,19 +1163,19 @@
var/image/I
switch(oxyloss)
if(10 to 20)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay1")
I = overlays_cache[11]
if(20 to 25)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay2")
I = overlays_cache[12]
if(25 to 30)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay3")
I = overlays_cache[13]
if(30 to 35)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay4")
I = overlays_cache[14]
if(35 to 40)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay5")
I = overlays_cache[15]
if(40 to 45)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay6")
I = overlays_cache[16]
if(45 to INFINITY)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay7")
I = overlays_cache[17]
damageoverlay.overlays += I
//Fire and Brute damage overlay (BSSR)
@@ -1155,17 +1185,17 @@
var/image/I
switch(hurtdamage)
if(10 to 25)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay1")
I = overlays_cache[18]
if(25 to 40)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay2")
I = overlays_cache[19]
if(40 to 55)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay3")
I = overlays_cache[20]
if(55 to 70)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay4")
I = overlays_cache[21]
if(70 to 85)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay5")
I = overlays_cache[22]
if(85 to INFINITY)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay6")
I = overlays_cache[23]
damageoverlay.overlays += I
if( stat == DEAD )
@@ -1390,8 +1420,9 @@
//0.1% chance of playing a scary sound to someone who's in complete darkness
if(isturf(loc) && rand(1,1000) == 1)
var/turf/currentTurf = loc
if(!currentTurf.lighting_lumcount)
var/turf/T = loc
var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T
if(L && L.lum_r + L.lum_g + L.lum_b == 0)
playsound_local(src,pick(scarySounds),50, 1, -1)
proc/handle_stomach()

View File

@@ -134,13 +134,20 @@
return
// OBJ CHECK
var/cannot_melt
if(isobj(O))
var/obj/I = O
if(I.unacidable) //So the aliens don't destroy energy fields/singularies/other aliens/etc with their acid.
src << "<span class='alium'>You cannot dissolve this object.</span>"
return
// TURF CHECK
else if(istype(O, /turf/simulated/wall/r_wall) || istype(O, /turf/simulated/floor/engine))
if(I.unacidable)
cannot_melt = 1
else
if(istype(O, /turf/simulated/wall))
var/turf/simulated/wall/W = O
if(W.material.unmeltable)
cannot_melt = 1
else if(istype(O, /turf/simulated/floor/engine))
cannot_melt = 1
if(cannot_melt)
src << "<span class='alium'>You cannot dissolve this object.</span>"
return

View File

@@ -1,6 +1,6 @@
/mob/living/carbon/process_resist()
//drop && roll
if(on_fire)
fire_stacks -= 2 //reduced
@@ -18,34 +18,34 @@
)
ExtinguishMob()
return
if(handcuffed)
spawn() escape_handcuffs()
else if(legcuffed)
spawn() escape_legcuffs()
..()
/mob/living/carbon/proc/escape_handcuffs()
if(!(last_special <= world.time)) return
next_move = world.time + 100
last_special = world.time + 100
if(can_break_cuffs()) //Don't want to do a lot of logic gating here.
break_handcuffs()
return
var/obj/item/weapon/handcuffs/HC = handcuffed
//A default in case you are somehow handcuffed with something that isn't an obj/item/weapon/handcuffs type
var/breakouttime = 1200
var/breakouttime = 1200
var/displaytime = 2 //Minutes to display in the "this will take X minutes."
//If you are handcuffed with actual handcuffs... Well what do I know, maybe someone will want to handcuff you with toilet paper in the future...
if(istype(HC))
breakouttime = HC.breakouttime
displaytime = breakouttime / 600 //Minutes
visible_message(
"<span class='danger'>[src] attempts to remove \the [HC]!</span>",
"<span class='warning'>You attempt to remove \the [HC]. (This will take around [displaytime] minutes and you need to stand still)</span>"
@@ -62,7 +62,7 @@
/mob/living/carbon/proc/escape_legcuffs()
if(!(last_special <= world.time)) return
next_move = world.time + 100
last_special = world.time + 100
@@ -71,7 +71,7 @@
return
var/obj/item/weapon/legcuffs/HC = legcuffed
//A default in case you are somehow legcuffed with something that isn't an obj/item/weapon/legcuffs type
var/breakouttime = 1200
var/displaytime = 2 //Minutes to display in the "this will take X minutes."
@@ -79,20 +79,20 @@
if(istype(HC))
breakouttime = HC.breakouttime
displaytime = breakouttime / 600 //Minutes
visible_message(
"<span class='danger'>[usr] attempts to remove \the [HC]!</span>",
visible_message(
"<span class='danger'>[usr] attempts to remove \the [HC]!</span>",
"<span class='warning'>You attempt to remove \the [HC]. (This will take around [displaytime] minutes and you need to stand still)</span>"
)
if(do_after(src, breakouttime))
if(!legcuffed || buckled)
return
return
visible_message(
"<span class='danger'>[src] manages to remove \the [legcuffed]!</span>",
"<span class='danger'>[src] manages to remove \the [legcuffed]!</span>",
"<span class='notice'>You successfully remove \the [legcuffed].</span>"
)
drop_from_inventory(legcuffed)
legcuffed = null
update_inv_legcuffed()
@@ -106,18 +106,18 @@
"<span class='danger'>[src] is trying to break \the [handcuffed]!</span>",
"<span class='warning'>You attempt to break your [handcuffed.name]. (This will take around 5 seconds and you need to stand still)</span>"
)
if(do_after(src, 50))
if(!handcuffed || buckled)
return
visible_message(
"<span class='danger'>[src] manages to break \the [handcuffed]!</span>",
"<span class='danger'>[src] manages to break \the [handcuffed]!</span>",
"<span class='warning'>You successfully break your [handcuffed.name].</span>"
)
say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
del(handcuffed)
handcuffed = null
if(buckled && buckled.buckle_require_restraints)
@@ -131,14 +131,14 @@
if(do_after(src, 50))
if(!legcuffed || buckled)
return
visible_message(
"<span class='danger'>[src] manages to break the legcuffs!</span>",
"<span class='warning'>You successfully break your legcuffs.</span>"
)
say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
del(legcuffed)
legcuffed = null
update_inv_legcuffed()

View File

@@ -132,6 +132,10 @@ default behaviour is:
now_pushing = 0
return
step(AM, t)
if(ishuman(AM) && AM:grabbed_by)
for(var/obj/item/weapon/grab/G in AM:grabbed_by)
step(G:assailant, get_dir(G:assailant, AM))
G.adjust_position()
now_pushing = 0
return
return

View File

@@ -139,7 +139,7 @@
var/obj/item/I = O
mass = I.w_class/THROWNOBJ_KNOCKBACK_DIVISOR
var/momentum = speed*mass
if(O.throw_source && momentum >= THROWNOBJ_KNOCKBACK_SPEED)
var/dir = get_dir(O.throw_source, src)
@@ -200,14 +200,14 @@
/mob/living/proc/IgniteMob()
if(fire_stacks > 0 && !on_fire)
on_fire = 1
src.AddLuminosity(3)
set_light(light_range + 3)
update_fire()
/mob/living/proc/ExtinguishMob()
if(on_fire)
on_fire = 0
fire_stacks = 0
src.AddLuminosity(-3)
set_light(max(0, light_range - 3))
update_fire()
/mob/living/proc/update_fire()
@@ -219,18 +219,18 @@
/mob/living/proc/handle_fire()
if(fire_stacks < 0)
fire_stacks = max(0, fire_stacks++) //If we've doused ourselves in water to avoid fire, dry off slowly
if(!on_fire)
return 1
else if(fire_stacks <= 0)
ExtinguishMob() //Fire's been put out.
return 1
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
if(G.gas["oxygen"] < 1)
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
return 1
var/turf/location = get_turf(src)
location.hotspot_expose(fire_burn_temperature(), 50, 1)
@@ -242,6 +242,6 @@
/mob/living/proc/fire_burn_temperature()
if (fire_stacks <= 0)
return 0
//Scale quadratically so that single digit numbers of fire stacks don't burn ridiculously hot.
return round(FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE*(fire_stacks/FIRE_MAX_FIRESUIT_STACKS)**2)

View File

@@ -282,7 +282,7 @@ var/list/ai_verbs_default = list(
//if(icon_state == initial(icon_state))
var/icontype = ""
if (custom_sprite == 1) icontype = ("Custom")//automagically selects custom sprite if one is available
else icontype = input("Select an icon!", "AI", null, null) in list("Monochrome", "Rainbow", "Blue", "Inverted", "Text", "Smiley", "Angry", "Dorf", "Matrix", "Bliss", "Firewall", "Green", "Red", "Static", "Triumvirate", "Triumvirate Static", "Soviet", "Trapped", "Heartline", "Chatterbox")
else icontype = input("Select an icon!", "AI", null, null) in list("Monochrome", "Rainbow", "Blue", "Inverted", "Text", "Smiley", "Angry", "Dorf", "Matrix", "Bliss", "Firewall", "Green", "Red", "Static", "Triumvirate", "Triumvirate Static", "Soviet", "Trapped", "Heartline", "Chatterbox", "Helios", "Dug Too Deep", "Goon", "Database", "Glitchman", "Lonestar", "Nanotrasen")
switch(icontype)
if("Custom") icon_state = "[src.ckey]-ai"
if("Rainbow") icon_state = "ai-clown"
@@ -304,6 +304,13 @@ var/list/ai_verbs_default = list(
if("Trapped") icon_state = "ai-hades"
if("Heartline") icon_state = "ai-heartline"
if("Chatterbox") icon_state = "ai-president"
if("Helios") icon_state = "ai-helios"
if("Dug Too Deep") icon_state = "ai-toodeep"
if("Goon") icon_state = "ai-goon"
if("Database") icon_state = "ai-database"
if("Glitchman") icon_state = "ai-glitchman"
if("Lonestar") icon_state = "ai-lonestar"
if("Nanotrasen") icon_state = "ai-nanotrasen"
else icon_state = "ai"
//else
//usr <<"You can only change your display once!"
@@ -468,13 +475,13 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/reset_view(atom/A)
if(camera)
camera.SetLuminosity(0)
camera.set_light(0)
if(istype(A,/obj/machinery/camera))
camera = A
..()
if(istype(A,/obj/machinery/camera))
if(camera_light_on) A.SetLuminosity(AI_CAMERA_LUMINOSITY)
else A.SetLuminosity(0)
if(camera_light_on) A.set_light(AI_CAMERA_LUMINOSITY)
else A.set_light(0)
/mob/living/silicon/ai/proc/switchCamera(var/obj/machinery/camera/C)
@@ -612,7 +619,7 @@ var/list/ai_verbs_default = list(
src << "Camera lights [camera_light_on ? "activated" : "deactivated"]."
if(!camera_light_on)
if(camera)
camera.SetLuminosity(0)
camera.set_light(0)
camera = null
else
lightNearbyCamera()
@@ -627,20 +634,20 @@ var/list/ai_verbs_default = list(
if(src.camera)
var/obj/machinery/camera/camera = near_range_camera(src.eyeobj)
if(camera && src.camera != camera)
src.camera.SetLuminosity(0)
src.camera.set_light(0)
if(!camera.light_disabled)
src.camera = camera
src.camera.SetLuminosity(AI_CAMERA_LUMINOSITY)
src.camera.set_light(AI_CAMERA_LUMINOSITY)
else
src.camera = null
else if(isnull(camera))
src.camera.SetLuminosity(0)
src.camera.set_light(0)
src.camera = null
else
var/obj/machinery/camera/camera = near_range_camera(src.eyeobj)
if(camera && !camera.light_disabled)
src.camera = camera
src.camera.SetLuminosity(AI_CAMERA_LUMINOSITY)
src.camera.set_light(AI_CAMERA_LUMINOSITY)
camera_light_on = world.timeofday + 1 * 20 // Update the light every 2 seconds.

View File

@@ -48,7 +48,7 @@
loc = T.loc
if (istype(loc, /area))
//stage = 4
if (!loc.master.power_equip && !istype(src.loc,/obj/item))
if (!loc.power_equip && !istype(src.loc,/obj/item))
//stage = 5
blind = 1
@@ -115,7 +115,7 @@
spawn(20)
src << "Backup battery online. Scanners, camera, and radio interface offline. Beginning fault-detection."
sleep(50)
if (loc.master.power_equip)
if (loc.power_equip)
if (!istype(T, /turf/space))
src << "Alert cancelled. Power has been restored without our assistance."
src:aiRestorePowerRoutine = 0
@@ -135,18 +135,17 @@
var/PRP
for (PRP=1, PRP<=4, PRP++)
for(var/area/A in current_area.master.related)
for (var/obj/machinery/power/apc/APC in A)
if (!(APC.stat & BROKEN))
theAPC = APC
break
for (var/obj/machinery/power/apc/APC in current_area)
if (!(APC.stat & BROKEN))
theAPC = APC
break
if (!theAPC)
switch(PRP)
if (1) src << "Unable to locate APC!"
else src << "Lost connection with the APC!"
src:aiRestorePowerRoutine = 2
return
if (loc.master.power_equip)
if (loc.power_equip)
if (!istype(T, /turf/space))
src << "Alert cancelled. Power has been restored without our assistance."
src:aiRestorePowerRoutine = 0
@@ -181,7 +180,7 @@
/mob/living/silicon/ai/proc/lacks_power()
var/turf/T = get_turf(src)
var/area/A = get_area(src)
return ((!A.master.power_equip) && A.requires_power == 1 || istype(T, /turf/space)) && !istype(src.loc,/obj/item)
return ((!A.power_equip) && A.requires_power == 1 || istype(T, /turf/space)) && !istype(src.loc,/obj/item)
/mob/living/silicon/ai/updatehealth()
if(status_flags & GODMODE)
@@ -195,4 +194,4 @@
/mob/living/silicon/ai/rejuvenate()
..()
add_ai_verbs(src)
add_ai_verbs(src)

View File

@@ -234,7 +234,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
if(c.ready)
var/found = 0
for(var/mob/dead/observer/o in player_list)
if(o.key == c.key)
if(o.key == c.key && o.MayRespawn())
found = 1
if(found)
available.Add(c)
@@ -347,7 +347,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
/datum/paiController/proc/requestRecruits(var/mob/user)
inquirer = user
for(var/mob/dead/observer/O in player_list)
if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
if(!O.MayRespawn())
continue
if(jobban_isbanned(O, "pAI"))
continue

View File

@@ -7,7 +7,13 @@ var/list/pai_emotions = list(
"Off" = 6,
"Sad" = 7,
"Angry" = 8,
"What" = 9
"What" = 9,
"Neutral" = 10,
"Silly" = 11,
"Nose" = 12,
"Smirk" = 13,
"Exclamation Points" = 14,
"Question Mark" = 15
)

View File

@@ -12,7 +12,7 @@
w_class = 2.0
throw_speed = 5
throw_range = 10
matter = list("metal" = 500, "glass" = 200)
matter = list(DEFAULT_WALL_MATERIAL = 500, "glass" = 200)
origin_tech = "magnets=2;biotech=1;engineering=2"
var/mode = 1;

View File

@@ -218,7 +218,7 @@
icon = 'icons/obj/robot_component.dmi'
icon_state = "working"
construction_time = 200
construction_cost = list("metal"=5000)
construction_cost = list(DEFAULT_WALL_MATERIAL=5000)
var/brute = 0
var/burn = 0
var/icon_state_broken = "broken"

View File

@@ -188,8 +188,8 @@
//Standard robots use config for crit, which is somewhat excessive for these guys.
//Drones killed by damage will gib.
/mob/living/silicon/robot/drone/handle_regular_status_updates()
if((health <= -35 || (master_fabricator && src.z != master_fabricator.z)) && src.stat != 2)
var/turf/T = get_turf(src)
if((!T || health <= -35 || (master_fabricator && T.z != master_fabricator.z)) && src.stat != DEAD)
timeofdeath = world.time
death() //Possibly redundant, having trouble making death() cooperate.
gib()
@@ -287,6 +287,7 @@
src.verbs -= silicon_subsystems
/mob/living/silicon/robot/drone/construction
icon_state = "constructiondrone"
law_type = /datum/ai_laws/construction_drone
module_type = /obj/item/weapon/robot_module/drone/construction
can_pull_size = 5

View File

@@ -16,10 +16,7 @@
/obj/item/weapon/airlock_electronics,
/obj/item/weapon/module/power_control,
/obj/item/weapon/stock_parts,
/obj/item/light_fixture_frame,
/obj/item/apc_frame,
/obj/item/alarm_frame,
/obj/item/firealarm_frame,
/obj/item/frame,
/obj/item/weapon/table_parts,
/obj/item/weapon/table_parts/rack,
/obj/item/weapon/camera_assembly,

View File

@@ -108,6 +108,9 @@
if(jobban_isbanned(src,"Cyborg"))
usr << "<span class='danger'>You are banned from playing synthetics and cannot spawn as a drone.</span>"
return
if(!MayRespawn(1))
return
var/deathtime = world.time - src.timeofdeath
if(istype(src,/mob/dead/observer))
@@ -145,4 +148,4 @@
var/choice = input(src,"Which fabricator do you wish to use?") as null|anything in all_fabricators
if(choice)
var/obj/machinery/drone_fabricator/chosen_fabricator = all_fabricators[choice]
chosen_fabricator.create_drone(src.client)
chosen_fabricator.create_drone(src.client)

View File

@@ -58,7 +58,7 @@
src.has_power = 0
if(lights_on) // Light is on but there is no power!
lights_on = 0
SetLuminosity(0)
set_light(0)
/mob/living/silicon/robot/proc/handle_regular_status_updates()

View File

@@ -367,9 +367,9 @@
lights_on = !lights_on
usr << "You [lights_on ? "enable" : "disable"] your integrated light."
if(lights_on)
SetLuminosity(integrated_light_power) // 1.5x luminosity of flashlight
set_light(integrated_light_power) // 1.5x luminosity of flashlight
else
SetLuminosity(0)
set_light(0)
/mob/living/silicon/robot/verb/self_diagnosis_verb()
set category = "Robot Commands"
@@ -594,6 +594,8 @@
user << "Close the panel first."
else if(cell)
user << "There is a power cell already installed."
else if(W.w_class != 3)
user << "\The [W] is too [W.w_class < 3? "small" : "large"] to fit here."
else
user.drop_item()
W.loc = src

View File

@@ -36,27 +36,31 @@ var/global/list/robot_modules = list(
// Bookkeeping
var/list/added_languages = list()
var/list/added_networks = list()
var/obj/item/device/radio/borg/modified_radio = null
var/list/modified_key = null
var/list/original_radio_channels = list()
/obj/item/weapon/robot_module/New(var/mob/living/silicon/robot/R)
..()
add_camera_networks(R)
add_languages(R)
add_radio_channels(R)
add_subsystems(R)
apply_status_flags(R)
if(R.radio)
R.radio.recalculateChannels()
/obj/item/weapon/robot_module/proc/Reset(var/mob/living/silicon/robot/R)
..()
R.module = null
remove_camera_networks(R)
remove_languages(R)
remove_radio_channels(R)
remove_subsystems(R)
remove_status_flags(R)
/obj/item/weapon/robot_module/Destroy()
if(R.radio)
R.radio.recalculateChannels()
qdel(src)
/obj/item/weapon/robot_module/Destroy()
qdel(modules)
qdel(synths)
qdel(emag)
@@ -115,23 +119,6 @@ var/global/list/robot_modules = list(
R.camera.remove_networks(added_networks)
added_networks.Cut()
/obj/item/weapon/robot_module/proc/add_radio_channels(var/mob/living/silicon/robot/R)
if(!R.radio)
return
modified_radio = R.radio
modified_key = R.radio.keyslot
original_radio_channels = modified_radio.channels.Copy()
modified_radio.config(channels)
/obj/item/weapon/robot_module/proc/remove_radio_channels(var/mob/living/silicon/robot/R)
// Only reset if the original radio component hasn't been altered/replaced
if(!(R.radio && R.radio == modified_radio && R.radio.keyslot == modified_key))
return
modified_radio.config(original_radio_channels)
original_radio_channels.Cut()
/obj/item/weapon/robot_module/proc/add_subsystems(var/mob/living/silicon/robot/R)
R.verbs |= subsystems
@@ -739,10 +726,3 @@ var/global/list/robot_modules = list(
LR.Charge(R, amount)
..()
return
//checks whether this item is a module of the robot it is located in.
/obj/item/proc/is_robot_module()
if (!istype(src.loc, /mob/living/silicon/robot))
return 0
var/mob/living/silicon/robot/R = src.loc
return (src in R.module.modules)

View File

@@ -1,23 +1,19 @@
/mob/living/silicon
var/register_alarms = 1
var/obj/nano_module/alarm_monitor/alarm_monitor
var/obj/nano_module/alarm_monitor/all/alarm_monitor
var/obj/nano_module/atmos_control/atmos_control
var/obj/nano_module/crew_monitor/crew_monitor
var/obj/nano_module/law_manager/law_manager
var/obj/nano_module/power_monitor/power_monitor
var/obj/nano_module/rcon/rcon
var/alarm_monitor_type = /obj/nano_module/alarm_monitor/borg
/mob/living/silicon
alarm_monitor_type = /obj/nano_module/alarm_monitor/borg
var/list/silicon_subsystems = list(
/mob/living/silicon/proc/subsystem_alarm_monitor,
/mob/living/silicon/proc/subsystem_law_manager
)
/mob/living/silicon/ai
alarm_monitor_type = /obj/nano_module/alarm_monitor/ai
silicon_subsystems = list(
/mob/living/silicon/proc/subsystem_alarm_monitor,
/mob/living/silicon/proc/subsystem_atmos_control,
@@ -32,7 +28,7 @@
silicon_subsystems = list(/mob/living/silicon/proc/subsystem_law_manager)
/mob/living/silicon/proc/init_subsystems()
alarm_monitor = new alarm_monitor_type(src)
alarm_monitor = new(src)
atmos_control = new(src)
crew_monitor = new(src)
law_manager = new(src)

View File

@@ -240,7 +240,7 @@
////////////////Glow//////////////////
/mob/living/simple_animal/construct/proc/add_glow()
overlays = 0
var/overlay_layer = LIGHTING_LAYER+1
var/overlay_layer = 11
if(layer != MOB_LAYER)
overlay_layer=TURF_LAYER+0.2

View File

@@ -94,7 +94,7 @@
emote_hear = list("clicks")
emote_see = list("clacks")
desc = "Free crabs!"
src.sd_SetLuminosity(0)
src.sd_set_light(0)
inventory_head.loc = src.loc
inventory_head = null
else

View File

@@ -277,9 +277,9 @@
qdel(MED)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("<span class='notice>[user] applies the [MED] on [src].</span>")
M.show_message("<span class='notice'>[user] applies the [MED] on [src].</span>")
else
user << "<span class='notice>\The [src] is dead, medical items won't bring it back to life.</span>"
user << "<span class='notice'>\The [src] is dead, medical items won't bring it back to life.</span>"
if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead.
if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch))
harvest(user)
@@ -300,7 +300,7 @@
usr << "<span class='danger>This weapon is ineffective, it does no damage.</span>"
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("<span class='notice>[user] gently taps [src] with the [O].</span>")
M.show_message("<span class='notice'>[user] gently taps [src] with \the [O].</span>")
/mob/living/simple_animal/movement_delay()
var/tally = 0 //Incase I need to add stuff other than "speed" later

View File

@@ -137,10 +137,9 @@
proc/AttemptToEat(var/atom/target)
if(istype(target,/turf/simulated/wall))
if((!istype(target,/turf/simulated/wall/r_wall) && eatingDuration >= 100) || eatingDuration >= 200) //need 20 ticks to eat an rwall, 10 for a regular one
var/turf/simulated/wall/wall = target
wall.ChangeTurf(/turf/simulated/floor)
new /obj/item/stack/sheet/metal(src, flatPlasmaValue)
var/turf/simulated/wall/W = target
if((!W.reinf_material && eatingDuration >= 100) || eatingDuration >= 200) //need 20 ticks to eat an rwall, 10 for a regular one
W.dismantle_wall()
return 1
else if(istype(target,/atom/movable))
if(istype(target,/mob) || eatingDuration >= 50) //5 ticks to eat stuff like airlocks

View File

@@ -3,14 +3,19 @@
/obj/item/weapon/grab
name = "grab"
flags = NOBLUDGEON
icon = 'icons/mob/screen1.dmi'
icon_state = "reinforce"
flags = 0
var/obj/screen/grab/hud = null
var/mob/affecting = null
var/mob/assailant = null
var/mob/living/affecting = null
var/mob/living/carbon/human/assailant = null
var/state = GRAB_PASSIVE
var/allow_upgrade = 1
var/last_upgrade = 0
var/last_action = 0
var/last_hit_zone = 0
var/force_down //determines if the affecting mob will be pinned to the ground
var/dancing //determines if assailant and affecting keep looking at each other. Basically a wrestling position
layer = 21
abstract = 1
@@ -24,7 +29,7 @@
assailant = user
affecting = victim
if(affecting.anchored)
if(affecting.anchored || !assailant.Adjacent(victim))
qdel(src)
return
@@ -32,20 +37,18 @@
hud = new /obj/screen/grab(src)
hud.icon_state = "reinforce"
icon_state = "grabbed"
hud.name = "reinforce grab"
hud.master = src
/obj/item/weapon/grab/Destroy()
//make sure the grabbed_by list doesn't fill up with nulls
if(affecting)
affecting.grabbed_by -= src
affecting = null
if(assailant)
if(assailant.client)
assailant.client.screen -= hud
assailant = null
qdel(hud)
..()
//check if assailant is grabbed by victim as well
if(assailant.grabbed_by)
for (var/obj/item/weapon/grab/G in assailant.grabbed_by)
if(G.assailant == affecting && G.affecting == assailant)
G.dancing = 1
G.adjust_position()
dancing = 1
adjust_position()
//Used by throw code to hand over the mob, instead of throwing the grab. The grab is then deleted by the throw code.
/obj/item/weapon/grab/proc/throw()
@@ -53,6 +56,7 @@
if(affecting.buckled)
return null
if(state >= GRAB_AGGRESSIVE)
animate(affecting, pixel_x = 0, pixel_y = 0, 4, 1)
return affecting
return null
@@ -68,6 +72,9 @@
/obj/item/weapon/grab/process()
confirm()
if(!assailant)
qdel(src)
return
if(assailant.client)
assailant.client.screen -= hud
@@ -87,20 +94,47 @@
var/obj/item/weapon/grab/G = assailant.r_hand
if(G.affecting != affecting)
allow_upgrade = 0
if(state == GRAB_AGGRESSIVE)
affecting.drop_l_hand()
affecting.drop_r_hand()
//disallow upgrading past aggressive if we're being grabbed aggressively
for(var/obj/item/weapon/grab/G in affecting.grabbed_by)
if(G == src) continue
if(G.state >= GRAB_AGGRESSIVE)
allow_upgrade = 0
//disallow upgrading past aggressive if we're being grabbed aggressively
for(var/obj/item/weapon/grab/G in affecting.grabbed_by)
if(G == src) continue
if(G.state >= GRAB_AGGRESSIVE)
allow_upgrade = 0
if(allow_upgrade)
hud.icon_state = "reinforce"
if(state < GRAB_AGGRESSIVE)
hud.icon_state = "reinforce"
else
hud.icon_state = "reinforce1"
else
hud.icon_state = "!reinforce"
else if(!affecting.buckled)
affecting.loc = assailant.loc
if(state >= GRAB_AGGRESSIVE)
affecting.drop_l_hand()
affecting.drop_r_hand()
var/hit_zone = assailant.zone_sel.selecting
var/announce = 0
if(hit_zone != last_hit_zone)
announce = 1
last_hit_zone = hit_zone
if(ishuman(affecting))
switch(hit_zone)
if("mouth")
if(announce)
assailant.visible_message("<span class='warning'>[assailant] covers [affecting]'s mouth!</span>")
if(affecting:silent < 3)
affecting:silent = 3
if("eyes")
if(announce)
assailant.visible_message("<span class='warning'>[assailant] covers [affecting]'s eyes!</span>")
if(affecting:eye_blind < 3)
affecting:eye_blind = 3
if(force_down)
if(affecting.loc != assailant.loc)
force_down = 0
else
affecting.Weaken(2)
if(state >= GRAB_NECK)
affecting.Stun(3)
@@ -112,7 +146,59 @@
//affecting.apply_effect(STUTTER, 5) //would do this, but affecting isn't declared as mob/living for some stupid reason.
affecting.stuttering = max(affecting.stuttering, 5) //It will hamper your voice, being choked and all.
affecting.Weaken(5) //Should keep you down unless you get help.
affecting.losebreath = min(affecting.losebreath + 2, 3)
affecting.losebreath = max(affecting.losebreath + 2, 3)
adjust_position()
/obj/item/weapon/grab/attack_self()
return s_click(hud)
//Updating pixelshift, position and direction
//Gets called on process, when the grab gets upgraded or the assailant moves
/obj/item/weapon/grab/proc/adjust_position()
if(affecting.buckled)
animate(affecting, pixel_x = 0, pixel_y = 0, 4, 1, LINEAR_EASING)
return
if(affecting.lying && state != GRAB_KILL)
animate(affecting, pixel_x = 0, pixel_y = 0, 5, 1, LINEAR_EASING)
if(force_down)
affecting.set_dir(SOUTH) //face up
return
var/shift = 0
var/adir = get_dir(assailant, affecting)
affecting.layer = 4
switch(state)
if(GRAB_PASSIVE)
shift = 8
if(dancing) //look at partner
shift = 10
assailant.set_dir(get_dir(assailant, affecting))
if(GRAB_AGGRESSIVE)
shift = 12
if(GRAB_NECK, GRAB_UPGRADING)
shift = -10
adir = assailant.dir
affecting.set_dir(assailant.dir)
affecting.loc = assailant.loc
if(GRAB_KILL)
shift = 0
adir = 1
affecting.set_dir(SOUTH) //face up
affecting.loc = assailant.loc
switch(adir)
if(NORTH)
animate(affecting, pixel_x = 0, pixel_y =-shift, 5, 1, LINEAR_EASING)
affecting.layer = 3.9
if(SOUTH)
animate(affecting, pixel_x = 0, pixel_y = shift, 5, 1, LINEAR_EASING)
if(WEST)
animate(affecting, pixel_x = shift, pixel_y = 0, 5, 1, LINEAR_EASING)
if(EAST)
animate(affecting, pixel_x =-shift, pixel_y = 0, 5, 1, LINEAR_EASING)
/obj/item/weapon/grab/proc/s_click(obj/screen/S)
@@ -122,20 +208,29 @@
return
if(assailant.next_move > world.time)
return
if(world.time < (last_upgrade + UPGRADE_COOLDOWN))
if(world.time < (last_action + UPGRADE_COOLDOWN))
return
if(!assailant.canmove || assailant.lying)
qdel(src)
return
last_upgrade = world.time
last_action = world.time
if(state < GRAB_AGGRESSIVE)
if(!allow_upgrade)
return
assailant.visible_message("<span class='warning'>[assailant] has grabbed [affecting] aggressively (now hands)!</span>")
if(!affecting.lying)
assailant.visible_message("<span class='warning'>[assailant] has grabbed [affecting] aggressively (now hands)!</span>")
else
assailant.visible_message("<span class='warning'>[assailant] pins [affecting] down to the ground (now hands)!</span>")
force_down = 1
affecting.Weaken(3)
step_to(assailant, affecting)
assailant.set_dir(EAST) //face the victim
affecting.set_dir(SOUTH) //face up
state = GRAB_AGGRESSIVE
icon_state = "grabbed1"
hud.icon_state = "reinforce1"
else if(state < GRAB_NECK)
if(isslime(affecting))
assailant << "<span class='notice'>You squeeze [affecting], but nothing interesting happens.</span>"
@@ -144,38 +239,27 @@
assailant.visible_message("<span class='warning'>[assailant] has reinforced \his grip on [affecting] (now neck)!</span>")
state = GRAB_NECK
icon_state = "grabbed+1"
if(!affecting.buckled)
affecting.loc = assailant.loc
assailant.set_dir(get_dir(assailant, affecting))
affecting.attack_log += "\[[time_stamp()]\] <font color='orange'>Has had their neck grabbed by [assailant.name] ([assailant.ckey])</font>"
assailant.attack_log += "\[[time_stamp()]\] <font color='red'>Grabbed the neck of [affecting.name] ([affecting.ckey])</font>"
msg_admin_attack("[key_name(assailant)] grabbed the neck of [key_name(affecting)]")
hud.icon_state = "disarm/kill"
hud.name = "disarm/kill"
hud.icon_state = "kill"
hud.name = "kill"
affecting.Stun(10) //10 ticks of ensured grab
else if(state < GRAB_UPGRADING)
assailant.visible_message("<span class='danger'>[assailant] starts to tighten \his grip on [affecting]'s neck!</span>")
hud.icon_state = "disarm/kill1"
state = GRAB_UPGRADING
if(do_after(assailant, UPGRADE_KILL_TIMER))
if(state == GRAB_KILL)
return
if(!affecting)
qdel(src)
return
if(!assailant.canmove || assailant.lying)
qdel(src)
return
state = GRAB_KILL
assailant.visible_message("<span class='danger'>[assailant] has tightened \his grip on [affecting]'s neck!</span>")
affecting.attack_log += "\[[time_stamp()]\] <font color='orange'>Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])</font>"
assailant.attack_log += "\[[time_stamp()]\] <font color='red'>Strangled (kill intent) [affecting.name] ([affecting.ckey])</font>"
msg_admin_attack("[key_name(assailant)] strangled (kill intent) [key_name(affecting)]")
hud.icon_state = "kill1"
assailant.next_move = world.time + 10
affecting.losebreath += 1
else
assailant.visible_message("<span class='warning'>[assailant] was unable to tighten \his grip on [affecting]'s neck!</span>")
hud.icon_state = "disarm/kill"
state = GRAB_NECK
state = GRAB_KILL
assailant.visible_message("<span class='danger'>[assailant] has tightened \his grip on [affecting]'s neck!</span>")
affecting.attack_log += "\[[time_stamp()]\] <font color='orange'>Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])</font>"
assailant.attack_log += "\[[time_stamp()]\] <font color='red'>Strangled (kill intent) [affecting.name] ([affecting.ckey])</font>"
msg_admin_attack("[key_name(assailant)] strangled (kill intent) [key_name(affecting)]")
assailant.next_move = world.time + 10
affecting.losebreath += 1
affecting.set_dir(WEST)
adjust_position()
//This is used to make sure the victim hasn't managed to yackety sax away before using the grab.
@@ -192,14 +276,109 @@
return 1
/obj/item/weapon/grab/attack(mob/M, mob/user)
/obj/item/weapon/grab/attack(mob/M, mob/living/user)
if(!affecting)
return
if(M == affecting)
s_click(hud)
if(world.time < (last_action + 20))
return
if(M == affecting)
if(ishuman(M))
last_action = world.time
var/hit_zone = assailant.zone_sel.selecting
flick(hud.icon_state, hud)
switch(assailant.a_intent)
if(I_HELP)
if(force_down)
assailant << "<span class='warning'>You are no longer pinning [affecting] to the ground.</span>"
force_down = 0
return
if(I_GRAB)
if(state < GRAB_AGGRESSIVE)
assailant << "<span class='warning'>You require a better grab to do this.</span>"
return
var/obj/item/organ/external/organ = affecting:get_organ(check_zone(hit_zone))
if(!organ || organ.dislocated == -1)
return
assailant.visible_message("<span class='danger'>[assailant] [pick("bent", "twisted")] [affecting]'s [organ.name] into a jointlock!</span>")
var/armor = affecting:run_armor_check(affecting, "melee")
if(armor < 2)
affecting << "<span class='danger'>You feel extreme pain!</span>"
affecting.adjustHalLoss(Clamp(0, 40-affecting.halloss, 40)) //up to 40 halloss
return
if(I_HURT)
if(hit_zone == "eyes")
if(state < GRAB_NECK)
assailant << "<span class='warning'>You require a better grab to do this.</span>"
return
if((affecting:head && affecting:head.flags & HEADCOVERSEYES) || \
(affecting:wear_mask && affecting:wear_mask.flags & MASKCOVERSEYES) || \
(affecting:glasses && affecting:glasses.flags & GLASSESCOVERSEYES))
assailant << "<span class='danger'>You're going to need to remove the eye covering first.</span>"
return
if(!affecting.has_eyes())
assailant << "<span class='danger'>You cannot locate any eyes on [affecting]!</span>"
return
assailant.visible_message("<span class='danger'>[assailant] pressed \his fingers into [affecting]'s eyes!</span>")
affecting << "<span class='danger'>You experience immense pain as you feel digits being pressed into your eyes!</span>"
assailant.attack_log += text("\[[time_stamp()]\] <font color='red'>Pressed fingers into the eyes of [affecting.name] ([affecting.ckey])</font>")
affecting.attack_log += text("\[[time_stamp()]\] <font color='orange'>Had fingers pressed into their eyes by [assailant.name] ([assailant.ckey])</font>")
msg_admin_attack("[key_name(assailant)] has pressed his fingers into [key_name(affecting)]'s eyes.")
var/obj/item/organ/eyes/eyes = affecting:internal_organs_by_name["eyes"]
eyes.damage += rand(3,4)
if (eyes.damage >= eyes.min_broken_damage)
if(affecting.stat != 2)
affecting << "\red You go blind!"
else if(hit_zone != "head")
if(state < GRAB_NECK)
assailant << "<span class='warning'>You require a better grab to do this.</span>"
return
if(affecting:grab_joint(assailant))
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
else
if(affecting.lying)
return
assailant.visible_message("<span class='danger'>[assailant] thrusts \his head into [affecting]'s skull!</span>")
var/damage = 20
var/obj/item/clothing/hat = assailant.head
if(istype(hat))
damage += hat.force * 10
var/armor = affecting:run_armor_check(affecting, "melee")
affecting.apply_damage(damage*rand(90, 110)/100, BRUTE, "head", armor)
assailant.apply_damage(10*rand(90, 110)/100, BRUTE, "head", assailant:run_armor_check("head", "melee"))
if(!armor && prob(damage))
affecting.apply_effect(20, PARALYZE)
affecting.visible_message("<span class='danger'>[affecting] has been knocked unconscious!</span>")
playsound(assailant.loc, "swing_hit", 25, 1, -1)
assailant.attack_log += text("\[[time_stamp()]\] <font color='red'>Headbutted [affecting.name] ([affecting.ckey])</font>")
affecting.attack_log += text("\[[time_stamp()]\] <font color='orange'>Headbutted by [assailant.name] ([assailant.ckey])</font>")
msg_admin_attack("[key_name(assailant)] has headbutted [key_name(affecting)]")
assailant.drop_from_inventory(src)
src.loc = null
qdel(src)
return
if(I_DISARM)
if(state < GRAB_AGGRESSIVE)
assailant << "<span class='warning'>You require a better grab to do this.</span>"
return
assailant << "<span class='warning'>You start forcing [affecting] to the ground.</span>"
if(!force_down)
if(do_after(assailant, 20) && affecting)
assailant.visible_message("<span class='danger'>[assailant] is forcing [affecting] to the ground!</span>")
force_down = 1
affecting.Weaken(3)
affecting.lying = 1
step_to(assailant, affecting)
assailant.set_dir(EAST) //face the victim
affecting.set_dir(SOUTH) //face up
return
else
assailant << "<span class='warning'>You are already pinning [affecting] to the ground.</span>"
return
if(M == assailant && state >= GRAB_AGGRESSIVE)
var/can_eat
@@ -227,8 +406,19 @@
/obj/item/weapon/grab/dropped()
loc = null
qdel(src)
/obj/item/weapon/grab/Destroy()
animate(affecting, pixel_x = 0, pixel_y = 0, 4, 1, LINEAR_EASING)
affecting.layer = 4
if(affecting)
affecting.grabbed_by -= src
affecting = null
if(assailant)
if(assailant.client)
assailant.client.screen -= hud
assailant = null
qdel(hud)
..()
hud = null
..()

View File

@@ -82,6 +82,7 @@
/mob/living/silicon/isSilicon()
return 1
/proc/isAI(A)
if(istype(A, /mob/living/silicon/ai))
return 1
@@ -93,10 +94,10 @@
/mob/living/silicon/ai/isAI()
return 1
/mob/proc/isRobot()
/mob/proc/isMobAI()
return 0
/mob/living/silicon/robot/isRobot()
/mob/living/silicon/ai/isMobAI()
return 1
/mob/proc/isSynthetic()
@@ -619,3 +620,61 @@ proc/is_blind(A)
// Returns true if the mob has a client which has been active in the last given X minutes.
/mob/proc/is_client_active(var/active = 1)
return client && client.inactivity < active MINUTES
#define SAFE_PERP -50
/mob/living/proc/assess_perp(var/auth_weapons, var/check_records, var/check_arrest)
if(stat == DEAD)
return SAFE_PERP
return 0
/mob/living/carbon/human/assess_perp(var/obj/access_obj, var/auth_weapons, var/check_records, var/check_arrest)
var/threatcount = ..()
if(. == SAFE_PERP)
return SAFE_PERP
//Agent cards lower threatlevel.
var/obj/item/weapon/card/id/id = GetIdCard(src)
if(id && istype(id, /obj/item/weapon/card/id/syndicate))
threatcount -= 2
// A proper CentCom id is hard currency.
else if(id && istype(id, /obj/item/weapon/card/id/centcom))
return SAFE_PERP
if(auth_weapons && !access_obj.allowed(src))
if(istype(l_hand, /obj/item/weapon/gun) || istype(l_hand, /obj/item/weapon/melee))
threatcount += 4
if(istype(r_hand, /obj/item/weapon/gun) || istype(r_hand, /obj/item/weapon/melee))
threatcount += 4
if(istype(belt, /obj/item/weapon/gun) || istype(belt, /obj/item/weapon/melee))
threatcount += 2
if(species.name != "Human")
threatcount += 2
if(check_records || check_arrest)
var/perpname = name
if(id)
perpname = id.registered_name
var/datum/data/record/R = find_security_record("name", perpname)
if(check_records && !R)
threatcount += 4
if(check_arrest && R && (R.fields["criminal"] == "*Arrest*"))
threatcount += 4
return threatcount
/mob/living/simple_animal/hostile/assess_perp(var/obj/access_obj, var/auth_weapons, var/check_records, var/check_arrest)
var/threatcount = ..()
if(. == SAFE_PERP)
return SAFE_PERP
if(!istype(src, /mob/living/simple_animal/hostile/retaliate/goat))
threatcount += 4
return threatcount
#undef SAFE_PERP

View File

@@ -343,6 +343,13 @@
else
. = mob.SelfMove(n, direct)
for (var/obj/item/weapon/grab/G in mob)
if (G.state == GRAB_NECK)
mob.set_dir(reverse_dir[direct])
G.adjust_position()
for (var/obj/item/weapon/grab/G in mob.grabbed_by)
G.adjust_position()
moving = 0
return .
@@ -360,7 +367,7 @@
for(var/obj/item/weapon/grab/G in list(mob.l_hand, mob.r_hand))
if(G.state == GRAB_KILL) //no wandering across the station/asteroid while choking someone
mob.visible_message("<span class='warning'>[mob] lost \his tight grip on [G.affecting]'s neck!</span>")
G.hud.icon_state = "disarm/kill"
G.hud.icon_state = "kill"
G.state = GRAB_NECK
///Process_Incorpmove

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