diff --git a/code/ATMOSPHERICS/components/unary/cold_sink.dm b/code/ATMOSPHERICS/components/unary/cold_sink.dm index faefa64883..d0280d3044 100644 --- a/code/ATMOSPHERICS/components/unary/cold_sink.dm +++ b/code/ATMOSPHERICS/components/unary/cold_sink.dm @@ -162,7 +162,7 @@ if(istype(P, /obj/item/weapon/stock_parts/matter_bin)) bin_rating += P.rating - power_rating = initial(power_rating) * cap_rating / 2 //more powerful + max_power_rating = initial(max_power_rating) * cap_rating / 2 //more powerful heatsink_temperature = initial(heatsink_temperature) / ((manip_rating + bin_rating) / 2) //more efficient air_contents.volume = max(initial(internal_volume) - 200, 0) + 200 * bin_rating set_power_level(power_setting) diff --git a/code/__defines/gamemode.dm b/code/__defines/gamemode.dm index 0be497843b..896553e809 100644 --- a/code/__defines/gamemode.dm +++ b/code/__defines/gamemode.dm @@ -63,6 +63,7 @@ var/list/be_special_flags = list( // Mode/antag template macros. #define MODE_BORER "borer" +#define MODE_XENOMORPH "xeno" #define MODE_LOYALIST "loyalist" #define MODE_MUTINEER "mutineer" #define MODE_COMMANDO "commando" diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index c2d04d9c93..fef25b9d10 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -35,42 +35,24 @@ datum/controller/game_controller/New() if(!syndicate_code_response) syndicate_code_response = generate_code_phrase() datum/controller/game_controller/proc/setup() - spawn(20) - createRandomZlevel() setup_objects() setupgenetics() SetupXenoarch() transfer_controller = new + admin_notice("Initializations complete.", R_DEBUG) +#if UNIT_TEST +#define CHECK_SLEEP_MASTER // For unit tests we don't care about a smooth lobby screen experience. We care about speed. +#else +#define CHECK_SLEEP_MASTER if(++initialized_objects > 500) { initialized_objects=0;sleep(world.tick_lag); } +#endif datum/controller/game_controller/proc/setup_objects() - admin_notice("Initializing objects", R_DEBUG) - sleep(-1) - for(var/atom/movable/object in world) - if(!QDELETED(object)) - object.initialize() - - admin_notice("Initializing areas", R_DEBUG) - sleep(-1) - for(var/area/area in all_areas) - area.initialize() - - admin_notice("Initializing pipe networks", R_DEBUG) - sleep(-1) - for(var/obj/machinery/atmospherics/machine in machines) - machine.build_network() - - admin_notice("Initializing atmos machinery.", R_DEBUG) - sleep(-1) - for(var/obj/machinery/atmospherics/unary/U in machines) - if(istype(U, /obj/machinery/atmospherics/unary/vent_pump)) - var/obj/machinery/atmospherics/unary/vent_pump/T = U - T.broadcast_status() - else if(istype(U, /obj/machinery/atmospherics/unary/vent_scrubber)) - var/obj/machinery/atmospherics/unary/vent_scrubber/T = U - T.broadcast_status() + #if !UNIT_TEST + var/initialized_objects = 0 + #endif // Set up antagonists. populate_antag_type_list() @@ -78,12 +60,50 @@ datum/controller/game_controller/proc/setup_objects() //Set up spawn points. populate_spawn_points() + admin_notice("Initializing Floor Decals", R_DEBUG) + var/list/turfs_with_decals = list() + for(var/obj/effect/floor_decal/D in world) + var/T = D.add_to_turf_decals() + if(T) turfs_with_decals |= T + CHECK_SLEEP_MASTER + for(var/item in turfs_with_decals) + var/turf/T = item + if(T.decals) T.apply_decals() + CHECK_SLEEP_MASTER + floor_decals_initialized = TRUE + sleep(1) + + admin_notice("Initializing objects", R_DEBUG) + for(var/atom/movable/object in world) + if(!QDELETED(object)) + object.initialize() + CHECK_SLEEP_MASTER + sleep(1) + + admin_notice("Initializing areas", R_DEBUG) + for(var/area/area in all_areas) + area.initialize() + CHECK_SLEEP_MASTER + sleep(1) + + admin_notice("Initializing pipe networks", R_DEBUG) + for(var/obj/machinery/atmospherics/machine in machines) + machine.build_network() + CHECK_SLEEP_MASTER + + admin_notice("Initializing atmos machinery.", R_DEBUG) + for(var/obj/machinery/atmospherics/unary/U in machines) + if(istype(U, /obj/machinery/atmospherics/unary/vent_pump)) + var/obj/machinery/atmospherics/unary/vent_pump/T = U + T.broadcast_status() + else if(istype(U, /obj/machinery/atmospherics/unary/vent_scrubber)) + var/obj/machinery/atmospherics/unary/vent_scrubber/T = U + T.broadcast_status() + CHECK_SLEEP_MASTER + admin_notice("Initializing turbolifts", R_DEBUG) for(var/thing in turbolifts) var/obj/turbolift_map_holder/lift = thing if(!QDELETED(lift)) lift.initialize() - sleep(-1) - - admin_notice("Initializations complete.", R_DEBUG) - sleep(-1) + CHECK_SLEEP_MASTER diff --git a/code/controllers/shuttle_controller.dm b/code/controllers/shuttle_controller.dm index d881a65a4a..5183304609 100644 --- a/code/controllers/shuttle_controller.dm +++ b/code/controllers/shuttle_controller.dm @@ -9,7 +9,7 @@ var/global/datum/shuttle_controller/shuttle_controller /datum/shuttle_controller/proc/process() //process ferry shuttles for (var/datum/shuttle/ferry/shuttle in process_shuttles) - if (shuttle.process_state) + if (shuttle.process_state || shuttle.always_process) shuttle.process() diff --git a/code/datums/autolathe/arms.dm b/code/datums/autolathe/arms.dm index 7e336cf64d..a79bf09d95 100644 --- a/code/datums/autolathe/arms.dm +++ b/code/datums/autolathe/arms.dm @@ -258,7 +258,7 @@ /datum/category_item/autolathe/arms/rifle_SVD name = "10rnd rifle magazine (7.62mm)" - path =/obj/item/ammo_magazine/SVD/empty + path =/obj/item/ammo_magazine/m762svd/empty category = "Arms and Ammunition" hidden = 1 diff --git a/code/datums/supplypacks/engineering.dm b/code/datums/supplypacks/engineering.dm index ad251c5f7e..bd16322e20 100644 --- a/code/datums/supplypacks/engineering.dm +++ b/code/datums/supplypacks/engineering.dm @@ -152,7 +152,7 @@ /datum/supply_packs/eng/teg contains = list(/obj/machinery/power/generator) name = "Mark I Thermoelectric Generator" - cost = 50 + cost = 40 containertype = /obj/structure/closet/crate/secure/large containername = "Mk1 TEG crate" access = access_engine @@ -160,7 +160,7 @@ /datum/supply_packs/eng/circulator contains = list(/obj/machinery/atmospherics/binary/circulator) name = "Binary atmospheric circulator" - cost = 50 + cost = 20 containertype = /obj/structure/closet/crate/secure/large containername = "Atmospheric circulator crate" access = access_engine diff --git a/code/datums/supplypacks/robotics.dm b/code/datums/supplypacks/robotics.dm index 5510bae9ce..9e3234cca6 100644 --- a/code/datums/supplypacks/robotics.dm +++ b/code/datums/supplypacks/robotics.dm @@ -68,6 +68,14 @@ containername = "Robolimb blueprints (Xion)" access = access_robotics +/datum/supply_packs/robotics/robolimbs/grayson + name = "Grayson robolimb blueprints" + contains = list(/obj/item/weapon/disk/limb/grayson) + cost = 30 + containertype = /obj/structure/closet/crate/secure/science + containername = "Robolimb blueprints (Grayson)" + access = access_robotics + /datum/supply_packs/robotics/robolimbs/hephaestus name = "Hephaestus robolimb blueprints" contains = list(/obj/item/weapon/disk/limb/hephaestus) diff --git a/code/datums/underwear/undershirts.dm b/code/datums/underwear/undershirts.dm index 59f33be094..1bbbae7fb5 100644 --- a/code/datums/underwear/undershirts.dm +++ b/code/datums/underwear/undershirts.dm @@ -161,4 +161,8 @@ /datum/category_item/underwear/undershirt/longstripe_blue name = "Longsleeve Striped Shirt, Blue" - icon_state = "longstripe_blue" \ No newline at end of file + icon_state = "longstripe_blue" + +/datum/category_item/underwear/undershirt/tiedye + name = "Tiedye Shirt" + icon_state = "tiedye" \ No newline at end of file diff --git a/code/datums/uplink/visible_weapons.dm b/code/datums/uplink/visible_weapons.dm index ba9ce3660a..f7d79c5b6a 100644 --- a/code/datums/uplink/visible_weapons.dm +++ b/code/datums/uplink/visible_weapons.dm @@ -110,7 +110,7 @@ desc = "A convenient collapsible rifle for covert assassination. Comes with 4 shots and its own secure carrying case." item_cost = DEFAULT_TELECRYSTAL_AMOUNT path = /obj/item/weapon/storage/secure/briefcase/rifle - antag_roles = list("traitor") + antag_roles = list("traitor", "autotraitor", "infiltrator") /datum/uplink_item/item/visible_weapons/tommygun name = "Tommygun (.45)" // We're keeping this because it's CLASSY. -Spades diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 12a05e6d3a..8bfe71121d 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -388,6 +388,10 @@ var/obj/machinery/machine +/obj/item/weapon/pai_cable/Destroy() + machine = null + return ..() + ///////////////////////////////////////Stock Parts ///////////////////////////////// /obj/item/weapon/storage/part_replacer diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm index fbc3624b7d..5c44353540 100644 --- a/code/defines/procs/announce.dm +++ b/code/defines/procs/announce.dm @@ -130,5 +130,5 @@ datum/announcement/proc/Log(message as text, message_title as text) rank = character.mind.role_alt_title AnnounceArrivalSimple(character.real_name, rank, join_message) -/proc/AnnounceArrivalSimple(var/name, var/rank = "visitor", var/join_message = "has arrived on the station") +/proc/AnnounceArrivalSimple(var/name, var/rank = "visitor", var/join_message = "will arrive to the station shortly by shuttle") global_announcer.autosay("[name], [rank], [join_message].", "Arrivals Announcement Computer") diff --git a/code/game/antagonist/alien/xenomorph.dm b/code/game/antagonist/alien/xenomorph.dm new file mode 100644 index 0000000000..e69db8aee7 --- /dev/null +++ b/code/game/antagonist/alien/xenomorph.dm @@ -0,0 +1,47 @@ +var/datum/antagonist/xenos/xenomorphs + +/datum/antagonist/xenos + id = MODE_XENOMORPH + role_type = BE_ALIEN + role_text = "Xenomorph" + role_text_plural = "Xenomorphs" + mob_path = /mob/living/carbon/alien/larva + bantype = "Xenomorph" + flags = ANTAG_OVERRIDE_MOB | ANTAG_RANDSPAWN | ANTAG_OVERRIDE_JOB | ANTAG_VOTABLE + welcome_text = "Hiss! You are a larval alien. Hide and bide your time until you are ready to evolve." + antaghud_indicator = "hudalien" + + hard_cap = 5 + hard_cap_round = 8 + initial_spawn_req = 4 + initial_spawn_target = 6 + + spawn_announcement = "Unidentified lifesigns detected coming aboard the station. Secure any exterior access, including ducting and ventilation." + spawn_announcement_title = "Lifesign Alert" + spawn_announcement_sound = 'sound/AI/aliens.ogg' + spawn_announcement_delay = 5000 + +/datum/antagonist/xenos/New(var/no_reference) + ..() + if(!no_reference) + xenomorphs = src + +/datum/antagonist/xenos/attempt_random_spawn() + if(config.aliens_allowed) ..() + +/datum/antagonist/xenos/proc/get_vents() + var/list/vents = list() + for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines) + if(!temp_vent.welded && temp_vent.network && temp_vent.loc.z in using_map.station_levels) + if(temp_vent.network.normal_members.len > 50) + vents += temp_vent + return vents + +/datum/antagonist/xenos/create_objectives(var/datum/mind/player) + if(!..()) + return + player.objectives += new /datum/objective/survive() + player.objectives += new /datum/objective/escape() + +/datum/antagonist/xenos/place_mob(var/mob/living/player) + player.forceMove(get_turf(pick(get_vents()))) diff --git a/code/game/antagonist/outsider/raider.dm b/code/game/antagonist/outsider/raider.dm index 7ac0a4729b..596ac1451e 100644 --- a/code/game/antagonist/outsider/raider.dm +++ b/code/game/antagonist/outsider/raider.dm @@ -80,7 +80,7 @@ var/datum/antagonist/raider/raiders /obj/item/weapon/gun/projectile/automatic/c20r, /obj/item/weapon/gun/projectile/automatic/wt550, /obj/item/weapon/gun/projectile/automatic/sts35, - /obj/item/weapon/gun/projectile/automatic/carbine, + /obj/item/weapon/gun/projectile/automatic/bullpup, /obj/item/weapon/gun/projectile/automatic/tommygun, /obj/item/weapon/gun/projectile/silenced, /obj/item/weapon/gun/projectile/shotgun/pump, diff --git a/code/game/antagonist/station/renegade.dm b/code/game/antagonist/station/renegade.dm index d9e3671546..d9796432c0 100644 --- a/code/game/antagonist/station/renegade.dm +++ b/code/game/antagonist/station/renegade.dm @@ -37,7 +37,7 @@ var/datum/antagonist/renegade/renegades /obj/item/weapon/gun/projectile/automatic/mini_uzi, /obj/item/weapon/gun/projectile/automatic/c20r, /obj/item/weapon/gun/projectile/automatic/sts35, - /obj/item/weapon/gun/projectile/automatic/carbine, + /obj/item/weapon/gun/projectile/automatic/bullpup, /obj/item/weapon/gun/projectile/automatic/wt550, /obj/item/weapon/gun/projectile/automatic/z8, /obj/item/weapon/gun/projectile/automatic/tommygun, diff --git a/code/game/gamemodes/technomancer/assistance/assistance.dm b/code/game/gamemodes/technomancer/assistance/assistance.dm index 8b060429e8..61c1390cc3 100644 --- a/code/game/gamemodes/technomancer/assistance/assistance.dm +++ b/code/game/gamemodes/technomancer/assistance/assistance.dm @@ -36,7 +36,7 @@ /obj/item/weapon/antag_spawner/technomancer_apprentice/Destroy() qdel(sparks) - ..() + return ..() /obj/item/weapon/antag_spawner/technomancer_apprentice/attack_self(mob/user) user << "Teleporter attempting to lock on to your apprentice." diff --git a/code/game/gamemodes/technomancer/assistance/golem.dm b/code/game/gamemodes/technomancer/assistance/golem.dm index e0a0a5fd71..3bd54ed1f5 100644 --- a/code/game/gamemodes/technomancer/assistance/golem.dm +++ b/code/game/gamemodes/technomancer/assistance/golem.dm @@ -60,7 +60,7 @@ /mob/living/simple_animal/technomancer_golem/Destroy() qdel(core) - ..() + return ..() /mob/living/simple_animal/technomancer_golem/update_icon() overlays.Cut() diff --git a/code/game/gamemodes/technomancer/core_obj.dm b/code/game/gamemodes/technomancer/core_obj.dm index 7cea66660e..d672115ff6 100644 --- a/code/game/gamemodes/technomancer/core_obj.dm +++ b/code/game/gamemodes/technomancer/core_obj.dm @@ -43,7 +43,7 @@ /obj/item/weapon/technomancer_core/Destroy() dismiss_all_summons() processing_objects.Remove(src) - ..() + return ..() // Add the spell buttons to the HUD. /obj/item/weapon/technomancer_core/equipped(mob/user) diff --git a/code/game/gamemodes/technomancer/devices/gloves_of_regen.dm b/code/game/gamemodes/technomancer/devices/gloves_of_regen.dm index a4761c847a..630a9bdb10 100644 --- a/code/game/gamemodes/technomancer/devices/gloves_of_regen.dm +++ b/code/game/gamemodes/technomancer/devices/gloves_of_regen.dm @@ -44,7 +44,7 @@ /obj/item/clothing/gloves/regen/Destroy() wearer = null processing_objects -= src - ..() + return ..() /obj/item/clothing/gloves/regen/process() if(!wearer || wearer.isSynthetic() || wearer.stat == DEAD || wearer.nutrition <= 10) diff --git a/code/game/gamemodes/technomancer/devices/shield_armor.dm b/code/game/gamemodes/technomancer/devices/shield_armor.dm index 0bbb6ef085..e36ce7bd3a 100644 --- a/code/game/gamemodes/technomancer/devices/shield_armor.dm +++ b/code/game/gamemodes/technomancer/devices/shield_armor.dm @@ -31,7 +31,7 @@ /obj/item/clothing/suit/armor/shield/Destroy() qdel(spark_system) - ..() + return ..() /obj/item/clothing/suit/armor/shield/handle_shield(mob/user, var/damage, atom/damage_source = null, mob/attacker = null, var/def_zone = null, var/attack_text = "the attack") //Since this is a pierce of armor that is passive, we do not need to check if the user is incapacitated. diff --git a/code/game/gamemodes/technomancer/spell_objs.dm b/code/game/gamemodes/technomancer/spell_objs.dm index 2dede11a94..5ba100a4b4 100644 --- a/code/game/gamemodes/technomancer/spell_objs.dm +++ b/code/game/gamemodes/technomancer/spell_objs.dm @@ -151,7 +151,7 @@ /obj/item/weapon/spell/Destroy() owner = null core = null - ..() + return ..() // Proc: update_icon() // Parameters: 0 diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 297040931f..082ab9240d 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -458,13 +458,18 @@ var/global/datum/controller/occupations/job_master if(istype(H)) //give humans wheelchairs, if they need them. var/obj/item/organ/external/l_foot = H.get_organ("l_foot") var/obj/item/organ/external/r_foot = H.get_organ("r_foot") - if(!l_foot || !r_foot) + var/obj/item/weapon/storage/S = locate() in H.contents + var/obj/item/wheelchair/R = locate() in S.contents + if(!l_foot || !r_foot || R) var/obj/structure/bed/chair/wheelchair/W = new /obj/structure/bed/chair/wheelchair(H.loc) H.buckled = W H.update_canmove() W.set_dir(H.dir) W.buckled_mob = H W.add_fingerprint(H) + if(R) + W.color = R.color + qdel(R) H << "You are [job.total_positions == 1 ? "the" : "a"] [alt_title ? alt_title : rank]." @@ -615,12 +620,12 @@ var/global/datum/controller/occupations/job_master if(spawnpos && istype(spawnpos) && spawnpos.turfs.len) // VOREStation Edit - Fix runtime if no landmarks exist for a spawntype if(spawnpos.check_job_spawning(rank)) - H.forceMove(pick(spawnpos.turfs)) + H.forceMove(spawnpos.get_spawn_position()) . = spawnpos.msg else H << "Your chosen spawnpoint ([spawnpos.display_name]) is unavailable for your chosen job. Spawning you at the Arrivals shuttle instead." H.forceMove(pick(latejoin)) - . = "has arrived on the station" + . = "will arrive to the station shortly by shuttle" else H.forceMove(pick(latejoin)) . = "has arrived on the station" diff --git a/code/game/machinery/biogenerator.dm b/code/game/machinery/biogenerator.dm index 07f0b8f9bd..b467a3a375 100644 --- a/code/game/machinery/biogenerator.dm +++ b/code/game/machinery/biogenerator.dm @@ -115,6 +115,13 @@ dat += "Utility belt ([round(300/build_eff)])
" dat += "Leather Satchel ([round(400/build_eff)])
" dat += "Cash Bag ([round(400/build_eff)])
" + dat += "Workboots ([round(400/build_eff)])
" + dat += "Leather Shoes ([round(400/build_eff)])
" + + dat += "Leather Chaps ([round(400/build_eff)])
" + dat += "Leather Coat ([round(500/build_eff)])
" + dat += "Leather Jacket ([round(500/build_eff)])
" + dat += "Winter Coat ([round(500/build_eff)])
" //dat += "Other
" //dat += "Monkey (500)
" else @@ -214,6 +221,18 @@ new/obj/item/weapon/storage/bag/cash(loc) if("monkey") new/mob/living/carbon/human/monkey(loc) + if("workboots") + new/obj/item/clothing/shoes/boots/workboots(loc) + if("leathershoes") + new/obj/item/clothing/shoes/leather(loc) + if("leatherchaps") + new/obj/item/clothing/under/pants/chaps + if("leathercoat") + new/obj/item/clothing/suit/leathercoat(loc) + if("leatherjacket") + new/obj/item/clothing/suit/storage/toggle/brown_jacket(loc) + if("wintercoat") + new/obj/item/clothing/suit/storage/hooded/wintercoat(loc) processing = 0 menustat = "complete" update_icon() diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 3282430c82..dc67821301 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -59,7 +59,7 @@ if(!istype(id_card)) return ..() - if(!scan && (access_change_ids in id_card.access) && user.unEquip(id_card)) + if(!scan && (access_change_ids in id_card.access) && (user.unEquip(id_card) || (id_card.loc == user && istype(user,/mob/living/silicon/robot)))) //Grippers. Again. ~Mechoid user.drop_item() id_card.forceMove(src) scan = id_card diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index 5cdbdeab9c..a75b494cea 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -99,5 +99,14 @@ if(computer_deconstruction_screwdriver(user, I)) return else + if(istype(I,/obj/item/weapon/gripper)) //Behold, Grippers and their horribleness. If ..() is called by any computers' attackby() now or in the future, this should let grippers work with them appropriately. + var/obj/item/weapon/gripper/B = I //B, for Borg. + if(!B.wrapped) + user << "\The [B] is not holding anything." + return + else + var/B_held = B.wrapped + user << "You use \the [B] to use \the [B_held] with \the [src]." + return attack_hand(user) return \ No newline at end of file diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 3ef7fe00a7..e02309abd4 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -430,6 +430,10 @@ else W.forceMove(src.loc) + for(var/obj/structure/B in items) + if(istype(B,/obj/structure/bed)) + qdel(B) + //Update any existing objectives involving this mob. for(var/datum/objective/O in all_objectives) // We don't want revs to get objectives that aren't for heads of staff. Letting @@ -521,6 +525,9 @@ for(var/obj/item/W in items) W.forceMove(get_turf(src)) + for(var/obj/structure/bed/S in src.contents) + S.forceMove(get_turf(src)) + go_out() add_fingerprint(usr) @@ -563,6 +570,8 @@ if(ishuman(usr) && applies_stasis) var/mob/living/carbon/human/H = occupant H.Stasis(1000) + if(usr.buckled && istype(usr.buckled, /obj/structure/bed/chair/wheelchair)) + usr.buckled.loc = usr.loc icon_state = occupied_icon_state @@ -660,6 +669,8 @@ if(ishuman(M) && applies_stasis) var/mob/living/carbon/human/H = M H.Stasis(1000) + if(M.buckled && istype(M.buckled, /obj/structure/bed/chair/wheelchair)) + M.buckled.loc = M.loc // Book keeping! var/turf/location = get_turf(src) @@ -667,4 +678,4 @@ message_admins("[key_name_admin(M)] has entered a stasis pod.") //Despawning occurs when process() is called with an occupant without a client. - add_fingerprint(M) \ No newline at end of file + add_fingerprint(M) diff --git a/code/game/machinery/kitchen/cooking_machines/_cooker.dm b/code/game/machinery/kitchen/cooking_machines/_cooker.dm index 552e05d95a..26b21c9a13 100644 --- a/code/game/machinery/kitchen/cooking_machines/_cooker.dm +++ b/code/game/machinery/kitchen/cooking_machines/_cooker.dm @@ -76,10 +76,21 @@ else if(istype(check, /obj/item/weapon/disk/nuclear)) user << "Central Command would kill you if you [cook_type] that." return 0 - else if(!istype(check) && !istype(check, /obj/item/weapon/holder) && !istype(check, /obj/item/organ)) - user << "That's not edible." - return 0 - + else if(!istype(check) && !istype(check, /obj/item/weapon/holder) && !istype(check, /obj/item/organ)) //Gripper check has to go here, else it still just cuts it off. ~Mechoid + // Is it a borg using a gripper? + if(istype(check, /obj/item/weapon/gripper)) // Grippers. ~Mechoid. + var/obj/item/weapon/gripper/B = check //B, for Borg. + if(!B.wrapped) + user << "\The [B] is not holding anything." + return 0 + else + var/B_held = B.wrapped + user << "You use \the [B] to put \the [B_held] into \the [src]." + return 0 + else + user << "That's not edible." + return 0 + if(istype(I, /obj/item/organ)) var/obj/item/organ/O = I if(O.robotic) @@ -91,8 +102,8 @@ for(var/mob/living/M in cooking_obj.contents) M.apply_damage(rand(30,40), BURN, "chest") - // Not sure why a food item that passed the previous checks would fail to drop, but safety first. - if(!user.unEquip(I)) + // Not sure why a food item that passed the previous checks would fail to drop, but safety first. (Hint: Borg grippers. That is why. ~Mechoid.) + if(!user.unEquip(I) && !istype(user,/mob/living/silicon/robot)) return // We can actually start cooking now. @@ -134,7 +145,7 @@ // Copy reagents over. trans_to_obj must be used, as trans_to fails for snacks due to is_open_container() failing. if(cooking_obj.reagents && cooking_obj.reagents.total_volume) cooking_obj.reagents.trans_to_obj(result, cooking_obj.reagents.total_volume) - + // Set cooked data. var/obj/item/weapon/reagent_containers/food/snacks/food_item = cooking_obj if(istype(food_item) && islist(food_item.cooked)) @@ -183,7 +194,7 @@ /obj/machinery/cooker/attack_hand(var/mob/user) - if(cooking_obj) + if(cooking_obj && user.Adjacent(src)) //Fixes borgs being able to teleport food in these machines to themselves. user << "You grab \the [cooking_obj] from \the [src]." user.put_in_hands(cooking_obj) cooking = 0 diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm index 9732b166f0..86b481b31b 100644 --- a/code/game/machinery/kitchen/smartfridge.dm +++ b/code/game/machinery/kitchen/smartfridge.dm @@ -244,6 +244,16 @@ if(P.contents.len > 0) user << "Some items are refused." + else if(istype(O, /obj/item/weapon/gripper)) // Grippers. ~Mechoid. + var/obj/item/weapon/gripper/B = O //B, for Borg. + if(!B.wrapped) + user << "\The [B] is not holding anything." + return + else + var/B_held = B.wrapped + user << "You use \the [B] to put \the [B_held] into \the [src]." + return + else user << "\The [src] smartly refuses [O]." return 1 diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 096bd090c1..8eba407e72 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -525,7 +525,7 @@ var/list/turret_icons if(isanimal(L) || issmall(L)) // Animals are not so dangerous return check_anomalies ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET - if(isalien(L)) // Xenos are dangerous + if(isxenomorph(L) || isalien(L)) // Xenos are dangerous return check_anomalies ? TURRET_PRIORITY_TARGET : TURRET_NOT_TARGET if(ishuman(L)) //if the target is a human, analyze threat level diff --git a/code/game/objects/effects/alien/aliens.dm b/code/game/objects/effects/alien/aliens.dm new file mode 100644 index 0000000000..3d9713cd29 --- /dev/null +++ b/code/game/objects/effects/alien/aliens.dm @@ -0,0 +1,443 @@ +/* Alien Effects! + * Contains: + * effect/alien + * Resin + * Weeds + * Acid + * Egg + */ + +/* + * effect/alien + */ +/obj/effect/alien + name = "alien thing" + desc = "theres something alien about this" + icon = 'icons/mob/alien.dmi' + +/* + * Resin + */ +/obj/effect/alien/resin + name = "resin" + desc = "Looks like some kind of slimy growth." + icon_state = "resin" + + density = 1 + opacity = 1 + anchored = 1 + var/health = 200 + //var/mob/living/affecting = null + +/obj/effect/alien/resin/wall + name = "resin wall" + desc = "Purple slime solidified into a wall." + icon_state = "resinwall" //same as resin, but consistency ho! + +/obj/effect/alien/resin/membrane + name = "resin membrane" + desc = "Purple slime just thin enough to let light pass through." + icon_state = "resinmembrane" + opacity = 0 + health = 120 + +/obj/effect/alien/resin/New() + ..() + var/turf/T = get_turf(src) + T.thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT + +/obj/effect/alien/resin/Destroy() + var/turf/T = get_turf(src) + T.thermal_conductivity = initial(T.thermal_conductivity) + ..() + +/obj/effect/alien/resin/proc/healthcheck() + if(health <=0) + density = 0 + qdel(src) + return + +/obj/effect/alien/resin/bullet_act(var/obj/item/projectile/Proj) + health -= Proj.damage + ..() + healthcheck() + return + +/obj/effect/alien/resin/ex_act(severity) + switch(severity) + if(1.0) + health-=50 + if(2.0) + health-=50 + if(3.0) + if (prob(50)) + health-=50 + else + health-=25 + healthcheck() + return + +/obj/effect/alien/resin/hitby(AM as mob|obj) + ..() + for(var/mob/O in viewers(src, null)) + O.show_message("[src] was hit by [AM].", 1) + var/tforce = 0 + if(ismob(AM)) + tforce = 10 + else + tforce = AM:throwforce + playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) + health = max(0, health - tforce) + healthcheck() + ..() + return + +/obj/effect/alien/resin/attack_hand() + usr.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + if (HULK in usr.mutations) + usr << "You easily destroy the [name]." + for(var/mob/O in oviewers(src)) + O.show_message("[usr] destroys the [name]!", 1) + health = 0 + else + + // Aliens can get straight through these. + if(istype(usr,/mob/living/carbon)) + var/mob/living/carbon/M = usr + if(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs) + for(var/mob/O in oviewers(src)) + O.show_message("[usr] strokes the [name] and it melts away!", 1) + health = 0 + healthcheck() + return + + usr << "You claw at the [name]." + for(var/mob/O in oviewers(src)) + O.show_message("[usr] claws at the [name]!", 1) + health -= rand(5,10) + healthcheck() + return + +/obj/effect/alien/resin/attackby(obj/item/weapon/W as obj, mob/user as mob) + + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + var/aforce = W.force + health = max(0, health - aforce) + playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) + healthcheck() + ..() + return + +/obj/effect/alien/resin/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + if(air_group) return 0 + if(istype(mover) && mover.checkpass(PASSGLASS)) + return !opacity + return !density + + +/* + * Weeds + */ +#define NODERANGE 3 + +/obj/effect/alien/weeds + name = "weeds" + desc = "Weird purple weeds." + icon_state = "weeds" + + anchored = 1 + density = 0 + layer = 2 + var/health = 15 + var/obj/effect/alien/weeds/node/linked_node = null + +/obj/effect/alien/weeds/node + icon_state = "weednode" + name = "purple sac" + desc = "Weird purple octopus-like thing." + layer = 3 + light_range = NODERANGE + var/node_range = NODERANGE + +/obj/effect/alien/weeds/node/New() + ..(src.loc, src) + + +/obj/effect/alien/weeds/New(pos, node) + ..() + if(istype(loc, /turf/space)) + qdel(src) + return + linked_node = node + if(icon_state == "weeds")icon_state = pick("weeds", "weeds1", "weeds2") + spawn(rand(150, 200)) + if(src) + Life() + return + +/obj/effect/alien/weeds/proc/Life() + set background = 1 + var/turf/U = get_turf(src) +/* + if (locate(/obj/movable, U)) + U = locate(/obj/movable, U) + if(U.density == 1) + qdel(src) + return +Alien plants should do something if theres a lot of poison + if(U.poison> 200000) + health -= round(U.poison/200000) + update() + return +*/ + if (istype(U, /turf/space)) + qdel(src) + return + + if(!linked_node || (get_dist(linked_node, src) > linked_node.node_range) ) + return + + direction_loop: + for(var/dirn in cardinal) + var/turf/T = get_step(src, dirn) + + if (!istype(T) || T.density || locate(/obj/effect/alien/weeds) in T || istype(T.loc, /area/arrival) || istype(T, /turf/space)) + continue + + // if (locate(/obj/movable, T)) // don't propogate into movables + // continue + + for(var/obj/O in T) + if(O.density) + continue direction_loop + + new /obj/effect/alien/weeds(T, linked_node) + + +/obj/effect/alien/weeds/ex_act(severity) + switch(severity) + if(1.0) + qdel(src) + if(2.0) + if (prob(50)) + qdel(src) + if(3.0) + if (prob(5)) + qdel(src) + return + +/obj/effect/alien/weeds/attackby(var/obj/item/weapon/W, var/mob/user) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) + if(W.attack_verb.len) + visible_message("\The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]") + else + visible_message("\The [src] have been attacked with \the [W][(user ? " by [user]." : ".")]") + + var/damage = W.force / 4.0 + + if(istype(W, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/WT = W + + if(WT.remove_fuel(0, user)) + damage = 15 + playsound(loc, 'sound/items/Welder.ogg', 100, 1) + + health -= damage + healthcheck() + +/obj/effect/alien/weeds/proc/healthcheck() + if(health <= 0) + qdel(src) + + +/obj/effect/alien/weeds/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) + if(exposed_temperature > 300 + T0C) + health -= 5 + healthcheck() + +#undef NODERANGE + + +/* + * Acid + */ +/obj/effect/alien/acid + name = "acid" + desc = "Burbling corrossive stuff. I wouldn't want to touch it." + icon_state = "acid" + + density = 0 + opacity = 0 + anchored = 1 + + var/atom/target + var/ticks = 0 + var/target_strength = 0 + +/obj/effect/alien/acid/New(loc, target) + ..(loc) + src.target = target + + if(isturf(target)) // Turf take twice as long to take down. + target_strength = 8 + else + target_strength = 4 + tick() + +/obj/effect/alien/acid/proc/tick() + if(!target) + qdel(src) + + ticks += 1 + + if(ticks >= target_strength) + + for(var/mob/O in hearers(src, null)) + O.show_message("[src.target] collapses under its own weight into a puddle of goop and undigested debris!", 1) + + if(istype(target, /turf/simulated/wall)) // I hate turf code. + var/turf/simulated/wall/W = target + W.dismantle_wall(1) + else + qdel(target) + qdel(src) + return + + switch(target_strength - ticks) + if(6) + visible_message("[src.target] is holding up against the acid!") + if(4) + visible_message("[src.target]\s structure is being melted by the acid!") + if(2) + visible_message("[src.target] is struggling to withstand the acid!") + if(0 to 1) + visible_message("[src.target] begins to crumble under the acid!") + spawn(rand(150, 200)) tick() + +/* + * Egg + */ +/var/const //for the status var + BURST = 0 + BURSTING = 1 + GROWING = 2 + GROWN = 3 + + MIN_GROWTH_TIME = 1800 //time it takes to grow a hugger + MAX_GROWTH_TIME = 3000 + +/obj/effect/alien/egg + desc = "It looks like a weird egg" + name = "egg" +// icon_state = "egg_growing" // So the egg looks 'grown', even though it's not. + icon_state = "egg" + density = 0 + anchored = 1 + + var/health = 100 + var/status = BURST //can be GROWING, GROWN or BURST; all mutually exclusive + flags = PROXMOVE + +/obj/effect/alien/egg/New() +/* + if(config.aliens_allowed) + ..() + spawn(rand(MIN_GROWTH_TIME,MAX_GROWTH_TIME)) + Grow() + else + qdel(src) +*/ +/obj/effect/alien/egg/attack_hand(user as mob) + + var/mob/living/carbon/M = user + if(!istype(M) || !(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs)) + return attack_hand(user) + + switch(status) + if(BURST) + user << "You clear the hatched egg." + qdel(src) + return +/* if(GROWING) + user << "The child is not developed yet." + return + if(GROWN) + user << "You retrieve the child." + Burst(0) + return + +/obj/effect/alien/egg/proc/GetFacehugger() // Commented out for future edit. + return locate(/obj/item/clothing/mask/facehugger) in contents + +/obj/effect/alien/egg/proc/Grow() + icon_state = "egg" +// status = GROWN + status = BURST +// new /obj/item/clothing/mask/facehugger(src) + return +*/ +/obj/effect/alien/egg/proc/Burst(var/kill = 1) //drops and kills the hugger if any is remaining + if(status == GROWN || status == GROWING) +// var/obj/item/clothing/mask/facehugger/child = GetFacehugger() + icon_state = "egg_hatched" +/* flick("egg_opening", src) + status = BURSTING + spawn(15) + status = BURST + child.loc = get_turf(src) + + if(kill && istype(child)) + child.Die() + else + for(var/mob/M in range(1,src)) + if(CanHug(M)) + child.Attach(M) + break +*/ +/obj/effect/alien/egg/bullet_act(var/obj/item/projectile/Proj) + health -= Proj.damage + ..() + healthcheck() + return + + +/obj/effect/alien/egg/attackby(var/obj/item/weapon/W, var/mob/user) + if(health <= 0) + return + if(W.attack_verb.len) + src.visible_message("\The [src] has been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]") + else + src.visible_message("\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]") + var/damage = W.force / 4.0 + + if(istype(W, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/WT = W + + if(WT.remove_fuel(0, user)) + damage = 15 + playsound(src.loc, 'sound/items/Welder.ogg', 100, 1) + + src.health -= damage + src.healthcheck() + + +/obj/effect/alien/egg/proc/healthcheck() + if(health <= 0) + Burst() + +/obj/effect/alien/egg/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) + if(exposed_temperature > 500 + T0C) + health -= 5 + healthcheck() +/* +/obj/effect/alien/egg/HasProximity(atom/movable/AM as mob|obj) + if(status == GROWN) + if(!CanHug(AM)) + return + + var/mob/living/carbon/C = AM + if(C.stat == CONSCIOUS && C.status_flags & XENO_HOST) + return + + Burst(0) +*/ \ No newline at end of file diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index e80b7d8f10..788e65827b 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -21,9 +21,9 @@ newplayer_start += loc delete_me = 1 return - if("JoinLate") - latejoin += loc - delete_me = 1 + if("JoinLate") // Bit difference, since we need the spawn point to move. + latejoin += src + // delete_me = 1 return if("JoinLateGateway") latejoin_gateway += loc diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 973cb522e7..dd10e80859 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -109,6 +109,7 @@ user << "You flick the switch on [src], but nothing happens." return 0 on = !on + playsound(src.loc, 'sound/weapons/empty.ogg', 15, 1, -3) update_icon() user.update_action_buttons() return 1 diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 4a7dc88597..584d6dd105 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -12,7 +12,7 @@ /obj/item/borg/upgrade/proc/action(var/mob/living/silicon/robot/R) if(R.stat == DEAD) - usr << "The [src] will not function on a deceased robot." + to_chat(usr, "The [src] will not function on a deceased robot.") return 1 return 0 @@ -66,7 +66,7 @@ /obj/item/borg/upgrade/restart/action(var/mob/living/silicon/robot/R) if(R.health < 0) - usr << "You have to repair the robot before using this module!" + to_chat(usr, "You have to repair the robot before using this module!") return 0 if(!R.key) @@ -110,8 +110,8 @@ if(..()) return 0 if(!R.module || !(type in R.module.supported_upgrades)) - R << "Upgrade mounting error! No suitable hardpoint detected!" - usr << "There's no mounting point for the module!" + to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!") + to_chat(usr, "There's no mounting point for the module!") return 0 var/obj/item/weapon/gun/energy/taser/mounted/cyborg/T = locate() in R.module @@ -120,12 +120,12 @@ if(!T) T = locate() in R.module.modules if(!T) - usr << "This robot has had its taser removed!" + to_chat(usr, "This robot has had its taser removed!") return 0 if(T.recharge_time <= 2) - R << "Maximum cooling achieved for this hardpoint!" - usr << "There's no room for another cooling unit!" + to_chat(R, "Maximum cooling achieved for this hardpoint!") + to_chat(usr, "There's no room for another cooling unit!") return 0 else @@ -135,7 +135,7 @@ /obj/item/borg/upgrade/jetpack name = "mining robot jetpack" - desc = "A carbon dioxide jetpack suitable for low-gravity mining operations." + desc = "A carbon dioxide jetpack suitable for low-gravity operations." icon_state = "cyborg_upgrade3" item_state = "cyborg_upgrade" require_module = 1 @@ -143,17 +143,20 @@ /obj/item/borg/upgrade/jetpack/action(var/mob/living/silicon/robot/R) if(..()) return 0 - if(!R.module || !(type in R.module.supported_upgrades)) - R << "Upgrade mounting error! No suitable hardpoint detected!" - usr << "There's no mounting point for the module!" - return 0 - else + var/obj/item/weapon/tank/jetpack/carbondioxide/T = locate() in R.module + if(!T) + T = locate() in R.module.contents + if(!T) + T = locate() in R.module.modules + if(!T) R.module.modules += new/obj/item/weapon/tank/jetpack/carbondioxide for(var/obj/item/weapon/tank/jetpack/carbondioxide in R.module.modules) R.internals = src - //R.icon_state="Miner+j" return 1 - + if(T) + to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!") + to_chat(usr, "There's no mounting point for the module!") + return 0 /obj/item/borg/upgrade/syndicate/ name = "scrambled equipment module" diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index d337d064e0..3a5505b10b 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -84,6 +84,24 @@ desc = "A piece of blue carpet. It is the same size as a normal floor tile!" icon_state = "tile-bluecarpet" +// VOREStation Edit +// TODO - Add descriptions to these +/obj/item/stack/tile/carpet/bcarpet + icon_state = "tile-carpet" +/obj/item/stack/tile/carpet/blucarpet + icon_state = "tile-carpet" +/obj/item/stack/tile/carpet/turcarpet + icon_state = "tile-carpet" +/obj/item/stack/tile/carpet/sblucarpet + icon_state = "tile-carpet" +/obj/item/stack/tile/carpet/gaycarpet + icon_state = "tile-carpet" +/obj/item/stack/tile/carpet/purcarpet + icon_state = "tile-carpet" +/obj/item/stack/tile/carpet/oracarpet + icon_state = "tile-carpet" +// VOREStation Edit End + /obj/item/stack/tile/floor name = "floor tile" singular_name = "floor tile" @@ -96,37 +114,55 @@ throw_range = 20 flags = CONDUCT -/obj/item/stack/tile/floor_red +/obj/item/stack/tile/floor/red name = "red floor tile" singular_name = "red floor tile" color = COLOR_RED_GRAY icon_state = "tile_white" -/obj/item/stack/tile/floor_steel +// VOREStation Edit +/obj/item/stack/tile/floor/techgrey + name = "grey techfloor tile" + singular_name = "grey techfloor tile" + icon_state = "techtile_grey" + +/obj/item/stack/tile/floor/techgrid + name = "grid techfloor tile" + singular_name = "grid techfloor tile" + icon_state = "techtile_grid" + +/obj/item/stack/tile/floor/steel_dirty + name = "steel floor tile" + singular_name = "steel floor tile" + icon_state = "tile_steel" + matter = list("plasteel" = SHEET_MATERIAL_AMOUNT / 4) +// VOREStation Edit End + +/obj/item/stack/tile/floor/steel name = "steel floor tile" singular_name = "steel floor tile" icon_state = "tile_steel" matter = list("plasteel" = SHEET_MATERIAL_AMOUNT / 4) -/obj/item/stack/tile/floor_white +/obj/item/stack/tile/floor/white name = "white floor tile" singular_name = "white floor tile" icon_state = "tile_white" matter = list("plastic" = SHEET_MATERIAL_AMOUNT / 4) -/obj/item/stack/tile/floor_yellow +/obj/item/stack/tile/floor/yellow name = "yellow floor tile" singular_name = "yellow floor tile" color = COLOR_BROWN icon_state = "tile_white" -/obj/item/stack/tile/floor_dark +/obj/item/stack/tile/floor/dark name = "dark floor tile" singular_name = "dark floor tile" icon_state = "fr_tile" matter = list("plasteel" = SHEET_MATERIAL_AMOUNT / 4) -/obj/item/stack/tile/floor_freezer +/obj/item/stack/tile/floor/freezer name = "freezer floor tile" singular_name = "freezer floor tile" icon_state = "tile_freezer" diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index 4f7ba66842..1bf4924507 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -583,6 +583,21 @@ CIGARETTE PACKETS ARE IN FANCY.DM desc = "Made of gold and obsidian, this is truly not worth however much you spent on it." icon_state = "cappiezippo" +/obj/item/weapon/flame/lighter/zippo/communist + name = "\improper communist Zippo lighter" + desc = "All you need to spark a revolution." + icon_state = "commiezippo" + +/obj/item/weapon/flame/lighter/zippo/royal + name = "\improper royal Zippo lighter" + desc = "An incredibly fancy lighter, gilded and covered in the color of royalty." + icon_state = "royalzippo" + +/obj/item/weapon/flame/lighter/zippo/gonzo + name = "\improper Gonzo Zippo lighter" + desc = "A lighter with the iconic Gonzo fist painted on it." + icon_state = "gonzozippo" + /obj/item/weapon/flame/lighter/zippo/rainbow name = "\improper rainbow Zippo lighter" icon_state = "rainbowzippo" \ No newline at end of file diff --git a/code/game/objects/items/weapons/policetape.dm b/code/game/objects/items/weapons/policetape.dm index 9b4cb3ca9b..cb6a982231 100644 --- a/code/game/objects/items/weapons/policetape.dm +++ b/code/game/objects/items/weapons/policetape.dm @@ -30,6 +30,7 @@ var/list/tape_roll_applications = list() name = "tape" icon = 'icons/policetape.dmi' anchored = 1 + layer = 3.2 var/lifted = 0 var/crumpled = 0 var/tape_dir = 0 @@ -56,6 +57,7 @@ var/list/tape_roll_applications = list() hazard_overlays["[EAST]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "E") hazard_overlays["[SOUTH]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "S") hazard_overlays["[WEST]"] = new/image('icons/effects/warning_stripes.dmi', icon_state = "W") + update_icon() /obj/item/taperoll/police name = "police tape" diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm index fac5e9fb70..8391c90434 100644 --- a/code/game/objects/items/weapons/storage/toolbox.dm +++ b/code/game/objects/items/weapons/storage/toolbox.dm @@ -72,12 +72,12 @@ /obj/item/weapon/storage/toolbox/syndicate/New() ..() new /obj/item/clothing/gloves/yellow(src) - new /obj/item/weapon/screwdriver(src) - new /obj/item/weapon/wrench(src) + new /obj/item/weapon/screwdriver/power(src) + new /obj/item/stack/cable_coil/random(src,30) new /obj/item/weapon/weldingtool/experimental(src) - new /obj/item/weapon/crowbar(src) - new /obj/item/weapon/wirecutters(src) + new /obj/item/weapon/crowbar/power(src) new /obj/item/device/multitool(src) + new /obj/item/device/analyzer(src) /obj/item/weapon/storage/toolbox/lunchbox max_storage_space = ITEMSIZE_COST_SMALL * 4 //slightly smaller than a toolbox diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm index be9c0c72d8..9364f1b859 100644 --- a/code/game/objects/items/weapons/surgery_tools.dm +++ b/code/game/objects/items/weapons/surgery_tools.dm @@ -61,7 +61,7 @@ /obj/item/weapon/surgical/surgicaldrill name = "surgical drill" desc = "You can drill using this item. You dig?" - icon_state = "surgery_drill" + icon_state = "drill" hitsound = 'sound/weapons/circsawhit.ogg' matter = list(DEFAULT_WALL_MATERIAL = 15000, "glass" = 10000) force = 15.0 diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 3a2746be47..df50214e94 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -53,7 +53,7 @@ icon_state = "drill_bolt" item_state = "drill" usesound = 'sound/items/drill_use.ogg' - matter = list(DEFAULT_WALL_MATERIAL = 150, MAT_SILVER = 50, MAT_TITANIUM = 25) + matter = list(DEFAULT_WALL_MATERIAL = 150, MAT_SILVER = 50) origin_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) force = 8 w_class = ITEMSIZE_SMALL @@ -155,7 +155,7 @@ desc = "A simple powered hand drill. It's fitted with a screw bit." icon_state = "drill_screw" item_state = "drill" - matter = list(DEFAULT_WALL_MATERIAL = 150, MAT_SILVER = 50, MAT_TITANIUM = 25) + matter = list(DEFAULT_WALL_MATERIAL = 150, MAT_SILVER = 50) origin_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) force = 8 @@ -240,7 +240,7 @@ icon_state = "jaws_cutter" item_state = "jawsoflife" origin_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) - matter = list(MAT_METAL=150, MAT_SILVER=50, MAT_TITANIUM=25) + matter = list(MAT_METAL=150, MAT_SILVER=50) usesound = 'sound/items/jaws_cut.ogg' force = 15 toolspeed = 0.25 @@ -801,7 +801,7 @@ toolspeed = 1 /obj/item/weapon/crowbar/red - icon = 'icons/obj/items.dmi' + icon = 'icons/obj/tools.dmi' icon_state = "red_crowbar" item_state = "crowbar_red" @@ -844,7 +844,7 @@ desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a prying head." icon_state = "jaws_pry" item_state = "jawsoflife" - matter = list(MAT_METAL=150, MAT_SILVER=50, MAT_TITANIUM=25) + matter = list(MAT_METAL=150, MAT_SILVER=50) origin_tech = list(TECH_MATERIALS = 2, TECH_ENGINEERING = 2) usesound = 'sound/items/jaws_pry.ogg' force = 15 diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm index bdce42f9f0..b5395456ed 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm @@ -56,6 +56,7 @@ return if(src.allowed(user)) src.locked = !src.locked + playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3) for(var/mob/O in viewers(user, 3)) if((O.client && !( O.blinded ))) O << "The locker has been [locked ? null : "un"]locked by [user]." diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index 96cc5a8ea0..fd4aaa33a3 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -242,7 +242,7 @@ /obj/structure/sign/kiddieplaque name = "\improper AI developers plaque" - desc = "Next to the extremely long list of names and job titles, there is a drawing of a little child. The child appears to be developmentally disabled. Beneath the image, someone has scratched the word \"PACKETS\"" + desc = "Next to the extremely long list of names and job titles. Beneath the image, someone has scratched the word \"PACKETS\"" icon_state = "kiddieplaque" /obj/structure/sign/atmosplaque diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm new file mode 100644 index 0000000000..9d79ad45a1 --- /dev/null +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -0,0 +1,85 @@ +#define NEST_RESIST_TIME 1200 + +/obj/structure/bed/nest + name = "alien nest" + desc = "It's a gruesome pile of thick, sticky resin shaped like a nest." + icon = 'icons/mob/alien.dmi' + icon_state = "nest" + var/health = 100 + +/obj/structure/bed/nest/update_icon() + return + +/obj/structure/bed/nest/user_unbuckle_mob(mob/user as mob) + if(buckled_mob) + if(buckled_mob.buckled == src) + if(buckled_mob != user) + buckled_mob.visible_message(\ + "[user.name] pulls [buckled_mob.name] free from the sticky nest!",\ + "[user.name] pulls you free from the gelatinous resin.",\ + "You hear squelching...") + buckled_mob.pixel_y = 0 + buckled_mob.old_y = 0 + unbuckle_mob() + else + if(world.time <= buckled_mob.last_special+NEST_RESIST_TIME) + return + buckled_mob.last_special = world.time + buckled_mob.visible_message(\ + "[buckled_mob.name] struggles to break free of the gelatinous resin...",\ + "You struggle to break free from the gelatinous resin...",\ + "You hear squelching...") + spawn(NEST_RESIST_TIME) + if(user && buckled_mob && user.buckled == src) + buckled_mob.last_special = world.time + buckled_mob.pixel_y = 0 + buckled_mob.old_y = 0 + unbuckle_mob() + src.add_fingerprint(user) + return + +/obj/structure/bed/nest/user_buckle_mob(mob/M as mob, mob/user as mob) + if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || usr.stat || M.buckled || istype(user, /mob/living/silicon/pai) ) + return + + unbuckle_mob() + + var/mob/living/carbon/xenos = user + var/mob/living/carbon/victim = M + + if(istype(victim) && locate(/obj/item/organ/internal/xenos/hivenode) in victim.internal_organs) + return + + if(istype(xenos) && !(locate(/obj/item/organ/internal/xenos/hivenode) in xenos.internal_organs)) + return + + if(M == usr) + return + else + M.visible_message(\ + "[user.name] secretes a thick vile goo, securing [M.name] into [src]!",\ + "[user.name] drenches you in a foul-smelling resin, trapping you in the [src]!",\ + "You hear squelching...") + M.buckled = src + M.loc = src.loc + M.set_dir(src.dir) + M.update_canmove() + M.pixel_y = 6 + M.old_y = 6 + src.buckled_mob = M + src.add_fingerprint(user) + return + +/obj/structure/bed/nest/attackby(obj/item/weapon/W as obj, mob/user as mob) + var/aforce = W.force + health = max(0, health - aforce) + playsound(loc, 'sound/effects/attackblob.ogg', 100, 1) + for(var/mob/M in viewers(src, 7)) + M.show_message("[user] hits [src] with [W]!", 1) + healthcheck() + +/obj/structure/bed/nest/proc/healthcheck() + if(health <=0) + density = 0 + qdel(src) + return diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm index 9ae19769eb..bdd4b87b0e 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm @@ -193,3 +193,31 @@ pulling = null usr.pulledby = null ..() + +/obj/item/wheelchair + name = "wheelchair" + desc = "A folded wheelchair that can be carried around." + icon = 'icons/obj/furniture.dmi' + icon_state = "wheelchair_folded" + item_state = "wheelchair" + w_class = ITEMSIZE_HUGE // Can't be put in backpacks. Oh well. + +/obj/item/wheelchair/attack_self(mob/user) + var/obj/structure/bed/chair/wheelchair/R = new /obj/structure/bed/chair/wheelchair(user.loc) + R.add_fingerprint(user) + R.name = src.name + R.color = src.color + qdel(src) + +/obj/structure/bed/chair/wheelchair/MouseDrop(over_object, src_location, over_location) + ..() + if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src)))) + if(!ishuman(usr)) return + if(buckled_mob) return 0 + visible_message("[usr] collapses \the [src.name].") + var/obj/item/wheelchair/R = new/obj/item/wheelchair(get_turf(src)) + R.name = src.name + R.color = src.color + spawn(0) + qdel(src) + return diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index ca9276c6c2..59d278ffc4 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -314,6 +314,8 @@ /obj/structure/window/proc/hit(var/damage, var/sound_effect = 1) if(reinf) damage *= 0.5 + if(damage < 5) + return take_damage(damage) return diff --git a/code/game/turfs/flooring/flooring.dm b/code/game/turfs/flooring/flooring.dm index 2170ea3019..82421dc3ac 100644 --- a/code/game/turfs/flooring/flooring.dm +++ b/code/game/turfs/flooring/flooring.dm @@ -18,7 +18,7 @@ var/list/flooring_types // [icon_base]_corners: directional overlays for non-edge corners. /decl/flooring - var/name + var/name = "floor" var/desc var/icon var/icon_base @@ -98,18 +98,49 @@ var/list/flooring_types 'sound/effects/footstep/carpet4.ogg', 'sound/effects/footstep/carpet5.ogg')) -/decl/flooring/carpet/blue - name = "carpet" +// VOREStation Edit - Eris Carpets +/decl/flooring/carpet/bcarpet + name = "black carpet" icon_base = "bcarpet" - build_type = /obj/item/stack/tile/carpet/blue - flags = TURF_HAS_EDGES | TURF_REMOVE_CROWBAR + build_type = /obj/item/stack/tile/carpet/bcarpet + +/decl/flooring/carpet/blucarpet + name = "blue carpet" + icon_base = "blucarpet" + build_type = /obj/item/stack/tile/carpet/blucarpet + +/decl/flooring/carpet/turcarpet + name = "tur carpet" + icon_base = "turcarpet" + build_type = /obj/item/stack/tile/carpet/turcarpet + +/decl/flooring/carpet/sblucarpet + name = "silver blue carpet" + icon_base = "sblucarpet" + build_type = /obj/item/stack/tile/carpet/sblucarpet + +/decl/flooring/carpet/gaycarpet + name = "clown carpet" + icon_base = "gaycarpet" + build_type = /obj/item/stack/tile/carpet/gaycarpet + +/decl/flooring/carpet/purcarpet + name = "purple carpet" + icon_base = "purcarpet" + build_type = /obj/item/stack/tile/carpet/purcarpet + +/decl/flooring/carpet/oracarpet + name = "orange carpet" + icon_base = "oracarpet" + build_type = /obj/item/stack/tile/carpet/oracarpet +// VOREStation Edit End /decl/flooring/tiling name = "floor" desc = "Scuffed from the passage of countless greyshirts." - icon = 'icons/turf/flooring/tiles.dmi' - icon_base = "steel" - has_damage_range = 4 + icon = 'icons/turf/flooring/tiles.dmi' // VOREStation Edit - Eris floors + icon_base = "tiled" // VOREStation Edit - Eris floors + has_damage_range = 2 // VOREStation Edit - Eris floors damage_temperature = T0C+1400 flags = TURF_REMOVE_CROWBAR | TURF_CAN_BREAK | TURF_CAN_BURN build_type = /obj/item/stack/tile/floor @@ -121,6 +152,45 @@ var/list/flooring_types 'sound/effects/footstep/floor4.ogg', 'sound/effects/footstep/floor5.ogg')) +//VOREStation Edit for icons and extra types +/decl/flooring/tiling/tech + desc = "Scuffed from the passage of countless greyshirts." + icon = 'icons/turf/flooring/techfloor.dmi' + icon_base = "techfloor_gray" + build_type = /obj/item/stack/tile/floor/techgrey + can_paint = null + +/decl/flooring/tiling/tech/grid + icon_base = "techfloor_grid" + build_type = /obj/item/stack/tile/floor/techgrid + +/decl/flooring/tiling/new_tile + name = "floor" + icon_base = "tile_full" + flags = TURF_CAN_BREAK | TURF_CAN_BURN | TURF_IS_FRAGILE + build_type = null + +/decl/flooring/tiling/new_tile/cargo_one + icon_base = "cargo_one_full" + +/decl/flooring/tiling/new_tile/kafel + icon_base = "kafel_full" + +/decl/flooring/tiling/new_tile/techmaint + icon_base = "techmaint" + +/decl/flooring/tiling/new_tile/monofloor + icon_base = "monofloor" + +/decl/flooring/tiling/new_tile/monotile + icon_base = "monotile" + +/decl/flooring/tiling/new_tile/steel_grid + icon_base = "steel_grid" + +/decl/flooring/tiling/new_tile/steel_ridged + icon_base = "steel_ridged" + /decl/flooring/linoleum name = "linoleum" desc = "It's like the 2390's all over again." @@ -135,36 +205,37 @@ var/list/flooring_types icon_base = "white" has_damage_range = null flags = TURF_REMOVE_CROWBAR - build_type = /obj/item/stack/tile/floor_red + build_type = /obj/item/stack/tile/floor/red /decl/flooring/tiling/steel + name = "floor" + icon_base = "steel" + build_type = /obj/item/stack/tile/floor/steel + +/decl/flooring/tiling/steel_dirty name = "floor" icon_base = "steel_dirty" - has_damage_range = null - flags = TURF_REMOVE_CROWBAR - build_type = /obj/item/stack/tile/floor_steel + build_type = /obj/item/stack/tile/floor/steel_dirty /decl/flooring/tiling/asteroidfloor name = "floor" icon_base = "asteroidfloor" has_damage_range = null flags = TURF_REMOVE_CROWBAR - build_type = /obj/item/stack/tile/floor_steel + build_type = /obj/item/stack/tile/floor/steel /decl/flooring/tiling/white name = "floor" desc = "How sterile." icon_base = "white" - has_damage_range = null - flags = TURF_REMOVE_CROWBAR - build_type = /obj/item/stack/tile/floor_white + build_type = /obj/item/stack/tile/floor/white /decl/flooring/tiling/yellow name = "floor" icon_base = "white" has_damage_range = null flags = TURF_REMOVE_CROWBAR - build_type = /obj/item/stack/tile/floor_yellow + build_type = /obj/item/stack/tile/floor/yellow /decl/flooring/tiling/dark name = "floor" @@ -172,29 +243,23 @@ var/list/flooring_types icon_base = "dark" has_damage_range = null flags = TURF_REMOVE_CROWBAR - build_type = /obj/item/stack/tile/floor_dark + build_type = /obj/item/stack/tile/floor/dark /decl/flooring/tiling/hydro name = "floor" icon_base = "hydrofloor" - has_damage_range = null - flags = TURF_REMOVE_CROWBAR - build_type = /obj/item/stack/tile/floor_steel + build_type = /obj/item/stack/tile/floor/steel /decl/flooring/tiling/neutral name = "floor" icon_base = "neutral" - has_damage_range = null - flags = TURF_REMOVE_CROWBAR - build_type = /obj/item/stack/tile/floor_steel + build_type = /obj/item/stack/tile/floor/steel /decl/flooring/tiling/freezer name = "floor" desc = "Don't slip." icon_base = "freezer" - has_damage_range = null - flags = TURF_REMOVE_CROWBAR - build_type = /obj/item/stack/tile/floor_freezer + build_type = /obj/item/stack/tile/floor/freezer /decl/flooring/wood name = "wooden floor" diff --git a/code/game/turfs/flooring/flooring_decals.dm b/code/game/turfs/flooring/flooring_decals.dm index 56b503c7c7..b50ac335d9 100644 --- a/code/game/turfs/flooring/flooring_decals.dm +++ b/code/game/turfs/flooring/flooring_decals.dm @@ -14,22 +14,16 @@ var/list/floor_decals = list() if(newcolour) color = newcolour ..(newloc) +// VOREStation Edit - Hack to workaround byond crash bug /obj/effect/floor_decal/initialize() - if(supplied_dir) set_dir(supplied_dir) + if(!floor_decals_initialized || !loc || QDELETED(src)) + return + add_to_turf_decals() var/turf/T = get_turf(src) - if(istype(T, /turf/simulated/floor) || istype(T, /turf/unsimulated/floor) || istype(T, /turf/simulated/shuttle/floor)) - var/cache_key = "[alpha]-[color]-[dir]-[icon_state]-[layer]" - if(!floor_decals[cache_key]) - var/image/I = image(icon = src.icon, icon_state = src.icon_state, dir = src.dir) - I.layer = T.layer - I.color = src.color - I.alpha = src.alpha - floor_decals[cache_key] = I - if(!T.decals) T.decals = list() - T.decals |= floor_decals[cache_key] - T.overlays |= floor_decals[cache_key] + T.apply_decals() qdel(src) return +// VOREStation Edit End /obj/effect/floor_decal/reset name = "reset marker" @@ -55,6 +49,24 @@ var/list/floor_decals = list() /obj/effect/floor_decal/corner/black/full icon_state = "corner_white_full" +/obj/effect/floor_decal/corner/black/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/black/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/black/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/black/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/black/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/black/bordercee + icon_state = "bordercolorcee" + /obj/effect/floor_decal/corner/blue name = "blue corner" color = COLOR_BLUE_GRAY @@ -65,6 +77,24 @@ var/list/floor_decals = list() /obj/effect/floor_decal/corner/blue/full icon_state = "corner_white_full" +/obj/effect/floor_decal/corner/blue/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/blue/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/blue/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/blue/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/blue/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/blue/bordercee + icon_state = "bordercolorcee" + /obj/effect/floor_decal/corner/paleblue name = "pale blue corner" color = COLOR_PALE_BLUE_GRAY @@ -75,6 +105,24 @@ var/list/floor_decals = list() /obj/effect/floor_decal/corner/paleblue/full icon_state = "corner_white_full" +/obj/effect/floor_decal/corner/paleblue/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/paleblue/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/paleblue/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/paleblue/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/paleblue/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/paleblue/bordercee + icon_state = "bordercolorcee" + /obj/effect/floor_decal/corner/green name = "green corner" color = COLOR_GREEN_GRAY @@ -85,6 +133,24 @@ var/list/floor_decals = list() /obj/effect/floor_decal/corner/green/full icon_state = "corner_white_full" +/obj/effect/floor_decal/corner/green/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/green/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/green/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/green/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/green/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/green/bordercee + icon_state = "bordercolorcee" + /obj/effect/floor_decal/corner/lime name = "lime corner" color = COLOR_PALE_GREEN_GRAY @@ -95,6 +161,24 @@ var/list/floor_decals = list() /obj/effect/floor_decal/corner/lime/full icon_state = "corner_white_full" +/obj/effect/floor_decal/corner/lime/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/lime/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/lime/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/lime/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/lime/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/lime/bordercee + icon_state = "bordercolorcee" + /obj/effect/floor_decal/corner/yellow name = "yellow corner" color = COLOR_BROWN @@ -105,6 +189,27 @@ var/list/floor_decals = list() /obj/effect/floor_decal/corner/yellow/full icon_state = "corner_white_full" +/obj/effect/floor_decal/corner/yellow/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/yellow/full + icon_state = "corner_white_full" + +/obj/effect/floor_decal/corner/yellow/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/yellow/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/yellow/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/yellow/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/yellow/bordercee + icon_state = "bordercolorcee" + /obj/effect/floor_decal/corner/beige name = "beige corner" color = COLOR_BEIGE @@ -115,6 +220,24 @@ var/list/floor_decals = list() /obj/effect/floor_decal/corner/beige/full icon_state = "corner_white_full" +/obj/effect/floor_decal/corner/beige/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/beige/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/beige/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/beige/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/beige/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/beige/bordercee + icon_state = "bordercolorcee" + /obj/effect/floor_decal/corner/red name = "red corner" color = COLOR_RED_GRAY @@ -125,6 +248,27 @@ var/list/floor_decals = list() /obj/effect/floor_decal/corner/red/full icon_state = "corner_white_full" +/obj/effect/floor_decal/corner/red/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/red/full + icon_state = "corner_white_full" + +/obj/effect/floor_decal/corner/red/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/red/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/red/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/red/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/red/bordercee + icon_state = "bordercolorcee" + /obj/effect/floor_decal/corner/pink name = "pink corner" color = COLOR_PALE_RED_GRAY @@ -135,6 +279,24 @@ var/list/floor_decals = list() /obj/effect/floor_decal/corner/pink/full icon_state = "corner_white_full" +/obj/effect/floor_decal/corner/pink/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/pink/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/pink/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/pink/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/pink/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/pink/bordercee + icon_state = "bordercolorcee" + /obj/effect/floor_decal/corner/purple name = "purple corner" color = COLOR_PURPLE_GRAY @@ -145,6 +307,24 @@ var/list/floor_decals = list() /obj/effect/floor_decal/corner/purple/full icon_state = "corner_white_full" +/obj/effect/floor_decal/corner/purple/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/purple/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/purple/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/purple/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/purple/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/purple/bordercee + icon_state = "bordercolorcee" + /obj/effect/floor_decal/corner/mauve name = "mauve corner" color = COLOR_PALE_PURPLE_GRAY @@ -155,6 +335,24 @@ var/list/floor_decals = list() /obj/effect/floor_decal/corner/mauve/full icon_state = "corner_white_full" +/obj/effect/floor_decal/corner/mauve/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/mauve/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/mauve/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/mauve/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/mauve/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/mauve/bordercee + icon_state = "bordercolorcee" + /obj/effect/floor_decal/corner/orange name = "orange corner" color = COLOR_DARK_ORANGE @@ -165,6 +363,24 @@ var/list/floor_decals = list() /obj/effect/floor_decal/corner/orange/full icon_state = "corner_white_full" +/obj/effect/floor_decal/corner/orange/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/orange/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/orange/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/orange/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/orange/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/orange/bordercee + icon_state = "bordercolorcee" + /obj/effect/floor_decal/corner/brown name = "brown corner" color = COLOR_DARK_BROWN @@ -175,6 +391,25 @@ var/list/floor_decals = list() /obj/effect/floor_decal/corner/brown/full icon_state = "corner_white_full" +/obj/effect/floor_decal/corner/brown/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/brown/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/brown/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/brown/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/brown/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/brown/bordercee + icon_state = "bordercolorcee" + + /obj/effect/floor_decal/corner/white name = "white corner" icon_state = "corner_white" @@ -185,6 +420,24 @@ var/list/floor_decals = list() /obj/effect/floor_decal/corner/white/full icon_state = "corner_white_full" +/obj/effect/floor_decal/corner/white/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/white/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/white/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/white/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/white/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/white/bordercee + icon_state = "bordercolorcee" + /obj/effect/floor_decal/corner/grey name = "grey corner" color = "#8D8C8C" @@ -195,6 +448,49 @@ var/list/floor_decals = list() /obj/effect/floor_decal/corner/grey/full icon_state = "corner_white_full" +/obj/effect/floor_decal/corner/grey/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/grey/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/grey/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/grey/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/grey/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/grey/bordercee + icon_state = "bordercolorcee" + +/obj/effect/floor_decal/corner/lightgrey + name = "lightgrey corner" + color = "#A8B2B6" + +/obj/effect/floor_decal/corner/lightgrey/diagonal + icon_state = "corner_white_diagonal" + +/obj/effect/floor_decal/corner/lightgrey/three_quarters + icon_state = "corner_white_three_quarters" + +/obj/effect/floor_decal/corner/lightgrey/border + icon_state = "bordercolor" + +/obj/effect/floor_decal/corner/lightgrey/bordercorner + icon_state = "bordercolorcorner" + +/obj/effect/floor_decal/corner/lightgrey/bordercorner2 + icon_state = "bordercolorcorner2" + +/obj/effect/floor_decal/corner/lightgrey/borderfull + icon_state = "bordercolorfull" + +/obj/effect/floor_decal/corner/lightgrey/bordercee + icon_state = "bordercolorcee" + /obj/effect/floor_decal/spline/plain name = "spline - plain" icon_state = "spline_plain" @@ -213,7 +509,7 @@ var/list/floor_decals = list() /obj/effect/floor_decal/spline/fancy/wood/cee icon_state = "spline_fancy_cee" -/obj/effect/floor_decal/spline/fancy/wood/full +/obj/effect/floor_decal/spline/fancy/wood/three_quarters icon_state = "spline_fancy_full" /obj/effect/floor_decal/industrial/warning @@ -229,6 +525,19 @@ var/list/floor_decals = list() /obj/effect/floor_decal/industrial/warning/cee icon_state = "warningcee" +/obj/effect/floor_decal/industrial/danger + name = "hazard stripes" + icon_state = "danger" + +/obj/effect/floor_decal/industrial/danger/corner + icon_state = "dangercorner" + +/obj/effect/floor_decal/industrial/danger/full + icon_state = "dangerfull" + +/obj/effect/floor_decal/industrial/danger/cee + icon_state = "dangercee" + /obj/effect/floor_decal/industrial/warning/dust name = "hazard stripes" icon_state = "warning_dust" @@ -403,4 +712,441 @@ var/list/floor_decals = list() icon_state = "white_d2" /obj/effect/floor_decal/sign/dock/three - icon_state = "white_d3" \ No newline at end of file + icon_state = "white_d3" + +/obj/effect/floor_decal/rust + name = "rust" + icon_state = "rust" + +/obj/effect/floor_decal/rust/mono_rusted1 + icon_state = "mono_rusted1" + +/obj/effect/floor_decal/rust/mono_rusted2 + icon_state = "mono_rusted2" + +/obj/effect/floor_decal/rust/mono_rusted3 + icon_state = "mono_rusted3" + +/obj/effect/floor_decal/rust/part_rusted1 + icon_state = "part_rusted1" + +/obj/effect/floor_decal/rust/part_rusted2 + icon_state = "part_rusted2" + +/obj/effect/floor_decal/rust/part_rusted3 + icon_state = "part_rusted3" + +/obj/effect/floor_decal/rust/color_rusted + icon_state = "color_rusted" + +/obj/effect/floor_decal/rust/color_rustedcorner + icon_state = "color_rustedcorner" + +/obj/effect/floor_decal/rust/color_rustedfull + icon_state = "color_rustedfull" + +/obj/effect/floor_decal/rust/color_rustedcee + icon_state = "color_rustedcee" + +/obj/effect/floor_decal/rust/steel_decals_rusted1 + icon_state = "steel_decals_rusted1" + +/obj/effect/floor_decal/rust/steel_decals_rusted2 + icon_state = "steel_decals_rusted2" + +//Old tile + +/obj/effect/floor_decal/corner_oldtile + name = "corner oldtile" + icon_state = "corner_oldtile" + +/obj/effect/floor_decal/corner_oldtile/white + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#d9d9d9" + +/obj/effect/floor_decal/corner_oldtile/white/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/white/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" + +/obj/effect/floor_decal/corner_oldtile/blue + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#8ba7ad" + +/obj/effect/floor_decal/corner_oldtile/blue/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/blue/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" + +/obj/effect/floor_decal/corner_oldtile/yellow + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#8c6d46" + +/obj/effect/floor_decal/corner_oldtile/yellow/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/yellow/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" + +/obj/effect/floor_decal/corner_oldtile/gray + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#687172" + +/obj/effect/floor_decal/corner_oldtile/gray/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/gray/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" + +/obj/effect/floor_decal/corner_oldtile/beige + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#385e60" + +/obj/effect/floor_decal/corner_oldtile/beige/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/beige/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" + +/obj/effect/floor_decal/corner_oldtile/red + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#964e51" + +/obj/effect/floor_decal/corner_oldtile/red/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/red/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" + +/obj/effect/floor_decal/corner_oldtile/purple + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#906987" + +/obj/effect/floor_decal/corner_oldtile/purple/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/purple/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" + +/obj/effect/floor_decal/corner_oldtile/green + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#46725c" + +/obj/effect/floor_decal/corner_oldtile/green/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/green/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" + +//Kafel + +/obj/effect/floor_decal/corner_kafel + name = "corner kafel" + icon_state = "corner_kafel" + +/obj/effect/floor_decal/corner_kafel/white + name = "corner kafel" + icon_state = "corner_kafel" + color = "#d9d9d9" + +/obj/effect/floor_decal/corner_kafel/white/diagonal + name = "corner kafel diagonal" + icon_state = "corner_kafel_diagonal" + +/obj/effect/floor_decal/corner_kafel/white/full + name = "corner kafel full" + icon_state = "corner_kafel_full" + +/obj/effect/floor_decal/corner_kafel/blue + name = "corner kafel" + icon_state = "corner_kafel" + color = "#8ba7ad" + +/obj/effect/floor_decal/corner_kafel/blue/diagonal + name = "corner kafel diagonal" + icon_state = "corner_kafel_diagonal" + +/obj/effect/floor_decal/corner_kafel/blue/full + name = "corner kafel full" + icon_state = "corner_kafel_full" + +/obj/effect/floor_decal/corner_kafel/yellow + name = "corner kafel" + icon_state = "corner_kafel" + color = "#8c6d46" + +/obj/effect/floor_decal/corner_kafel/yellow/diagonal + name = "corner kafel diagonal" + icon_state = "corner_kafel_diagonal" + +/obj/effect/floor_decal/corner_kafel/yellow/full + name = "corner kafel full" + icon_state = "corner_kafel_full" + +/obj/effect/floor_decal/corner_kafel/gray + name = "corner kafel" + icon_state = "corner_kafel" + color = "#687172" + +/obj/effect/floor_decal/corner_kafel/gray/diagonal + name = "corner kafel diagonal" + icon_state = "corner_kafel_diagonal" + +/obj/effect/floor_decal/corner_kafel/gray/full + name = "corner kafel full" + icon_state = "corner_kafel_full" + +/obj/effect/floor_decal/corner_kafel/beige + name = "corner kafel" + icon_state = "corner_kafel" + color = "#385e60" + +/obj/effect/floor_decal/corner_kafel/beige/diagonal + name = "corner kafel diagonal" + icon_state = "corner_kafel_diagonal" + +/obj/effect/floor_decal/corner_kafel/beige/full + name = "corner kafel full" + icon_state = "corner_kafel_full" + +/obj/effect/floor_decal/corner_kafel/red + name = "corner kafel" + icon_state = "corner_kafel" + color = "#964e51" + +/obj/effect/floor_decal/corner_kafel/red/diagonal + name = "corner kafel diagonal" + icon_state = "corner_kafel_diagonal" + +/obj/effect/floor_decal/corner_kafel/red/full + name = "corner kafel full" + icon_state = "corner_kafel_full" + +/obj/effect/floor_decal/corner_kafel/purple + name = "corner kafel" + icon_state = "corner_kafel" + color = "#906987" + +/obj/effect/floor_decal/corner_kafel/purple/diagonal + name = "corner kafel diagonal" + icon_state = "corner_kafel_diagonal" + +/obj/effect/floor_decal/corner_kafel/purple/full + name = "corner kafel full" + icon_state = "corner_kafel_full" + +/obj/effect/floor_decal/corner_kafel/green + name = "corner kafel" + icon_state = "corner_kafel" + color = "#46725c" + +/obj/effect/floor_decal/corner_kafel/green/diagonal + name = "corner kafel diagonal" + icon_state = "corner_kafel_diagonal" + +/obj/effect/floor_decal/corner_kafel/green/full + name = "corner kafel full" + icon_state = "corner_kafel_full" + +//Techfloor + +/obj/effect/floor_decal/corner_techfloor_gray + name = "corner techfloorgray" + icon_state = "corner_techfloor_gray" + +/obj/effect/floor_decal/corner_techfloor_gray/diagonal + name = "corner techfloorgray diagonal" + icon_state = "corner_techfloor_gray_diagonal" + +/obj/effect/floor_decal/corner_techfloor_gray/full + name = "corner techfloorgray full" + icon_state = "corner_techfloor_gray_full" + +/obj/effect/floor_decal/corner_techfloor_grid + name = "corner techfloorgrid" + icon_state = "corner_techfloor_grid" + +/obj/effect/floor_decal/corner_techfloor_grid/diagonal + name = "corner techfloorgrid diagonal" + icon_state = "corner_techfloor_grid_diagonal" + +/obj/effect/floor_decal/corner_techfloor_grid/full + name = "corner techfloorgrid full" + icon_state = "corner_techfloor_grid_full" + +/obj/effect/floor_decal/corner_steel_grid + name = "corner steel_grid" + icon_state = "steel_grid" + +/obj/effect/floor_decal/corner_steel_grid/diagonal + name = "corner tsteel_grid diagonal" + icon_state = "steel_grid_diagonal" + +/obj/effect/floor_decal/corner_steel_grid/full + name = "corner steel_grid full" + icon_state = "steel_grid_full" + +/obj/effect/floor_decal/borderfloor + name = "border floor" + icon_state = "borderfloor" + +/obj/effect/floor_decal/borderfloor/corner + icon_state = "borderfloorcorner" + +/obj/effect/floor_decal/borderfloor/corner2 + icon_state = "borderfloorcorner2" + +/obj/effect/floor_decal/borderfloor/full + icon_state = "borderfloorfull" + +/obj/effect/floor_decal/borderfloor/cee + icon_state = "borderfloorcee" + +/obj/effect/floor_decal/borderfloorblack + name = "border floor" + icon_state = "borderfloor_black" + +/obj/effect/floor_decal/borderfloorblack/corner + icon_state = "borderfloorcorner_black" + +/obj/effect/floor_decal/borderfloorblack/corner2 + icon_state = "borderfloorcorner2_black" + +/obj/effect/floor_decal/borderfloorblack/full + icon_state = "borderfloorfull_black" + +/obj/effect/floor_decal/borderfloorblack/cee + icon_state = "borderfloorcee_black" + +/obj/effect/floor_decal/borderfloorwhite + name = "border floor" + icon_state = "borderfloor_white" + +/obj/effect/floor_decal/borderfloorwhite/corner + icon_state = "borderfloorcorner_white" + +/obj/effect/floor_decal/borderfloorwhite/corner2 + icon_state = "borderfloorcorner2_white" + +/obj/effect/floor_decal/borderfloorwhite/full + icon_state = "borderfloorfull_white" + +/obj/effect/floor_decal/borderfloorwhite/cee + icon_state = "borderfloorcee_white" + +/obj/effect/floor_decal/steeldecal + name = "steel decal" + icon_state = "steel_decals1" + +/obj/effect/floor_decal/steeldecal/steel_decals1 + icon_state = "steel_decals1" + +/obj/effect/floor_decal/steeldecal/steel_decals2 + icon_state = "steel_decals2" + +/obj/effect/floor_decal/steeldecal/steel_decals3 + icon_state = "steel_decals3" + +/obj/effect/floor_decal/steeldecal/steel_decals4 + icon_state = "steel_decals4" + +/obj/effect/floor_decal/steeldecal/steel_decals5 + icon_state = "steel_decals5" + +/obj/effect/floor_decal/steeldecal/steel_decals6 + icon_state = "steel_decals6" + +/obj/effect/floor_decal/steeldecal/steel_decals7 + icon_state = "steel_decals7" + +/obj/effect/floor_decal/steeldecal/steel_decals8 + icon_state = "steel_decals8" + +/obj/effect/floor_decal/steeldecal/steel_decals9 + icon_state = "steel_decals9" + +/obj/effect/floor_decal/steeldecal/steel_decals10 + icon_state = "steel_decals10" + +/obj/effect/floor_decal/steeldecal/steel_decals_central1 + icon_state = "steel_decals_central1" + +/obj/effect/floor_decal/steeldecal/steel_decals_central2 + icon_state = "steel_decals_central2" + +/obj/effect/floor_decal/steeldecal/steel_decals_central3 + icon_state = "steel_decals_central3" + +/obj/effect/floor_decal/steeldecal/steel_decals_central4 + icon_state = "steel_decals_central4" + +/obj/effect/floor_decal/steeldecal/steel_decals_central5 + icon_state = "steel_decals_central5" + +/obj/effect/floor_decal/steeldecal/steel_decals_central6 + icon_state = "steel_decals_central6" + +/obj/effect/floor_decal/steeldecal/steel_decals_central7 + icon_state = "steel_decals_central7" + + +/obj/effect/floor_decal/techfloor + name = "techfloor edges" + icon_state = "techfloor_edges" + +/obj/effect/floor_decal/techfloor/corner + name = "techfloor corner" + icon_state = "techfloor_corners" + +/obj/effect/floor_decal/techfloor/orange + name = "techfloor edges" + icon_state = "techfloororange_edges" + +/obj/effect/floor_decal/techfloor/orange/corner + name = "techfloor corner" + icon_state = "techfloororange_corners" + +/obj/effect/floor_decal/techfloor/hole + name = "hole left" + icon_state = "techfloor_hole_left" + +/obj/effect/floor_decal/techfloor/hole/right + name = "hole right" + icon_state = "techfloor_hole_right" + + +//Grass for ship garden + +/obj/effect/floor_decal/grass_edge + name = "grass edge" + icon_state = "grass_edge" + +/obj/effect/floor_decal/grass_edge/corner + name = "grass edge" + icon_state = "grass_edge_corner" diff --git a/code/game/turfs/flooring/flooring_premade.dm b/code/game/turfs/flooring/flooring_premade.dm index ed5b8661ab..f3176a748c 100644 --- a/code/game/turfs/flooring/flooring_premade.dm +++ b/code/game/turfs/flooring/flooring_premade.dm @@ -4,6 +4,47 @@ icon_state = "carpet" initial_flooring = /decl/flooring/carpet +/turf/simulated/floor/carpet/bcarpet + name = "black carpet" + icon_state = "bcarpet" + initial_flooring = /decl/flooring/carpet/bcarpet + +/turf/simulated/floor/carpet/blucarpet + name = "blue carpet" + icon_state = "blucarpet" + initial_flooring = /decl/flooring/carpet/blucarpet + +// Legacy support for existing paths for blue carpet +/turf/simulated/floor/carpet/blue + name = "blue carpet" + icon_state = "blucarpet" + initial_flooring = /decl/flooring/carpet/blucarpet + +/turf/simulated/floor/carpet/turcarpet + name = "tur carpet" + icon_state = "turcarpet" + initial_flooring = /decl/flooring/carpet/turcarpet + +/turf/simulated/floor/carpet/sblucarpet + name = "sblue carpet" + icon_state = "sblucarpet" + initial_flooring = /decl/flooring/carpet/sblucarpet + +/turf/simulated/floor/carpet/gaycarpet + name = "clown carpet" + icon_state = "gaycarpet" + initial_flooring = /decl/flooring/carpet/gaycarpet + +/turf/simulated/floor/carpet/purcarpet + name = "purple carpet" + icon_state = "purcarpet" + initial_flooring = /decl/flooring/carpet/purcarpet + +/turf/simulated/floor/carpet/oracarpet + name = "orange carpet" + icon_state = "oracarpet" + initial_flooring = /decl/flooring/carpet/oracarpet + /turf/simulated/floor/bluegrid name = "mainframe floor" icon = 'icons/turf/flooring/circuit.dmi' @@ -28,17 +69,120 @@ icon_state = "grass0" initial_flooring = /decl/flooring/grass -/turf/simulated/floor/carpet/blue - name = "blue carpet" - icon_state = "bcarpet" - initial_flooring = /decl/flooring/carpet/blue - /turf/simulated/floor/tiled name = "floor" icon = 'icons/turf/flooring/tiles.dmi' - icon_state = "steel" + icon_state = "tiled" initial_flooring = /decl/flooring/tiling +/turf/simulated/floor/tiled/techmaint + name = "floor" + icon = 'icons/turf/flooring/tiles.dmi' + icon_state = "techmaint" + initial_flooring = /decl/flooring/tiling/new_tile/techmaint + +/turf/simulated/floor/tiled/monofloor + name = "floor" + icon = 'icons/turf/flooring/tiles.dmi' + icon_state = "monofloor" + initial_flooring = /decl/flooring/tiling/new_tile/monofloor + +/turf/simulated/floor/tiled/techfloor + name = "floor" + icon = 'icons/turf/flooring/techfloor.dmi' + icon_state = "techfloor_gray" + initial_flooring = /decl/flooring/tiling/tech + +/turf/simulated/floor/tiled/monotile + name = "floor" + icon = 'icons/turf/flooring/tiles.dmi' + icon_state = "monotile" + initial_flooring = /decl/flooring/tiling/new_tile/monotile + +/turf/simulated/floor/tiled/steel_grid + name = "floor" + icon = 'icons/turf/flooring/tiles.dmi' + icon_state = "steel_grid" + initial_flooring = /decl/flooring/tiling/new_tile/steel_grid + +/turf/simulated/floor/tiled/steel_ridged + name = "floor" + icon = 'icons/turf/flooring/tiles.dmi' + icon_state = "steel_ridged" + initial_flooring = /decl/flooring/tiling/new_tile/steel_ridged + +/turf/simulated/floor/tiled/old_tile + name = "floor" + icon_state = "tile_full" + initial_flooring = /decl/flooring/tiling/new_tile +/turf/simulated/floor/tiled/old_tile/white + color = "#d9d9d9" +/turf/simulated/floor/tiled/old_tile/blue + color = "#8ba7ad" +/turf/simulated/floor/tiled/old_tile/yellow + color = "#8c6d46" +/turf/simulated/floor/tiled/old_tile/gray + color = "#687172" +/turf/simulated/floor/tiled/old_tile/beige + color = "#385e60" +/turf/simulated/floor/tiled/old_tile/red + color = "#964e51" +/turf/simulated/floor/tiled/old_tile/purple + color = "#906987" +/turf/simulated/floor/tiled/old_tile/green + color = "#46725c" + + + +/turf/simulated/floor/tiled/old_cargo + name = "floor" + icon_state = "cargo_one_full" + initial_flooring = /decl/flooring/tiling/new_tile/cargo_one +/turf/simulated/floor/tiled/old_cargo/white + color = "#d9d9d9" +/turf/simulated/floor/tiled/old_cargo/blue + color = "#8ba7ad" +/turf/simulated/floor/tiled/old_cargo/yellow + color = "#8c6d46" +/turf/simulated/floor/tiled/old_cargo/gray + color = "#687172" +/turf/simulated/floor/tiled/old_cargo/beige + color = "#385e60" +/turf/simulated/floor/tiled/old_cargo/red + color = "#964e51" +/turf/simulated/floor/tiled/old_cargo/purple + color = "#906987" +/turf/simulated/floor/tiled/old_cargo/green + color = "#46725c" + + +/turf/simulated/floor/tiled/kafel_full + name = "floor" + icon_state = "kafel_full" + initial_flooring = /decl/flooring/tiling/new_tile/kafel +/turf/simulated/floor/tiled/kafel_full/white + color = "#d9d9d9" +/turf/simulated/floor/tiled/kafel_full/blue + color = "#8ba7ad" +/turf/simulated/floor/tiled/kafel_full/yellow + color = "#8c6d46" +/turf/simulated/floor/tiled/kafel_full/gray + color = "#687172" +/turf/simulated/floor/tiled/kafel_full/beige + color = "#385e60" +/turf/simulated/floor/tiled/kafel_full/red + color = "#964e51" +/turf/simulated/floor/tiled/kafel_full/purple + color = "#906987" +/turf/simulated/floor/tiled/kafel_full/green + color = "#46725c" + + +/turf/simulated/floor/tiled/techfloor/grid + name = "floor" + icon_state = "techfloor_grid" + initial_flooring = /decl/flooring/tiling/tech/grid + /turf/simulated/floor/reinforced name = "reinforced floor" icon = 'icons/turf/flooring/tiles.dmi' @@ -113,9 +257,14 @@ /turf/simulated/floor/tiled/steel name = "steel floor" - icon_state = "steel_dirty" + icon_state = "steel" initial_flooring = /decl/flooring/tiling/steel +/turf/simulated/floor/tiled/steel_dirty + name = "steel floor" + icon_state = "steel_dirty" + initial_flooring = /decl/flooring/tiling/steel_dirty + /turf/simulated/floor/tiled/steel/airless oxygen = 0 nitrogen = 0 diff --git a/code/game/turfs/flooring/turf_overlay_holder.dm b/code/game/turfs/flooring/turf_overlay_holder.dm new file mode 100644 index 0000000000..a0326b8240 --- /dev/null +++ b/code/game/turfs/flooring/turf_overlay_holder.dm @@ -0,0 +1,90 @@ +// +// Initialize floor decals! Woo! This is crazy. +// + +var/global/floor_decals_initialized = FALSE + +// The Turf Decal Holder +// Since it is unsafe to add overlays to turfs, we hold them here for now. +// Since I want this object to basically not exist, I am modeling it in part after lighting_overlay +/atom/movable/turf_overlay_holder + name = "turf overlay holder" + density = 0 + simulated = 0 + anchored = 1 + layer = TURF_LAYER + icon = null + icon_state = null + mouse_opacity = 0 + auto_init = 0 + +/atom/movable/turf_overlay_holder/New(var/atom/newloc) + ..() + verbs.Cut() + var/turf/T = loc + T.overlay_holder = src + +/atom/movable/turf_overlay_holder/Destroy() + if(loc) + var/turf/T = loc + if(T.overlay_holder == src) + T.overlay_holder = null + . = ..() + +// Variety of overrides so the overlays don't get affected by weird things. +/atom/movable/turf_overlay_holder/ex_act() + return + +/atom/movable/turf_overlay_holder/singularity_act() + return + +/atom/movable/turf_overlay_holder/singularity_pull() + return + +/atom/movable/turf_overlay_holder/forceMove() + return 0 //should never move + +/atom/movable/turf_overlay_holder/Move() + return 0 + +/atom/movable/turf_overlay_holder/throw_at() + return 0 + +/obj/effect/floor_decal/proc/add_to_turf_decals() + if(src.supplied_dir) src.set_dir(src.supplied_dir) + var/turf/T = get_turf(src) + if(istype(T, /turf/simulated/floor) || istype(T, /turf/unsimulated/floor) || istype(T, /turf/simulated/shuttle/floor)) + var/cache_key = "[src.alpha]-[src.color]-[src.dir]-[src.icon_state]-[T.layer]" + var/image/I = floor_decals[cache_key] + if(!I) + I = image(icon = src.icon, icon_state = src.icon_state, dir = src.dir) + I.layer = T.layer + I.color = src.color + I.alpha = src.alpha + floor_decals[cache_key] = I + if(!T.decals) T.decals = list() + //world.log << "About to add img:\ref[I] onto decals at turf:\ref[T] ([T.x],[T.y],[T.z]) which has appearance:\ref[T.appearance] and decals.len=[T.decals.len]" + T.decals += I + return T + // qdel(D) + src.loc = null + src.tag = null + +// Changes to turf to let us do this +/turf + var/atom/movable/turf_overlay_holder/overlay_holder = null + +// After a turf change, destroy the old overlay holder since we will have lost access to it. +/turf/post_change() + var/atom/movable/turf_overlay_holder/TOH = locate(/atom/movable/turf_overlay_holder, src) + if(TOH) + qdel(TOH) + ..() + +/turf/proc/apply_decals() + if(decals) + if(!overlay_holder) + overlay_holder = new(src) + overlay_holder.overlays = src.decals + else if(overlay_holder) + overlay_holder.overlays.Cut() diff --git a/code/game/turfs/simulated/floor_icon.dm b/code/game/turfs/simulated/floor_icon.dm index 0ad44622b7..007108c72e 100644 --- a/code/game/turfs/simulated/floor_icon.dm +++ b/code/game/turfs/simulated/floor_icon.dm @@ -60,8 +60,11 @@ var/list/flooring_cache = list() if(!(istype(T) && T.flooring && T.flooring.name == flooring.name)) overlays |= get_flooring_overlay("[flooring.icon_base]-corner-[SOUTHWEST]", "[flooring.icon_base]_corners", SOUTHWEST) - if(decals && decals.len) - overlays |= decals + // VOREStation Edit - Hack workaround to byond crash bug + //if(decals && decals.len) + //overlays |= decals + apply_decals() + // VOREStation Edit End if(is_plating() && !(isnull(broken) && isnull(burnt))) //temp, todo icon = 'icons/turf/flooring/plating.dmi' diff --git a/code/game/turfs/space/transit.dm b/code/game/turfs/space/transit.dm index 5426eb43e6..236f94de82 100644 --- a/code/game/turfs/space/transit.dm +++ b/code/game/turfs/space/transit.dm @@ -20,7 +20,10 @@ return result +//------------------------ + /turf/space/transit/north // moving to the north + icon_state = "arrow-north" pushdirection = SOUTH // south because the space tile is scrolling south var/static/list/phase_shift_by_x @@ -33,8 +36,28 @@ var/transit_state = (world.maxy - src.y + x_shift)%15 + 1 icon_state = "speedspace_ns_[transit_state]" +//------------------------ + +/turf/space/transit/south // moving to the south + icon_state = "arrow-south" + pushdirection = SOUTH // south because the space tile is scrolling south + var/static/list/phase_shift_by_x + +/turf/space/transit/south/New() + ..() + if(!phase_shift_by_x) + phase_shift_by_x = get_cross_shift_list(15) + + var/x_shift = phase_shift_by_x[src.x % (phase_shift_by_x.len - 1) + 1] + var/transit_state = (world.maxy - src.y + x_shift)%15 + 1 + + var/icon/I = new(icon, "speedspace_ns_[transit_state]") + I.Flip(SOUTH) + icon = I +//------------------------ /turf/space/transit/east // moving to the east + icon_state = "arrow-east" pushdirection = WEST var/static/list/phase_shift_by_y @@ -47,3 +70,23 @@ var/transit_state = (world.maxx - src.x + y_shift)%15 + 1 icon_state = "speedspace_ew_[transit_state]" +//------------------------ + +/turf/space/transit/west // moving to the west + icon_state = "arrow-west" + pushdirection = WEST + var/static/list/phase_shift_by_y + +/turf/space/transit/west/New() + ..() + if(!phase_shift_by_y) + phase_shift_by_y = get_cross_shift_list(15) + + var/y_shift = phase_shift_by_y[src.y % (phase_shift_by_y.len - 1) + 1] + var/transit_state = (world.maxx - src.x + y_shift)%15 + 1 + + var/icon/I = new(icon, "speedspace_ew_[transit_state]") + I.Flip(WEST) + icon = I + +//------------------------ \ No newline at end of file diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 84a2320a2f..2f2f17dd1d 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -145,6 +145,11 @@ proc/admin_notice(var/message, var/rights) body += {"

Rudimentary transformation:
These transformations only create a new mob type and copy stuff over. They do not take into account MMIs and similar mob-specific things. The buttons in 'Transformations' are preferred, when possible.

Observer | + \[ Xenos: Larva + Drone + Hunter + Sentinel + Queen \] | \[ Crew: Human Unathi Tajaran diff --git a/code/modules/admin/secrets/random_events/trigger_xenomorph_infestation.dm b/code/modules/admin/secrets/random_events/trigger_xenomorph_infestation.dm new file mode 100644 index 0000000000..a8af34137a --- /dev/null +++ b/code/modules/admin/secrets/random_events/trigger_xenomorph_infestation.dm @@ -0,0 +1,7 @@ +/datum/admin_secret_item/random_event/trigger_xenomorph_infestation + name = "Trigger a Xenomorph Infestation" + +/datum/admin_secret_item/random_event/trigger_xenomorph_infestation/execute(var/mob/user) + . = ..() + if(.) + return xenomorphs.attempt_random_spawn() diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index db16b214b2..350bfe9a24 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1146,6 +1146,16 @@ log_admin("[key_name(usr)] AIized [key_name(H)]") H.AIize() + else if(href_list["makealien"]) + if(!check_rights(R_SPAWN)) return + + var/mob/living/carbon/human/H = locate(href_list["makealien"]) + if(!istype(H)) + usr << "This can only be used on instances of type /mob/living/carbon/human" + return + + usr.client.cmd_admin_alienize(H) + else if(href_list["makerobot"]) if(!check_rights(R_SPAWN)) return diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 4e81807995..5f3206b6df 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -91,8 +91,8 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey"," //Options bar: mob, details ( admin = 2, dev = 3, mentor = 4, character name (0 = just ckey, 1 = ckey and character name), link? (0 no don't make it a link, 1 do so), // highlight special roles (0 = everyone has same looking name, 1 = antags / special roles get a golden name) - var/mentor_msg = "Request for Help: [get_options_bar(mob, 4, 1, 1, 0)][ai_cl]: [msg]" - msg = "Request for Help:: [get_options_bar(mob, 2, 1, 1)][ai_cl]: [msg]" + var/mentor_msg = "Request for Help: [get_options_bar(mob, 4, 1, 1, 0)][ai_cl]: [msg]" + msg = "Request for Help: [get_options_bar(mob, 2, 1, 1)][ai_cl] [msg]" var/admin_number_afk = 0 diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index a3fd6acf3e..968e7459e5 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -100,6 +100,23 @@ paiController.pai_candidates.Remove(candidate) feedback_add_details("admin_verb","MPAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/proc/cmd_admin_alienize(var/mob/M in mob_list) + set category = "Fun" + set name = "Make Alien" + + if(!ticker) + alert("Wait until the game starts") + return + if(ishuman(M)) + log_admin("[key_name(src)] has alienized [M.key].") + spawn(10) + M:Alienize() + feedback_add_details("admin_verb","MKAL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + log_admin("[key_name(usr)] made [key_name(M)] into an alien.") + message_admins("[key_name_admin(usr)] made [key_name(M)] into an alien.", 1) + else + alert("Invalid mob") + /* /client/proc/cmd_admin_monkeyize(var/mob/M in world) set category = "Fun" diff --git a/code/modules/admin/view_variables/helpers.dm b/code/modules/admin/view_variables/helpers.dm index 81780f2103..c00e598cb3 100644 --- a/code/modules/admin/view_variables/helpers.dm +++ b/code/modules/admin/view_variables/helpers.dm @@ -68,6 +68,7 @@ + "} /obj/get_view_variables_options() diff --git a/code/modules/client/preference_setup/loadout/loadout_utility.dm b/code/modules/client/preference_setup/loadout/loadout_utility.dm index c30291c3a5..5e7fa24d9f 100644 --- a/code/modules/client/preference_setup/loadout/loadout_utility.dm +++ b/code/modules/client/preference_setup/loadout/loadout_utility.dm @@ -90,4 +90,13 @@ /datum/gear/utility/pen display_name = "Fountain Pen" - path = /obj/item/weapon/pen/fountain \ No newline at end of file + path = /obj/item/weapon/pen/fountain + +/datum/gear/utility/wheelchair/color + display_name = "wheelchair" + path = /obj/item/wheelchair + cost = 4 + +/datum/gear/utility/wheelchair/color/New() + ..() + gear_tweaks = list(gear_tweak_free_color_choice) diff --git a/code/modules/client/preference_setup/loadout/loadout_xeno.dm b/code/modules/client/preference_setup/loadout/loadout_xeno.dm index 83f59b3a7b..3ace6ac998 100644 --- a/code/modules/client/preference_setup/loadout/loadout_xeno.dm +++ b/code/modules/client/preference_setup/loadout/loadout_xeno.dm @@ -83,31 +83,47 @@ ..() gear_tweaks = list(gear_tweak_free_color_choice) -/datum/gear/uniform/teshari - display_name = "smock, grey (Teshari)" - path = /obj/item/clothing/under/seromi +/datum/gear/uniform/smock + display_name = "smock selection (Teshari)" + path = /obj/item/clothing/under/seromi/smock whitelisted = "Teshari" sort_category = "Xenowear" -/datum/gear/uniform/teshari/jumpsuit - display_name = "smock, yellow (Teshari)" - path = /obj/item/clothing/under/seromi/yellow +/datum/gear/uniform/smock/New() + ..() + var/list/smocks = list() + for(var/smock in typesof(/obj/item/clothing/under/seromi/smock)) + var/obj/item/clothing/under/seromi/smock/smock_type = smock + smocks[initial(smock_type.name)] = smock_type + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(smocks)) -/datum/gear/uniform/teshari/jumpsuit/red - display_name = "smock, red (Teshari)" - path = /obj/item/clothing/under/seromi/red +/datum/gear/uniform/undercoat + display_name = "undercoat selection (Teshari)" + path = /obj/item/clothing/under/seromi/undercoat + whitelisted = "Teshari" + sort_category = "Xenowear" -/datum/gear/uniform/teshari/jumpsuit/white - display_name = "smock, white (Teshari)" - path = /obj/item/clothing/under/seromi/white +/datum/gear/uniform/undercoat/New() + ..() + var/list/undercoats = list() + for(var/undercoat in typesof(/obj/item/clothing/under/seromi/undercoat)) + var/obj/item/clothing/under/seromi/undercoat/undercoat_type = undercoat + undercoats[initial(undercoat_type.name)] = undercoat_type + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(undercoats)) -/datum/gear/uniform/teshari/jumpsuit/medical - display_name = "smock, Medical (Teshari)" - path = /obj/item/clothing/under/seromi/medical +/datum/gear/suit/cloak + display_name = "cloak selection (Teshari)" + path = /obj/item/clothing/suit/storage/seromi/cloak + whitelisted = "Teshari" + sort_category = "Xenowear" -/datum/gear/uniform/teshari/jumpsuit/rainbow - display_name = "smock, rainbow (Teshari)" - path = /obj/item/clothing/under/seromi/rainbow +/datum/gear/suit/cloak/New() + ..() + var/list/cloaks = list() + for(var/cloak in typesof(/obj/item/clothing/suit/storage/seromi/cloak)) + var/obj/item/clothing/suit/storage/seromi/cloak/cloak_type = cloak + cloaks[initial(cloak_type.name)] = cloak_type + gear_tweaks += new/datum/gear_tweak/path(sortAssoc(cloaks)) /datum/gear/mask/ipc_monitor display_name = "display monitor (Full Body Prosthetic)" diff --git a/code/modules/client/preferences_spawnpoints.dm b/code/modules/client/preferences_spawnpoints.dm index 309af7d590..5a19adddb2 100644 --- a/code/modules/client/preferences_spawnpoints.dm +++ b/code/modules/client/preferences_spawnpoints.dm @@ -22,9 +22,12 @@ var/list/spawntypes = list() return 1 +/datum/spawnpoint/proc/get_spawn_position() + return get_turf(pick(turfs)) + /datum/spawnpoint/arrivals display_name = "Arrivals Shuttle" - msg = "has arrived on the station" + msg = "will arrive to the station shortly by shuttle" /datum/spawnpoint/arrivals/New() ..() diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 6cf5d16c4a..106500add0 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -51,7 +51,7 @@ BLIND // can't see anything user.update_action_buttons() /obj/item/clothing/glasses/meson - name = "Optical Meson Scanner" + name = "optical meson scanner" desc = "Used for seeing walls, floors, and stuff through anything." icon_state = "meson" item_state_slots = list(slot_r_hand_str = "meson", slot_l_hand_str = "meson") @@ -70,7 +70,7 @@ BLIND // can't see anything prescription = 1 /obj/item/clothing/glasses/meson/aviator - name = "Engineering Aviators" + name = "engineering aviators" icon_state = "aviator_eng" off_state = "aviator" item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") @@ -78,7 +78,7 @@ BLIND // can't see anything activation_sound = 'sound/effects/pop.ogg' /obj/item/clothing/glasses/meson/aviator/prescription - name = "Prescription Engineering Aviators" + name = "prescription engineering aviators" desc = "Engineering Aviators with prescription lenses." prescription = 1 @@ -96,7 +96,7 @@ BLIND // can't see anything overlay = global_hud.science /obj/item/clothing/glasses/goggles - name = "Goggles" + name = "goggles" desc = "Just some plain old goggles." icon_state = "plaingoggles" item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") @@ -104,7 +104,7 @@ BLIND // can't see anything body_parts_covered = EYES /obj/item/clothing/glasses/night - name = "Night Vision Goggles" + name = "night vision goggles" desc = "You can totally see in the dark now!" icon_state = "night" item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") @@ -154,7 +154,7 @@ BLIND // can't see anything body_parts_covered = 0 /obj/item/clothing/glasses/material - name = "Optical Material Scanner" + name = "optical material scanner" desc = "Very confusing glasses." icon_state = "material" item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") @@ -164,11 +164,11 @@ BLIND // can't see anything vision_flags = SEE_OBJS /obj/item/clothing/glasses/material/prescription - name = "Prescription Optical Material Scanner" + name = "prescription optical material scanner" prescription = 1 /obj/item/clothing/glasses/regular - name = "Prescription Glasses" + name = "prescription glasses" desc = "Made by Nerd. Co." icon_state = "glasses" item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") @@ -176,12 +176,12 @@ BLIND // can't see anything body_parts_covered = 0 /obj/item/clothing/glasses/regular/scanners - name = "Scanning Goggles" + name = "scanning goggles" desc = "A very oddly shaped pair of goggles with bits of wire poking out the sides. A soft humming sound emanates from it." icon_state = "uzenwa_sissra_1" /obj/item/clothing/glasses/regular/hipster - name = "Prescription Glasses" + name = "prescription glasses" desc = "Made by Uncool. Co." icon_state = "hipster_glasses" @@ -193,15 +193,15 @@ BLIND // can't see anything body_parts_covered = 0 /obj/item/clothing/glasses/gglasses - name = "Green Glasses" + name = "green glasses" desc = "Forest green glasses, like the kind you'd wear when hatching a nasty scheme." icon_state = "gglasses" item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") body_parts_covered = 0 /obj/item/clothing/glasses/sunglasses - desc = "Strangely ancient technology used to help provide rudimentary eye cover. Enhanced shielding blocks many flashes." name = "sunglasses" + desc = "Strangely ancient technology used to help provide rudimentary eye cover. Enhanced shielding blocks many flashes." icon_state = "sun" item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") darkness_view = -1 @@ -280,7 +280,7 @@ BLIND // can't see anything icon_state = "aviator" /obj/item/clothing/glasses/sunglasses/sechud - name = "HUDSunglasses" + name = "\improper HUD sunglasses" desc = "Sunglasses with a HUD." icon_state = "sunSecHud" var/obj/item/clothing/glasses/hud/security/hud = null @@ -296,7 +296,7 @@ BLIND // can't see anything icon_state = "swatgoggles" /obj/item/clothing/glasses/sunglasses/sechud/aviator - name = "Security HUD aviators" + name = "security HUD aviators" desc = "Modified aviator glasses that can be switch between HUD and flash protection modes." icon_state = "aviator_sec" off_state = "aviator" @@ -338,12 +338,12 @@ BLIND // can't see anything icon_state = off_state /obj/item/clothing/glasses/sunglasses/sechud/aviator/prescription - name = "Prescription Security HUD aviators" + name = "prescription security HUD aviators" desc = "Modified aviator glasses that can be switch between HUD and flash protection modes. Comes with bonus prescription lenses." prescription = 6 /obj/item/clothing/glasses/sunglasses/medhud - name = "HUDSunglasses" + name = "\improper HUD sunglasses" desc = "Sunglasses with a HUD." icon_state = "sunMedHud" var/obj/item/clothing/glasses/hud/health/hud = null @@ -354,7 +354,7 @@ BLIND // can't see anything return /obj/item/clothing/glasses/sunglasses/medhud/aviator - name = "Medical HUD aviators" + name = "medical HUD aviators" desc = "Modified aviator glasses with a toggled health HUD." icon_state = "aviator_med" off_state = "aviator" @@ -396,12 +396,12 @@ BLIND // can't see anything icon_state = off_state /obj/item/clothing/glasses/sunglasses/medhud/aviator/prescription - name = "Prescription Medical HUD aviators" + name = "prescription medical HUD aviators" desc = "Modified aviator glasses with a toggled health HUD. Comes with bonus prescription lenses." prescription = 6 /obj/item/clothing/glasses/thermal - name = "Optical Thermal Scanner" + name = "optical thermal scanner" desc = "Thermals in the shape of glasses." icon_state = "thermal" item_state_slots = list(slot_r_hand_str = "glasses", slot_l_hand_str = "glasses") @@ -431,7 +431,7 @@ BLIND // can't see anything overlay = global_hud.thermal /obj/item/clothing/glasses/thermal/syndi //These are now a traitor item, concealed as mesons. -Pete - name = "Optical Meson Scanner" + name = "optical meson scanner" desc = "Used for seeing walls, floors, and stuff through anything." icon_state = "meson" item_state_slots = list(slot_r_hand_str = "meson", slot_l_hand_str = "meson") @@ -443,7 +443,7 @@ BLIND // can't see anything action_button_name = null /obj/item/clothing/glasses/thermal/plain/monocle - name = "Thermoncle" + name = "thermonocle" desc = "A monocle thermal." icon_state = "thermoncle" item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") @@ -454,7 +454,7 @@ BLIND // can't see anything body_parts_covered = 0 /obj/item/clothing/glasses/thermal/plain/eyepatch - name = "Optical Thermal Eyepatch" + name = "optical thermal eyepatch" desc = "An eyepatch with built-in thermal optics" icon_state = "eyepatch" item_state_slots = list(slot_r_hand_str = "blindfold", slot_l_hand_str = "blindfold") @@ -463,7 +463,7 @@ BLIND // can't see anything action_button_name = "Toggle Eyepatch" /obj/item/clothing/glasses/thermal/plain/jensen - name = "Optical Thermal Implants" + name = "optical thermal implants" desc = "A set of implantable lenses designed to augment your vision" icon_state = "thermalimplants" item_state_slots = list(slot_r_hand_str = "sunglasses", slot_l_hand_str = "sunglasses") \ No newline at end of file diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index b7df12fa0a..876340cb2a 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -104,9 +104,9 @@ flags_inv = HIDEEARS|HIDEFACE item_state_slots = list(slot_r_hand_str = "mime", slot_l_hand_str = "mime") -/obj/item/clothing/mask/gas/death_commando - name = "Death Commando Mask" - icon_state = "death_commando_mask" +/obj/item/clothing/mask/gas/commando + name = "commando mask" + icon_state = "fullgas" item_state_slots = list(slot_r_hand_str = "swat", slot_l_hand_str = "swat") siemens_coefficient = 0.2 diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index 01c1861448..159957bddb 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -62,10 +62,6 @@ var/list/supporting_limbs //If not-null, automatically splints breaks. Checked when removing the suit. -/obj/item/clothing/suit/space/New() - ..() - desc += " \"[using_map.station_short]\" is written in large block letters on the back." - /obj/item/clothing/suit/space/equipped(mob/M) check_limb_support(M) ..() diff --git a/code/modules/clothing/suits/xenos/seromi.dm b/code/modules/clothing/suits/xenos/seromi.dm new file mode 100644 index 0000000000..ccba8986d5 --- /dev/null +++ b/code/modules/clothing/suits/xenos/seromi.dm @@ -0,0 +1,134 @@ +/obj/item/clothing/suit/storage/seromi/cloak + name = "black and orange cloak " + desc = "It drapes over a Teshari's shoulders and closes at the neck with pockets convienently placed inside." + icon = 'icons/mob/species/seromi/teshari_cloak.dmi' + icon_override = 'icons/mob/species/seromi/teshari_cloak.dmi' + icon_state = "tesh_cloak_bo" + item_state = "tesh_cloak_bo" + species_restricted = list("Teshari") + body_parts_covered = UPPER_TORSO|ARMS + +/obj/item/clothing/suit/storage/seromi/cloak/black_orange + name = "black and orange cloak" + icon_state = "tesh_cloak_bo" + item_state = "tesh_cloak_bo" + +/obj/item/clothing/suit/storage/seromi/cloak/black_grey + name = "black and grey cloak" + icon_state = "tesh_cloak_bg" + item_state = "tesh_cloak_bg" + +/obj/item/clothing/suit/storage/seromi/cloak/black_midgrey + name = "black and medium grey cloak" + icon_state = "tesh_cloak_bmg" + item_state = "tesh_cloak_bmg" + +/obj/item/clothing/suit/storage/seromi/cloak/black_lightgrey + name = "black and light grey cloak" + icon_state = "tesh_cloak_blg" + item_state = "tesh_cloak_blg" + +/obj/item/clothing/suit/storage/seromi/cloak/black_white + name = "black and white cloak" + icon_state = "tesh_cloak_bw" + item_state = "tesh_cloak_bw" + +/obj/item/clothing/suit/storage/seromi/cloak/black_red + name = "black and red cloak" + icon_state = "tesh_cloak_br" + item_state = "tesh_cloak_br" + +/obj/item/clothing/suit/storage/seromi/cloak/black + name = "black cloak" + icon_state = "tesh_cloak_bn" + item_state = "tesh_cloak_bn" + +/obj/item/clothing/suit/storage/seromi/cloak/black_yellow + name = "black and yellow cloak" + icon_state = "tesh_cloak_by" + item_state = "tesh_cloak_by" + +/obj/item/clothing/suit/storage/seromi/cloak/black_green + name = "black and Green cloak" + icon_state = "tesh_cloak_bgr" + item_state = "tesh_cloak_bgr" + +/obj/item/clothing/suit/storage/seromi/cloak/black_blue + name = "black and blue cloak" + icon_state = "tesh_cloak_bbl" + item_state = "tesh_cloak_bbl" + +/obj/item/clothing/suit/storage/seromi/cloak/black_purple + name = "black and purple cloak" + icon_state = "tesh_cloak_bp" + item_state = "tesh_cloak_bp" + +/obj/item/clothing/suit/storage/seromi/cloak/black_pink + name = "black and pink cloak" + icon_state = "tesh_cloak_bpi" + item_state = "tesh_cloak_bpi" + +/obj/item/clothing/suit/storage/seromi/cloak/black_brown + name = "black and brown cloak" + icon_state = "tesh_cloak_bbr" + item_state = "tesh_cloak_bbr" + +/obj/item/clothing/suit/storage/seromi/cloak/orange_grey + name = "orange and grey cloak" + icon_state = "tesh_cloak_og" + item_state = "tesh_cloak_og" + +/obj/item/clothing/suit/storage/seromi/cloak/rainbow + name = "rainbow cloak" + icon_state = "tesh_cloak_rainbow" + item_state = "tesh_cloak_rainbow" + +/obj/item/clothing/suit/storage/seromi/cloak/lightgrey_grey + name = "light grey and grey cloak" + icon_state = "tesh_cloak_lgg" + item_state = "tesh_cloak_lgg" + +/obj/item/clothing/suit/storage/seromi/cloak/white_grey + name = "white and grey cloak" + icon_state = "tesh_cloak_wg" + item_state = "tesh_cloak_wg" + +/obj/item/clothing/suit/storage/seromi/cloak/red_grey + name = "red and grey cloak" + icon_state = "tesh_cloak_rg" + item_state = "tesh_cloak_rg" + +/obj/item/clothing/suit/storage/seromi/cloak/orange + name = "orange cloak" + icon_state = "tesh_cloak_on" + item_state = "tesh_cloak_on" + +/obj/item/clothing/suit/storage/seromi/cloak/yellow_grey + name = "yellow and grey cloak" + icon_state = "tesh_cloak_yg" + item_state = "tesh_cloak_yg" + +/obj/item/clothing/suit/storage/seromi/cloak/green_grey + name = "green and grey cloak" + icon_state = "tesh_cloak_gg" + item_state = "tesh_cloak_gg" + +/obj/item/clothing/suit/storage/seromi/cloak/blue_grey + name = "blue and grey cloak" + icon_state = "tesh_cloak_blg" + item_state = "tesh_cloak_blg" + +/obj/item/clothing/suit/storage/seromi/cloak/purple_grey + name = "purple and grey cloak" + icon_state = "tesh_cloak_pg" + item_state = "tesh_cloak_pg" + +/obj/item/clothing/suit/storage/seromi/cloak/pink_grey + name = "black and orange cloak" + icon_state = "tesh_cloak_pig" + item_state = "tesh_cloak_pig" + +/obj/item/clothing/suit/storage/seromi/cloak/brown_grey + name = "purple and grey cloak" + icon_state = "tesh_cloak_brg" + item_state = "tesh_cloak_brg" \ No newline at end of file diff --git a/code/modules/clothing/under/xenos/seromi.dm b/code/modules/clothing/under/xenos/seromi.dm index 16eb2c47fe..f99317b7d0 100644 --- a/code/modules/clothing/under/xenos/seromi.dm +++ b/code/modules/clothing/under/xenos/seromi.dm @@ -1,27 +1,167 @@ /obj/item/clothing/under/seromi - name = "small grey smock" - desc = "It looks fitted to nonhuman proportions." icon = 'icons/obj/clothing/species/seromi/uniform.dmi' icon_state = "seromi_grey" species_restricted = list("Teshari") + +/obj/item/clothing/under/seromi/smock + name = "small grey smock" + desc = "It looks fitted to nonhuman proportions." + icon_state = "seromi_grey" body_parts_covered = 0 // It's a thin piece of cloth with a neck hole. -/obj/item/clothing/under/seromi/white +/obj/item/clothing/under/seromi/smock/white name = "small white smock" icon_state = "seromi_white" -/obj/item/clothing/under/seromi/red +/obj/item/clothing/under/seromi/smock/red name = "small Security smock" icon_state = "seromi_red" -/obj/item/clothing/under/seromi/yellow +/obj/item/clothing/under/seromi/smock/yellow name = "small Engineering smock" icon_state = "seromi_yellow" -/obj/item/clothing/under/seromi/medical +/obj/item/clothing/under/seromi/smock/medical name = "small Medical uniform" icon_state = "seromi_medical" - -/obj/item/clothing/under/seromi/rainbow + +/obj/item/clothing/under/seromi/smock/science + name = "small Research uniform" + icon_state = "teshari_science" + +/obj/item/clothing/under/seromi/smock/rainbow name = "small rainbow smock" - icon_state = "seromi_rainbow" \ No newline at end of file + icon_state = "seromi_rainbow" + +/obj/item/clothing/under/seromi/undercoat + desc = "A Teshari traditional garb, with a modern twist! Made of micro and nanofibres to make it light and billowy, perfect for going fast and stylishly!" + icon = 'icons/mob/species/seromi/teshari_uniform.dmi' + icon_override = 'icons/mob/species/seromi/teshari_uniform.dmi' + icon_state = "tesh_uniform_bo" + item_state = "tesh_uniform_bo" + body_parts_covered = UPPER_TORSO|LOWER_TORSO + +/obj/item/clothing/under/seromi/undercoat/black_orange + name = "black and orange undercoat" + icon_state = "tesh_uniform_bo" + item_state = "tesh_uniform_bo" + +/obj/item/clothing/under/seromi/undercoat/black_grey + name = "black and grey undercoat" + icon_state = "tesh_uniform_bg" + item_state = "tesh_uniform_bg" + +/obj/item/clothing/under/seromi/undercoat/black_midgrey + name = "black and medium grey undercoat" + icon_state = "tesh_uniform_bmg" + item_state = "tesh_uniform_bmg" + +/obj/item/clothing/under/seromi/undercoat/black_lightgrey + name = "black and light grey undercoat" + icon_state = "tesh_uniform_blg" + item_state = "tesh_uniform_blg" + +/obj/item/clothing/under/seromi/undercoat/black_white + name = "black and white undercoat" + icon_state = "tesh_uniform_bw" + item_state = "tesh_uniform_bw" + +/obj/item/clothing/under/seromi/undercoat/black_red + name = "black and red undercoat" + icon_state = "tesh_uniform_br" + item_state = "tesh_uniform_br" + +/obj/item/clothing/under/seromi/undercoat/black + name = "black undercoat" + icon_state = "tesh_uniform_bn" + item_state = "tesh_uniform_bn" + +/obj/item/clothing/under/seromi/undercoat/black_yellow + name = "black and yellow undercoat" + icon_state = "tesh_uniform_by" + item_state = "tesh_uniform_by" + +/obj/item/clothing/under/seromi/undercoat/black_green + name = "black and Green undercoat" + icon_state = "tesh_uniform_bgr" + item_state = "tesh_uniform_bgr" + +/obj/item/clothing/under/seromi/undercoat/black_blue + name = "black and blue undercoat" + icon_state = "tesh_uniform_bbl" + item_state = "tesh_uniform_bbl" + +/obj/item/clothing/under/seromi/undercoat/black_purple + name = "black and purple undercoat" + icon_state = "tesh_uniform_bp" + item_state = "tesh_uniform_bp" + +/obj/item/clothing/under/seromi/undercoat/black_pink + name = "black and pink undercoat" + icon_state = "tesh_uniform_bpi" + item_state = "tesh_uniform_bpi" + +/obj/item/clothing/under/seromi/undercoat/black_brown + name = "black and brown undercoat" + icon_state = "tesh_uniform_bbr" + item_state = "tesh_uniform_bbr" + +/obj/item/clothing/under/seromi/undercoat/orange_grey + name = "orange and grey undercoat" + icon_state = "tesh_uniform_og" + item_state = "tesh_uniform_og" + +/obj/item/clothing/under/seromi/undercoat/rainbow + name = "rainbow undercoat" + icon_state = "tesh_uniform_rainbow" + item_state = "tesh_uniform_rainbow" + +/obj/item/clothing/under/seromi/undercoat/lightgrey_grey + name = "light grey and grey undercoat" + icon_state = "tesh_uniform_lgg" + item_state = "tesh_uniform_lgg" + +/obj/item/clothing/under/seromi/undercoat/white_grey + name = "white and grey undercoat" + icon_state = "tesh_uniform_wg" + item_state = "tesh_uniform_wg" + +/obj/item/clothing/under/seromi/undercoat/red_grey + name = "red and grey undercoat" + icon_state = "tesh_uniform_rg" + item_state = "tesh_uniform_rg" + +/obj/item/clothing/under/seromi/undercoat/orange + name = "orange undercoat" + icon_state = "tesh_uniform_on" + item_state = "tesh_uniform_on" + +/obj/item/clothing/under/seromi/undercoat/yellow_grey + name = "yellow and grey undercoat" + icon_state = "tesh_uniform_yg" + item_state = "tesh_uniform_yg" + +/obj/item/clothing/under/seromi/undercoat/green_grey + name = "green and grey undercoat" + icon_state = "tesh_uniform_gg" + item_state = "tesh_uniform_gg" + +/obj/item/clothing/under/seromi/undercoat/blue_grey + name = "blue and grey undercoat" + icon_state = "tesh_uniform_blg" + item_state = "tesh_uniform_blg" + +/obj/item/clothing/under/seromi/undercoat/purple_grey + name = "purple and grey undercoat" + icon_state = "tesh_uniform_pg" + item_state = "tesh_uniform_pg" + +/obj/item/clothing/under/seromi/undercoat/pink_grey + name = "black and orange undercoat" + icon_state = "tesh_uniform_pig" + item_state = "tesh_uniform_pig" + +/obj/item/clothing/under/seromi/undercoat/brown_grey + name = "purple and grey undercoat" + icon_state = "tesh_uniform_brg" + item_state = "tesh_uniform_brg" \ No newline at end of file diff --git a/code/modules/economy/economy_misc.dm b/code/modules/economy/economy_misc.dm index 78c9e7d012..a2cc9aafb9 100644 --- a/code/modules/economy/economy_misc.dm +++ b/code/modules/economy/economy_misc.dm @@ -50,10 +50,10 @@ /var/list/economic_species_modifier = list( /datum/species/human = 10, /datum/species/skrell = 12, - /datum/species/teshari = 9, // Skrell sponsored, - /datum/species/tajaran = 7, /datum/species/unathi = 7, - /datum/species/diona = 7, + /datum/species/tajaran = 7, + /datum/species/teshari = 6, + /datum/species/diona = 4, /datum/species/shapeshifter/promethean = 3 ) diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm index e4a1237f2b..7ee8a7bcb4 100644 --- a/code/modules/hydroponics/seed_datums.dm +++ b/code/modules/hydroponics/seed_datums.dm @@ -1170,3 +1170,23 @@ set_trait(TRAIT_PRODUCTION,7) set_trait(TRAIT_YIELD,3) set_trait(TRAIT_POTENCY,3) + +// Alien weeds. +/datum/seed/xenomorph + name = "xenomorph" + seed_name = "alien weed" + display_name = "alien weeds" + force_layer = 3 + chems = list("phoron" = list(1,3)) + +/datum/seed/xenomorph/New() + ..() + set_trait(TRAIT_PLANT_ICON,"vine2") + set_trait(TRAIT_IMMUTABLE,1) + set_trait(TRAIT_PRODUCT_COLOUR,"#3D1934") + set_trait(TRAIT_FLESH_COLOUR,"#3D1934") + set_trait(TRAIT_PLANT_COLOUR,"#3D1934") + set_trait(TRAIT_PRODUCTION,1) + set_trait(TRAIT_YIELD,-1) + set_trait(TRAIT_SPREAD,2) + set_trait(TRAIT_POTENCY,50) diff --git a/code/modules/integrated_electronics/core/special_pins/color_pin.dm b/code/modules/integrated_electronics/core/special_pins/color_pin.dm index 0fa82b4506..2d20560fb6 100644 --- a/code/modules/integrated_electronics/core/special_pins/color_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/color_pin.dm @@ -6,7 +6,6 @@ var/new_data = input("Please select a color.","[src] color writing") as null|color if(holder.check_interactivity(user) ) to_chat(user, "You input a new color into the pin.") - world << "new_data equals [new_data]." write_data_to_pin(new_data) /datum/integrated_io/color/write_data_to_pin(var/new_data) @@ -15,24 +14,18 @@ if(istext(new_data)) new_data = uppertext(new_data) if(length(new_data) != 7) // We can hex if we want to, we can leave your strings behind - world << "Wrong length." return // Cause your strings don't hex and if they don't hex var/friends = copytext(new_data, 2, 8) // Well they're are no strings of mine - world << "friends equal [friends]." // I say, we can go where we want to, a place where they will never find var/safety_dance = 1 while(safety_dance >= 7) // And we can act like we come from out of this world.log var/hex = copytext(friends, safety_dance, safety_dance+1) - world << "Checking [hex]." if(!(hex in list("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"))) - world << "Hex [hex] failed" return // Leave the fake one far behind, safety_dance++ data = new_data // And we can hex holder.on_data_written() - world << "Done." - world << "Rip." // This randomizes the color. /datum/integrated_io/color/scramble() diff --git a/code/modules/integrated_electronics/core/special_pins/list_pin.dm b/code/modules/integrated_electronics/core/special_pins/list_pin.dm index 535a535514..77d83f82b5 100644 --- a/code/modules/integrated_electronics/core/special_pins/list_pin.dm +++ b/code/modules/integrated_electronics/core/special_pins/list_pin.dm @@ -133,7 +133,6 @@ clear_list(usr) if(href_list["remove"]) - world << "Removing [href_list["pos"]]" if(href_list["pos"]) remove_from_list_by_position(usr, text2num(href_list["pos"])) else diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm index 2b8c200a27..c417c3e4fd 100644 --- a/code/modules/integrated_electronics/passive/power.dm +++ b/code/modules/integrated_electronics/passive/power.dm @@ -101,6 +101,6 @@ return var/area/A = get_area(src) if(A) - if(A.powered(EQUIP)) + if(A.powered(EQUIP) && assembly.give_power(power_amount)) A.use_power(power_amount, EQUIP) - assembly.give_power(power_amount) // give_power() handles CELLRATE on its own. + // give_power() handles CELLRATE on its own. diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm index 68fb129108..6dc7cdfc48 100644 --- a/code/modules/materials/material_recipes.dm +++ b/code/modules/materials/material_recipes.dm @@ -95,7 +95,7 @@ recipes += new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = 1) recipes += new/datum/stack_recipe("Metal crate", /obj/structure/closet/crate, 10, time = 50, one_per_turf = 1) recipes += new/datum/stack_recipe("knife grip", /obj/item/weapon/material/butterflyhandle, 4, time = 20, one_per_turf = 0, on_floor = 1, supplied_material = "[name]") - recipes += new/datum/stack_recipe("dark floor tile", /obj/item/stack/tile/floor_dark, 1, 4, 20) + recipes += new/datum/stack_recipe("dark floor tile", /obj/item/stack/tile/floor/dark, 1, 4, 20) recipes += new/datum/stack_recipe("roller bed", /obj/item/roller, 5, time = 30, on_floor = 1) recipes += new/datum/stack_recipe("whetstone", /obj/item/weapon/whetstone, 2, time = 10) @@ -111,8 +111,8 @@ recipes += new/datum/stack_recipe("reagent dispenser cartridge (large)", /obj/item/weapon/reagent_containers/chem_disp_cartridge, 5, on_floor=0) // 500u recipes += new/datum/stack_recipe("reagent dispenser cartridge (med)", /obj/item/weapon/reagent_containers/chem_disp_cartridge/medium, 3, on_floor=0) // 250u recipes += new/datum/stack_recipe("reagent dispenser cartridge (small)", /obj/item/weapon/reagent_containers/chem_disp_cartridge/small, 1, on_floor=0) // 100u - recipes += new/datum/stack_recipe("white floor tile", /obj/item/stack/tile/floor_white, 1, 4, 20) - recipes += new/datum/stack_recipe("freezer floor tile", /obj/item/stack/tile/floor_freezer, 1, 4, 20) + recipes += new/datum/stack_recipe("white floor tile", /obj/item/stack/tile/floor/white, 1, 4, 20) + recipes += new/datum/stack_recipe("freezer floor tile", /obj/item/stack/tile/floor/freezer, 1, 4, 20) recipes += new/datum/stack_recipe("shower curtain", /obj/structure/curtain, 4, time = 15, one_per_turf = 1, on_floor = 1) recipes += new/datum/stack_recipe("plastic flaps", /obj/structure/plasticflaps, 4, time = 25, one_per_turf = 1, on_floor = 1) recipes += new/datum/stack_recipe("airtight plastic flaps", /obj/structure/plasticflaps/mining, 5, time = 25, one_per_turf = 1, on_floor = 1) diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm index 12d78b366b..1de0db081e 100644 --- a/code/modules/materials/materials.dm +++ b/code/modules/materials/materials.dm @@ -642,6 +642,22 @@ var/list/name_to_material display_name = "elevator panelling" icon_colour = "#666666" +/material/resin + name = "resin" + icon_colour = "#E85DD8" + dooropen_noise = 'sound/effects/attackblob.ogg' + door_icon_base = "resin" + melting_point = T0C+300 + sheet_singular_name = "blob" + sheet_plural_name = "blobs" + +/material/resin/can_open_material_door(var/mob/living/user) + var/mob/living/carbon/M = user + if(istype(M) && locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs) + return 1 + return 0 + + /material/wood name = "wood" stack_type = /obj/item/stack/material/wood diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index ed82999950..64893a973b 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -528,11 +528,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/obj/machinery/atmospherics/unary/vent_pump/vent_found var/list/found_vents = list() for(var/obj/machinery/atmospherics/unary/vent_pump/v in machines) - if(!v.welded && v.z == T.z) + if(!v.welded && v.z == T.z && v.network && v.network.normal_members.len > 20) found_vents.Add(v) if(found_vents.len) vent_found = pick(found_vents) - host = new /mob/living/simple_animal/mouse(vent_found.loc) + host = new /mob/living/simple_animal/mouse(vent_found) else src << "Unable to find any unwelded vents to spawn mice at." @@ -541,6 +541,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp host.universal_understand = 0 announce_ghost_joinleave(src, 0, "They are now a mouse.") host.ckey = src.ckey + host.add_ventcrawl(vent_found) host << "You are now a mouse. Try to avoid interaction with players, and do not give hints away that you are more than a simple rodent." /mob/observer/dead/verb/view_manfiest() diff --git a/code/modules/mob/language/outsider.dm b/code/modules/mob/language/outsider.dm index 3e85f4efec..0a721e6f56 100644 --- a/code/modules/mob/language/outsider.dm +++ b/code/modules/mob/language/outsider.dm @@ -84,3 +84,34 @@ key = "y" machine_understands = 0 flags = RESTRICTED | HIVEMIND + +/datum/language/xenocommon + name = "Xenomorph" + colour = "alien" + desc = "The common tongue of the xenomorphs." + speech_verb = "hisses" + ask_verb = "hisses" + exclaim_verb = "hisses" + key = "4" + flags = RESTRICTED + syllables = list("sss","sSs","SSS") + +/datum/language/xenos + name = "Hivemind" + desc = "Xenomorphs have the strange ability to commune over a psychic hivemind." + speech_verb = "hisses" + ask_verb = "hisses" + exclaim_verb = "hisses" + colour = "alien" + key = "a" + flags = RESTRICTED | HIVEMIND + +/datum/language/xenos/check_special_condition(var/mob/other) + + var/mob/living/carbon/M = other + if(!istype(M)) + return 1 + if(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs) + return 1 + + return 0 diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm new file mode 100644 index 0000000000..9b72fb658f --- /dev/null +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -0,0 +1,14 @@ +/mob/living/carbon/alien/larva + name = "alien larva" + real_name = "alien larva" + adult_form = /mob/living/carbon/human + speak_emote = list("hisses") + icon_state = "larva" + language = "Hivemind" + maxHealth = 25 + health = 25 + +/mob/living/carbon/alien/larva/New() + ..() + add_language("Xenomorph") //Bonus language. + internal_organs |= new /obj/item/organ/internal/xenos/hivenode(src) diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm new file mode 100644 index 0000000000..641e572586 --- /dev/null +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -0,0 +1,13 @@ + +//Larvae regenerate health and nutrition from plasma and alien weeds. +/mob/living/carbon/alien/larva/handle_environment(var/datum/gas_mixture/environment) + + if(!environment) return + + var/turf/T = get_turf(src) + if(environment.gas["phoron"] > 0 || (T && locate(/obj/effect/alien/weeds) in T.contents)) + update_progression() + adjustBruteLoss(-1) + adjustFireLoss(-1) + adjustToxLoss(-1) + adjustOxyLoss(-1) diff --git a/code/modules/mob/living/carbon/alien/larva/progression.dm b/code/modules/mob/living/carbon/alien/larva/progression.dm new file mode 100644 index 0000000000..166ae53676 --- /dev/null +++ b/code/modules/mob/living/carbon/alien/larva/progression.dm @@ -0,0 +1,12 @@ +/mob/living/carbon/alien/larva/confirm_evolution() + + src << "You are growing into a beautiful alien! It is time to choose a caste." + src << "There are three to choose from:" + src << "Hunters are strong and agile, able to hunt away from the hive and rapidly move through ventilation shafts. Hunters generate plasma slowly and have low reserves." + src << "Sentinels are tasked with protecting the hive and are deadly up close and at a range. They are not as physically imposing nor fast as the hunters." + src << "Drones are the working class, offering the largest plasma storage and generation. They are the only caste which may evolve again, turning into the dreaded alien queen." + var/alien_caste = alert(src, "Please choose which alien caste you shall belong to.",,"Hunter","Sentinel","Drone") + return alien_caste ? "Xenomorph [alien_caste]" : null + +/mob/living/carbon/alien/larva/show_evolution_blurb() + return diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm index 1e2185fbf3..9f1f778ad2 100644 --- a/code/modules/mob/living/carbon/brain/posibrain.dm +++ b/code/modules/mob/living/carbon/brain/posibrain.dm @@ -68,7 +68,8 @@ var/turf/T = get_turf_or_move(src.loc) for (var/mob/M in viewers(T)) - M.show_message("The positronic brain chimes quietly.") + M.show_message("The positronic brain beeps as it loads a personality.") + playsound(src, 'sound/misc/boobeebeep.ogg', 50, 1) icon_state = "posibrain-occupied" /obj/item/device/mmi/digital/posibrain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer. @@ -81,7 +82,8 @@ var/turf/T = get_turf_or_move(src.loc) for (var/mob/M in viewers(T)) - M.show_message("The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?") + M.show_message("The positronic brain buzzes and beeps, and the golden lights fade away. Perhaps you could try again?") + playsound(src, 'sound/misc/buzzbeep.ogg', 50, 1) /obj/item/device/mmi/digital/posibrain/examine(mob/user) if(!..(user)) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 6a42fc6b41..f586ecd56c 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -78,6 +78,11 @@ stat("Tank Pressure", internal.air_contents.return_pressure()) stat("Distribution Pressure", internal.distribute_pressure) + var/obj/item/organ/internal/xenos/plasmavessel/P = internal_organs_by_name[O_PLASMA] //Xenomorphs. Mech. + if(P) + stat(null, "Phoron Stored: [P.stored_plasma]/[P.max_plasma]") + + if(back && istype(back,/obj/item/weapon/rig)) var/obj/item/weapon/rig/suit = back var/cell_status = "ERROR" diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 98f8f81d9c..7720016611 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -35,7 +35,7 @@ var/obj/item/organ/external/E = get_organ(organ_name) if(!E || E.is_stump()) tally += 4 - if(E.splinted) + else if(E.splinted) tally += 0.5 else if(E.status & ORGAN_BROKEN) tally += 1.5 diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 69b55e20ed..03833cfab4 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -162,6 +162,10 @@ sleep(50) var/output = "Self-Diagnostic Results:\n" + output += "Internal Temperature: [convert_k2c(bodytemperature)] Degrees Celsius\n" + + output += "Current Battery Charge: [nutrition]\n" + for(var/obj/item/organ/external/EO in organs) if(EO.brute_dam || EO.burn_dam) output += "[EO.name] - [EO.burn_dam + EO.brute_dam > ROBOLIMB_REPAIR_CAP ? "Heavy Damage" : "Light Damage"]\n" diff --git a/code/modules/mob/living/carbon/human/species/station/prometheans.dm b/code/modules/mob/living/carbon/human/species/station/prometheans.dm index 3a2eb6af49..b56b3f6308 100644 --- a/code/modules/mob/living/carbon/human/species/station/prometheans.dm +++ b/code/modules/mob/living/carbon/human/species/station/prometheans.dm @@ -22,7 +22,7 @@ var/datum/species/shapeshifter/promethean/prometheans push_flags = MONKEY|SLIME|SIMPLE_ANIMAL flags = NO_SCAN | NO_SLIP | NO_MINOR_CUT appearance_flags = HAS_SKIN_COLOR | HAS_EYE_COLOR | HAS_HAIR_COLOR | RADIATION_GLOWS - spawn_flags = SPECIES_IS_RESTRICTED + spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED health_hud_intensity = 2 breath_type = null diff --git a/code/modules/mob/living/carbon/human/species/station/seromi.dm b/code/modules/mob/living/carbon/human/species/station/seromi.dm index 120400413b..d3dd435997 100644 --- a/code/modules/mob/living/carbon/human/species/station/seromi.dm +++ b/code/modules/mob/living/carbon/human/species/station/seromi.dm @@ -13,6 +13,12 @@ max_age = 45 health_hud_intensity = 3 + + male_cough_sounds = list('sound/effects/mob_effects/tesharicougha.ogg','sound/effects/mob_effects/tesharicoughb.ogg') + female_cough_sounds = list('sound/effects/mob_effects/tesharicougha.ogg','sound/effects/mob_effects/tesharicoughb.ogg') + male_sneeze_sound = 'sound/effects/mob_effects/tesharisneeze.ogg' + female_sneeze_sound = 'sound/effects/mob_effects/tesharisneeze.ogg' + blood_color = "#D514F7" flesh_color = "#5F7BB0" base_color = "#001144" @@ -95,5 +101,4 @@ /datum/species/teshari/equip_survival_gear(var/mob/living/carbon/human/H) ..() - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H),slot_shoes) - + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H),slot_shoes) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm new file mode 100644 index 0000000000..f4022366a8 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm @@ -0,0 +1,161 @@ +// This is to replace the previous datum/disease/alien_embryo for slightly improved handling and maintainability +// It functions almost identically (see code/datums/diseases/alien_embryo.dm) + +/* +/obj/item/alien_embryo //Commented out as reference for future reproduction methods, or addition later. + name = "alien embryo" + desc = "All slimy and yuck." + icon = 'icons/mob/alien.dmi' + icon_state = "larva0_dead" + var/mob/living/affected_mob + var/stage = 0 + +/obj/item/alien_embryo/New() + if(istype(loc, /mob/living)) + affected_mob = loc + processing_objects.Add(src) + spawn(0) + AddInfectionImages(affected_mob) + else + qdel(src) + +/obj/item/alien_embryo/Destroy() + if(affected_mob) + affected_mob.status_flags &= ~(XENO_HOST) + spawn(0) + RemoveInfectionImages(affected_mob) + ..() + +/obj/item/alien_embryo/process() + if(!affected_mob) return + if(loc != affected_mob) + affected_mob.status_flags &= ~(XENO_HOST) + processing_objects.Remove(src) + spawn(0) + RemoveInfectionImages(affected_mob) + affected_mob = null + return + + if(stage < 5 && prob(3)) + stage++ + spawn(0) + RefreshInfectionImage(affected_mob) + + switch(stage) + if(2, 3) + if(prob(1)) + affected_mob.emote("sneeze") + if(prob(1)) + affected_mob.emote("cough") + if(prob(1)) + affected_mob << "Your throat feels sore." + if(prob(1)) + affected_mob << "Mucous runs down the back of your throat." + if(4) + if(prob(1)) + affected_mob.emote("sneeze") + if(prob(1)) + affected_mob.emote("cough") + if(prob(2)) + affected_mob << " Your muscles ache." + if(prob(20)) + affected_mob.take_organ_damage(1) + if(prob(2)) + affected_mob << "Your stomach hurts." + if(prob(20)) + affected_mob.adjustToxLoss(1) + affected_mob.updatehealth() + if(5) + affected_mob << "You feel something tearing its way out of your stomach..." + affected_mob.adjustToxLoss(10) + affected_mob.updatehealth() + if(prob(50)) + AttemptGrow() + +/obj/item/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1) + var/list/candidates = get_alien_candidates() + var/picked = null + + // To stop clientless larva, we will check that our host has a client + // if we find no ghosts to become the alien. If the host has a client + // he will become the alien but if he doesn't then we will set the stage + // to 2, so we don't do a process heavy check everytime. + + if(candidates.len) + picked = pick(candidates) + else if(affected_mob.client) + picked = affected_mob.key + else + stage = 4 // Let's try again later. + return + + if(affected_mob.lying) + affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_lie") + else + affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_stand") + spawn(6) + var/mob/living/carbon/alien/larva/new_xeno = new(affected_mob.loc) + new_xeno.key = picked + new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100) //To get the player's attention + if(gib_on_success) + affected_mob.gib() + qdel(src) + +/*---------------------------------------- +Proc: RefreshInfectionImage() +Des: Removes all infection images from aliens and places an infection image on all infected mobs for aliens. +----------------------------------------*/ +/obj/item/alien_embryo/proc/RefreshInfectionImage() + + for(var/mob/living/carbon/alien in player_list) + + if(!locate(/obj/item/organ/internal/xenos/hivenode) in alien.internal_organs) + continue + + if(alien.client) + for(var/image/I in alien.client.images) + if(dd_hasprefix_case(I.icon_state, "infected")) + qdel(I) + for(var/mob/living/L in mob_list) + if(iscorgi(L) || iscarbon(L)) + if(L.status_flags & XENO_HOST) + var/I = image('icons/mob/alien.dmi', loc = L, icon_state = "infected[stage]") + alien.client.images += I + +/*---------------------------------------- +Proc: AddInfectionImages(C) +Des: Checks if the passed mob (C) is infected with the alien egg, then gives each alien client an infected image at C. +----------------------------------------*/ +/obj/item/alien_embryo/proc/AddInfectionImages(var/mob/living/C) + if(C) + + for(var/mob/living/carbon/alien in player_list) + + if(!locate(/obj/item/organ/internal/xenos/hivenode) in alien.internal_organs) + continue + + if(alien.client) + if(C.status_flags & XENO_HOST) + var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[stage]") + alien.client.images += I + +/*---------------------------------------- +Proc: RemoveInfectionImage(C) +Des: Removes the alien infection image from all aliens in the world located in passed mob (C). +----------------------------------------*/ + +/obj/item/alien_embryo/proc/RemoveInfectionImages(var/mob/living/C) + + if(C) + + for(var/mob/living/carbon/alien in player_list) + + if(!locate(/obj/item/organ/internal/xenos/hivenode) in alien.internal_organs) + continue + + if(alien.client) + for(var/image/I in alien.client.images) + if(I.loc == C) + if(dd_hasprefix_case(I.icon_state, "infected")) + qdel(I) +*/ diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm new file mode 100644 index 0000000000..549e888858 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm @@ -0,0 +1,222 @@ +//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 + +//TODO: Make these simple_animals +/* //Commented out as reference for future reproduction methods, or addition later if needed. - Mech +var/const/MIN_IMPREGNATION_TIME = 100 //time it takes to impregnate someone +var/const/MAX_IMPREGNATION_TIME = 150 + +var/const/MIN_ACTIVE_TIME = 200 //time between being dropped and going idle +var/const/MAX_ACTIVE_TIME = 400 + +/obj/item/clothing/mask/facehugger + name = "alien" + desc = "It has some sort of a tube at the end of its tail." + icon = 'icons/mob/alien.dmi' + icon_state = "facehugger" + item_state = "facehugger" + w_class = 3 //note: can be picked up by aliens unlike most other items of w_class below 4 + flags = PROXMOVE + body_parts_covered = FACE|EYES + throw_range = 5 + + var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case + var/sterile = 0 + var/strength = 5 + var/attached = 0 + +/obj/item/clothing/mask/facehugger/attack_hand(user as mob) + + if((stat == CONSCIOUS && !sterile)) + if(Attach(user)) + return + + ..() + +/obj/item/clothing/mask/facehugger/attack(mob/living/M as mob, mob/user as mob) + ..() + user.drop_from_inventory(src) + Attach(M) + +/obj/item/clothing/mask/facehugger/New() + if(config.aliens_allowed) + ..() + else + qdel(src) + +/obj/item/clothing/mask/facehugger/examine(mob/user) + ..(user) + switch(stat) + if(DEAD,UNCONSCIOUS) + user << "[src] is not moving." + if(CONSCIOUS) + user << "[src] seems to be active." + if (sterile) + user << "It looks like the proboscis has been removed." + return + +/obj/item/clothing/mask/facehugger/attackby(obj/item/I, mob/user) + if(I.force) + user.do_attack_animation(src) + Die() + return + +/obj/item/clothing/mask/facehugger/bullet_act() + Die() + return + +/obj/item/clothing/mask/facehugger/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) + if(exposed_temperature > T0C+80) + Die() + return + +/obj/item/clothing/mask/facehugger/equipped(mob/M) + ..() + Attach(M) + +/obj/item/clothing/mask/facehugger/Crossed(atom/target) + HasProximity(target) + return + +/obj/item/clothing/mask/facehugger/on_found(mob/finder as mob) + if(stat == CONSCIOUS) + HasProximity(finder) + return 1 + return + +/obj/item/clothing/mask/facehugger/HasProximity(atom/movable/AM as mob|obj) + if(CanHug(AM)) + Attach(AM) + +/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed) + ..() + if(stat == CONSCIOUS) + icon_state = "[initial(icon_state)]_thrown" + spawn(15) + if(icon_state == "[initial(icon_state)]_thrown") + icon_state = "[initial(icon_state)]" + +/obj/item/clothing/mask/facehugger/throw_impact(atom/hit_atom) + ..() + if(stat == CONSCIOUS) + icon_state = "[initial(icon_state)]" + throwing = 0 + GoIdle(30,100) //stunned for a few seconds - allows throwing them to be useful for positioning but not as an offensive action (unless you're setting up a trap) + +/obj/item/clothing/mask/facehugger/proc/Attach(M as mob) + + if((!iscorgi(M) && !iscarbon(M))) + return + + if(attached) + return + + var/mob/living/carbon/C = M + if(istype(C) && locate(/obj/item/organ/internal/xenos/hivenode) in C.internal_organs) + return + + + attached++ + spawn(MAX_IMPREGNATION_TIME) + attached = 0 + + var/mob/living/L = M //just so I don't need to use : + + if(loc == L) return + if(stat != CONSCIOUS) return + if(!sterile) L.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage + + L.visible_message(" [src] leaps at [L]'s face!") + + if(iscarbon(M)) + var/mob/living/carbon/target = L + + if(target.wear_mask) + if(prob(20)) return + var/obj/item/clothing/W = target.wear_mask + if(!W.canremove) return + target.drop_from_inventory(W) + + target.visible_message(" [src] tears [W] off of [target]'s face!") + + target.equip_to_slot(src, slot_wear_mask) + target.contents += src // Monkey sanity check - Snapshot + + if(!sterile) L.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings + + GoIdle() //so it doesn't jump the people that tear it off + + spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME)) + Impregnate(L) + + return + +/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/target as mob) + if(!target || target.wear_mask != src || target.stat == DEAD) //was taken off or something + return + + if(!sterile) + new /obj/item/alien_embryo(target) + target.status_flags |= XENO_HOST + + target.visible_message(" [src] falls limp after violating [target]'s face!") + + Die() + icon_state = "[initial(icon_state)]_impregnated" + + else + target.visible_message(" [src] violates [target]'s face!") + return + +/obj/item/clothing/mask/facehugger/proc/GoActive() + if(stat == DEAD || stat == CONSCIOUS) + return + + stat = CONSCIOUS + icon_state = "[initial(icon_state)]" + + return + +/obj/item/clothing/mask/facehugger/proc/GoIdle(var/min_time=MIN_ACTIVE_TIME, var/max_time=MAX_ACTIVE_TIME) + if(stat == DEAD || stat == UNCONSCIOUS) + return + +/* RemoveActiveIndicators() */ + + stat = UNCONSCIOUS + icon_state = "[initial(icon_state)]_inactive" + + spawn(rand(min_time,max_time)) + GoActive() + return + +/obj/item/clothing/mask/facehugger/proc/Die() + if(stat == DEAD) + return + +/* RemoveActiveIndicators() */ + + icon_state = "[initial(icon_state)]_dead" + stat = DEAD + + src.visible_message("[src] curls up into a ball!") + + return + +/proc/CanHug(var/mob/M) + + if(iscorgi(M)) + return 1 + + if(!iscarbon(M)) + return 0 + + var/mob/living/carbon/C = M + if(istype(C) && locate(/obj/item/organ/internal/xenos/hivenode) in C.internal_organs) + return 0 + + if(ishuman(C)) + var/mob/living/carbon/human/H = C + if(H.head && (H.head.body_parts_covered & FACE) && !(H.head.item_flags & FLEXIBLEMATERIAL)) + return 0 + return 1 +*/ \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm new file mode 100644 index 0000000000..221808ff2e --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm @@ -0,0 +1,310 @@ +/proc/alien_queen_exists(var/ignore_self,var/mob/living/carbon/human/self) + for(var/mob/living/carbon/human/Q in living_mob_list) + if(self && ignore_self && self == Q) + continue + if(Q.species.name != "Xenomorph Queen") + continue + if(!Q.key || !Q.client || Q.stat) + continue + return 1 + return 0 + +/mob/living/carbon/human/proc/gain_plasma(var/amount) + + var/obj/item/organ/internal/xenos/plasmavessel/I = internal_organs_by_name[O_PLASMA] + if(!istype(I)) return + + if(amount) + I.stored_plasma += amount + I.stored_plasma = max(0,min(I.stored_plasma,I.max_plasma)) + +/mob/living/carbon/human/proc/check_alien_ability(var/cost,var/needs_foundation,var/needs_organ) + + var/obj/item/organ/internal/xenos/plasmavessel/P = internal_organs_by_name[O_PLASMA] + if(!istype(P)) + src << "Your plasma vessel has been removed!" + return + + if(needs_organ) + var/obj/item/organ/internal/I = internal_organs_by_name[needs_organ] + if(!I) + src << "Your [needs_organ] has been removed!" + return + else if((I.status & ORGAN_CUT_AWAY) || I.is_broken()) + src << "Your [needs_organ] is too damaged to function!" + return + + if(P.stored_plasma < cost) + src << "You don't have enough phoron stored to do that." + return 0 + + if(needs_foundation) + var/turf/T = get_turf(src) + var/has_foundation + if(T) + //TODO: Work out the actual conditions this needs. + if(!(istype(T,/turf/space))) + has_foundation = 1 + if(!has_foundation) + src << "You need a solid foundation to do that on." + return 0 + + P.stored_plasma -= cost + return 1 + +// Free abilities. +/mob/living/carbon/human/proc/transfer_plasma(mob/living/carbon/human/M as mob in oview()) + set name = "Transfer Plasma" + set desc = "Transfer Plasma to another alien" + set category = "Abilities" + + if (get_dist(src,M) <= 1) + src << "You need to be closer." + return + + var/obj/item/organ/internal/xenos/plasmavessel/I = M.internal_organs_by_name[O_PLASMA] + if(!istype(I)) + src << "Their plasma vessel is missing." + return + + var/amount = input("Amount:", "Transfer Plasma to [M]") as num + if (amount) + amount = abs(round(amount)) + if(check_alien_ability(amount,0,O_PLASMA)) + M.gain_plasma(amount) + M << "[src] has transfered [amount] plasma to you." + src << "You have transferred [amount] plasma to [M]." + return + +// Queen verbs. +/mob/living/carbon/human/proc/lay_egg() + + set name = "Lay Egg (75)" + set desc = "Lay an egg to produce huggers to impregnate prey with." + set category = "Abilities" + + if(!config.aliens_allowed) + src << "You begin to lay an egg, but hesitate. You suspect it isn't allowed." + verbs -= /mob/living/carbon/human/proc/lay_egg + return + + if(locate(/obj/effect/alien/egg) in get_turf(src)) + src << "There's already an egg here." + return + + if(check_alien_ability(75,1,O_EGG)) + visible_message("[src] has laid an egg!") + new /obj/effect/alien/egg(loc) + + return + +// Drone verbs. +/mob/living/carbon/human/proc/evolve() + set name = "Evolve (500)" + set desc = "Produce an interal egg sac capable of spawning children. Only one queen can exist at a time." + set category = "Abilities" + + if(alien_queen_exists()) + src << "We already have an active queen." + return + + if(check_alien_ability(500)) + visible_message("[src] begins to twist and contort!", "You begin to evolve!") + src.set_species("Xenomorph Queen") + + return + +/mob/living/carbon/human/proc/plant() + set name = "Plant Weeds (50)" + set desc = "Plants some alien weeds" + set category = "Abilities" + + if(check_alien_ability(50,1,O_RESIN)) + visible_message("[src] has planted some alien weeds!") + new /obj/effect/alien/weeds/node(loc) + return + +/mob/living/carbon/human/proc/corrosive_acid(O as obj|turf in oview(1)) //If they right click to corrode, an error will flash if its an invalid target./N + set name = "Corrosive Acid (200)" + set desc = "Drench an object in acid, destroying it over time." + set category = "Abilities" + + if(!O in oview(1)) + src << "[O] is too far away." + return + + // OBJ CHECK + var/cannot_melt + if(isobj(O)) + var/obj/I = O + if(I.unacidable) + cannot_melt = 1 + else + if(istype(O, /turf/simulated/wall)) + var/turf/simulated/wall/W = O + if(W.material.flags & MATERIAL_UNMELTABLE) + cannot_melt = 1 + else if(istype(O, /turf/simulated/floor)) +/* var/turf/simulated/floor/F = O //Turfs are qdel'd to space (Even asteroid tiles), will need to be touched by someone smarter than myself. -Mech + if(F.flooring && (F.flooring.flags & TURF_ACID_IMMUNE)) +*/ + cannot_melt = 1 + + if(cannot_melt) + src << "You cannot dissolve this object." + return + + if(check_alien_ability(200,0,O_ACID)) + new /obj/effect/alien/acid(get_turf(O), O) + visible_message("[src] vomits globs of vile stuff all over [O]. It begins to sizzle and melt under the bubbling mess of acid!") + + return + +/mob/living/carbon/human/proc/neurotoxin(mob/target as mob in oview()) + set name = "Spit Neurotoxin (50)" + set desc = "Spits neurotoxin at someone, paralyzing them for a short time if they are not wearing protective gear." + set category = "Abilities" + + if(!check_alien_ability(50,0,O_ACID)) + return + + if(stat || paralysis || stunned || weakened || lying || restrained() || buckled) + src << "You cannot spit neurotoxin in your current state." + return + + visible_message("[src] spits neurotoxin at [target]!", "You spit neurotoxin at [target].") + + var/obj/item/projectile/energy/neurotoxin/A = new(get_turf(src)) + A.firer = src + A.launch(target) + return + +/mob/living/carbon/human/proc/resin() // -- TLE + set name = "Secrete Resin (75)" + set desc = "Secrete tough malleable resin." + set category = "Abilities" + + var/choice = input("Choose what you wish to shape.","Resin building") as null|anything in list("resin door","resin wall","resin membrane","resin nest") //would do it through typesof but then the player choice would have the type path and we don't want the internal workings to be exposed ICly - Urist + if(!choice) + return + + if(!check_alien_ability(75,1,O_RESIN)) + return + + visible_message("[src] vomits up a thick purple substance and begins to shape it!", "You shape a [choice].") + switch(choice) + if("resin door") + new /obj/structure/simple_door/resin(loc) + if("resin wall") + new /obj/effect/alien/resin/wall(loc) + if("resin membrane") + new /obj/effect/alien/resin/membrane(loc) + if("resin nest") + new /obj/structure/bed/nest(loc) + return + +/mob/living/carbon/human/proc/leap() + set category = "Abilities" + set name = "Leap" + set desc = "Leap at a target and grab them aggressively." + + if(last_special > world.time) + return + + if(stat || paralysis || stunned || weakened || lying || restrained() || buckled) + src << "You cannot leap in your current state." + return + + var/list/choices = list() + for(var/mob/living/M in view(6,src)) + if(!istype(M,/mob/living/silicon)) + choices += M + choices -= src + + var/mob/living/T = input(src,"Who do you wish to leap at?") as null|anything in choices + + if(!T || !src || src.stat) return + + if(get_dist(get_turf(T), get_turf(src)) > 4) return + + if(last_special > world.time) + return + + if(stat || paralysis || stunned || weakened || lying || restrained() || buckled) + src << "You cannot leap in your current state." + return + + last_special = world.time + 75 + status_flags |= LEAPING + + src.visible_message("\The [src] leaps at [T]!") + src.throw_at(get_step(get_turf(T),get_turf(src)), 4, 1, src) + playsound(src.loc, 'sound/voice/shriek1.ogg', 50, 1) + + sleep(5) + + if(status_flags & LEAPING) status_flags &= ~LEAPING + + if(!src.Adjacent(T)) + src << "You miss!" + return + + T.Weaken(3) + + var/use_hand = "left" + if(l_hand) + if(r_hand) + src << "You need to have one hand free to grab someone." + return + else + use_hand = "right" + + src.visible_message("\The [src] seizes [T] aggressively!") + + var/obj/item/weapon/grab/G = new(src,T) + if(use_hand == "left") + l_hand = G + else + r_hand = G + + G.state = GRAB_PASSIVE + G.icon_state = "grabbed1" + G.synch() + +/mob/living/carbon/human/proc/gut() + set category = "Abilities" + set name = "Gut" + set desc = "While grabbing someone aggressively, rip their guts out or tear them apart." + + if(last_special > world.time) + return + + if(stat || paralysis || stunned || weakened || lying) + src << "You cannot do that in your current state." + return + + var/obj/item/weapon/grab/G = locate() in src + if(!G || !istype(G)) + src << "You are not grabbing anyone." + return + + if(G.state < GRAB_AGGRESSIVE) + src << "You must have an aggressive grab to gut your prey!" + return + + last_special = world.time + 50 + + visible_message("\The [src] rips viciously at \the [G.affecting]'s body with its claws!") + + if(istype(G.affecting,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = G.affecting + H.apply_damage(50,BRUTE) + if(H.stat == 2) + H.gib() + + else + var/mob/living/M = G.affecting + if(!istype(M)) return //wut + M.apply_damage(50,BRUTE) + if(M.stat == 2) + M.gib() diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm new file mode 100644 index 0000000000..e9a1ec1673 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm @@ -0,0 +1,326 @@ +//Stand-in until this is made more lore-friendly. +/datum/species/xenos + name = "Xenomorph" + name_plural = "Xenomorphs" + + default_language = "Xenomorph" + language = "Hivemind" + unarmed_types = list(/datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong) + hud_type = /datum/hud_data/alien + rarity_value = 3 + + has_fine_manipulation = 0 + siemens_coefficient = 0 + gluttonous = 3 + + brute_mod = 0.5 // Hardened carapace. + burn_mod = 2 // Weak to fire. + + warning_low_pressure = 50 + hazard_low_pressure = -1 + + cold_level_1 = 50 + cold_level_2 = -1 + cold_level_3 = -1 + + flags = NO_SCAN | NO_PAIN | NO_SLIP | NO_POISON | NO_MINOR_CUT + spawn_flags = SPECIES_IS_RESTRICTED + + reagent_tag = IS_XENOS + + blood_color = "#05EE05" + flesh_color = "#282846" + gibbed_anim = "gibbed-a" + dusted_anim = "dust-a" + death_message = "lets out a waning guttural screech, green blood bubbling from its maw." + death_sound = 'sound/voice/hiss6.ogg' + + speech_sounds = list('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg') + speech_chance = 100 + + breath_type = null + poison_type = null + + vision_flags = SEE_SELF|SEE_MOBS + + has_organ = list( + O_HEART = /obj/item/organ/internal/heart, + O_BRAIN = /obj/item/organ/internal/brain/xeno, + O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel, + O_HIVE = /obj/item/organ/internal/xenos/hivenode, + O_NUTRIENT = /obj/item/organ/internal/diona/nutrients + ) + + bump_flag = ALIEN + swap_flags = ~HEAVY + push_flags = (~HEAVY) ^ ROBOT + + var/alien_number = 0 + var/caste_name = "creature" // Used to update alien name. + var/weeds_heal_rate = 1 // Health regen on weeds. + var/weeds_plasma_rate = 5 // Plasma regen on weeds. + + has_limbs = list( + BP_TORSO = list("path" = /obj/item/organ/external/chest), + BP_GROIN = list("path" = /obj/item/organ/external/groin), + BP_HEAD = list("path" = /obj/item/organ/external/head/no_eyes), + BP_L_ARM = list("path" = /obj/item/organ/external/arm), + BP_R_ARM = list("path" = /obj/item/organ/external/arm/right), + BP_L_LEG = list("path" = /obj/item/organ/external/leg), + BP_R_LEG = list("path" = /obj/item/organ/external/leg/right), + BP_L_HAND = list("path" = /obj/item/organ/external/hand), + BP_R_HAND = list("path" = /obj/item/organ/external/hand/right), + BP_L_FOOT = list("path" = /obj/item/organ/external/foot), + BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right) + ) + +/datum/species/xenos/get_bodytype() + return "Xenomorph" + +/datum/species/xenos/get_random_name() + return "alien [caste_name] ([alien_number])" + +/datum/species/xenos/can_understand(var/mob/other) + + if(istype(other,/mob/living/carbon/alien/larva)) + return 1 + + return 0 + +/datum/species/xenos/hug(var/mob/living/carbon/human/H,var/mob/living/target) + H.visible_message("[H] caresses [target] with its scythe-like arm.", \ + "You caress [target] with your scythe-like arm.") + +/datum/species/xenos/handle_post_spawn(var/mob/living/carbon/human/H) + + if(H.mind) + H.mind.assigned_role = "Alien" + H.mind.special_role = "Alien" + + alien_number++ //Keep track of how many aliens we've had so far. + H.real_name = "alien [caste_name] ([alien_number])" + H.name = H.real_name + + ..() + +/datum/species/xenos/handle_environment_special(var/mob/living/carbon/human/H) + + var/turf/T = H.loc + if(!T) return + var/datum/gas_mixture/environment = T.return_air() + if(!environment) return + + if(environment.gas["phoron"] > 0 || locate(/obj/effect/alien/weeds) in T) + if(!regenerate(H)) + var/obj/item/organ/internal/xenos/plasmavessel/P = H.internal_organs_by_name[O_PLASMA] + P.stored_plasma += weeds_plasma_rate + P.stored_plasma = min(max(P.stored_plasma,0),P.max_plasma) + ..() + +/datum/species/xenos/proc/regenerate(var/mob/living/carbon/human/H) + var/heal_rate = weeds_heal_rate + var/mend_prob = 10 + if (!H.resting) + heal_rate = weeds_heal_rate / 3 + mend_prob = 1 + + //first heal damages + if (H.getBruteLoss() || H.getFireLoss() || H.getOxyLoss() || H.getToxLoss()) + H.adjustBruteLoss(-heal_rate) + H.adjustFireLoss(-heal_rate) + H.adjustOxyLoss(-heal_rate) + H.adjustToxLoss(-heal_rate) + if (prob(5)) + H << "You feel a soothing sensation come over you..." + return 1 + + //next internal organs + for(var/obj/item/organ/I in H.internal_organs) + if(I.damage > 0) + I.damage = max(I.damage - heal_rate, 0) + if (prob(5)) + H << "You feel a soothing sensation within your [I.parent_organ]..." + return 1 + + //next mend broken bones, approx 10 ticks each + for(var/obj/item/organ/external/E in H.bad_external_organs) + if (E.status & ORGAN_BROKEN) + if (prob(mend_prob)) + if (E.mend_fracture()) + H << "You feel something mend itself inside your [E.name]." + return 1 + + return 0 +/* +/datum/species/xenos/handle_login_special(var/mob/living/carbon/human/H) + H.AddInfectionImages() + ..() + +/datum/species/xenos/handle_logout_special(var/mob/living/carbon/human/H) + H.RemoveInfectionImages() + ..() +*/ +/datum/species/xenos/drone + name = "Xenomorph Drone" + caste_name = "drone" + weeds_plasma_rate = 15 + slowdown = 1 + tail = "xenos_drone_tail" + rarity_value = 5 + + icobase = 'icons/mob/human_races/xenos/r_xenos_drone.dmi' + deform = 'icons/mob/human_races/xenos/r_xenos_drone.dmi' + + has_organ = list( + O_HEART = /obj/item/organ/internal/heart, + O_BRAIN = /obj/item/organ/internal/brain/xeno, + O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/queen, + O_ACID = /obj/item/organ/internal/xenos/acidgland, + O_HIVE = /obj/item/organ/internal/xenos/hivenode, + O_RESIN = /obj/item/organ/internal/xenos/resinspinner, + O_NUTRIENT = /obj/item/organ/internal/diona/nutrients + ) + + inherent_verbs = list( + /mob/living/proc/ventcrawl, + /mob/living/carbon/human/proc/regurgitate, + /mob/living/carbon/human/proc/plant, + /mob/living/carbon/human/proc/transfer_plasma, + /mob/living/carbon/human/proc/evolve, + /mob/living/carbon/human/proc/resin, + /mob/living/carbon/human/proc/corrosive_acid + ) + +/datum/species/xenos/drone/handle_post_spawn(var/mob/living/carbon/human/H) + + var/mob/living/carbon/human/A = H + if(!istype(A)) + return ..() + ..() + +/datum/species/xenos/hunter + + name = "Xenomorph Hunter" + weeds_plasma_rate = 5 + caste_name = "hunter" + slowdown = -2 + total_health = 150 + tail = "xenos_hunter_tail" + + icobase = 'icons/mob/human_races/xenos/r_xenos_hunter.dmi' + deform = 'icons/mob/human_races/xenos/r_xenos_hunter.dmi' + + has_organ = list( + O_HEART = /obj/item/organ/internal/heart, + O_BRAIN = /obj/item/organ/internal/brain/xeno, + O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/hunter, + O_HIVE = /obj/item/organ/internal/xenos/hivenode, + O_NUTRIENT = /obj/item/organ/internal/diona/nutrients + ) + + inherent_verbs = list( + /mob/living/proc/ventcrawl, + /mob/living/carbon/human/proc/tackle, + /mob/living/carbon/human/proc/gut, + /mob/living/carbon/human/proc/leap, + /mob/living/carbon/human/proc/psychic_whisper, + /mob/living/carbon/human/proc/regurgitate + ) + +/datum/species/xenos/sentinel + name = "Xenomorph Sentinel" + weeds_plasma_rate = 10 + caste_name = "sentinel" + slowdown = 0 + total_health = 125 + tail = "xenos_sentinel_tail" + + icobase = 'icons/mob/human_races/xenos/r_xenos_sentinel.dmi' + deform = 'icons/mob/human_races/xenos/r_xenos_sentinel.dmi' + + has_organ = list( + O_HEART = /obj/item/organ/internal/heart, + O_BRAIN = /obj/item/organ/internal/brain/xeno, + O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/sentinel, + O_ACID = /obj/item/organ/internal/xenos/acidgland, + O_HIVE = /obj/item/organ/internal/xenos/hivenode, + O_NUTRIENT = /obj/item/organ/internal/diona/nutrients + ) + + inherent_verbs = list( + /mob/living/proc/ventcrawl, + /mob/living/carbon/human/proc/tackle, + /mob/living/carbon/human/proc/regurgitate, + /mob/living/carbon/human/proc/transfer_plasma, + /mob/living/carbon/human/proc/corrosive_acid, + /mob/living/carbon/human/proc/neurotoxin + ) + +/datum/species/xenos/queen + + name = "Xenomorph Queen" + total_health = 250 + weeds_heal_rate = 5 + weeds_plasma_rate = 20 + caste_name = "queen" + slowdown = 4 + tail = "xenos_queen_tail" + rarity_value = 10 + + icobase = 'icons/mob/human_races/xenos/r_xenos_queen.dmi' + deform = 'icons/mob/human_races/xenos/r_xenos_queen.dmi' + + has_organ = list( + O_HEART = /obj/item/organ/internal/heart, + O_BRAIN = /obj/item/organ/internal/brain/xeno, + O_EGG = /obj/item/organ/internal/xenos/eggsac, + O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/queen, + O_ACID = /obj/item/organ/internal/xenos/acidgland, + O_HIVE = /obj/item/organ/internal/xenos/hivenode, + O_RESIN = /obj/item/organ/internal/xenos/resinspinner, + O_NUTRIENT = /obj/item/organ/internal/diona/nutrients + ) + + inherent_verbs = list( + /mob/living/proc/ventcrawl, + /mob/living/carbon/human/proc/psychic_whisper, + /mob/living/carbon/human/proc/regurgitate, + /mob/living/carbon/human/proc/lay_egg, + /mob/living/carbon/human/proc/plant, + /mob/living/carbon/human/proc/transfer_plasma, + /mob/living/carbon/human/proc/corrosive_acid, + /mob/living/carbon/human/proc/neurotoxin, + /mob/living/carbon/human/proc/resin + ) + +/datum/species/xenos/queen/handle_login_special(var/mob/living/carbon/human/H) + ..() + // Make sure only one official queen exists at any point. + if(!alien_queen_exists(1,H)) + H.real_name = "alien queen ([alien_number])" + H.name = H.real_name + else + H.real_name = "alien princess ([alien_number])" + H.name = H.real_name + +/datum/hud_data/alien + + icon = 'icons/mob/screen1_alien.dmi' + has_a_intent = 1 + has_m_intent = 1 + has_warnings = 1 + has_hands = 1 + has_drop = 1 + has_throw = 1 + has_resist = 1 + has_pressure = 0 + has_nutrition = 0 + has_bodytemp = 0 + has_internals = 0 + + gear = list( + "o_clothing" = list("loc" = ui_belt, "name" = "Suit", "slot" = slot_wear_suit, "state" = "equip", "dir" = SOUTH), + "head" = list("loc" = ui_id, "name" = "Hat", "slot" = slot_head, "state" = "hair"), + "storage1" = list("loc" = ui_storage1, "name" = "Left Pocket", "slot" = slot_l_store, "state" = "pocket"), + "storage2" = list("loc" = ui_storage2, "name" = "Right Pocket", "slot" = slot_r_store, "state" = "pocket"), + ) diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/xenomorphs.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/xenomorphs.dm new file mode 100644 index 0000000000..3fb6958427 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/xenomorphs.dm @@ -0,0 +1,52 @@ +proc/create_new_xenomorph(var/alien_caste,var/target) + + target = get_turf(target) + if(!target || !alien_caste) return + + var/mob/living/carbon/human/new_alien = new(target) + new_alien.set_species("Xenomorph [alien_caste]") + return new_alien + +/mob/living/carbon/human/xdrone/New(var/new_loc) + h_style = "Bald" + ..(new_loc, "Xenomorph Drone") + +/mob/living/carbon/human/xsentinel/New(var/new_loc) + h_style = "Bald" + ..(new_loc, "Xenomorph Sentinel") + +/mob/living/carbon/human/xhunter/New(var/new_loc) + h_style = "Bald" + ..(new_loc, "Xenomorph Hunter") + +/mob/living/carbon/human/xqueen/New(var/new_loc) + h_style = "Bald" + ..(new_loc, "Xenomorph Queen") + +// I feel like we should generalize/condense down all the various icon-rendering antag procs. +/*---------------------------------------- +Proc: AddInfectionImages() +Des: Gives the client of the alien an image on each infected mob. +----------------------------------------*/ +/* +/mob/living/carbon/human/proc/AddInfectionImages() + if (client) + for (var/mob/living/C in mob_list) + if(C.status_flags & XENO_HOST) + var/obj/item/alien_embryo/A = locate() in C + var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]") + client.images += I + return +*/ +/*---------------------------------------- +Proc: RemoveInfectionImages() +Des: Removes all infected images from the alien. +----------------------------------------*/ +/* +/mob/living/carbon/human/proc/RemoveInfectionImages() + if (client) + for(var/image/I in client.images) + if(dd_hasprefix_case(I.icon_state, "infected")) + qdel(I) + return +*/ diff --git a/code/modules/mob/living/silicon/pai/life.dm b/code/modules/mob/living/silicon/pai/life.dm index 374cfd5acc..d818d6edf2 100644 --- a/code/modules/mob/living/silicon/pai/life.dm +++ b/code/modules/mob/living/silicon/pai/life.dm @@ -9,6 +9,7 @@ for (var/mob/M in viewers(T)) M.show_message("The data cable rapidly retracts back into its spool.", 3, "You hear a click and the sound of wire spooling rapidly.", 2) qdel(src.cable) + src.cable = null handle_regular_hud_updates() diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 0c63b55608..78e40b6667 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -312,21 +312,20 @@ var/finalized = "No" while(finalized == "No" && src.client) - choice = input(usr,"What would you like to use for your mobile chassis icon? This decision can only be made once.") as null|anything in possible_chassis + choice = input(usr,"What would you like to use for your mobile chassis icon?") as null|anything in possible_chassis if(!choice) return icon_state = possible_chassis[choice] finalized = alert("Look at your sprite. Is this what you wish to use?",,"No","Yes") chassis = possible_chassis[choice] - verbs -= /mob/living/silicon/pai/proc/choose_chassis - verbs += /mob/living/proc/hide + verbs |= /mob/living/proc/hide /mob/living/silicon/pai/proc/choose_verbs() set category = "pAI Commands" set name = "Choose Speech Verbs" - var/choice = input(usr,"What theme would you like to use for your speech verbs? This decision can only be made once.") as null|anything in possible_say_verbs + var/choice = input(usr,"What theme would you like to use for your speech verbs?") as null|anything in possible_say_verbs if(!choice) return var/list/sayverbs = possible_say_verbs[choice] @@ -334,8 +333,6 @@ speak_exclamation = sayverbs[(sayverbs.len>1 ? 2 : sayverbs.len)] speak_query = sayverbs[(sayverbs.len>2 ? 3 : sayverbs.len)] - verbs -= /mob/living/silicon/pai/proc/choose_verbs - /mob/living/silicon/pai/lay_down() set name = "Rest" set category = "IC" diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 70bf0c7475..4932f52bdf 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -671,7 +671,6 @@ var/global/list/robot_modules = list( "Treadhead" = "Miner", "Drone" = "drone-miner" ) - supported_upgrades = list(/obj/item/borg/upgrade/jetpack) /obj/item/weapon/robot_module/robot/miner/New() ..() diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index b915411544..c6b8bee691 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -248,14 +248,14 @@ if((stat == CONSCIOUS) && (!icon_rest || !resting || !incapacitated(INCAPACITATION_DISABLED) )) icon_state = icon_living - //Resting or KO'd - else if(((stat == UNCONSCIOUS) || resting || incapacitated(INCAPACITATION_DISABLED) ) && icon_rest) - icon_state = icon_rest - //Dead else if(stat >= DEAD) icon_state = icon_dead + //Resting or KO'd + else if(((stat == UNCONSCIOUS) || resting || incapacitated(INCAPACITATION_DISABLED) ) && icon_rest) + icon_state = icon_rest + //Backup else icon_state = initial(icon_state) diff --git a/code/modules/mob/living/simple_animal/slime/combat.dm b/code/modules/mob/living/simple_animal/slime/combat.dm index eb77f338c2..0068ee728c 100644 --- a/code/modules/mob/living/simple_animal/slime/combat.dm +++ b/code/modules/mob/living/simple_animal/slime/combat.dm @@ -32,7 +32,7 @@ if(L.isSynthetic()) to_chat(src, "This subject is not biological...") return FALSE - if(L.getarmor(null, "bio") >= 80) + if(L.getarmor(null, "bio") >= 75) to_chat(src, "I cannot reach this subject's biological matter...") return FALSE if(istype(L, /mob/living/simple_animal/slime)) diff --git a/code/modules/mob/living/simple_animal/slime/subtypes.dm b/code/modules/mob/living/simple_animal/slime/subtypes.dm index 4f71f91d3f..0de8c33b4c 100644 --- a/code/modules/mob/living/simple_animal/slime/subtypes.dm +++ b/code/modules/mob/living/simple_animal/slime/subtypes.dm @@ -331,7 +331,8 @@ glows = TRUE coretype = /obj/item/slime_extract/ruby - description_info = "This slime is unnaturally stronger, allowing it to hit much harder, take less damage, and be stunned for less time." + description_info = "This slime is unnaturally stronger, allowing it to hit much harder, take less damage, and be stunned for less time. \ + Their glomp attacks also send the victim flying." slime_mutation = list( /mob/living/simple_animal/slime/dark_purple, @@ -344,6 +345,17 @@ ..() add_modifier(/datum/modifier/slime_strength, null, src) // Slime is always swole. +/mob/living/simple_animal/slime/ruby/DoPunch(var/mob/living/L) + ..() // Do regular attacks. + + if(istype(L)) + if(a_intent == I_HURT) + visible_message("\The [src] sends \the [L] flying with the impact!") + playsound(src, "punch", 50, 1) + L.Weaken(1) + var/throwdir = get_dir(src, L) + L.throw_at(get_edge_target_turf(L, throwdir), 3, 1, src) + /mob/living/simple_animal/slime/amber desc = "This slime seems to be an expert in the culinary arts, as they create their own food to share with others. \ @@ -355,7 +367,7 @@ coretype = /obj/item/slime_extract/amber description_info = "This slime feeds nearby entities passively while it is alive. This can cause uncontrollable \ - slime growth and reproduction if not kept in check." + slime growth and reproduction if not kept in check. The amber slime cannot feed itself, but can be fed by other amber slimes." slime_mutation = list( /mob/living/simple_animal/slime/silver, diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index b01d346c23..0d4b3ad085 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -1,4 +1,10 @@ // fun if you want to typecast humans/monkeys/etc without writing long path-filled lines. +/proc/isxenomorph(A) + if(istype(A, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = A + return istype(H.species, /datum/species/xenos) + return 0 + /proc/issmall(A) if(A && istype(A, /mob/living)) var/mob/living/L = A diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 03e4227f6e..da4b79e33a 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -161,6 +161,31 @@ qdel(src) return O +//human -> alien +/mob/living/carbon/human/proc/Alienize() + if (transforming) + return + for(var/obj/item/W in src) + drop_from_inventory(W) + regenerate_icons() + transforming = 1 + canmove = 0 + icon = null + invisibility = 101 + for(var/t in organs) + qdel(t) + + var/alien_caste = pick("Hunter","Sentinel","Drone") + var/mob/living/carbon/human/new_xeno = create_new_xenomorph(alien_caste,loc) + + new_xeno.a_intent = I_HURT + new_xeno.key = key + + new_xeno << "You are now an alien." + qdel(src) + return + + /mob/living/carbon/human/proc/corgize() if (transforming) return diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm index a055409531..1a40a3d072 100644 --- a/code/modules/organs/robolimbs.dm +++ b/code/modules/organs/robolimbs.dm @@ -21,7 +21,9 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ scroll=ipc_scroll;\ console=ipc_console;\ glider=ipc_gol_glider;\ - rainbow=ipc_rainbow" + rainnbow=ipc_rainbow;\ + smiley=ipc_smiley;\ + database=ipc_database" /proc/populate_robolimb_list() basic_robolimb = new() @@ -80,6 +82,35 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ parts = list(BP_HEAD) monitor_styles = standard_monitor_styles +/datum/robolimb/grayson + company = "Grayson" + desc = "This limb has a sturdy and heavy build to it." + icon = 'icons/mob/human_races/cyberlimbs/grayson/grayson_main.dmi' + unavailable_to_build = 1 + monitor_styles = "blank=grayson_off;\ + green=grayson_green;\ + rgb=grayson_rgb" + +/datum/robolimb/grayson_alt1 + company = "Grayson - Reinforced" + desc = "This limb has a sturdy and heavy build to it." + icon = 'icons/mob/human_races/cyberlimbs/grayson/grayson_alt1.dmi' + unavailable_to_build = 1 + parts = list(BP_HEAD) + monitor_styles = "blank=grayson_alt_off;\ + green=grayson_alt_green;\ + scroll=grayson_alt_scroll;\ + rgb=grayson_alt_rgb;\ + rainbow=grayson_alt_rainbow" + +/datum/robolimb/grayson_monitor + company = "Grayson Monitor" + desc = "This limb has a sturdy and heavy build to it, and uses plastics in the place of glass for the monitor." + icon = 'icons/mob/human_races/cyberlimbs/grayson/grayson_monitor.dmi' + unavailable_to_build = 1 + parts = list(BP_HEAD) + monitor_styles = standard_monitor_styles + /datum/robolimb/hephaestus company = "Hephaestus" desc = "This limb has a militaristic black and green casing with gold stripes." @@ -201,6 +232,9 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\ /obj/item/weapon/disk/limb/bishop company = "Bishop" +/obj/item/weapon/disk/limb/grayson + company = "Grayson" + /obj/item/weapon/disk/limb/hephaestus company = "Hephaestus" diff --git a/code/modules/organs/subtypes/xenos.dm b/code/modules/organs/subtypes/xenos.dm new file mode 100644 index 0000000000..95024a6355 --- /dev/null +++ b/code/modules/organs/subtypes/xenos.dm @@ -0,0 +1,51 @@ +//XENOMORPH ORGANS +/obj/item/organ/internal/xenos + name = "xeno organ" + icon = 'icons/effects/blood.dmi' + desc = "It smells like an accident in a chemical factory." + +/obj/item/organ/internal/xenos/eggsac + name = "egg sac" + parent_organ = BP_GROIN + icon_state = "xgibmid1" + organ_tag = O_EGG + +/obj/item/organ/internal/xenos/plasmavessel + name = "plasma vessel" + parent_organ = BP_TORSO + icon_state = "xgibdown1" + organ_tag = O_PLASMA + var/stored_plasma = 0 + var/max_plasma = 500 + +/obj/item/organ/internal/xenos/plasmavessel/queen + name = "bloated plasma vessel" + stored_plasma = 200 + max_plasma = 500 + +/obj/item/organ/internal/xenos/plasmavessel/sentinel + stored_plasma = 100 + max_plasma = 250 + +/obj/item/organ/internal/xenos/plasmavessel/hunter + name = "tiny plasma vessel" + stored_plasma = 100 + max_plasma = 150 + +/obj/item/organ/internal/xenos/acidgland + name = "acid gland" + parent_organ = BP_HEAD + icon_state = "xgibtorso" + organ_tag = O_ACID + +/obj/item/organ/internal/xenos/hivenode + name = "hive node" + parent_organ = BP_TORSO + icon_state = "xgibmid2" + organ_tag = O_HIVE + +/obj/item/organ/internal/xenos/resinspinner + name = "resin spinner" + parent_organ = BP_HEAD + icon_state = "xgibmid2" + organ_tag = O_RESIN diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index e7dfe7d095..990c97b1c2 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -79,7 +79,6 @@ /obj/item/weapon/pen/reagent flags = OPENCONTAINER - slot_flags = SLOT_BELT origin_tech = list(TECH_MATERIAL = 2, TECH_ILLEGAL = 5) /obj/item/weapon/pen/reagent/New() diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 7e4de1841c..dd5c5336bd 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -302,7 +302,7 @@ var/list/solars_list = list() M.unset_control() if(connected_tracker) connected_tracker.unset_control() - ..() + return ..() /obj/machinery/power/solar_control/disconnect_from_network() ..() @@ -408,25 +408,23 @@ var/list/solars_list = list() if(do_after(user, 20)) if (src.stat & BROKEN) user << "The broken glass falls out." - var/obj/structure/frame/A = new /obj/structure/frame( src.loc ) + var/obj/structure/frame/A = new /obj/structure/frame/computer( src.loc ) new /obj/item/weapon/material/shard( src.loc ) var/obj/item/weapon/circuitboard/solar_control/M = new /obj/item/weapon/circuitboard/solar_control( A ) for (var/obj/C in src) C.loc = src.loc A.circuit = M - A.frame_type = "computer" A.state = 3 A.icon_state = "computer_3" A.anchored = 1 qdel(src) else user << "You disconnect the monitor." - var/obj/structure/frame/A = new /obj/structure/frame( src.loc ) + var/obj/structure/frame/A = new /obj/structure/frame/computer( src.loc ) var/obj/item/weapon/circuitboard/solar_control/M = new /obj/item/weapon/circuitboard/solar_control( A ) for (var/obj/C in src) C.loc = src.loc A.circuit = M - A.frame_type = "computer" A.state = 4 A.icon_state = "computer_4" A.anchored = 1 diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 2e8373866c..c3f9532a51 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -460,6 +460,23 @@ name = "rifle clip (7.62mm practice)" ammo_type = /obj/item/ammo_casing/a762p +/obj/item/ammo_magazine/m762svd + name = "\improper SVD magazine (7.62mm)" + icon_state = "SVD" + mag_type = MAGAZINE + caliber = "7.62mm" + matter = list(DEFAULT_WALL_MATERIAL = 2000) + ammo_type = /obj/item/ammo_casing/a762 + max_ammo = 10 + multiple_sprites = 1 + +/obj/item/ammo_magazine/m762svd/ap + name = "\improper SVD magazine (7.62mm armor-piercing)" + ammo_type = /obj/item/ammo_casing/a762/ap + +/obj/item/ammo_magazine/m762svd/empty + initial_ammo = 0 + ///////// 12g ///////// /obj/item/ammo_magazine/m12gdrum @@ -487,10 +504,34 @@ /obj/item/ammo_magazine/m12gdrum/empty initial_ammo = 0 +/obj/item/ammo_magazine/clip/c12g + name = "ammo clip (12g slug)" + icon_state = "12gclipslug" //largely a codersprite, looks good enough. feel free to make a better one. + desc = "A color-coded metal clip for holding and quickly loading shotgun shells. This one is loaded with slugs." + caliber = "12g" + ammo_type = /obj/item/ammo_casing/a12g + matter = list(DEFAULT_WALL_MATERIAL = 1790) // slugs shells x4 + 350 metal for the clip itself. + max_ammo = 4 + multiple_sprites = 1 + +/obj/item/ammo_magazine/clip/c12g/pellet + name = "ammo clip (12g buckshot)" + icon_state = "12gclipshell" + desc = "A color-coded metal clip for holding and quickly loading shotgun shells. This one is loaded with buckshot." + ammo_type = /obj/item/ammo_casing/a12g/pellet + matter = list(DEFAULT_WALL_MATERIAL = 1790) // buckshot and slugs cost the same + +/obj/item/ammo_magazine/clip/c12g/beanbag + name = "ammo clip (12g beanbag)" + icon_state = "12gclipbeanbag" + desc = "A color-coded metal clip for holding and quickly loading shotgun shells. This one is loaded with beanbags." + ammo_type = /obj/item/ammo_casing/a12g/beanbag + matter = list(DEFAULT_WALL_MATERIAL = 1070) //beanbags x4 + 350 metal + ///////// .75 Gyrojet ///////// /obj/item/ammo_magazine/m75 - name = "ammo magazine (.75 Gyrojet)" + name = "magazine (.75 Gyrojet)" icon_state = "75" mag_type = MAGAZINE caliber = ".75" @@ -511,32 +552,4 @@ ammo_type = /obj/item/ammo_casing/cap matter = list(DEFAULT_WALL_MATERIAL = 600) max_ammo = 7 - multiple_sprites = 1 - - -/obj/item/ammo_magazine/clip/c12g - name = "ammo clip (12g slug)" - icon_state = "12gclip_s" //largely a codersprite, looks good enough. feel free to make a better one. - desc = "A color-coded metal clip for holding and quickly loading shotgun shells. This one is loaded with slugs." - caliber = "12g" - ammo_type = /obj/item/ammo_casing/a12g - matter = list(DEFAULT_WALL_MATERIAL = 1790) // slugs shells x4 + 350 metal for the clip itself. - max_ammo = 4 - -/obj/item/ammo_magazine/clip/c12g/pellet - name = "ammo clip (12g buckshot)" - icon_state = "12gclip_p" - desc = "A color-coded metal clip for holding and quickly loading shotgun shells. This one is loaded with buckshot." - ammo_type = /obj/item/ammo_casing/a12g/pellet - matter = list(DEFAULT_WALL_MATERIAL = 1790) // buckshot and slugs cost the same - -/obj/item/ammo_magazine/clip/c12g/beanbag - name = "ammo clip (12g beanbag)" - icon_state = "12gclip_bean" - desc = "A color-coded metal clip for holding and quickly loading shotgun shells. This one is loaded with beanbags." - ammo_type = /obj/item/ammo_casing/a12g/beanbag - matter = list(DEFAULT_WALL_MATERIAL = 1070) //beanbags x4 + 350 metal - - - - + multiple_sprites = 1 \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 604c936172..de28d0d7c5 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -111,7 +111,8 @@ obj/item/weapon/gun/energy/retro desc = "The HI DMR 9E is an older design of Hesphaistos Industries. A designated marksman rifle capable of shooting powerful \ ionized beams, this is a weapon to kill from a distance." icon_state = "sniper" - item_state_slots = list(slot_r_hand_str = "laser", slot_l_hand_str = "laser") //placeholder + item_state = "sniper" + item_state_slots = list(slot_r_hand_str = "z8carbine", slot_l_hand_str = "z8carbine") //placeholder fire_sound = 'sound/weapons/gauss_shoot.ogg' origin_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 5, TECH_POWER = 4) projectile_type = /obj/item/projectile/beam/sniper diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 85cb07264f..16aaf4c14d 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -23,7 +23,7 @@ /obj/item/weapon/gun/projectile/automatic/c20r name = "submachine gun" - desc = "The C-20r is a lightweight and rapid firing SMG, for when you REALLY need someone dead. Uses 10mm rounds. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp." + desc = "The C-20r is a lightweight and rapid firing SMG, for when you REALLY need someone dead. It has 'Scarborough Arms - Per falcis, per pravitas' inscribed on the stock. Uses 10mm rounds." icon_state = "c20r" item_state = "c20r" w_class = ITEMSIZE_NORMAL @@ -51,7 +51,7 @@ /obj/item/weapon/gun/projectile/automatic/sts35 name = "assault rifle" - desc = "The rugged STS-35 is a durable automatic weapon of a make popular on the frontier worlds. Uses 5.45mm rounds. This one is unmarked." + desc = "The rugged STS-35 is a durable automatic weapon of a make popular on the frontier worlds. Uses 5.45mm rounds." icon_state = "arifle" item_state = null w_class = ITEMSIZE_LARGE @@ -173,7 +173,7 @@ /obj/item/weapon/gun/projectile/automatic/l6_saw name = "light machine gun" - desc = "A rather traditionally made L6 SAW with a pleasantly lacquered wooden pistol grip. Has 'Aussec Armoury- 2531' engraved on the reciever" + desc = "A rather traditionally made L6 SAW with a pleasantly lacquered wooden pistol grip. 'Aussec Armoury-2531' is engraved on the reciever. Uses 5.45mm rounds. It's also compatible with magazines from STS-35 assault rifles." icon_state = "l6closed100" item_state = "l6closed" w_class = ITEMSIZE_LARGE @@ -245,7 +245,7 @@ /obj/item/weapon/gun/projectile/automatic/as24 name = "automatic shotgun" - desc = "The AS-24 is a durable, rugged looking automatic weapon of a make popular on the frontier worlds. Uses 12 gauge shells. It is unmarked." + desc = "The AS-24 is a rugged looking automatic shotgun produced for the military by Gurov Projectile Weapons LLC. For very obvious reasons, it's illegal to own in many juristictions. Uses 12g rounds." icon_state = "ashot" item_state = null w_class = ITEMSIZE_LARGE @@ -276,7 +276,7 @@ /obj/item/weapon/gun/projectile/automatic/mini_uzi name = "\improper Uzi" - desc = "A lightweight, compact, fast firing gun, for when you want someone really dead. Uses .45 rounds." + desc = "The iconic Uzi is a lightweight, compact, fast firing machine pistol. Cybersun Industries famously still produces these designs, which have changed little since the 20th century. Uses .45 rounds." icon_state = "mini-uzi" w_class = ITEMSIZE_NORMAL load_method = MAGAZINE @@ -341,10 +341,10 @@ icon_state = (ammo_magazine)? "tommygun" : "tommygun-empty" // update_held_icon() -/obj/item/weapon/gun/projectile/automatic/carbine // Admin abuse assault rifle. ToDo: Make this less shit. Maybe remove its autofire, and make it spawn with only 10 rounds at start. - name = "assault carbine" - desc = "The bullpup configured GP3000 is a lightweight, compact, military-grade assault rifle produced by Gurov Projectile Weapons LLC. It is sold almost exclusively to standing armies. The serial number on this one has been scratched off. Uses 5.45mm rounds." - icon_state = "bullpup" +/obj/item/weapon/gun/projectile/automatic/bullpup // Admin abuse assault rifle. ToDo: Make this less shit. Maybe remove its autofire, and make it spawn with only 10 rounds at start. + name = "bullpup rifle" + desc = "The bullpup configured GP3000 is a battle rifle produced by Gurov Projectile Weapons LLC. It is sold almost exclusively to standing armies. Uses 7.62mm rounds." + icon_state = "bullpup-small" item_state = "bullpup" w_class = ITEMSIZE_LARGE force = 10 @@ -352,21 +352,22 @@ origin_tech = list(TECH_COMBAT = 6, TECH_MATERIAL = 1, TECH_ILLEGAL = 4) slot_flags = SLOT_BACK load_method = MAGAZINE - magazine_type = /obj/item/ammo_magazine/m762m + magazine_type = /obj/item/ammo_magazine/m762 allowed_magazines = list(/obj/item/ammo_magazine/m762, /obj/item/ammo_magazine/m762m) one_handed_penalty = 4 firemodes = list( list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null), - list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=6, burst_accuracy=list(0,-1,-2), dispersion=list(0.0, 0.6, 0.6)) + list(mode_name="2-round bursts", burst=2, fire_delay=null, move_delay=6, burst_accuracy=list(0,-1), dispersion=list(0.0, 0.6)) ) -/obj/item/weapon/gun/projectile/automatic/carbine/update_icon(var/ignore_inhands) +/obj/item/weapon/gun/projectile/automatic/bullpup/update_icon(var/ignore_inhands) ..() if(istype(ammo_magazine,/obj/item/ammo_magazine/m762)) - icon_state = "bullpup-small" // If using the smaller magazines, use the small mag sprite. + icon_state = "bullpup-small" + else if(istype(ammo_magazine,/obj/item/ammo_magazine/m762m)) + icon_state = "bullpup" else - icon_state = "bullpup-empty" - item_state = (ammo_magazine)? "bullpup" : "bullpup-empty" + item_state = "bullpup-empty" if(!ignore_inhands) update_held_icon() \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile/pistol.dm b/code/modules/projectiles/guns/projectile/pistol.dm index e77f219edc..504350a198 100644 --- a/code/modules/projectiles/guns/projectile/pistol.dm +++ b/code/modules/projectiles/guns/projectile/pistol.dm @@ -10,11 +10,7 @@ fire_sound = 'sound/weapons/semiauto.ogg' load_method = MAGAZINE -/obj/item/weapon/gun/projectile/colt/detective - desc = "A Martian recreation of an old Terran pistol. Uses .45 rounds." - magazine_type = /obj/item/ammo_magazine/m45/rubber - -/obj/item/weapon/gun/projectile/colt/detective/update_icon() +/obj/item/weapon/gun/projectile/colt/update_icon() if(ammo_magazine) if(unique_reskin) icon_state = unique_reskin @@ -26,6 +22,10 @@ else icon_state = "[initial(icon_state)]-e" +/obj/item/weapon/gun/projectile/colt/detective + desc = "A Martian recreation of an old Terran pistol. Uses .45 rounds." + magazine_type = /obj/item/ammo_magazine/m45/rubber + /obj/item/weapon/gun/projectile/colt/detective/verb/rename_gun() set name = "Name Gun" set category = "Object" diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index bddbdfb741..75697bccb2 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -68,8 +68,8 @@ // Blade Runner pistol. /obj/item/weapon/gun/projectile/revolver/deckard - name = "Deckard .38" - desc = "A custom-built revolver, based off the semi-popular Detective Special model." + name = "\improper Deckard .38" + desc = "A custom-built revolver, based off the semi-popular Detective Special model. Uses .38-Special rounds." icon_state = "deckard-empty" caliber = ".38" origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2) @@ -105,7 +105,7 @@ /obj/item/weapon/gun/projectile/revolver/judge name = "\"The Judge\"" - desc = "A revolving hand-shotgun by Cybersun Industries that packs the power of a 12 guage in the palm of your hand (if you don't break your wrist). Uses 12 shotgun rounds." + desc = "A revolving hand-shotgun by Cybersun Industries that packs the power of a 12 guage in the palm of your hand (if you don't break your wrist). Uses 12g rounds." icon_state = "judge" caliber = "12g" origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2, TECH_ILLEGAL = 4) @@ -118,7 +118,7 @@ /obj/item/weapon/gun/projectile/revolver/lemat name = "LeMat Revolver" - desc = "The LeMat Revolver is a 9 shot revolver with a secondary firing barrel loading shotgun shells. For when you really need something dead." + desc = "The LeMat Revolver is a 9 shot revolver with a secondary firing barrel loading shotgun shells. For when you really need something dead. Uses .38-Special and 12g rounds depending on the barrel." icon_state = "lemat" item_state = "revolver" origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2) diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 2f4ba9d978..d2012b4c66 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -1,6 +1,6 @@ /obj/item/weapon/gun/projectile/shotgun/pump name = "shotgun" - desc = "The mass-produced W-T Remmington 29x shotgun is a favourite of police and security forces on many worlds. Useful for sweeping alleys." + desc = "The mass-produced W-T Remmington 29x shotgun is a favourite of police and security forces on many worlds. Uses 12g rounds." icon_state = "shotgun" item_state = "shotgun" max_shells = 4 @@ -43,7 +43,7 @@ /obj/item/weapon/gun/projectile/shotgun/pump/combat name = "combat shotgun" - desc = "Built for close quarters combat, the Hesphaistos Industries KS-40 is widely regarded as a weapon of choice for repelling boarders." + desc = "Built for close quarters combat, the Hesphaistos Industries KS-40 is widely regarded as a weapon of choice for repelling boarders. Uses 12g rounds." icon_state = "cshotgun" item_state = "cshotgun" origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 2) @@ -53,7 +53,7 @@ /obj/item/weapon/gun/projectile/shotgun/doublebarrel name = "double-barreled shotgun" - desc = "A true classic." + desc = "A truely classic weapon. No need to change what works. Uses 12g rounds." icon_state = "dshotgun" item_state = "dshotgun" //SPEEDLOADER because rapid unloading. @@ -80,7 +80,7 @@ /obj/item/weapon/gun/projectile/shotgun/doublebarrel/flare name = "signal shotgun" - desc = "A double-barreled shotgun meant to fire signal flash shells." + desc = "A double-barreled shotgun meant to fire signal flash shells. Uses 12g rounds." ammo_type = /obj/item/ammo_casing/a12g/flash /obj/item/weapon/gun/projectile/shotgun/doublebarrel/unload_ammo(user, allow_dump) @@ -112,7 +112,7 @@ /obj/item/weapon/gun/projectile/shotgun/doublebarrel/sawn name = "sawn-off shotgun" - desc = "Omar's coming!" + desc = "Omar's coming!" // I'm not gonna add "Uses 12g rounds." to this one. I'll just let this reference go undisturbed. icon_state = "sawnshotgun" item_state = "sawnshotgun" slot_flags = SLOT_BELT|SLOT_HOLSTER diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm index 9a16f68a4c..183de3cf17 100644 --- a/code/modules/projectiles/guns/projectile/sniper.dm +++ b/code/modules/projectiles/guns/projectile/sniper.dm @@ -4,8 +4,7 @@ name = "anti-materiel rifle" desc = "A portable anti-armour rifle fitted with a scope, the HI PTR-7 Rifle was originally designed to used against armoured exosuits. It is capable of punching through windows and non-reinforced walls with ease. Fires armor piercing 14.5mm shells." icon_state = "heavysniper" - item_state = "l6closed-empty" // placeholder - item_state_slots = list(slot_r_hand_str = "heavysniper", slot_l_hand_str = "heavysniper") + item_state_slots = list(slot_r_hand_str = "l6closed-empty", slot_l_hand_str = "l6closed-empty") // placeholder w_class = ITEMSIZE_HUGE // So it can't fit in a backpack. force = 10 slot_flags = SLOT_BACK @@ -69,17 +68,15 @@ ////////////// Dragunov Sniper Rifle ////////////// -/* // Commented out until it's not worthless. Also might be nice to have a new icon that looks more sci-fi Dragunov-ish. /obj/item/weapon/gun/projectile/SVD name = "\improper Dragunov" - desc = "The SVD, also known as the Dragunov, was mass produced with an Optical Sniper Sight so simple that even Ivan can figure out how it works. Too bad for you that it's written in Russian. Uses 7.62mm rounds." + desc = "The SVD, also known as the Dragunov, is mass produced with an Optical Sniper Sight so simple that even Ivan can use it. Too bad for you that the inscriptions are written in Russian. Uses 7.62mm rounds." icon_state = "SVD" item_state = "SVD" w_class = ITEMSIZE_HUGE // So it can't fit in a backpack. force = 10 slot_flags = SLOT_BACK // Needs a sprite. origin_tech = list(TECH_COMBAT = 8, TECH_MATERIAL = 2, TECH_ILLEGAL = 8) - recoil = 2 //extra kickback caliber = "7.62mm" load_method = MAGAZINE accuracy = -3 //shooting at the hip @@ -87,13 +84,11 @@ // requires_two_hands = 1 one_handed_penalty = 4 // The weapon itself is heavy, and the long barrel makes it hard to hold steady with just one hand. fire_sound = 'sound/weapons/SVD_shot.ogg' - magazine_type = /obj/item/ammo_magazine/SVD - allowed_magazines = list(/obj/item/ammo_magazine/SVD, /obj/item/ammo_magazine/m762) + magazine_type = /obj/item/ammo_magazine/m762svd + allowed_magazines = list(/obj/item/ammo_magazine/m762svd) /obj/item/weapon/gun/projectile/SVD/update_icon() ..() -// if(istype(ammo_magazine,/obj/item/ammo_magazine/m762) -// icon_state = "SVD-bigmag" //No icon for this exists yet. if(ammo_magazine) icon_state = "SVD" else @@ -104,4 +99,4 @@ set name = "Use Scope" set popup_menu = 1 - toggle_scope(2.0)*/ \ No newline at end of file + toggle_scope(2.0) \ No newline at end of file diff --git a/code/modules/random_map/drop/drop_types.dm b/code/modules/random_map/drop/drop_types.dm index 722aeec09e..f66198e095 100644 --- a/code/modules/random_map/drop/drop_types.dm +++ b/code/modules/random_map/drop/drop_types.dm @@ -82,7 +82,7 @@ var/global/list/datum/supply_drop_loot/supply_drop /obj/item/weapon/storage/belt/security/tactical/bandolier, /obj/item/clothing/accessory/storage/black_drop_pouches, /obj/item/weapon/storage/backpack/dufflebag/sec, - /obj/item/weapon/gun/projectile/automatic/carbine, + /obj/item/weapon/gun/projectile/automatic/bullpup, /obj/item/ammo_magazine/m762/ap, /obj/item/ammo_magazine/m762, /obj/item/weapon/shield/energy, diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index 3c71a0b089..e1d6211786 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -363,6 +363,17 @@ src.updateUsrDialog() return 0 + if(istype(O,/obj/item/weapon/gripper)) + var/obj/item/weapon/gripper/B = O //B, for Borg. + if(!B.wrapped) + user << "\The [B] is not holding anything." + return 0 + else + var/B_held = B.wrapped + user << "You use \the [B] to load \the [src] with \the [B_held]." + + return 0 + if(!sheet_reagents[O.type] && (!O.reagents || !O.reagents.total_volume)) user << "\The [O] is not suitable for blending." return 1 diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index 25f6025b98..0bb6b223ab 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -258,6 +258,10 @@ /datum/reagent/toxin/plantbgone/touch_obj(var/obj/O, var/volume) if(istype(O, /obj/effect/plant)) qdel(O) + else if(istype(O, /obj/effect/alien/weeds/)) + var/obj/effect/alien/weeds/alien_weeds = O + alien_weeds.health -= rand(15, 35) + alien_weeds.healthcheck() /datum/reagent/toxin/plantbgone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) if(alien == IS_DIONA) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 55981fd672..a66b02cded 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -747,13 +747,31 @@ other types of metals and chemistry for reagents). sort_string = "VASBA" /datum/design/item/experimental_welder - name = "Expiermental Welding Tool" + name = "Experimental welding tool" desc = "A welding tool that generate fuel for itself." id = "expwelder" req_tech = list(TECH_ENGINEERING = 4, TECH_PHORON = 3, TECH_MATERIAL = 4) materials = list(DEFAULT_WALL_MATERIAL = 70, "glass" = 120, "phoron" = 100) build_path = /obj/item/weapon/weldingtool/experimental sort_string = "VASCA" + +/datum/design/item/hand_drill + name = "Hand drill" + desc = "A simple powered hand drill." + id = "handdrill" + req_tech = list(TECH_ENGINEERING = 3, TECH_MATERIAL = 2) + materials = list(DEFAULT_WALL_MATERIAL = 300, "silver" = 100) + build_path = /obj/item/weapon/screwdriver/power + sort_string = "VASDA" + +/datum/design/item/jaws_life + name = "Jaws of life" + desc = "A set of jaws of life, compressed through the magic of science." + id = "jawslife" + req_tech = list(TECH_ENGINEERING = 3, TECH_MATERIAL = 2) + materials = list(DEFAULT_WALL_MATERIAL = 300, "silver" = 100) + build_path = /obj/item/weapon/crowbar/power + sort_string = "VASEA" /* CIRCUITS BELOW */ @@ -1618,7 +1636,7 @@ CIRCUITS BELOW build_path = /obj/item/device/integrated_circuit_printer sort_string = "VCAAG" -/datum/design/item/custom_circuit_printer +/datum/design/item/custom_circuit_printer_upgrade name = "Integrated circuit printer upgrade - advanced designs" desc = "Allows the integrated circuit printer to create advanced circuits" id = "ic_printer_upgrade_adv" diff --git a/code/modules/research/prosfab_designs.dm b/code/modules/research/prosfab_designs.dm index 1323d0a449..f26c66bc9a 100644 --- a/code/modules/research/prosfab_designs.dm +++ b/code/modules/research/prosfab_designs.dm @@ -298,7 +298,7 @@ build_path = /obj/item/borg/upgrade/jetpack /datum/design/item/prosfab/robot_upgrade/syndicate - name = "Illegal upgrade" + name = "Scrambled equipment module" desc = "Allows for the construction of lethal upgrades for cyborgs." id = "borg_syndicate_module" req_tech = list(TECH_COMBAT = 4, TECH_ILLEGAL = 3) diff --git a/code/modules/shuttles/shuttle.dm b/code/modules/shuttles/shuttle.dm index e42196b56b..3f7d7473a9 100644 --- a/code/modules/shuttles/shuttle.dm +++ b/code/modules/shuttles/shuttle.dm @@ -42,16 +42,30 @@ if(!istype(docking_controller)) world << "warning: shuttle with docking tag [docking_controller_tag] could not find it's controller!" +// Return false to abort a jump, before the 'warmup' phase. +/datum/shuttle/proc/pre_warmup_checks() + return TRUE + +// Ditto, but for afterwards. +/datum/shuttle/proc/post_warmup_checks() + return TRUE + /datum/shuttle/proc/short_jump(var/area/origin,var/area/destination) if(moving_status != SHUTTLE_IDLE) return + if(!pre_warmup_checks()) + return + moving_status = SHUTTLE_WARMUP spawn(warmup_time*10) make_sounds(origin, HYPERSPACE_WARMUP) sleep(5 SECONDS) // so the sound finishes. + if(!post_warmup_checks()) + moving_status = SHUTTLE_IDLE + if (moving_status == SHUTTLE_IDLE) make_sounds(origin, HYPERSPACE_END) return //someone cancelled the launch @@ -66,6 +80,9 @@ if(moving_status != SHUTTLE_IDLE) return + if(!pre_warmup_checks()) + return + //it would be cool to play a sound here moving_status = SHUTTLE_WARMUP spawn(warmup_time*10) @@ -73,6 +90,9 @@ make_sounds(departing, HYPERSPACE_WARMUP) sleep(5 SECONDS) // so the sound finishes. + if(!post_warmup_checks()) + moving_status = SHUTTLE_IDLE + if (moving_status == SHUTTLE_IDLE) make_sounds(departing, HYPERSPACE_END) return //someone cancelled the launch diff --git a/code/modules/shuttles/shuttle_arrivals.dm b/code/modules/shuttles/shuttle_arrivals.dm new file mode 100644 index 0000000000..7b8a6026c8 --- /dev/null +++ b/code/modules/shuttles/shuttle_arrivals.dm @@ -0,0 +1,69 @@ +// The new arrivals shuttle. +/datum/shuttle/ferry/arrivals + name = "Arrivals" + location = 1 + warmup_time = 25 // Warmup takes 5 seconds, so 30 total. + always_process = TRUE + var/launch_delay = 3 + + area_offsite = /area/shuttle/arrival/pre_game // not really 'pre game' but this area is already defined and unused + area_station = /area/shuttle/arrival/station + docking_controller_tag = "arrivals_shuttle" + dock_target_station = "arrivals_dock" + +// For debugging. +/obj/machinery/computer/shuttle_control/arrivals + name = "shuttle control console" + req_access = list(access_cent_general) + shuttle_tag = "Arrivals" + +// Unlike most shuttles, the arrivals shuttle is completely automated, so we need to put some additional code here. + + +// This proc checks if anyone is on the shuttle. +/datum/shuttle/ferry/arrivals/proc/check_for_passengers(area/A) + for(var/mob/living/L in A) + return TRUE + return FALSE + +// This is to stop the shuttle if someone tries to stow away when its leaving. +/datum/shuttle/ferry/arrivals/post_warmup_checks() + if(!location) // If we're at station. + if(check_for_passengers(area_station)) + return FALSE + return TRUE + +/datum/shuttle/ferry/arrivals/process() + if(process_state == IDLE_STATE) + + if(location) // If we're off-station (space). + if(check_for_passengers(area_offsite)) // No point arriving with an empty shuttle. + warmup_time = initial(warmup_time) + launch() + message_passengers(area_offsite, "Arriving at [using_map.station_name] in thirty seconds...") + spawn(10 SECONDS) + message_passengers(area_offsite, "Arriving at [using_map.station_name] in twenty seconds.") + spawn(10 SECONDS) + message_passengers(area_offsite, "Arriving at [using_map.station_name] in ten seconds. Please buckle up.") + + else // We are at the station. + if(!check_for_passengers(area_station)) // Don't leave with anyone. + if(launch_delay) // Give some time to get on the docks so people don't get trapped inbetween the dock airlocks. + launch_delay-- + else + launch_delay = initial(launch_delay) + warmup_time = 0 // Gotta go fast. + launch() + + ..() // Do everything else + +/datum/shuttle/ferry/arrivals/proc/message_passengers(area/A, var/message) + for(var/mob/M in A) + to_chat(M, message) + +/* +/datum/shuttle/ferry/arrivals/current_dock_target() + if(location) // If we're off station. + return null // Nothing to dock to in space. + return ..() +*/ \ No newline at end of file diff --git a/code/modules/shuttles/shuttle_ferry.dm b/code/modules/shuttles/shuttle_ferry.dm index d076357735..c122da96f1 100644 --- a/code/modules/shuttles/shuttle_ferry.dm +++ b/code/modules/shuttles/shuttle_ferry.dm @@ -4,6 +4,7 @@ var/location = 0 //0 = at area_station, 1 = at area_offsite var/direction = 0 //0 = going to station, 1 = going to offsite. var/process_state = IDLE_STATE + var/always_process = FALSE var/in_use = null //tells the controller whether this shuttle needs processing diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm index 205089773d..9dc0f65836 100644 --- a/code/modules/surgery/organs_internal.dm +++ b/code/modules/surgery/organs_internal.dm @@ -12,6 +12,47 @@ var/obj/item/organ/external/affected = target.get_organ(target_zone) return affected && affected.open == (affected.encased ? 3 : 2) + +////////////////////////////////////////////////////////////////// +// ALIEN EMBRYO SURGERY // +////////////////////////////////////////////////////////////////// // Here for future reference incase it's needed. See: Alien_embryo.dm and Alien_facehugger.dm +/* +/datum/surgery_step/internal/remove_embryo + allowed_tools = list( + /obj/item/weapon/surgical/hemostat = 100, \ + /obj/item/weapon/wirecutters = 75, \ + /obj/item/weapon/material/kitchen/utensil/fork = 20 + ) + blood_level = 2 + + min_duration = 80 + max_duration = 100 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/embryo = 0 + for(var/obj/item/alien_embryo/A in target) + embryo = 1 + break + + if (!hasorgans(target)) + return + var/obj/item/organ/external/affected = target.get_organ(target_zone) + return ..() && affected && embryo && affected.open == 3 && target_zone == BP_TORSO + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/msg = "[user] starts to pull something out from [target]'s ribcage with \the [tool]." + var/self_msg = "You start to pull something out from [target]'s ribcage with \the [tool]." + user.visible_message(msg, self_msg) + target.custom_pain("Something hurts horribly in your chest!",1) + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + user.visible_message("[user] rips the larva out of [target]'s ribcage!", + "You rip the larva out of [target]'s ribcage!") + + for(var/obj/item/alien_embryo/A in target) + A.loc = A.loc.loc +*/ ////////////////////////////////////////////////////////////////// // CHEST INTERNAL ORGAN SURGERY // ////////////////////////////////////////////////////////////////// diff --git a/html/changelog.html b/html/changelog.html index e062e723b9..2debd89613 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -53,6 +53,105 @@ -->
+

26 August 2017

+

Belsima updated:

+ +

MagmaRam updated:

+ + +

20 August 2017

+

Anewbe updated:

+ +

Atermonera updated:

+ +

Belsima updated:

+ +

Cirra updated:

+ +

Leshana updated:

+ +

LorenLuke updated:

+ +

MagmaRam updated:

+ +

Nalarac updated:

+ +

PrismaticGynoid updated:

+ +

Sarmie updated:

+ +

09 May 2017

Anewbe updated: