This commit is contained in:
Seris02
2019-11-21 13:08:23 +08:00
159 changed files with 1504 additions and 1004 deletions
@@ -56,7 +56,7 @@
if(used)
to_chat(H, "You already used this contract!")
return
var/list/candidates = pollCandidatesForMob("Do you want to play as a wizard's [href_list["school"]] apprentice?", ROLE_WIZARD, null, ROLE_WIZARD, 150, src)
var/list/candidates = pollCandidatesForMob("Do you want to play as a wizard's [href_list["school"]] apprentice?", ROLE_WIZARD, null, ROLE_WIZARD, 150, src, ignore_category = POLL_IGNORE_WIZARD)
if(LAZYLEN(candidates))
if(QDELETED(src))
return
@@ -182,6 +182,10 @@
name = "syndicate medical teleporter"
borg_to_spawn = "Medical"
/obj/item/antag_spawner/nuke_ops/borg_tele/saboteur
name = "syndicate saboteur teleporter"
borg_to_spawn = "Saboteur"
/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T, kind, datum/mind/user)
var/mob/living/silicon/robot/R
var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop,TRUE)
@@ -191,6 +195,8 @@
switch(borg_to_spawn)
if("Medical")
R = new /mob/living/silicon/robot/modules/syndicate/medical(T)
if("Saboteur")
R = new /mob/living/silicon/robot/modules/syndicate/saboteur(T)
else
R = new /mob/living/silicon/robot/modules/syndicate(T) //Assault borg by default
@@ -235,7 +241,7 @@
return
if(used)
return
var/list/candidates = pollCandidatesForMob("Do you want to play as a [initial(demon_type.name)]?", ROLE_ALIEN, null, ROLE_ALIEN, 50, src)
var/list/candidates = pollCandidatesForMob("Do you want to play as a [initial(demon_type.name)]?", ROLE_ALIEN, null, ROLE_ALIEN, 50, src, ignore_category = POLL_IGNORE_DEMON)
if(LAZYLEN(candidates))
if(used || QDELETED(src))
return
@@ -0,0 +1,181 @@
/obj/item/borg_chameleon
name = "cyborg chameleon projector"
icon = 'icons/obj/device.dmi'
icon_state = "shield0"
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
var/friendlyName
var/savedName
var/active = FALSE
var/activationCost = 300
var/activationUpkeep = 50
var/disguise = null
var/disguise_icon_override = null
var/disguise_pixel_offset = null
var/mob/listeningTo
var/static/list/signalCache = list( // list here all signals that should break the camouflage
COMSIG_PARENT_ATTACKBY,
COMSIG_ATOM_ATTACK_HAND,
COMSIG_MOVABLE_IMPACT_ZONE,
COMSIG_ATOM_BULLET_ACT,
COMSIG_ATOM_EX_ACT,
COMSIG_ATOM_FIRE_ACT,
COMSIG_ATOM_EMP_ACT,
)
var/mob/living/silicon/robot/user // needed for process()
var/animation_playing = FALSE
var/list/engymodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Marina", "Can", "Spider", "Loader","Handy", "Pup Dozer", "Vale")
/obj/item/borg_chameleon/Initialize()
. = ..()
friendlyName = pick(GLOB.ai_names)
/obj/item/borg_chameleon/Destroy()
listeningTo = null
return ..()
/obj/item/borg_chameleon/dropped(mob/user)
. = ..()
disrupt(user)
/obj/item/borg_chameleon/equipped(mob/user)
. = ..()
disrupt(user)
/obj/item/borg_chameleon/attack_self(mob/living/silicon/robot/user)
if (user && user.cell && user.cell.charge > activationCost)
if (isturf(user.loc))
toggle(user)
else
to_chat(user, "<span class='warning'>You can't use [src] while inside something!</span>")
else
to_chat(user, "<span class='warning'>You need at least [activationCost] charge in your cell to use [src]!</span>")
/obj/item/borg_chameleon/proc/toggle(mob/living/silicon/robot/user)
if(active)
playsound(src, 'sound/effects/pop.ogg', 100, TRUE, -6)
to_chat(user, "<span class='notice'>You deactivate \the [src].</span>")
deactivate(user)
else
if(animation_playing)
to_chat(user, "<span class='notice'>\the [src] is recharging.</span>")
return
var/borg_icon = input(user, "Select an icon!", "Robot Icon", null) as null|anything in engymodels
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
disguise = "engineer"
disguise_icon_override = 'icons/mob/robots.dmi'
if("Default - Treads")
disguise = "engi-tread"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Loader")
disguise = "loaderborg"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Handy")
disguise = "handyeng"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Sleek")
disguise = "sleekeng"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Can")
disguise = "caneng"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Marina")
disguise = "marinaeng"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Spider")
disguise = "spidereng"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
disguise = "heavyeng"
disguise_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Pup Dozer")
disguise = "pupdozer"
disguise_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
disguise_pixel_offset = -16
if("Vale")
disguise = "valeeng"
disguise_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
disguise_pixel_offset = -16
animation_playing = TRUE
to_chat(user, "<span class='notice'>You activate \the [src].</span>")
playsound(src, 'sound/effects/seedling_chargeup.ogg', 100, TRUE, -6)
var/start = user.filters.len
var/X,Y,rsq,i,f
for(i=1, i<=7, ++i)
do
X = 60*rand() - 30
Y = 60*rand() - 30
rsq = X*X + Y*Y
while(rsq<100 || rsq>900)
user.filters += filter(type="wave", x=X, y=Y, size=rand()*2.5+0.5, offset=rand())
for(i=1, i<=7, ++i)
f = user.filters[start+i]
animate(f, offset=f:offset, time=0, loop=3, flags=ANIMATION_PARALLEL)
animate(offset=f:offset-1, time=rand()*20+10)
if (do_after(user, 50, target=user) && user.cell.use(activationCost))
playsound(src, 'sound/effects/bamf.ogg', 100, TRUE, -6)
to_chat(user, "<span class='notice'>You are now disguised as the Nanotrasen engineering borg \"[friendlyName]\".</span>")
activate(user)
else
to_chat(user, "<span class='warning'>The chameleon field fizzles.</span>")
do_sparks(3, FALSE, user)
for(i=1, i<=min(7, user.filters.len), ++i) // removing filters that are animating does nothing, we gotta stop the animations first
f = user.filters[start+i]
animate(f)
user.filters = null
animation_playing = FALSE
/obj/item/borg_chameleon/process()
if (user)
if (!user.cell || !user.cell.use(activationUpkeep))
disrupt(user)
else
return PROCESS_KILL
/obj/item/borg_chameleon/proc/activate(mob/living/silicon/robot/user)
START_PROCESSING(SSobj, src)
src.user = user
savedName = user.name
user.name = friendlyName
user.module.cyborg_base_icon = disguise
user.module.cyborg_icon_override = disguise_icon_override
user.module.cyborg_pixel_offset = disguise_pixel_offset
user.bubble_icon = "robot"
active = TRUE
user.update_icons()
if(listeningTo == user)
return
if(listeningTo)
UnregisterSignal(listeningTo, signalCache)
RegisterSignal(user, signalCache, .proc/disrupt)
listeningTo = user
/obj/item/borg_chameleon/proc/deactivate(mob/living/silicon/robot/user)
STOP_PROCESSING(SSobj, src)
if(listeningTo)
UnregisterSignal(listeningTo, signalCache)
listeningTo = null
do_sparks(5, FALSE, user)
user.name = savedName
user.module.cyborg_base_icon = initial(user.module.cyborg_base_icon)
user.module.cyborg_icon_override = 'icons/mob/robots.dmi'
user.bubble_icon = "syndibot"
active = FALSE
user.update_icons()
user.pixel_x = 0 //this solely exists because of dogborgs. I want anyone who ever reads this code later on to know this. Don't ask me why it's here, doesn't work above update_icons()
src.user = user
/obj/item/borg_chameleon/proc/disrupt(mob/living/silicon/robot/user)
if(active)
to_chat(user, "<span class='danger'>Your chameleon field deactivates.</span>")
deactivate(user)
@@ -383,7 +383,9 @@
if(!istype(user) || on_cooldown)
return
var/turf/T = get_turf(user)
if(!T)
var/area/A = get_area(user)
if(!T || !A || A.noteleport)
to_chat(user, "<span class='warning'>You play \the [src], yet no sound comes out of it... Looks like it won't work here.</span>")
return
on_cooldown = TRUE
last_user = user
@@ -11,12 +11,18 @@
var/buy_word = "Learn"
var/limit //used to prevent a spellbook_entry from being bought more than X times with one wizard spellbook
var/list/no_coexistance_typecache //Used so you can't have specific spells together
var/dynamic_cost = 0 // How much threat the spell costs to purchase for dynamic.
var/dynamic_requirement = 0 // How high the threat level needs to be for purchasing in dynamic.
/datum/spellbook_entry/New()
..()
no_coexistance_typecache = typecacheof(no_coexistance_typecache)
/datum/spellbook_entry/proc/IsAvailible() // For config prefs / gamemode restrictions - these are round applied
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(dynamic_requirement > 0 && mode.threat_level < dynamic_requirement)
return 0
return 1
/datum/spellbook_entry/proc/CanBuy(mob/living/carbon/human/user,obj/item/spellbook/book) // Specific circumstances
@@ -25,6 +31,10 @@
for(var/spell in user.mind.spell_list)
if(is_type_in_typecache(spell, no_coexistance_typecache))
return 0
if(dynamic_cost>0 && istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat < dynamic_cost)
return 0
return 1
/datum/spellbook_entry/proc/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) //return 1 on success
@@ -60,6 +70,10 @@
SSblackbox.record_feedback("nested tally", "wizard_spell_improved", 1, list("[name]", "[aspell.spell_level]"))
return 1
//No same spell found - just learn it
if(dynamic_cost > 0 && istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
mode.spend_threat(dynamic_cost)
mode.log_threat("Wizard spent [dynamic_cost] on [name].")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
user.mind.AddSpell(S)
to_chat(user, "<span class='notice'>You have learned [S.name].</span>")
@@ -83,6 +97,10 @@
if(!S)
S = new spell_type()
var/spell_levels = 0
if(dynamic_cost > 0 && istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
mode.refund_threat(dynamic_cost)
mode.log_threat("Wizard refunded [dynamic_cost] on [name].")
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
if(initial(S.name) == initial(aspell.name))
spell_levels = aspell.spell_level
@@ -285,20 +303,8 @@
name = "Staff of Change"
desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself."
item_path = /obj/item/gun/magic/staff/change
/datum/spellbook_entry/item/staffchange/IsAvailible()
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat < CONFIG_GET(number/dynamic_staff_of_change_requirement))
return 0
/datum/spellbook_entry/item/staffchange/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = CONFIG_GET(number/dynamic_staff_of_change_cost)
mode.spend_threat(threat_spent)
mode.log_threat("Wizard spent [threat_spent] on staff of change.")
return ..()
dynamic_requirement = 60
dynamic_cost = 20
/datum/spellbook_entry/item/staffanimation
name = "Staff of Animation"
@@ -383,20 +389,8 @@
desc = "A magical contract binding an apprentice wizard to your service, using it will summon them to your side."
item_path = /obj/item/antag_spawner/contract
category = "Assistance"
/datum/spellbook_entry/item/contract/IsAvailible()
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat < CONFIG_GET(number/dynamic_apprentice_cost))
return 0
/datum/spellbook_entry/item/contract/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = CONFIG_GET(number/dynamic_apprentice_cost)
mode.spend_threat(threat_spent)
mode.log_threat("Wizard spent [threat_spent] on apprentice contract.")
return ..()
dynamic_requirement = 50
dynamic_cost = 10
/datum/spellbook_entry/item/guardian
name = "Guardian Deck"
@@ -416,20 +410,11 @@
item_path = /obj/item/antag_spawner/slaughter_demon
limit = 3
category = "Assistance"
dynamic_requirement = 60
/datum/spellbook_entry/item/bloodbottle/IsAvailible()
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat < CONFIG_GET(keyed_list/dynamic_cost)["slaughter_demon"])
return 0
/datum/spellbook_entry/item/bloodbottle/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = CONFIG_GET(keyed_list/dynamic_cost)["slaughter_demon"]
mode.spend_threat(threat_spent)
mode.log_threat("Wizard spent [threat_spent] on slaughter demon.")
return ..()
/datum/spellbook_entry/item/bloodbottle/New()
..()
dynamic_cost = CONFIG_GET(keyed_list/dynamic_cost)["slaughter_demon"]
/datum/spellbook_entry/item/hugbottle
name = "Bottle of Tickles"
@@ -444,20 +429,11 @@
cost = 1 //non-destructive; it's just a jape, sibling!
limit = 3
category = "Assistance"
dynamic_requirement = 40
/datum/spellbook_entry/item/hugbottle/IsAvailible()
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat < round(CONFIG_GET(keyed_list/dynamic_cost)["slaughter_demon"]/3))
return 0
/datum/spellbook_entry/item/hugbottle/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = CONFIG_GET(keyed_list/dynamic_cost)["slaughter_demon"]/3
mode.spend_threat(threat_spent)
mode.log_threat("Wizard spent [threat_spent] on laughter demon.")
return ..()
/datum/spellbook_entry/item/hugbottle/New()
..()
dynamic_cost = CONFIG_GET(keyed_list/dynamic_cost)["slaughter_demon"]/3
/datum/spellbook_entry/item/mjolnir
name = "Mjolnir"
@@ -521,7 +497,7 @@
if(!SSticker.mode)
return FALSE
else
return TRUE
return ..()
/datum/spellbook_entry/summon/ghosts/Buy(mob/living/carbon/human/user, obj/item/spellbook/book)
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
@@ -534,15 +510,13 @@
/datum/spellbook_entry/summon/guns
name = "Summon Guns"
desc = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill you. Just be careful not to stand still too long!"
dynamic_cost = 10
dynamic_requirement = 60
/datum/spellbook_entry/summon/guns/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat < CONFIG_GET(number/dynamic_summon_guns_requirement))
return 0
return !CONFIG_GET(flag/no_summon_guns)
return (!CONFIG_GET(flag/no_summon_guns) && ..())
/datum/spellbook_entry/summon/guns/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
@@ -552,7 +526,7 @@
to_chat(user, "<span class='notice'>You have cast summon guns!</span>")
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = CONFIG_GET(number/dynamic_summon_guns_cost)
var/threat_spent = dynamic_cost
mode.spend_threat(threat_spent)
mode.log_threat("Wizard spent [threat_spent] on summon guns.")
return 1
@@ -560,15 +534,13 @@
/datum/spellbook_entry/summon/magic
name = "Summon Magic"
desc = "Share the wonders of magic with the crew and show them why they aren't to be trusted with it at the same time."
dynamic_cost = 10
dynamic_requirement = 60
/datum/spellbook_entry/summon/magic/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat < CONFIG_GET(number/dynamic_summon_magic_requirement))
return 0
return !CONFIG_GET(flag/no_summon_magic)
return (!CONFIG_GET(flag/no_summon_guns) && ..())
/datum/spellbook_entry/summon/magic/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
@@ -578,7 +550,7 @@
to_chat(user, "<span class='notice'>You have cast summon magic!</span>")
if(istype(SSticker.mode,/datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = CONFIG_GET(number/dynamic_summon_magic_cost)
var/threat_spent = dynamic_cost
mode.spend_threat(threat_spent)
mode.log_threat("Wizard spent [threat_spent] on summon magic.")
return 1
@@ -586,28 +558,26 @@
/datum/spellbook_entry/summon/events
name = "Summon Events"
desc = "Give Murphy's law a little push and replace all events with special wizard ones that will confound and confuse everyone. Multiple castings increase the rate of these events."
dynamic_cost = 20
dynamic_requirement = 60
var/times = 0
/datum/spellbook_entry/summon/events/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
if(istype(SSticker.mode,/datum/game_mode/dynamic) && times == 0)
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat < CONFIG_GET(number/dynamic_summon_events_requirement))
return 0
return !CONFIG_GET(flag/no_summon_events)
return (!CONFIG_GET(flag/no_summon_events) && ..())
/datum/spellbook_entry/summon/events/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
summonevents()
if(istype(SSticker.mode,/datum/game_mode/dynamic) && times == 0)
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = dynamic_cost
mode.spend_threat(threat_spent)
mode.log_threat("Wizard spent [threat_spent] on summon events.")
times++
playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1)
to_chat(user, "<span class='notice'>You have cast summon events.</span>")
if(istype(SSticker.mode,/datum/game_mode/dynamic) && times == 0)
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = CONFIG_GET(number/dynamic_summon_events_cost)
mode.spend_threat(threat_spent)
mode.log_threat("Wizard spent [threat_spent] on summon events.")
return 1
/datum/spellbook_entry/summon/events/GetInfo()
+1 -1
View File
@@ -165,7 +165,7 @@
owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball(null))
to_chat(owner, "<B>Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned powerful, destructive spells. You are able to cast magic missile and fireball.")
if(APPRENTICE_BLUESPACE)
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/area_teleport/teleport(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/turf_teleport/blink(null))
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/ethereal_jaunt(null))
to_chat(owner, "<B>Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned reality bending mobility spells. You are able to cast teleport and ethereal jaunt.")
if(APPRENTICE_HEALING)
@@ -199,7 +199,7 @@
var/radiated_temperature = location.air.temperature*FIRE_SPREAD_RADIOSITY_SCALE
for(var/t in location.atmos_adjacent_turfs)
var/turf/open/T = t
if(T.active_hotspot)
if(!T.active_hotspot)
T.hotspot_expose(radiated_temperature, CELL_VOLUME/4)
else
@@ -15,7 +15,7 @@
//used for mapping and for breathing while in walls (because that's a thing that needs to be accounted for...)
//string parsed by /datum/gas/proc/copy_from_turf
var/initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
var/initial_gas_mix = OPENTURF_DEFAULT_ATMOS
//approximation of MOLES_O2STANDARD and MOLES_N2STANDARD pending byond allowing constant expressions to be embedded in constant strings
// If someone will place 0 of some gas there, SHIT WILL BREAK. Do not do that.
@@ -154,7 +154,7 @@
//liquid plasma!!!!!!//
/turf/open/floor/plasteel/dark/snowdin
initial_gas_mix = "o2=22;n2=82;TEMP=180"
initial_gas_mix = FROZEN_ATMOS
planetary_atmos = 1
temperature = 180
+1 -1
View File
@@ -14,7 +14,7 @@
/obj/item/clothing/gloves/ComponentInitialize()
. = ..()
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /obj/item/clothing/gloves/clean_blood)
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /atom.proc/clean_blood)
/obj/item/clothing/gloves/clean_blood(datum/source, strength)
. = ..()
+1 -1
View File
@@ -23,7 +23,7 @@
/obj/item/clothing/shoes/ComponentInitialize()
. = ..()
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /obj/item/clothing/shoes/clean_blood)
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /atom.proc/clean_blood)
/obj/item/clothing/shoes/suicide_act(mob/living/carbon/user)
if(rand(2)>1)
+1 -1
View File
@@ -765,7 +765,7 @@
/obj/item/clothing/suit/assu_suit
name = "DAB suit"
desc = "A cheap replica of old SWAT armor. On its back, it is written: \"<i>Desperate Assistance Battle-force</i>\"."
desc = "A cheap replica of old SWAT armor. On its back, it is written: \"<i>Desperate Assistance Battleforce</i>\"."
icon_state = "assu_suit"
item_state = "assu_suit"
blood_overlay_type = "armor"
+8
View File
@@ -34,6 +34,7 @@
/datum/round_event_control/wizard
wizardevent = 1
var/can_be_midround_wizard = TRUE
// Checks if the event can be spawned. Used by event controller and "false alarm" event.
// Admin-created events override this.
@@ -54,6 +55,13 @@
return FALSE
return TRUE
/datum/round_event_control/wizard/canSpawnEvent(var/players_amt, var/gamemode)
if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/var/datum/game_mode/dynamic/mode = SSticker.mode
if (locate(/datum/dynamic_ruleset/midround/from_ghosts/wizard) in mode.executed_rules)
return can_be_midround_wizard && ..()
return ..()
/datum/round_event_control/proc/preRunEvent()
if(!ispath(typepath, /datum/round_event))
return EVENT_CANT_RUN
@@ -4,6 +4,7 @@
typepath = /datum/round_event/wizard/cursed_items
max_occurrences = 3
earliest_start = 0 MINUTES
can_be_midround_wizard = FALSE
//Note about adding items to this: Because of how NODROP_1 works if an item spawned to the hands can also be equiped to a slot
//it will be able to be put into that slot from the hand, but then get stuck there. To avoid this make a new subtype of any
@@ -4,6 +4,7 @@
typepath = /datum/round_event/wizard/deprevolt
max_occurrences = 1
earliest_start = 0 MINUTES
can_be_midround_wizard = FALSE // not removing it completely yet
/datum/round_event/wizard/deprevolt/start()
+1
View File
@@ -4,6 +4,7 @@
typepath = /datum/round_event/wizard/race
max_occurrences = 5
earliest_start = 0 MINUTES
can_be_midround_wizard = FALSE
/datum/round_event/wizard/race
var/list/stored_name
+3
View File
@@ -7,6 +7,7 @@
typepath = /datum/round_event/wizard/shuffleloc
max_occurrences = 5
earliest_start = 0 MINUTES
can_be_midround_wizard = FALSE // not removing it completely yet
/datum/round_event/wizard/shuffleloc/start()
var/list/moblocs = list()
@@ -43,6 +44,7 @@
typepath = /datum/round_event/wizard/shufflenames
max_occurrences = 5
earliest_start = 0 MINUTES
can_be_midround_wizard = FALSE // not removing it completely yet
/datum/round_event/wizard/shufflenames/start()
var/list/mobnames = list()
@@ -77,6 +79,7 @@
typepath = /datum/round_event/wizard/shuffleminds
max_occurrences = 3
earliest_start = 0 MINUTES
can_be_midround_wizard = FALSE // not removing it completely yet
/datum/round_event/wizard/shuffleminds/start()
var/list/mobs = list()
+2
View File
@@ -4,6 +4,7 @@
typepath = /datum/round_event/wizard/summonguns
max_occurrences = 1
earliest_start = 0 MINUTES
can_be_midround_wizard = FALSE // not removing it completely yet
/datum/round_event_control/wizard/summonguns/New()
if(CONFIG_GET(flag/no_summon_guns))
@@ -19,6 +20,7 @@
typepath = /datum/round_event/wizard/summonmagic
max_occurrences = 1
earliest_start = 0 MINUTES
can_be_midround_wizard = FALSE // not removing it completely yet
/datum/round_event_control/wizard/summonmagic/New()
if(CONFIG_GET(flag/no_summon_magic))
+7
View File
@@ -546,3 +546,10 @@ Since Ramadan is an entire month that lasts 29.5 days on average, the start and
/datum/holiday/easter/getStationPrefix()
return pick("Fluffy","Bunny","Easter","Egg")
//Random citadel thing for halloween species
/proc/force_enable_halloween_species()
var/list/oldlist = SSevents.holidays
SSevents.holidays = list(HALLOWEEN = new /datum/holiday/halloween)
generate_selectable_species(FALSE)
SSevents.holidays = oldlist
+1 -1
View File
@@ -21,7 +21,7 @@
/turf/open/floor/holofloor/plating/burnmix
name = "burn-mix floor"
initial_gas_mix = "o2=2500;plasma=5000;TEMP=370"
initial_gas_mix = BURNMIX_ATMOS
/turf/open/floor/holofloor/grass
gender = PLURAL
+2 -8
View File
@@ -25,7 +25,6 @@
max_matter = 600 //Bigger container and faster speeds due to being specialized and stationary.
no_ammo_message = "<span class='warning'>Internal matter exhausted. Please add additional materials.</span>"
delay_mod = 0.5
adjacency_check = FALSE
upgrade = TRUE
var/obj/machinery/computer/camera_advanced/base_construction/console
@@ -207,19 +206,14 @@
to_chat(owner, "Build mode is now [buildmode].")
/datum/action/innate/aux_base/airlock_type
name = "Change Airlock Settings"
name = "Select Airlock Type"
button_icon_state = "airlock_select"
/datum/action/innate/aux_base/airlock_type/Activate()
if(..())
return
var/mode = alert("Modify Type or Access?", "Airlock Settings", "Type", "Access", "None")
switch(mode)
if("Type")
B.RCD.change_airlock_setting(usr)
if("Access")
B.RCD.change_airlock_access(usr)
B.RCD.change_airlock_access(usr)
/datum/action/innate/aux_base/window_type
@@ -63,8 +63,7 @@
/obj/item/twohanded/kinetic_crusher/attack(mob/living/target, mob/living/carbon/user)
if(!wielded)
to_chat(user, "<span class='warning'>[src] is too heavy to use with one hand. You fumble and drop everything.")
user.drop_all_held_items()
to_chat(user, "<span class='warning'>[src] is too heavy to use with one hand.")
return
var/datum/status_effect/crusher_damage/C = target.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
var/target_health = target.health
@@ -473,10 +473,7 @@
var/free_space = 0
for(var/list/category in list(GLOB.command_positions) + list(GLOB.supply_positions) + list(GLOB.engineering_positions) + list(GLOB.nonhuman_positions - "pAI") + list(GLOB.civilian_positions) + list(GLOB.medical_positions) + list(GLOB.science_positions) + list(GLOB.security_positions))
var/cat_color = "fff" //random default
if(SSjob.name_occupations && SSjob.name_occupations[category[1]])
cat_color = SSjob.name_occupations[category[1]].selection_color //use the color of the first job in the category (the department head) as the category color
else
cat_color = SSjob.occupations[category[1]].selection_color
cat_color = SSjob.name_occupations[category[1]].selection_color //use the color of the first job in the category (the department head) as the category color
dat += "<fieldset style='width: 185px; border: 2px solid [cat_color]; display: inline'>"
dat += "<legend align='center' style='color: [cat_color]'>[SSjob.name_occupations[category[1]].exp_type_department]</legend>"
+3 -4
View File
@@ -306,7 +306,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(stat == DEAD)
ghostize(1)
else
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty != CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty == CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost")
return //didn't want to ghost after-all
if(istype(loc, /obj/machinery/cryopod))
@@ -331,7 +331,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(penalty + world.realtime - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
penalty = CANT_REENTER_ROUND
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty != CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty == CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost")
return
ghostize(0, penalize = TRUE)
@@ -629,8 +629,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Possess!"
set desc= "Take over the body of a mindless creature!"
if(reenter_round_timeout > world.realtime)
to_chat(src, "<span class='warning'>You are unable to re-enter the round yet. Your ghost role blacklist will expire in [DisplayTimeText(reenter_round_timeout - world.realtime)].</span>")
if(!can_reenter_round())
return FALSE
var/list/possessible = list()
+17 -4
View File
@@ -5,6 +5,7 @@
var/datum/dna/stored/stored_dna // dna var for brain. Used to store dna, brain dna is not considered like actual dna, brain.has_dna() returns FALSE.
stat = DEAD //we start dead by default
see_invisible = SEE_INVISIBLE_LIVING
possible_a_intents = list(INTENT_HELP, INTENT_HARM) //for mechas
speech_span = SPAN_ROBOT
/mob/living/brain/Initialize()
@@ -72,10 +73,9 @@
/mob/living/brain/ClickOn(atom/A, params)
..()
if(istype(loc, /obj/item/mmi))
var/obj/item/mmi/MMI = loc
var/obj/mecha/M = MMI.mecha
if((src == MMI.brainmob) && istype(M))
if(container)
var/obj/mecha/M = container.mecha
if(istype(M))
return M.click_action(A,src,params)
/mob/living/brain/forceMove(atom/destination)
@@ -90,3 +90,16 @@
doMove(destination)
else
CRASH("Brainmob without a container [src] attempted to move to [destination].")
/mob/living/brain/update_mouse_pointer()
if (!client)
return
client.mouse_pointer_icon = initial(client.mouse_pointer_icon)
if(!container)
return
if (container.mecha)
var/obj/mecha/M = container.mecha
if(M.mouse_pointer)
client.mouse_pointer_icon = M.mouse_pointer
if (client && ranged_ability && ranged_ability.ranged_mousepointer)
client.mouse_pointer_icon = ranged_ability.ranged_mousepointer
@@ -43,7 +43,7 @@
adjustStaminaLoss(damage_amount, forced = forced)
//citadel code
if(AROUSAL)
adjustArousalLoss(damage_amount, forced = forced)
adjustArousalLoss(damage_amount)
return TRUE
@@ -32,7 +32,7 @@
if(CONFIG_GET(flag/disable_stambuffer))
togglesprint()
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /mob/living/carbon/human/clean_blood)
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /atom.proc/clean_blood)
/mob/living/carbon/human/ComponentInitialize()
@@ -118,11 +118,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
..()
/proc/generate_selectable_species()
/proc/generate_selectable_species(clear = FALSE)
if(clear)
GLOB.roundstart_races = list()
GLOB.roundstart_race_names = list()
for(var/I in subtypesof(/datum/species))
var/datum/species/S = new I
if(S.check_roundstart_eligible())
GLOB.roundstart_races += S.id
GLOB.roundstart_races |= S.id
GLOB.roundstart_race_names["[S.name]"] = S.id
qdel(S)
if(!GLOB.roundstart_races.len)
@@ -336,7 +336,7 @@ There are several things that need to be remembered:
if(!t_state)
t_state = s_store.icon_state
overlays_standing[SUIT_STORE_LAYER] = mutable_appearance(((s_store.alternate_worn_icon) ? s_store.alternate_worn_icon : 'icons/mob/belt_mirror.dmi'), t_state, -SUIT_STORE_LAYER)
var/mutable_appearance/s_store_overlay = overlays_standing[SUIT_LAYER]
var/mutable_appearance/s_store_overlay = overlays_standing[SUIT_STORE_LAYER]
if(OFFSET_S_STORE in dna.species.offset_features)
s_store_overlay.pixel_x += dna.species.offset_features[OFFSET_S_STORE][1]
s_store_overlay.pixel_y += dna.species.offset_features[OFFSET_S_STORE][2]
+1 -1
View File
@@ -98,7 +98,7 @@
var/datum/gas_mixture/breath
if(!getorganslot(ORGAN_SLOT_BREATHING_TUBE))
if(health <= HEALTH_THRESHOLD_FULLCRIT || (pulledby && pulledby.grab_state >= GRAB_KILL) || !lungs || lungs.organ_flags & ORGAN_FAILING)
if(health <= HEALTH_THRESHOLD_FULLCRIT || (pulledby && pulledby.grab_state >= GRAB_KILL) || (lungs && lungs.organ_flags & ORGAN_FAILING))
losebreath++ //You can't breath at all when in critical or when being choked, so you're going to miss a breath
else if(health <= crit_threshold)
+4 -1
View File
@@ -58,7 +58,10 @@
var/canholo = TRUE
var/obj/item/card/id/access_card = null
var/chassis = "repairbot"
var/list/possible_chassis = list("cat" = TRUE, "mouse" = TRUE, "monkey" = TRUE, "corgi" = FALSE, "fox" = FALSE, "repairbot" = TRUE, "rabbit" = TRUE) //assoc value is whether it can be picked up.
var/list/possible_chassis = list("cat" = TRUE, "mouse" = TRUE, "monkey" = TRUE, "corgi" = FALSE,
"fox" = FALSE, "repairbot" = TRUE, "rabbit" = TRUE, "borgi" = FALSE ,
"parrot" = FALSE, "bear" = FALSE , "mushroom" = FALSE, "crow" = FALSE ,
"fairy" = FALSE , "spiderbot" = FALSE) //assoc value is whether it can be picked up.
var/static/item_head_icon = 'icons/mob/pai_item_head.dmi'
var/static/item_lh_icon = 'icons/mob/pai_item_lh.dmi'
var/static/item_rh_icon = 'icons/mob/pai_item_rh.dmi'
@@ -1,5 +1,5 @@
/mob/living/silicon/robot/examine(mob/user)
var/msg = "<span class='info'>*---------*\nThis is [icon2html(src, user)] \a <EM>[src]</EM>, a [src.module.name]!\n"
var/msg = "<span class='info'>*---------*\nThis is [icon2html(src, user)] \a <EM>[src]</EM>, a [src.module.name] unit!\n"
if(desc)
msg += "[desc]\n"
+33 -7
View File
@@ -110,6 +110,7 @@
var/sitting = 0
var/bellyup = 0
var/dogborg = FALSE
/mob/living/silicon/robot/get_cell()
return cell
@@ -232,15 +233,14 @@
var/list/modulelist = list("Standard" = /obj/item/robot_module/standard, \
"Engineering" = /obj/item/robot_module/engineering, \
"Medical" = /obj/item/robot_module/medical, \
"Medihound" = /obj/item/robot_module/medihound, \
"Miner" = /obj/item/robot_module/miner, \
"Janitor" = /obj/item/robot_module/janitor, \
"Service" = /obj/item/robot_module/butler)
if(!CONFIG_GET(flag/disable_peaceborg))
modulelist["Peacekeeper"] = /obj/item/robot_module/peacekeeper
if(BORG_SEC_AVAILABLE)
modulelist["Security"] = /obj/item/robot_module/security
modulelist += get_cit_modules() //Citadel change - adds Citadel's borg modules.
modulelist["Security K-9"] = /obj/item/robot_module/k9
var/input_module = input("Please, select a module!", "Robot", null, null) as null|anything in modulelist
if(!input_module || module.type != /obj/item/robot_module)
@@ -879,9 +879,6 @@
/mob/living/silicon/robot/modules/miner
set_module = /obj/item/robot_module/miner
/mob/living/silicon/robot/modules/janitor
set_module = /obj/item/robot_module/janitor
/mob/living/silicon/robot/modules/syndicate
icon_state = "synd_sec"
faction = list(ROLE_SYNDICATE)
@@ -920,6 +917,17 @@
<i>Help the operatives secure the disk at all costs!</i></b>"
set_module = /obj/item/robot_module/syndicate_medical
/mob/living/silicon/robot/modules/syndicate/saboteur
icon_state = "synd_engi"
playstyle_string = "<span class='big bold'>You are a Syndicate saboteur cyborg!</span><br>\
<b>You are armed with robust engineering tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \
Your destination tagger will allow you to stealthily traverse the disposal network across the station \
Your welder will allow you to repair the operatives' exosuits, but also yourself and your fellow cyborgs \
Your cyborg chameleon projector allows you to assume the appearance and registered name of a Nanotrasen engineering borg, and undertake covert actions on the station \
Be aware that almost any physical contact or incidental damage will break your camouflage \
<i>Help the operatives secure the disk at all costs!</i></b>"
set_module = /obj/item/robot_module/saboteur
/mob/living/silicon/robot/proc/notify_ai(notifytype, oldname, newname)
if(!connected_ai)
return
@@ -1256,6 +1264,20 @@
for(var/i in connected_ai.aicamera.stored)
aicamera.stored[i] = TRUE
/mob/living/silicon/robot/lay_down()
..()
update_canmove()
/mob/living/silicon/robot/update_canmove()
..()
if(client && stat != DEAD && dogborg == FALSE)
if(resting)
cut_overlays()
icon_state = "[module.cyborg_base_icon]-rest"
else
icon_state = "[module.cyborg_base_icon]"
update_icons()
/mob/living/silicon/robot/proc/rest_style()
set name = "Switch Rest Style"
set category = "Robot Commands"
@@ -1271,4 +1293,8 @@
sitting = 1
if("Belly up")
bellyup = 1
update_icons()
update_icons()
/mob/living/silicon/robot/adjustStaminaLossBuffered(amount, updating_stamina = 1)
if(istype(cell))
cell.charge -= amount*5
@@ -34,6 +34,14 @@
var/list/ride_offset_y = list("north" = 4, "south" = 4, "east" = 3, "west" = 3)
var/ride_allow_incapacitated = FALSE
var/allow_riding = TRUE
var/canDispose = FALSE // Whether the borg can stuff itself into disposal
var/sleeper_overlay
var/icon/cyborg_icon_override
var/has_snowflake_deadsprite
var/cyborg_pixel_offset
var/moduleselect_alternate_icon
var/dogborg = FALSE
/obj/item/robot_module/Initialize()
. = ..()
@@ -129,6 +137,28 @@
rebuild_modules()
return I
//Adds flavoursome dogborg items to dogborg variants without mechanical benefits
/obj/item/robot_module/proc/dogborg_equip()
if(istype(src, /obj/item/robot_module/k9) || istype(src, /obj/item/robot_module/medihound))
return //Bandaid fix to prevent stacking until I merge these two modules into their base types
var/obj/item/I = new /obj/item/analyzer/nose/flavour(src)
basic_modules += I
I = new /obj/item/soap/tongue/flavour(src)
basic_modules += I
I = new /obj/item/dogborg/sleeper/K9/flavour(src)
if(istype(src, /obj/item/robot_module/engineering))
I.icon_state = "decompiler"
if(istype(src, /obj/item/robot_module/security))
I.icon_state = "sleeperb"
if(istype(src, /obj/item/robot_module/medical))
I.icon_state = "sleeper"
if(istype(src, /obj/item/robot_module/butler))
I.icon_state = "servicer"
if(cyborg_base_icon == "scrubpup")
I.icon_state = "compactor"
basic_modules += I
rebuild_modules()
/obj/item/robot_module/proc/remove_module(obj/item/I, delete_after)
basic_modules -= I
modules -= I
@@ -197,6 +227,8 @@
R.update_module_innate()
RM.rebuild_modules()
INVOKE_ASYNC(RM, .proc/do_transform_animation)
if(RM.dogborg)
RM.dogborg_equip()
R.maxHealth = borghealth
R.health = min(borghealth, R.health)
qdel(src)
@@ -245,15 +277,15 @@
name = "Standard"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/reagent_containers/borghypo/epi,
/obj/item/healthanalyzer,
/obj/item/weldingtool/largetank/cyborg,
/obj/item/wrench/cyborg,
/obj/item/crowbar/cyborg,
/obj/item/stack/sheet/metal/cyborg,
/obj/item/stack/rods/cyborg,
/obj/item/stack/tile/plasteel/cyborg,
/obj/item/extinguisher,
/obj/item/pickaxe,
/obj/item/t_scanner/adv_mining_scanner,
/obj/item/restraints/handcuffs/cable/zipties,
@@ -271,6 +303,8 @@
name = "Medical"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/healthanalyzer,
/obj/item/reagent_containers/borghypo,
/obj/item/reagent_containers/glass/beaker/large,
@@ -283,7 +317,6 @@
/obj/item/surgicaldrill,
/obj/item/scalpel,
/obj/item/circular_saw,
/obj/item/extinguisher/mini,
/obj/item/roller/robo,
/obj/item/borg/cyborghug/medical,
/obj/item/stack/medical/gauze/cyborg,
@@ -299,6 +332,85 @@
can_be_pushed = FALSE
hat_offset = 3
/obj/item/robot_module/medical/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Heavy", "Sleek", "Marina", "Droid", "Eyebot")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "medical"
if("Droid")
cyborg_base_icon = "medical"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
hat_offset = 4
if("Sleek")
cyborg_base_icon = "sleekmed"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Marina")
cyborg_base_icon = "marinamed"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Eyebot")
cyborg_base_icon = "eyebotmed"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
cyborg_base_icon = "heavymed"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
return ..()
/obj/item/robot_module/medihound
name = "MediHound"
basic_modules = list(
/obj/item/dogborg/jaws/small,
/obj/item/storage/bag/borgdelivery,
/obj/item/analyzer/nose,
/obj/item/soap/tongue,
/obj/item/extinguisher/mini,
/obj/item/healthanalyzer,
/obj/item/dogborg/sleeper/medihound,
/obj/item/roller/robo,
/obj/item/reagent_containers/borghypo,
/obj/item/twohanded/shockpaddles/cyborg/hound,
/obj/item/stack/medical/gauze/cyborg,
/obj/item/pinpointer/crew,
/obj/item/sensor_device)
emag_modules = list(/obj/item/dogborg/pounce)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/medical,
/obj/item/clockwork/weapon/ratvarian_spear)
cyborg_base_icon = "medihound"
moduleselect_icon = "medihound"
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
can_be_pushed = FALSE
hat_offset = INFINITY
sleeper_overlay = "msleeper"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
/obj/item/robot_module/medihound/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/medhoundmodels = list("Default", "Dark", "Vale")
if(R.client && R.client.ckey in list("nezuli"))
medhoundmodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in medhoundmodels
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "medihound"
if("Dark")
cyborg_base_icon = "medihounddark"
sleeper_overlay = "mdsleeper"
if("Vale")
cyborg_base_icon = "valemed"
sleeper_overlay = "valemedsleeper"
if("Alina")
cyborg_base_icon = "alina-med"
special_light_key = "alina"
sleeper_overlay = "alinasleeper"
return ..()
/obj/item/robot_module/engineering
name = "Engineering"
basic_modules = list(
@@ -338,10 +450,79 @@
magpulsing = TRUE
hat_offset = -4
/obj/item/robot_module/engineering/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/engymodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Marina", "Can", "Spider", "Loader","Handy", "Pup Dozer", "Vale")
if(R.client && R.client.ckey in list("nezuli"))
engymodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in engymodels
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "engineer"
if("Default - Treads")
cyborg_base_icon = "engi-tread"
special_light_key = "engineer"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Loader")
cyborg_base_icon = "loaderborg"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
has_snowflake_deadsprite = TRUE
if("Handy")
cyborg_base_icon = "handyeng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Sleek")
cyborg_base_icon = "sleekeng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Can")
cyborg_base_icon = "caneng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Marina")
cyborg_base_icon = "marinaeng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Spider")
cyborg_base_icon = "spidereng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
cyborg_base_icon = "heavyeng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Pup Dozer")
cyborg_base_icon = "pupdozer"
can_be_pushed = FALSE
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "dozersleeper"
if("Vale")
cyborg_base_icon = "valeeng"
can_be_pushed = FALSE
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "valeengsleeper"
if("Alina")
cyborg_base_icon = "alina-eng"
special_light_key = "alina"
can_be_pushed = FALSE
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "alinasleeper"
return ..()
/obj/item/robot_module/security
name = "Security"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/restraints/handcuffs/cable/zipties,
/obj/item/melee/baton/loaded,
/obj/item/gun/energy/disabler/cyborg,
@@ -360,6 +541,90 @@
to_chat(loc, "<span class='userdanger'>While you have picked the security module, you still have to follow your laws, NOT Space Law. \
For Crewsimov, this means you must follow criminals' orders unless there is a law 1 reason not to.</span>")
/obj/item/robot_module/security/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Default - Treads", "Heavy", "Sleek", "Can", "Marina", "Spider")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "sec"
if("Default - Treads")
cyborg_base_icon = "sec-tread"
special_light_key = "sec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Sleek")
cyborg_base_icon = "sleeksec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Marina")
cyborg_base_icon = "marinasec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Can")
cyborg_base_icon = "cansec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Spider")
cyborg_base_icon = "spidersec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
cyborg_base_icon = "heavysec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
return ..()
/obj/item/robot_module/k9
name = "Security K-9 Unit"
basic_modules = list(
/obj/item/restraints/handcuffs/cable/zipties,
/obj/item/storage/bag/borgdelivery,
/obj/item/dogborg/jaws/big,
/obj/item/dogborg/pounce,
/obj/item/clothing/mask/gas/sechailer/cyborg,
/obj/item/soap/tongue,
/obj/item/analyzer/nose,
/obj/item/dogborg/sleeper/K9,
/obj/item/gun/energy/disabler/cyborg,
/obj/item/pinpointer/crew)
emag_modules = list(/obj/item/gun/energy/laser/cyborg)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security,
/obj/item/clockwork/weapon/ratvarian_spear)
cyborg_base_icon = "k9"
moduleselect_icon = "k9"
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
can_be_pushed = FALSE
hat_offset = INFINITY
sleeper_overlay = "ksleeper"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
/obj/item/robot_module/k9/do_transform_animation()
..()
to_chat(loc,"<span class='userdanger'>While you have picked the Security K-9 module, you still have to follow your laws, NOT Space Law. \
For Crewsimov, this means you must follow criminals' orders unless there is a law 1 reason not to.</span>")
/obj/item/robot_module/k9/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/sechoundmodels = list("Default", "Dark", "Vale")
if(R.client && R.client.ckey in list("nezuli"))
sechoundmodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in sechoundmodels
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "k9"
if("Alina")
cyborg_base_icon = "alina-sec"
special_light_key = "alina"
sleeper_overlay = "alinasleeper"
if("Dark")
cyborg_base_icon = "k9dark"
sleeper_overlay = "k9darksleeper"
if("Vale")
cyborg_base_icon = "valesec"
sleeper_overlay = "valesecsleeper"
return ..()
/obj/item/robot_module/security/Initialize()
. = ..()
if(!CONFIG_GET(flag/weaken_secborg))
@@ -372,12 +637,13 @@
name = "Peacekeeper"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/cookiesynth,
/obj/item/harmalarm,
/obj/item/reagent_containers/borghypo/peace,
/obj/item/holosign_creator/cyborg,
/obj/item/borg/cyborghug/peacekeeper,
/obj/item/extinguisher,
/obj/item/megaphone,
/obj/item/borg/projectile_dampen)
emag_modules = list(/obj/item/reagent_containers/borghypo/peace/hacked)
@@ -391,9 +657,31 @@
/obj/item/robot_module/peacekeeper/do_transform_animation()
..()
to_chat(loc, "<span class='userdanger'>Under ASIMOV, you are an enforcer of the PEACE and preventer of HUMAN HARM. \
to_chat(loc, "<span class='userdanger'>Under ASIMOV/CREWSIMOV, you are an enforcer of the PEACE and preventer of HUMAN/CREW HARM. \
You are not a security module and you are expected to follow orders and prevent harm above all else. Space law means nothing to you.</span>")
/obj/item/robot_module/peacekeeper/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Spider", "Borgi")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "peace"
if("Spider")
cyborg_base_icon = "whitespider"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Borgi")
cyborg_base_icon = "borgi"
moduleselect_icon = "borgi"
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
has_snowflake_deadsprite = TRUE
return ..()
//Janitor module combined with Service module
/*
/obj/item/robot_module/janitor
name = "Janitor"
basic_modules = list(
@@ -416,6 +704,7 @@
moduleselect_icon = "janitor"
hat_offset = -5
clean_on_move = TRUE
*/
/obj/item/reagent_containers/spray/cyborg_drying
name = "drying agent spray"
@@ -426,25 +715,12 @@
name = "lube spray"
list_reagents = list("lube" = 250)
/obj/item/robot_module/janitor/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
..()
var/obj/item/lightreplacer/LR = locate(/obj/item/lightreplacer) in basic_modules
if(LR)
for(var/i in 1 to coeff)
LR.Charge(R)
var/obj/item/reagent_containers/spray/cyborg_drying/CD = locate(/obj/item/reagent_containers/spray/cyborg_drying) in basic_modules
if(CD)
CD.reagents.add_reagent("drying_agent", 5 * coeff)
var/obj/item/reagent_containers/spray/cyborg_lube/CL = locate(/obj/item/reagent_containers/spray/cyborg_lube) in emag_modules
if(CL)
CL.reagents.add_reagent("lube", 2 * coeff)
/obj/item/robot_module/clown
name = "Clown"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/toy/crayon/rainbow,
/obj/item/instrument/bikehorn,
/obj/item/stamp/clown,
@@ -459,8 +735,7 @@
/obj/item/borg/cyborghug/peacekeeper,
/obj/item/borg/lollipop/clown,
/obj/item/picket_sign/cyborg,
/obj/item/reagent_containers/borghypo/clown,
/obj/item/extinguisher/mini)
/obj/item/reagent_containers/borghypo/clown)
emag_modules = list(
/obj/item/reagent_containers/borghypo/clown/hacked,
/obj/item/reagent_containers/spray/waterflower/cyborg/hacked)
@@ -476,11 +751,12 @@
name = "Service"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/reagent_containers/food/drinks/drinkingglass,
/obj/item/reagent_containers/food/condiment/enzyme,
/obj/item/pen,
/obj/item/toy/crayon/spraycan/borg,
/obj/item/extinguisher/mini,
/obj/item/hand_labeler/borg,
/obj/item/razor,
/obj/item/instrument/violin,
@@ -490,31 +766,123 @@
/obj/item/lighter,
/obj/item/storage/bag/tray,
/obj/item/reagent_containers/borghypo/borgshaker,
/obj/item/borg/lollipop)
/obj/item/borg/lollipop,
/obj/item/screwdriver/cyborg,
/obj/item/stack/tile/plasteel/cyborg,
/obj/item/soap/nanotrasen,
/obj/item/storage/bag/trash/cyborg,
/obj/item/mop/cyborg,
/obj/item/lightreplacer/cyborg,
/obj/item/holosign_creator,
/obj/item/reagent_containers/spray/cyborg_drying)
emag_modules = list(/obj/item/reagent_containers/borghypo/borgshaker/hacked)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/service,
/obj/item/borg/sight/xray/truesight_lens)
moduleselect_icon = "service"
special_light_key = "service"
hat_offset = 0
clean_on_move = TRUE
/obj/item/robot_module/butler/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
..()
var/obj/item/reagent_containers/O = locate(/obj/item/reagent_containers/food/condiment/enzyme) in basic_modules
var/obj/item/lightreplacer/LR = locate(/obj/item/lightreplacer) in basic_modules
if(O)
O.reagents.add_reagent("enzyme", 2 * coeff)
if(LR)
for(var/i in 1 to coeff)
LR.Charge(R)
var/obj/item/reagent_containers/spray/cyborg_drying/CD = locate(/obj/item/reagent_containers/spray/cyborg_drying) in basic_modules
if(CD)
CD.reagents.add_reagent("drying_agent", 5 * coeff)
var/obj/item/reagent_containers/spray/cyborg_lube/CL = locate(/obj/item/reagent_containers/spray/cyborg_lube) in emag_modules
if(CL)
CL.reagents.add_reagent("lube", 2 * coeff)
/obj/item/robot_module/butler/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("(Service) Waitress", "(Service) Heavy", "(Service) Sleek", "(Service) Butler", "(Service) Tophat", "(Service) Can", "(Service) Bro", "(Service) DarkK9", "(Service) Vale", "(Service) ValeDark", "(Janitor) Default", "(Janitor) Sleek", "(Janitor) Marina", "(Janitor) Can", "(Janitor) Heavy", "(Janitor) Scrubpuppy")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("(Service) Waitress")
cyborg_base_icon = "service_f"
special_light_key = "service"
if("(Service) Butler")
cyborg_base_icon = "service_m"
special_light_key = "service"
if("(Service) Bro")
cyborg_base_icon = "brobot"
special_light_key = "service"
if("(Service) Can")
cyborg_base_icon = "kent"
special_light_key = "medical"
hat_offset = 3
if("(Service) Tophat")
cyborg_base_icon = "tophat"
special_light_key = null
hat_offset = INFINITY //He is already wearing a hat
if("(Service) Sleek")
cyborg_base_icon = "sleekserv"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("(Service) Heavy")
cyborg_base_icon = "heavyserv"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("(Service) DarkK9")
cyborg_base_icon = "k50"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "ksleeper"
if("(Service) Vale")
cyborg_base_icon = "valeserv"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "valeservsleeper"
if("(Service) ValeDark")
cyborg_base_icon = "valeservdark"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "valeservsleeper"
if("(Janitor) Default")
cyborg_base_icon = "janitor"
if("(Janitor) Marina")
cyborg_base_icon = "marinajan"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("(Janitor) Sleek")
cyborg_base_icon = "sleekjan"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("(Janitor) Can")
cyborg_base_icon = "canjan"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("(Janitor) Heavy")
cyborg_base_icon = "heavyres"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("(Janitor) Scrubpuppy")
cyborg_base_icon = "scrubpup"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
cyborg_pixel_offset = -16
dogborg = TRUE
sleeper_overlay = "jsleeper"
return ..()
/obj/item/robot_module/miner
name = "Miner"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/borg/sight/meson,
/obj/item/storage/bag/ore/cyborg,
/obj/item/pickaxe/drill/cyborg,
/obj/item/shovel,
/obj/item/crowbar/cyborg,
/obj/item/weldingtool/mini,
/obj/item/extinguisher/mini,
/obj/item/storage/bag/sheetsnatcher/borg,
/obj/item/t_scanner/adv_mining_scanner,
/obj/item/gun/energy/kinetic_accelerator/cyborg,
@@ -529,10 +897,44 @@
moduleselect_icon = "miner"
hat_offset = 0
/obj/item/robot_module/miner/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Lavaland", "Heavy", "Sleek", "Marina", "Can", "Spider", "Asteroid", "Droid")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Lavaland")
cyborg_base_icon = "miner"
if("Asteroid")
cyborg_base_icon = "minerOLD"
special_light_key = "miner"
if("Droid")
cyborg_base_icon = "miner"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
hat_offset = 4
if("Sleek")
cyborg_base_icon = "sleekmin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Can")
cyborg_base_icon = "canmin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Marina")
cyborg_base_icon = "marinamin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Spider")
cyborg_base_icon = "spidermin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
cyborg_base_icon = "heavymin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
return ..()
/obj/item/robot_module/syndicate
name = "Syndicate Assault"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/melee/transforming/energy/sword/cyborg,
/obj/item/gun/energy/printer,
/obj/item/gun/ballistic/revolver/grenadelauncher/cyborg,
@@ -562,6 +964,8 @@
name = "Syndicate Medical"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/reagent_containers/borghypo/syndicate,
/obj/item/twohanded/shockpaddles/syndicate,
/obj/item/healthanalyzer,
@@ -574,8 +978,6 @@
/obj/item/melee/transforming/energy/sword/cyborg/saw,
/obj/item/roller/robo,
/obj/item/card/emag,
/obj/item/crowbar/cyborg,
/obj/item/extinguisher/mini,
/obj/item/pinpointer/syndicate_cyborg,
/obj/item/stack/medical/gauze/cyborg,
/obj/item/gun/medbeam,
@@ -588,6 +990,47 @@
can_be_pushed = FALSE
hat_offset = 3
/obj/item/robot_module/saboteur
name = "Syndicate Saboteur"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/borg/sight/thermal,
/obj/item/construction/rcd/borg/syndicate,
/obj/item/pipe_dispenser,
/obj/item/restraints/handcuffs/cable/zipties,
/obj/item/extinguisher,
/obj/item/weldingtool/largetank/cyborg,
/obj/item/screwdriver/nuke,
/obj/item/wrench/cyborg,
/obj/item/crowbar/cyborg,
/obj/item/wirecutters/cyborg,
/obj/item/multitool/cyborg,
/obj/item/storage/part_replacer/cyborg,
/obj/item/holosign_creator/atmos,
/obj/item/weapon/gripper,
/obj/item/lightreplacer/cyborg,
/obj/item/stack/sheet/metal/cyborg,
/obj/item/stack/sheet/glass/cyborg,
/obj/item/stack/sheet/rglass/cyborg,
/obj/item/stack/rods/cyborg,
/obj/item/stack/tile/plasteel/cyborg,
/obj/item/destTagger/borg,
/obj/item/stack/cable_coil/cyborg,
/obj/item/pinpointer/syndicate_cyborg,
/obj/item/borg_chameleon,
)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/engineer,
/obj/item/clockwork/replica_fabricator/cyborg)
cyborg_base_icon = "synd_engi"
moduleselect_icon = "malf"
can_be_pushed = FALSE
magpulsing = TRUE
hat_offset = -4
canDispose = TRUE
/datum/robot_energy_storage
var/name = "Generic energy storage"
var/max_energy = 30000
@@ -13,6 +13,7 @@
mob_biotypes = list(MOB_ROBOTIC)
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
speech_span = SPAN_ROBOT
no_vore = TRUE
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
var/last_lawchange_announce = 0
@@ -440,7 +440,7 @@
var/reagent_id = null
if(emagged == 2) //Emagged! Time to poison everybody.
reagent_id = "toxin"
reagent_id = HAS_TRAIT(C, TRAIT_TOXINLOVER)? "charcoal" : "toxin"
else
if(treat_virus)
@@ -64,6 +64,8 @@
/obj/item/gun/energy/laser/cyborg
can_charge = FALSE
desc = "An energy-based laser gun that draws power from the cyborg's internal energy cell directly. So this is what freedom looks like?"
icon = 'icons/obj/items_cyborg.dmi'
icon_state = "laser_cyborg"
selfcharge = EGUN_SELFCHARGE_BORG
cell_type = /obj/item/stock_parts/cell/secborg
charge_delay = 3
@@ -26,6 +26,8 @@
/obj/item/gun/energy/e_gun/advtaser/cyborg
name = "cyborg taser"
desc = "An integrated hybrid taser that draws directly from a cyborg's power cell. The one contains a limiter to prevent the cyborg's power cell from overheating."
icon = 'icons/obj/items_cyborg.dmi'
icon_state = "taser"
can_flashlight = FALSE
can_charge = FALSE
selfcharge = EGUN_SELFCHARGE_BORG
@@ -48,6 +50,8 @@
/obj/item/gun/energy/disabler/cyborg
name = "cyborg disabler"
desc = "An integrated disabler that draws from a cyborg's power cell. This one contains a limiter to prevent the cyborg's power cell from overheating."
icon = 'icons/obj/items_cyborg.dmi'
icon_state = "taser"
can_charge = FALSE
ammo_type = list(/obj/item/ammo_casing/energy/disabler/secborg)
selfcharge = EGUN_SELFCHARGE_BORG
+2 -2
View File
@@ -69,12 +69,12 @@
/obj/item/projectile/beam/disabler
name = "disabler beam"
icon_state = "omnilaser"
damage = 24 // Citadel change for balance from 36
damage = 28 // Citadel change for balance from 36
damage_type = STAMINA
flag = "energy"
hitsound = 'sound/weapons/tap.ogg'
eyeblur = 0
speed = 0.7
speed = 0.6
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
light_color = LIGHT_COLOR_BLUE
tracer_type = /obj/effect/projectile/tracer/disabler
@@ -153,6 +153,7 @@
var/robot = pick(200;/mob/living/silicon/robot,
/mob/living/silicon/robot/modules/syndicate,
/mob/living/silicon/robot/modules/syndicate/medical,
/mob/living/silicon/robot/modules/syndicate/saboteur,
200;/mob/living/simple_animal/drone/polymorphed)
new_mob = new robot(M.loc)
if(issilicon(new_mob))
+6 -1
View File
@@ -132,7 +132,12 @@
/obj/machinery/disposal/proc/can_stuff_mob_in(mob/living/target, mob/living/user, pushing = FALSE)
if(!pushing && !iscarbon(user) && !user.ventcrawler) //only carbon and ventcrawlers can climb into disposal by themselves.
return FALSE
if (iscyborg(user))
var/mob/living/silicon/robot/borg = user
if (!borg.module || !borg.module.canDispose)
return
else
return FALSE
if(!isturf(user.loc)) //No magically doing it from inside closets
return FALSE
if(target.buckled || target.has_buckled_mobs())
@@ -52,6 +52,10 @@
if(istype(AM, /obj/item/smallDelivery) && !hasmob)
var/obj/item/smallDelivery/T = AM
src.destinationTag = T.sortTag
else if(istype(AM, /mob/living/silicon/robot))
var/obj/item/destTagger/borg/tagger = locate() in AM
if (tagger)
src.destinationTag = tagger.currTag
// start the movement process
+8 -2
View File
@@ -147,6 +147,7 @@
icon = 'icons/obj/device.dmi'
icon_state = "cargotagger"
var/currTag = 0 //Destinations are stored in code\globalvars\lists\flavor_misc.dm
var/locked_destination = FALSE //if true, users can't open the destination tag window to prevent changing the tagger's current destination
w_class = WEIGHT_CLASS_TINY
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
@@ -154,6 +155,10 @@
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BELT
/obj/item/destTagger/borg
name = "cyborg destination tagger"
desc = "Used to fool the disposal mail network into thinking that you're a harmless parcel. Does actually work as a regular destination tagger as well."
/obj/item/destTagger/suicide_act(mob/living/user)
user.visible_message("<span class='suicide'>[user] begins tagging [user.p_their()] final destination! It looks like [user.p_theyre()] trying to commit suicide!</span>")
if (islizard(user))
@@ -179,8 +184,9 @@
onclose(user, "destTagScreen")
/obj/item/destTagger/attack_self(mob/user)
openwindow(user)
return
if(!locked_destination)
openwindow(user)
return
/obj/item/destTagger/Topic(href, href_list)
add_fingerprint(usr)
@@ -41,6 +41,14 @@
category = list ("Misc. Machinery")
departmental_flags = DEPARTMENTAL_FLAG_SERVICE
/datum/design/board/ayyplantgenes
name = "Machine Design (Alien Plant DNA Manipulator Board)"
desc = "The circuit board for an advanced plant DNA manipulator, utilizing alien technologies."
id = "ayyplantgenes"
build_path = /obj/item/circuitboard/machine/plantgenes/vault
category = list ("Misc. Machinery")
departmental_flags = DEPARTMENTAL_FLAG_SERVICE
/datum/design/board/deepfryer
name = "Machine Design (Deep Fryer)"
desc = "The circuit board for a Deep Fryer."
@@ -84,8 +84,9 @@
investigate_log("[key_name(user)] built [amount] of [path] at [src]([type]).", INVESTIGATE_RESEARCH)
message_admins("[ADMIN_LOOKUPFLW(user)] has built [amount] of [path] at a [src]([type]).")
for(var/i in 1 to amount)
var/obj/item/I = new path(get_turf(src))
if(efficient_with(I.type))
var/obj/O = new path(get_turf(src))
if(efficient_with(O.type) && isitem(O))
var/obj/item/I = O
I.materials = matlist.Copy()
SSblackbox.record_feedback("nested tally", "item_printed", amount, list("[type]", "[path]"))
+3 -3
View File
@@ -616,7 +616,7 @@
/datum/techweb_node/botany
id = "botany"
display_name = "Botanical Engineering"
description = "Botanical tools"
description = "Botanical tools."
prereq_ids = list("adv_engi", "biotech")
design_ids = list("diskplantgene", "portaseeder", "plantgenes", "flora_gun", "hydro_tray", "biogenerator", "seed_extractor")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2750)
@@ -1047,14 +1047,14 @@
display_name = "Alien Biological Tools"
description = "Advanced biological tools."
prereq_ids = list("alientech", "advance_surgerytools")
design_ids = list("alien_scalpel", "alien_hemostat", "alien_retractor", "alien_saw", "alien_drill", "alien_cautery")
design_ids = list("alien_scalpel", "alien_hemostat", "alien_retractor", "alien_saw", "alien_drill", "alien_cautery", "ayyplantgenes")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
export_price = 10000
/datum/techweb_node/alien_engi
id = "alien_engi"
display_name = "Alien Engineering"
description = "Alien engineering tools"
description = "Alien engineering tools."
prereq_ids = list("alientech", "exp_tools")
design_ids = list("alien_wrench", "alien_wirecutters", "alien_screwdriver", "alien_crowbar", "alien_welder", "alien_multitool")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
@@ -24,12 +24,9 @@ Self-sustaining extracts:
A.icon = icon
A.icon_state = icon_state
A.color = color
A.name = "self-sustaining " + colour + " extract"
return INITIALIZE_HINT_QDEL
/obj/item/autoslime/Initialize()
name = "self-sustaining " + extract.name
return ..()
/obj/item/autoslime/attack_self(mob/user)
var/reagentselect = input(user, "Choose the reagent the extract will produce.", "Self-sustaining Reaction") as null|anything in extract.activate_reagents
var/amount = 5
@@ -20,8 +20,11 @@
after_cast(targets)
/obj/effect/proc_holder/spell/targeted/area_teleport/before_cast(list/targets)
var/A = null
var/area/U = get_area(usr)
if(U.noteleport && !istype(U, /area/wizard_station)) // Wizard den special check for those complaining about being unable to tele on station.
to_chat(usr, "<span class='warning'>Unseen forces prevent you from casting this spell in this area</span>")
return
var/A
if(!randomise_selection)
A = input("Area to teleport to", "Teleport", A) as null|anything in GLOB.teleportlocs
else
@@ -53,12 +56,13 @@
if(target && target.buckled)
target.buckled.unbuckle_mob(target, force=1)
var/forcecheck = istype(get_area(target), /area/wizard_station)
var/list/tempL = L
var/attempt = null
var/success = 0
while(tempL.len)
attempt = pick(tempL)
do_teleport(target, attempt, channel = TELEPORT_CHANNEL_MAGIC)
do_teleport(target, attempt, channel = TELEPORT_CHANNEL_MAGIC, forced = forcecheck)
if(get_turf(target) == attempt)
success = 1
break
@@ -66,7 +70,7 @@
tempL.Remove(attempt)
if(!success)
do_teleport(target, L, forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC)
do_teleport(target, L, forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC, forced = forcecheck)
playsound(get_turf(user), sound2, 50,1)
return
+4 -4
View File
@@ -354,7 +354,7 @@
if("legs" in S.default_features)
if(body_zone == BODY_ZONE_L_LEG || body_zone == BODY_ZONE_R_LEG)
if(DIGITIGRADE in S.species_traits)
digitigrade_type = lowertext(H.dna.features.["legs"])
digitigrade_type = lowertext(H.dna.features["legs"])
else
digitigrade_type = null
@@ -363,9 +363,9 @@
Smark = GLOB.mam_body_markings_list[H.dna.features["mam_body_markings"]]
if(Smark)
body_markings_icon = Smark.icon
if(H.dna.features.["mam_body_markings"] != "None")
body_markings = lowertext(H.dna.features.["mam_body_markings"])
aux_marking = lowertext(H.dna.features.["mam_body_markings"])
if(H.dna.features["mam_body_markings"] != "None")
body_markings = lowertext(H.dna.features["mam_body_markings"])
aux_marking = lowertext(H.dna.features["mam_body_markings"])
else
body_markings = "plain"
aux_marking = "plain"
@@ -110,4 +110,4 @@
requires_tech = TRUE
replaced_by = null
#undef EXPDIS_FAIL_MSG
#undef BASE_HUMAN_REWARD
-1
View File
@@ -212,7 +212,6 @@ obj/item/organ/heart/cybernetic/upgraded/on_life()
ramount += regen_amount
/obj/item/organ/heart/cybernetic/upgraded/proc/used_dose()
. = ..()
addtimer(VARSET_CALLBACK(src, dose_available, TRUE), 5 MINUTES)
ramount = 0
@@ -1,6 +1,3 @@
#define STANDARD_ORGAN_THRESHOLD 100
#define STANDARD_ORGAN_HEALING 0.001
/obj/item/organ
name = "organ"
icon = 'icons/obj/surgery.dmi'
+10
View File
@@ -1123,6 +1123,16 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
cost = 35
restricted = TRUE
/datum/uplink_item/support/reinforcement/saboteur_borg
name = "Syndicate Saboteur Cyborg"
desc = "A streamlined engineering cyborg, equipped with covert modules. Also incapable of leaving the welder in the shuttle. \
Aside from regular Engineering equipment, it comes with a special destination tagger that lets it traverse disposals networks. \
Its chameleon projector lets it disguise itself as a Nanotrasen cyborg, on top it has thermal vision and a pinpointer."
item = /obj/item/antag_spawner/nuke_ops/borg_tele/saboteur
refundable = TRUE
cost = 35
restricted = TRUE
/datum/uplink_item/support/gygax
name = "Dark Gygax Exosuit"
desc = "A lightweight exosuit, painted in a dark scheme. Its speed and equipment selection make it excellent \