Conflicts galore
This commit is contained in:
@@ -22,6 +22,11 @@
|
||||
sparks.set_up(2,0)
|
||||
sparks.attach(src)
|
||||
update_icon()
|
||||
new_occupant_dir = dir
|
||||
|
||||
/obj/machinery/vr_sleeper/setDir(newdir)
|
||||
. = ..()
|
||||
new_occupant_dir = dir
|
||||
|
||||
/obj/machinery/vr_sleeper/attackby(obj/item/I, mob/user, params)
|
||||
if(!state_open && !occupant)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
var/F = file("[GLOB.log_directory]/[subject].html")
|
||||
WRITE_FILE(F, "<small>[TIME_STAMP("hh:mm:ss", FALSE)] [REF(src)] ([x],[y],[z])</small> || [src] [message]<br>")
|
||||
|
||||
/client/proc/investigate_show(subject in list("notes, memos, watchlist", INVESTIGATE_RCD, INVESTIGATE_RESEARCH, INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION, INVESTIGATE_CIRCUIT, INVESTIGATE_NANITES) )
|
||||
/client/proc/investigate_show(subject in list("notes, memos, watchlist", INVESTIGATE_RCD, INVESTIGATE_RESEARCH, INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION, INVESTIGATE_CIRCUIT, INVESTIGATE_NANITES, INVESTIGATE_CRYOGENICS) )
|
||||
set name = "Investigate"
|
||||
set category = "Admin"
|
||||
if(!holder)
|
||||
|
||||
@@ -106,6 +106,7 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list(
|
||||
/client/proc/show_tip,
|
||||
/client/proc/smite,
|
||||
/client/proc/admin_away,
|
||||
/client/proc/cmd_admin_toggle_fov,
|
||||
/client/proc/roll_dices //CIT CHANGE - Adds dice verb
|
||||
))
|
||||
GLOBAL_PROTECT(admin_verbs_fun)
|
||||
|
||||
@@ -69,11 +69,6 @@
|
||||
<A href='?src=[REF(src)];[HrefToken()];secrets=floorlava'>The floor is lava! (DANGEROUS: extremely lame)</A><BR>
|
||||
<A href='?src=[REF(src)];[HrefToken()];secrets=customportal'>Spawn a custom portal storm</A><BR>
|
||||
<BR>
|
||||
<A href='?src=[REF(src)];[HrefToken()];secrets=flipmovement'>Flip client movement directions</A><BR>
|
||||
<A href='?src=[REF(src)];[HrefToken()];secrets=randommovement'>Randomize client movement directions</A><BR>
|
||||
<A href='?src=[REF(src)];[HrefToken()];secrets=custommovement'>Set each movement direction manually</A><BR>
|
||||
<A href='?src=[REF(src)];[HrefToken()];secrets=resetmovement'>Reset movement directions to default</A><BR>
|
||||
<BR>
|
||||
<A href='?src=[REF(src)];[HrefToken()];secrets=changebombcap'>Change bomb cap</A><BR>
|
||||
<A href='?src=[REF(src)];[HrefToken()];secrets=masspurrbation'>Mass Purrbation</A><BR>
|
||||
<A href='?src=[REF(src)];[HrefToken()];secrets=massremovepurrbation'>Mass Remove Purrbation</A><BR>
|
||||
@@ -603,60 +598,6 @@
|
||||
purrbation.")
|
||||
log_admin("[key_name(usr)] has removed everyone from purrbation.")
|
||||
|
||||
if("flipmovement")
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
if(alert("Flip all movement controls?","Confirm","Yes","Cancel") == "Cancel")
|
||||
return
|
||||
var/list/movement_keys = SSinput.movement_keys
|
||||
for(var/i in 1 to movement_keys.len)
|
||||
var/key = movement_keys[i]
|
||||
movement_keys[key] = turn(movement_keys[key], 180)
|
||||
message_admins("[key_name_admin(usr)] has flipped all movement directions.")
|
||||
log_admin("[key_name(usr)] has flipped all movement directions.")
|
||||
|
||||
if("randommovement")
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
if(alert("Randomize all movement controls?","Confirm","Yes","Cancel") == "Cancel")
|
||||
return
|
||||
var/list/movement_keys = SSinput.movement_keys
|
||||
for(var/i in 1 to movement_keys.len)
|
||||
var/key = movement_keys[i]
|
||||
movement_keys[key] = turn(movement_keys[key], 45 * rand(1, 8))
|
||||
message_admins("[key_name_admin(usr)] has randomized all movement directions.")
|
||||
log_admin("[key_name(usr)] has randomized all movement directions.")
|
||||
|
||||
if("custommovement")
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
if(alert("Are you sure you want to change every movement key?","Confirm","Yes","Cancel") == "Cancel")
|
||||
return
|
||||
var/list/movement_keys = SSinput.movement_keys
|
||||
var/list/new_movement = list()
|
||||
for(var/i in 1 to movement_keys.len)
|
||||
var/key = movement_keys[i]
|
||||
|
||||
var/msg = "Please input the new movement direction when the user presses [key]. Ex. northeast"
|
||||
var/title = "New direction for [key]"
|
||||
var/new_direction = text2dir(input(usr, msg, title) as text|null)
|
||||
if(!new_direction)
|
||||
new_direction = movement_keys[key]
|
||||
|
||||
new_movement[key] = new_direction
|
||||
SSinput.movement_keys = new_movement
|
||||
message_admins("[key_name_admin(usr)] has configured all movement directions.")
|
||||
log_admin("[key_name(usr)] has configured all movement directions.")
|
||||
|
||||
if("resetmovement")
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
if(alert("Are you sure you want to reset movement keys to default?","Confirm","Yes","Cancel") == "Cancel")
|
||||
return
|
||||
SSinput.setup_default_movement_keys()
|
||||
message_admins("[key_name_admin(usr)] has reset all movement keys.")
|
||||
log_admin("[key_name(usr)] has reset all movement keys.")
|
||||
|
||||
if("customportal")
|
||||
if(!check_rights(R_FUN))
|
||||
return
|
||||
|
||||
@@ -1025,8 +1025,6 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
|
||||
v = SSnpcpool
|
||||
if("SSmobs")
|
||||
v = SSmobs
|
||||
if("SSmood")
|
||||
v = SSmood
|
||||
if("SSquirks")
|
||||
v = SSquirks
|
||||
if("SSwet_floors")
|
||||
|
||||
@@ -1211,6 +1211,58 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
|
||||
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggled Hub Visibility", "[GLOB.hub_visibility ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_admin_toggle_fov()
|
||||
set category = "Fun"
|
||||
set name = "Enable/Disable Field of Vision"
|
||||
|
||||
var/static/busy_toggling_fov = FALSE
|
||||
if(!check_rights(R_ADMIN) || !check_rights(R_FUN))
|
||||
return
|
||||
|
||||
var/on_off = CONFIG_GET(flag/use_field_of_vision)
|
||||
|
||||
if(busy_toggling_fov)
|
||||
to_chat(usr, "<span class='warning'>A previous call of this function is still busy toggling FoV [on_off ? "on" : "off"]. Have some patiece</span>.")
|
||||
return
|
||||
busy_toggling_fov = TRUE
|
||||
|
||||
log_admin("[key_name(usr)] has [on_off ? "disabled" : "enabled"] the Field of Vision configuration.")
|
||||
CONFIG_SET(flag/use_field_of_vision, !on_off)
|
||||
|
||||
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggled Field of Vision", "[on_off ? "Enabled" : "Disabled"]"))
|
||||
|
||||
if(on_off)
|
||||
for(var/k in GLOB.mob_list)
|
||||
if(!k)
|
||||
continue
|
||||
var/mob/M = k
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(!(H.dna?.species.has_field_of_vision))
|
||||
continue
|
||||
else if(!M.has_field_of_vision)
|
||||
continue
|
||||
var/datum/component/field_of_vision/FoV = M.GetComponent(/datum/component/field_of_vision)
|
||||
if(FoV)
|
||||
qdel(FoV)
|
||||
CHECK_TICK
|
||||
else
|
||||
for(var/k in GLOB.clients)
|
||||
if(!k)
|
||||
continue
|
||||
var/client/C = k
|
||||
var/mob/M = C.mob
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(!(H.dna?.species.has_field_of_vision))
|
||||
continue
|
||||
else if(!M.has_field_of_vision)
|
||||
continue
|
||||
M.LoadComponent(/datum/component/field_of_vision, M.field_of_vision_type)
|
||||
CHECK_TICK
|
||||
|
||||
busy_toggling_fov = FALSE
|
||||
|
||||
/client/proc/smite(mob/living/carbon/human/target as mob)
|
||||
set name = "Smite"
|
||||
set category = "Fun"
|
||||
|
||||
@@ -24,6 +24,8 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
var/list/blacklisted_quirks = list(/datum/quirk/nonviolent,/datum/quirk/mute) // Quirks that will be removed upon gaining this antag. Pacifist and mute are default.
|
||||
var/threat = 0 // Amount of threat this antag poses, for dynamic mode
|
||||
|
||||
var/list/skill_modifiers
|
||||
|
||||
/datum/antagonist/New()
|
||||
GLOB.antagonists += src
|
||||
typecache_datum_blacklist = typecacheof(typecache_datum_blacklist)
|
||||
@@ -68,15 +70,19 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
|
||||
//Proc called when the datum is given to a mind.
|
||||
/datum/antagonist/proc/on_gain()
|
||||
if(owner && owner.current)
|
||||
if(!silent)
|
||||
greet()
|
||||
apply_innate_effects()
|
||||
give_antag_moodies()
|
||||
remove_blacklisted_quirks()
|
||||
if(is_banned(owner.current) && replace_banned)
|
||||
replace_banned_player()
|
||||
SEND_SIGNAL(owner.current, COMSIG_MOB_ANTAG_ON_GAIN, src)
|
||||
if(!(owner?.current))
|
||||
return
|
||||
if(!silent)
|
||||
greet()
|
||||
apply_innate_effects()
|
||||
give_antag_moodies()
|
||||
remove_blacklisted_quirks()
|
||||
if(is_banned(owner.current) && replace_banned)
|
||||
replace_banned_player()
|
||||
if(skill_modifiers)
|
||||
for(var/A in skill_modifiers)
|
||||
ADD_SINGLETON_SKILL_MODIFIER(owner, A, type)
|
||||
SEND_SIGNAL(owner.current, COMSIG_MOB_ANTAG_ON_GAIN, src)
|
||||
|
||||
/datum/antagonist/proc/is_banned(mob/M)
|
||||
if(!M)
|
||||
@@ -99,6 +105,8 @@ GLOBAL_LIST_EMPTY(antagonists)
|
||||
clear_antag_moodies()
|
||||
if(owner)
|
||||
LAZYREMOVE(owner.antag_datums, src)
|
||||
for(var/A in skill_modifiers)
|
||||
owner.remove_skill_modifier(GET_SKILL_MOD_ID(A, type))
|
||||
if(!silent && owner.current)
|
||||
farewell()
|
||||
var/datum/team/team = get_team()
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
landmark_type = /obj/effect/landmark/abductor/agent
|
||||
greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve."
|
||||
show_in_antagpanel = TRUE
|
||||
skill_modifiers = list(/datum/skill_modifier/job/level/wiring)
|
||||
|
||||
/datum/antagonist/abductor/scientist
|
||||
name = "Abductor Scientist"
|
||||
@@ -29,6 +30,7 @@
|
||||
landmark_type = /obj/effect/landmark/abductor/scientist
|
||||
greet_text = "Use your experimental console and surgical equipment to monitor your agent and experiment upon abducted humans."
|
||||
show_in_antagpanel = TRUE
|
||||
skill_modifiers = list(/datum/skill_modifier/job/affinity/surgery)
|
||||
|
||||
/datum/antagonist/abductor/create_team(datum/team/abductor_team/new_team)
|
||||
if(!new_team)
|
||||
|
||||
@@ -23,5 +23,5 @@
|
||||
addtimer(CALLBACK(src, .proc/zap), rand(30, 100))
|
||||
|
||||
/obj/item/organ/heart/gland/electric/proc/zap()
|
||||
tesla_zap(owner, 4, 8000, TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN)
|
||||
tesla_zap(owner, 4, 8000, ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_MOB_STUN)
|
||||
playsound(get_turf(owner), 'sound/magic/lightningshock.ogg', 50, TRUE)
|
||||
@@ -86,7 +86,8 @@
|
||||
melee_damage_upper = 4
|
||||
obj_damage = 20
|
||||
environment_smash = ENVIRONMENT_SMASH_STRUCTURES
|
||||
attacktext = "hits"
|
||||
attack_verb_continuous = "hits"
|
||||
attack_verb_simple = "hit"
|
||||
attack_sound = 'sound/weapons/genhit1.ogg'
|
||||
movement_type = FLYING
|
||||
del_on_death = 1
|
||||
@@ -205,7 +206,8 @@
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 20
|
||||
obj_damage = 60
|
||||
attacktext = "slams"
|
||||
attack_verb_continuous = "slams"
|
||||
attack_verb_simple = "slam"
|
||||
attack_sound = 'sound/effects/blobattack.ogg'
|
||||
verb_say = "gurgles"
|
||||
verb_ask = "demands"
|
||||
@@ -284,11 +286,11 @@
|
||||
if(overmind) //if we have an overmind, we're doing chemical reactions instead of pure damage
|
||||
melee_damage_lower = 4
|
||||
melee_damage_upper = 4
|
||||
attacktext = overmind.blobstrain.blobbernaut_message
|
||||
attack_verb_continuous = overmind.blobstrain.blobbernaut_message
|
||||
else
|
||||
melee_damage_lower = initial(melee_damage_lower)
|
||||
melee_damage_upper = initial(melee_damage_upper)
|
||||
attacktext = initial(attacktext)
|
||||
attack_verb_continuous = initial(attack_verb_continuous)
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/death(gibbed)
|
||||
..(gibbed)
|
||||
|
||||
@@ -207,8 +207,8 @@
|
||||
if(prob(100 - severity * 30))
|
||||
new /obj/effect/temp_visual/emp(get_turf(src))
|
||||
|
||||
/obj/structure/blob/tesla_act(power)
|
||||
..()
|
||||
/obj/structure/blob/zap_act(power)
|
||||
. = ..()
|
||||
if(overmind)
|
||||
if(overmind.blobstrain.tesla_reaction(src, power))
|
||||
take_damage(power/400, BURN, "energy")
|
||||
|
||||
@@ -113,3 +113,5 @@
|
||||
|
||||
/mob/living/proc/StartFrenzy(inTime = 120)
|
||||
set waitfor = FALSE
|
||||
|
||||
|
||||
|
||||
@@ -216,8 +216,8 @@
|
||||
// for (var/datum/action/bloodsucker/masquerade/P in powers)
|
||||
// P.Deactivate()
|
||||
// TEMP DEATH
|
||||
var/total_brute = owner.current.getBruteLoss()
|
||||
var/total_burn = owner.current.getFireLoss()
|
||||
var/total_brute = owner.current.getBruteLoss_nonProsthetic()
|
||||
var/total_burn = owner.current.getFireLoss_nonProsthetic()
|
||||
var/total_toxloss = owner.current.getToxLoss() //This is neater than just putting it in total_damage
|
||||
var/total_damage = total_brute + total_burn + total_toxloss
|
||||
// Died? Convert to Torpor (fake death)
|
||||
|
||||
@@ -328,8 +328,8 @@
|
||||
// to_chat(user, "<span class='danger'><i>The ritual has been interrupted!</i></span>")
|
||||
// useLock = FALSE
|
||||
// return
|
||||
user.playsound_local(null, 'sound/effects/explosion_distant.ogg', 40, TRUE)
|
||||
target.playsound_local(null, 'sound/effects/explosion_distant.ogg', 40, TRUE)
|
||||
user.playsound_local(null, 'sound/effects/explosion_distant.ogg', 40, TRUE)
|
||||
target.playsound_local(null, 'sound/effects/explosion_distant.ogg', 40, TRUE)
|
||||
target.playsound_local(null, 'sound/effects/singlebeat.ogg', 40, TRUE)
|
||||
target.Jitter(25)
|
||||
target.emote("laugh")
|
||||
@@ -490,13 +490,14 @@
|
||||
update_icon()
|
||||
|
||||
/obj/structure/bloodsucker/candelabrum/process()
|
||||
if(lit)
|
||||
for(var/mob/living/carbon/human/H in viewers(7, src))
|
||||
var/datum/antagonist/vassal/T = H.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
|
||||
if(AmBloodsucker(H) || T) //We dont want vassals or vampires affected by this
|
||||
return
|
||||
H.hallucination = 20
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "vampcandle", /datum/mood_event/vampcandle)
|
||||
if(!lit)
|
||||
return
|
||||
for(var/mob/living/carbon/human/H in fov_viewers(7, src))
|
||||
var/datum/antagonist/vassal/T = H.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
|
||||
if(AmBloodsucker(H) || T) //We dont want vassals or vampires affected by this
|
||||
return
|
||||
H.hallucination = 20
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "vampcandle", /datum/mood_event/vampcandle)
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// OTHER THINGS TO USE: HUMAN BLOOD. /obj/effect/decal/cleanable/blood
|
||||
|
||||
|
||||
@@ -19,10 +19,9 @@
|
||||
if(!.)
|
||||
return
|
||||
// must have nobody around to see the cloak
|
||||
for(var/mob/living/M in viewers(9, owner))
|
||||
if(M != owner)
|
||||
to_chat(owner, "<span class='warning'>You may only vanish into the shadows unseen.</span>")
|
||||
return FALSE
|
||||
for(var/mob/living/M in fov_viewers(9, owner) - owner)
|
||||
to_chat(owner, "<span class='warning'>You may only vanish into the shadows unseen.</span>")
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/action/bloodsucker/cloak/ActivatePower()
|
||||
@@ -35,7 +34,7 @@
|
||||
// Pay Blood Toll (if awake)
|
||||
owner.alpha = max(35, owner.alpha - min(75, 10 + 5 * level_current))
|
||||
bloodsuckerdatum.AddBloodVolume(-0.2)
|
||||
|
||||
|
||||
runintent = (user.m_intent == MOVE_INTENT_RUN)
|
||||
var/turf/T = get_turf(user)
|
||||
lum = T.get_lumcount()
|
||||
@@ -50,7 +49,7 @@
|
||||
if(!runintent)
|
||||
user.toggle_move_intent()
|
||||
REMOVE_TRAIT(user, TRAIT_NORUNNING, "cloak of darkness")
|
||||
|
||||
|
||||
sleep(5) // Check every few ticks
|
||||
|
||||
/datum/action/bloodsucker/cloak/ContinueActive(mob/living/user, mob/living/target)
|
||||
|
||||
@@ -169,8 +169,8 @@
|
||||
vision_distance = notice_range, ignored_mobs = target) // Only people who AREN'T the target will notice this action.
|
||||
// Warn Feeder about Witnesses...
|
||||
var/was_unnoticed = TRUE
|
||||
for(var/mob/living/M in viewers(notice_range, owner))
|
||||
if(M != owner && M != target && iscarbon(M) && M.mind && !M.silicon_privileges && !M.eye_blind && !M.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
|
||||
for(var/mob/living/M in fov_viewers(notice_range, owner) - owner - target)
|
||||
if(M.client && !M.silicon_privileges && !M.eye_blind && !M.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
|
||||
was_unnoticed = FALSE
|
||||
break
|
||||
if(was_unnoticed)
|
||||
|
||||
@@ -64,8 +64,8 @@
|
||||
var/turf/T = get_turf(user)
|
||||
if(T && T.lighting_object && T.get_lumcount()>= 0.1)
|
||||
// B) Check for Viewers
|
||||
for(var/mob/living/M in viewers(get_turf(owner)))
|
||||
if(M != owner && isliving(M) && M.mind && !M.silicon_privileges && !M.eye_blind) // M.client <--- add this in after testing!
|
||||
for(var/mob/living/M in fov_viewers(world.view, get_turf(owner)) - owner)
|
||||
if(M.client && !M.silicon_privileges && !M.eye_blind)
|
||||
am_seen = TRUE
|
||||
if (!M.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER))
|
||||
drop_item = TRUE
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
to_chat(owner, "<span class='warning'>Your victim's eyes are glazed over. They cannot perceive you.</span>")
|
||||
return FALSE
|
||||
// Check: Target See Me? (behind wall)
|
||||
if(!(target in viewers(target_range, get_turf(owner))))
|
||||
if(!(owner in target.fov_view()))
|
||||
// Sub-Check: GET CLOSER
|
||||
//if (!(owner in range(target_range, get_turf(target)))
|
||||
// if (display_error)
|
||||
@@ -137,7 +137,7 @@
|
||||
if(istype(target) && success)
|
||||
target.notransform = FALSE
|
||||
REMOVE_TRAIT(target, TRAIT_COMBAT_MODE_LOCKED, src)
|
||||
if(istype(L) && target.stat == CONSCIOUS && (target in view(10, get_turf(L)))) // They Woke Up! (Notice if within view)
|
||||
if(istype(L) && target.stat == CONSCIOUS && (target in L.fov_view(10))) // They Woke Up! (Notice if within view)
|
||||
to_chat(L, "<span class='warning'>[target] has snapped out of their trance.</span>")
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
clockwork_desc = "A sigil of some purpose."
|
||||
icon_state = "sigil"
|
||||
layer = LOW_OBJ_LAYER
|
||||
plane = ABOVE_WALL_PLANE
|
||||
alpha = 50
|
||||
resistance_flags = NONE
|
||||
var/affects_servants = FALSE
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
//Subtype of (riot) shield because of already implemented shieldbash stuff aswell as integrity and simillar things
|
||||
//ratvarian shield: A shield that absorbs energy from attacks and uses it to empower its bashes with remendous force. It is also quite resistant to damage, though less so against lasers and energy weaponry.
|
||||
|
||||
/obj/item/shield/riot/ratvarian
|
||||
name = "ratvarian shield"
|
||||
icon_state = "ratvarian_shield" //Its icons are in the same place the normal shields are in
|
||||
item_state = "ratvarian_shield"
|
||||
desc = "A resilient shield made out of brass.. It feels warm to the touch."
|
||||
var/clockwork_desc = "A powerful shield of ratvarian making. It absorbs blocked attacks to charge devastating bashes."
|
||||
armor = list("melee" = 80, "bullet" = 70, "laser" = -10, "energy" = -20, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
shield_flags = SHIELD_FLAGS_DEFAULT
|
||||
max_integrity = 300 //High integrity, extremely strong against melee / bullets, but still quite easy to destroy with lasers and energy
|
||||
repair_material = /obj/item/stack/tile/brass
|
||||
var/dam_absorbed = 0
|
||||
var/bash_mult_steps = 30
|
||||
var/max_bash_mult = 4
|
||||
|
||||
/obj/item/shield/riot/ratvarian/examine(mob/user)
|
||||
if((is_servant_of_ratvar(user) || isobserver(user)))
|
||||
desc = clockwork_desc
|
||||
desc +="\n <span class='inathneq_small'>The shield has absorbed [dam_absorbed] damage, multiplying the effectiveness of its bashes by [calc_bash_mult()]</span>"
|
||||
. = ..()
|
||||
desc = initial(desc)
|
||||
|
||||
obj/item/shield/riot/ratvarian/proc/calc_bash_mult()
|
||||
var/bash_mult = 0
|
||||
if(!dam_absorbed)
|
||||
return 1
|
||||
else
|
||||
bash_mult += round(clamp(1 + (dam_absorbed / bash_mult_steps), 1, max_bash_mult), 0.1) //Multiplies the effect of bashes by up to [max_bash_mult], though never less than one
|
||||
return bash_mult
|
||||
|
||||
/obj/item/shield/riot/ratvarian/proc/calc_bash_absorb_use()
|
||||
var/absorb_use = 0
|
||||
absorb_use = max(0, round(dam_absorbed * (calc_bash_mult() / round(1 + (dam_absorbed / bash_mult_steps), 0.1)), 1)) //Calculates how much of the absorbed damage the bash would actually use, so its not wasted
|
||||
return absorb_use
|
||||
|
||||
/obj/item/shield/riot/ratvarian/on_shield_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(!damage)
|
||||
return ..()
|
||||
|
||||
if(!is_servant_of_ratvar(owner))
|
||||
owner.visible_message("<span class='warning'>As [owner] blocks the attack with [src], [owner.p_they()] suddenly drops it, whincing in pain! </span>", "<span class='warning'>As you block the attack with [src], it heats up tremendously, forcing you to drop it from the pain alone! </span>")
|
||||
owner.emote("scream")
|
||||
playsound(src, 'sound/machines/fryer/deep_fryer_emerge.ogg', 50)
|
||||
if(iscarbon(owner)) //Type safety for if a drone somehow got a shield (ratvar protect us)
|
||||
var/mob/living/carbon/C = owner
|
||||
var/obj/item/bodypart/part = C.get_holding_bodypart_of_item(src)
|
||||
C.apply_damage((iscultist(C) ? damage * 2 : damage), BURN, (istype(part, /obj/item/bodypart/l_arm) ? BODY_ZONE_L_ARM : BODY_ZONE_R_ARM)) //Deals the damage to the holder instead of absorbing it instead + forcedrops. Doubled if a cultist of Nar'Sie.
|
||||
else
|
||||
owner.adjustFireLoss(iscultist(owner) ? damage * 2 : damage)
|
||||
addtimer(CALLBACK(owner, /mob/living.proc/dropItemToGround, src, TRUE), 1)
|
||||
else if(!is_servant_of_ratvar(attacker)) //No exploiting my snowflake mechanics
|
||||
dam_absorbed += damage
|
||||
playsound(owner, 'sound/machines/clockcult/steam_whoosh.ogg', 30)
|
||||
|
||||
if(damage <= 10) //The shield itself is hard to break, this DOES NOT modify the actual blocking-mechanic
|
||||
damage = 0
|
||||
else
|
||||
damage -= 5
|
||||
return ..()
|
||||
|
||||
/obj/item/shield/riot/ratvarian/shatter(mob/living/carbon/human/owner)
|
||||
playsound(owner, 'sound/magic/clockwork/anima_fragment_death.ogg', 50)
|
||||
new /obj/item/clockwork/alloy_shards/large(get_turf(src))
|
||||
|
||||
/obj/item/shield/riot/ratvarian/user_shieldbash(mob/living/user, atom/target, harmful)
|
||||
if(!harmful || !is_servant_of_ratvar(user)) // No fun for non-clockies, but you can keep the normal bashes. Until you try to block with it.
|
||||
shieldbash_knockback = initial(shieldbash_knockback)
|
||||
shieldbash_brutedamage = initial(shieldbash_brutedamage) //Prevention for funky stuff that might happen otherwise
|
||||
shieldbash_stamdmg = initial(shieldbash_stamdmg)
|
||||
return ..()
|
||||
var/actual_bash_mult = calc_bash_mult()
|
||||
shieldbash_knockback = round(initial(shieldbash_knockback) * actual_bash_mult, 1) //Modifying the strength of the bash, done with initial() to prevent magic-number issues if the original shieldbash values are changed
|
||||
shieldbash_brutedamage = round(initial(shieldbash_brutedamage) * actual_bash_mult, 1) //Where I think of it, better round this stuff because we don't need even more things that deal like 3.25 damage
|
||||
shieldbash_stamdmg = round(initial(shieldbash_stamdmg) * actual_bash_mult, 1) //Like 20 brute and 60 stam + a fuckton of knockback at the moment (at maximum charge), seems mostly fine? I think?
|
||||
. = ..()
|
||||
if(.) //If this bash actually hit someone
|
||||
if(actual_bash_mult > 1)
|
||||
playsound(user, 'sound/magic/fireball.ogg', 50, TRUE, frequency = 1.25)
|
||||
dam_absorbed -= calc_bash_absorb_use()
|
||||
return
|
||||
@@ -17,7 +17,8 @@
|
||||
obj_damage = 40
|
||||
melee_damage_lower = 12
|
||||
melee_damage_upper = 12
|
||||
attacktext = "slashes"
|
||||
attack_verb_continuous = "slashes"
|
||||
attack_verb_simple = "slash"
|
||||
attack_sound = 'sound/weapons/bladeslice.ogg'
|
||||
weather_immunities = list("lava")
|
||||
movement_type = FLYING
|
||||
@@ -68,14 +69,16 @@
|
||||
maxHealth = 300
|
||||
melee_damage_upper = 25
|
||||
melee_damage_lower = 25
|
||||
attacktext = "devastates"
|
||||
attack_verb_continuous = "devastates"
|
||||
attack_verb_simple = "devastate"
|
||||
speed = -1
|
||||
obj_damage = 100
|
||||
max_shield_health = INFINITY
|
||||
else if(GLOB.ratvar_approaches) //Hefty health bonus and slight attack damage increase
|
||||
melee_damage_upper = 15
|
||||
melee_damage_lower = 15
|
||||
attacktext = "carves"
|
||||
attack_verb_continuous = "carves"
|
||||
attack_verb_simple = "carve"
|
||||
obj_damage = 50
|
||||
max_shield_health = 4
|
||||
|
||||
|
||||
@@ -100,6 +100,24 @@
|
||||
quickbind = TRUE
|
||||
quickbind_desc = "Creates a Judicial Visor, which can smite an area, applying Belligerent and briefly stunning."
|
||||
|
||||
//Nezbere's shield: Creates a ratvarian shield which absorbs attacks, see ratvarian_shield.dm for details.
|
||||
/datum/clockwork_scripture/create_object/nezberes_shield
|
||||
descname = "Shield with empowerable bashes"
|
||||
name = "Nezbere's shield"
|
||||
desc = "Creates a shield which generates charge from blocking damage, using it to empower its bashes tremendously. It is repaired with brass, and while very durable, extremely weak to lasers and, even more so, to energy weaponry."
|
||||
invocations = list("Shield me...", "... from the coming dark!")
|
||||
channel_time = 20
|
||||
power_cost = 600 //Shouldn't be too spammable but not too hard to get either
|
||||
whispered = TRUE
|
||||
creator_message = "You form a ratvarian shield, which is capable of absorbing blocked attacks to empower its bashes."
|
||||
object_path = /obj/item/shield/riot/ratvarian
|
||||
usage_tip = "Bashes will only use charge when performed with intent to harm."
|
||||
tier = SCRIPTURE_SCRIPT
|
||||
space_allowed = TRUE
|
||||
primary_component = VANGUARD_COGWHEEL
|
||||
sort_priority = 5
|
||||
quickbind = TRUE
|
||||
quickbind_desc = "Creates a Ratvarian shield, which can absorb energy from attacks for use in powerful bashes."
|
||||
|
||||
//Clockwork Armaments: Grants the invoker the ability to call forth a Ratvarian spear and clockwork armor.
|
||||
/datum/clockwork_scripture/clockwork_armaments
|
||||
@@ -113,7 +131,7 @@
|
||||
usage_tip = "Throwing the spear at a mob will do massive damage and knock them down, but break the spear. You will need to wait for 30 seconds before resummoning it."
|
||||
tier = SCRIPTURE_SCRIPT
|
||||
primary_component = VANGUARD_COGWHEEL
|
||||
sort_priority = 5
|
||||
sort_priority = 6
|
||||
important = TRUE
|
||||
quickbind = TRUE
|
||||
quickbind_desc = "Permanently binds clockwork armor and a Ratvarian spear to you."
|
||||
@@ -213,7 +231,7 @@
|
||||
usage_tip = "This gateway is strictly one-way and will only allow things through the invoker's portal."
|
||||
tier = SCRIPTURE_SCRIPT
|
||||
primary_component = GEIS_CAPACITOR
|
||||
sort_priority = 6
|
||||
sort_priority = 7
|
||||
quickbind = TRUE
|
||||
quickbind_desc = "Allows you to create a one-way Spatial Gateway to a living Servant or Clockwork Obelisk."
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
antagpanel_category = "Clockcult"
|
||||
job_rank = ROLE_SERVANT_OF_RATVAR
|
||||
antag_moodlet = /datum/mood_event/cult
|
||||
skill_modifiers = list(/datum/skill_modifier/job/level/wiring)
|
||||
var/datum/action/innate/hierophant/hierophant_network = new
|
||||
threat = 3
|
||||
var/datum/team/clockcult/clock_team
|
||||
|
||||
@@ -7,9 +7,12 @@
|
||||
desc = "A large, menacing creature covered in armored black scales."
|
||||
speak_emote = list("cackles")
|
||||
emote_hear = list("cackles","screeches")
|
||||
response_help = "thinks better of touching"
|
||||
response_disarm = "flails at"
|
||||
response_harm = "punches"
|
||||
response_help_continuous = "thinks better of touching"
|
||||
response_help_simple = "think better of touching"
|
||||
response_disarm_continuous = "flails at"
|
||||
response_disarm_simple = "flail at"
|
||||
response_harm_continuous = "punches"
|
||||
response_harm_simple = "punch"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "imp"
|
||||
icon_living = "imp"
|
||||
@@ -23,7 +26,8 @@
|
||||
minbodytemp = 250 //Weak to cold
|
||||
maxbodytemp = INFINITY
|
||||
faction = list("hell")
|
||||
attacktext = "wildly tears into"
|
||||
attack_verb_continuous = "wildly tears into"
|
||||
attack_verb_simple = "wildly tear into"
|
||||
maxHealth = 200
|
||||
health = 200
|
||||
healable = 0
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
/datum/antagonist/ert/engineer
|
||||
role = "Engineer"
|
||||
outfit = /datum/outfit/ert/engineer
|
||||
skill_modifiers = list(/datum/skill_modifier/job/level/wiring)
|
||||
|
||||
/datum/antagonist/ert/engineer/amber
|
||||
outfit = /datum/outfit/ert/engineer/alert
|
||||
@@ -61,6 +62,7 @@
|
||||
/datum/antagonist/ert/medic
|
||||
role = "Medical Officer"
|
||||
outfit = /datum/outfit/ert/medic
|
||||
skill_modifiers = list(/datum/skill_modifier/job/affinity/surgery)
|
||||
|
||||
/datum/antagonist/ert/medic/amber
|
||||
outfit = /datum/outfit/ert/medic/alert
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
vision_range = 1 // Only attack when target is close
|
||||
wander = FALSE
|
||||
attacktext = "glomps"
|
||||
attack_verb_continuous = "glomps"
|
||||
attack_verb_simple = "glomp"
|
||||
attack_sound = 'sound/effects/blobattack.ogg'
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2)
|
||||
|
||||
|
||||
@@ -453,9 +453,9 @@
|
||||
return
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/nuclearbomb/tesla_act(power, tesla_flags)
|
||||
/obj/machinery/nuclearbomb/zap_act(power, zap_flags)
|
||||
..()
|
||||
if(tesla_flags & TESLA_MACHINE_EXPLOSIVE)
|
||||
if(zap_flags & ZAP_MACHINE_EXPLOSIVE)
|
||||
qdel(src)//like the singulo, tesla deletes it. stops it from exploding over and over
|
||||
|
||||
#define NUKERANGE 127
|
||||
@@ -608,6 +608,7 @@ This is here to make the tiles around the station mininuke change when it's arme
|
||||
lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi'
|
||||
icon_state = "datadisk0"
|
||||
w_volume = ITEM_VOLUME_DISK
|
||||
|
||||
/obj/item/disk/nuclear
|
||||
name = "nuclear authentication disk"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
job_rank = ROLE_OPERATIVE
|
||||
antag_moodlet = /datum/mood_event/focused
|
||||
threat = 10
|
||||
skill_modifiers = list(/datum/skill_modifier/job/level/wiring)
|
||||
var/datum/team/nuclear/nuke_team
|
||||
var/always_new_team = FALSE //If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team.
|
||||
var/send_to_spawnpoint = TRUE //Should the user be moved to default spawnpoint.
|
||||
|
||||
@@ -27,19 +27,24 @@
|
||||
sight = SEE_SELF
|
||||
throwforce = 0
|
||||
blood_volume = 0
|
||||
has_field_of_vision = FALSE //we are a spoopy ghost
|
||||
|
||||
see_in_dark = 8
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
response_help = "passes through"
|
||||
response_disarm = "swings through"
|
||||
response_harm = "punches through"
|
||||
response_help_continuous = "passes through"
|
||||
response_help_simple = "pass through"
|
||||
response_disarm_continuous = "swings through"
|
||||
response_disarm_simple = "swing through"
|
||||
response_harm_continuous = "punches through"
|
||||
response_harm_simple = "punch through"
|
||||
unsuitable_atmos_damage = 0
|
||||
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) //I don't know how you'd apply those, but revenants no-sell them anyway.
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
maxbodytemp = INFINITY
|
||||
harm_intent_damage = 0
|
||||
friendly = "touches"
|
||||
friendly_verb_continuous = "touches"
|
||||
friendly_verb_simple = "touch"
|
||||
status_flags = 0
|
||||
wander = FALSE
|
||||
density = FALSE
|
||||
|
||||
@@ -6,9 +6,12 @@
|
||||
desc = "A large, menacing creature covered in armored black scales."
|
||||
speak_emote = list("gurgles")
|
||||
emote_hear = list("wails","screeches")
|
||||
response_help = "thinks better of touching"
|
||||
response_disarm = "flails at"
|
||||
response_harm = "punches"
|
||||
response_help_continuous = "thinks better of touching"
|
||||
response_help_simple = "think better of touching"
|
||||
response_disarm_continuous = "flails at"
|
||||
response_disarm_simple = "flail at"
|
||||
response_harm_continuous = "punches"
|
||||
response_harm_simple = "punch"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "daemon"
|
||||
icon_living = "daemon"
|
||||
@@ -24,7 +27,8 @@
|
||||
minbodytemp = 0
|
||||
maxbodytemp = INFINITY
|
||||
faction = list("slaughter")
|
||||
attacktext = "wildly tears into"
|
||||
attack_verb_continuous = "wildly tears into"
|
||||
attack_verb_simple = "wildly tear into"
|
||||
maxHealth = 200
|
||||
health = 200
|
||||
healable = 0
|
||||
@@ -116,8 +120,10 @@
|
||||
desc = "A large, adorable creature covered in armor with pink bows."
|
||||
speak_emote = list("giggles","titters","chuckles")
|
||||
emote_hear = list("guffaws","laughs")
|
||||
response_help = "hugs"
|
||||
attacktext = "wildly tickles"
|
||||
response_help_continuous = "hugs"
|
||||
response_help_simple = "hug"
|
||||
attack_verb_continuous = "wildly tickles"
|
||||
attack_verb_simple = "wildly tickle"
|
||||
|
||||
attack_sound = 'sound/items/bikehorn.ogg'
|
||||
feast_sound = 'sound/spookoween/scary_horn2.ogg'
|
||||
|
||||
@@ -84,9 +84,11 @@
|
||||
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD)
|
||||
obj_damage = 0
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
attacktext = "shocks"
|
||||
attack_verb_continuous = "shocks"
|
||||
attack_verb_simple = "shock"
|
||||
attack_sound = 'sound/effects/empulse.ogg'
|
||||
friendly = "pinches"
|
||||
friendly_verb_continuous = "pinches"
|
||||
friendly_verb_simple = "pinch"
|
||||
speed = 0
|
||||
faction = list("swarmer")
|
||||
AIStatus = AI_OFF
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
antagpanel_category = "Traitor"
|
||||
job_rank = ROLE_TRAITOR
|
||||
antag_moodlet = /datum/mood_event/focused
|
||||
skill_modifiers = list(/datum/skill_modifier/job/level/wiring/basic)
|
||||
var/special_role = ROLE_TRAITOR
|
||||
var/employer = "The Syndicate"
|
||||
var/give_objectives = TRUE
|
||||
|
||||
@@ -226,7 +226,11 @@
|
||||
|
||||
/datum/spellbook_entry/lightningbolt/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) //return 1 on success
|
||||
. = ..()
|
||||
user.flags_1 |= TESLA_IGNORE_1
|
||||
ADD_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "lightning_bolt_spell")
|
||||
|
||||
/datum/spellbook_entry/lightningbolt/Refund(mob/living/carbon/human/user, obj/item/spellbook/book)
|
||||
. = ..()
|
||||
REMOVE_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "lightning_bolt_spell")
|
||||
|
||||
/datum/spellbook_entry/infinite_guns
|
||||
name = "Lesser Summon Guns"
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
desc = "A machine that monitors atmosphere levels. Goes off if the area is dangerous."
|
||||
icon = 'icons/obj/monitors.dmi'
|
||||
icon_state = "alarm0"
|
||||
plane = ABOVE_WALL_PLANE
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 4
|
||||
active_power_usage = 8
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
active_power_usage = 0
|
||||
power_channel = ENVIRON
|
||||
layer = GAS_PIPE_HIDDEN_LAYER //under wires
|
||||
plane = ABOVE_WALL_PLANE
|
||||
resistance_flags = FIRE_PROOF
|
||||
max_integrity = 200
|
||||
obj_flags = CAN_BE_HIT | ON_BLUEPRINTS
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
name = "circulator/heat exchanger"
|
||||
desc = "A gas circulator pump and heat exchanger."
|
||||
icon_state = "circ-off-0"
|
||||
plane = GAME_PLANE
|
||||
|
||||
var/active = FALSE
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
var/turf/T = loc
|
||||
if(level == 2 || (istype(T) && !T.intact))
|
||||
showpipe = TRUE
|
||||
plane = GAME_PLANE
|
||||
plane = ABOVE_WALL_PLANE
|
||||
else
|
||||
showpipe = FALSE
|
||||
plane = FLOOR_PLANE
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
max_integrity = 350
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 30, "acid" = 30)
|
||||
layer = ABOVE_WINDOW_LAYER
|
||||
plane = GAME_PLANE
|
||||
state_open = FALSE
|
||||
circuit = /obj/item/circuitboard/machine/cryo_tube
|
||||
pipe_flags = PIPING_ONE_PER_TURF | PIPING_DEFAULT_LAYER_ONLY
|
||||
@@ -15,8 +16,8 @@
|
||||
var/volume = 100
|
||||
|
||||
var/efficiency = 1
|
||||
var/sleep_factor = 0.00125
|
||||
var/unconscious_factor = 0.001
|
||||
var/base_knockout = 30 SECONDS
|
||||
var/knockout_factor = 1
|
||||
var/heat_capacity = 20000
|
||||
var/conduction_coefficient = 0.3
|
||||
|
||||
@@ -53,10 +54,9 @@
|
||||
var/C
|
||||
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
|
||||
C += M.rating
|
||||
|
||||
// 2 bins total, so C ranges from 2 to 8.
|
||||
efficiency = initial(efficiency) * C
|
||||
sleep_factor = initial(sleep_factor) * C
|
||||
unconscious_factor = initial(unconscious_factor) * C
|
||||
knockout_factor = initial(knockout_factor) / max(1, (C * 0.33))
|
||||
heat_capacity = initial(heat_capacity) / C
|
||||
conduction_coefficient = initial(conduction_coefficient) * C
|
||||
|
||||
@@ -188,8 +188,10 @@
|
||||
|
||||
if(air1.gases.len)
|
||||
if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic.
|
||||
mob_occupant.Sleeping((mob_occupant.bodytemperature * sleep_factor) * 2000)
|
||||
mob_occupant.Unconscious((mob_occupant.bodytemperature * unconscious_factor) * 2000)
|
||||
// temperature factor goes from 1 to about 2.5
|
||||
var/amount = max(1, (4 * log(T0C - mob_occupant.bodytemperature)) - 20) * knockout_factor * base_knockout
|
||||
mob_occupant.Sleeping(amount)
|
||||
mob_occupant.Unconscious(amount)
|
||||
if(beaker)
|
||||
if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic.
|
||||
beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents.
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
max_integrity = 800
|
||||
density = TRUE
|
||||
layer = ABOVE_WINDOW_LAYER
|
||||
plane = GAME_PLANE
|
||||
pipe_flags = PIPING_ONE_PER_TURF
|
||||
var/volume = 10000 //in liters
|
||||
var/gas_type = 0
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
max_integrity = 300
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 30)
|
||||
layer = OBJ_LAYER
|
||||
plane = GAME_PLANE
|
||||
circuit = /obj/item/circuitboard/machine/thermomachine
|
||||
ui_x = 300
|
||||
ui_y = 230
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
|
||||
/datum/bounty/item/medical/defibrillator
|
||||
name = "New defibillators"
|
||||
description = "After years of storge our defib units have become liabilities. Please send us some new ones."
|
||||
description = "After years of storage our defibrillation units have worn out. Please send us some new ones."
|
||||
reward = 2250
|
||||
required_count = 5
|
||||
wanted_types = list(/obj/item/defibrillator)
|
||||
|
||||
@@ -119,6 +119,7 @@
|
||||
var/list/data = list()
|
||||
data["requestonly"] = requestonly
|
||||
data["supplies"] = list()
|
||||
data["emagged"] = obj_flags & EMAGGED
|
||||
for(var/pack in SSshuttle.supply_packs)
|
||||
var/datum/supply_pack/P = SSshuttle.supply_packs[pack]
|
||||
if(!data["supplies"][P.group])
|
||||
@@ -133,7 +134,8 @@
|
||||
"cost" = P.cost,
|
||||
"id" = pack,
|
||||
"desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name.
|
||||
"access" = P.access
|
||||
"access" = P.access,
|
||||
"can_private_buy" = P.can_private_buy
|
||||
))
|
||||
return data
|
||||
|
||||
@@ -195,9 +197,10 @@
|
||||
rank = "Silicon"
|
||||
|
||||
var/datum/bank_account/account
|
||||
if(self_paid && ishuman(usr))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
var/obj/item/card/id/id_card = H.get_idcard(TRUE)
|
||||
if(self_paid)
|
||||
if(!pack.can_private_buy && !(obj_flags & EMAGGED))
|
||||
return
|
||||
var/obj/item/card/id/id_card = usr.get_idcard(TRUE)
|
||||
if(!istype(id_card))
|
||||
say("No ID card detected.")
|
||||
return
|
||||
|
||||
@@ -68,7 +68,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
|
||||
var/unit_name = "" // Unit name. Only used in "Received [total_amount] [name]s [message]." message
|
||||
var/message = ""
|
||||
var/cost = 100 // Cost of item, in cargo credits. Must not alow for infinite price dupes, see above.
|
||||
var/k_elasticity = 1/300 //coefficient used in marginal price calculation that roughly corresponds to the inverse of price elasticity, or "quantity elasticity" - CIT EDIT 1/30 - > 0
|
||||
var/k_elasticity = 1/100 //coefficient used in marginal price calculation that roughly corresponds to the inverse of price elasticity, or "quantity elasticity" - CIT EDIT 1/30 - > 100
|
||||
var/list/export_types = list() // Type of the exported object. If none, the export datum is considered base type.
|
||||
var/include_subtypes = TRUE // Set to FALSE to make the datum apply only to a strict type.
|
||||
var/list/exclude_types = list() // Types excluded from export
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/datum/export/gear
|
||||
include_subtypes = FALSE
|
||||
k_elasticity = 0 //We always want clothing/gear
|
||||
|
||||
//blanket
|
||||
/datum/export/gear/hat
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
include_subtypes = FALSE
|
||||
|
||||
/datum/export/large/am_control_unit
|
||||
cost = 4000
|
||||
cost = 2000
|
||||
unit_name = "antimatter control unit"
|
||||
export_types = list(/obj/machinery/power/am_control_unit)
|
||||
|
||||
|
||||
@@ -2,15 +2,14 @@
|
||||
|
||||
/datum/export/robotics
|
||||
include_subtypes = FALSE
|
||||
k_elasticity = 0 //ALWAYS worth selling upgrades
|
||||
k_elasticity = 1/50
|
||||
|
||||
/datum/export/implant
|
||||
include_subtypes = FALSE
|
||||
k_elasticity = 0 //ALWAYS worth selling upgrades
|
||||
k_elasticity = 1/50
|
||||
|
||||
/datum/export/organs
|
||||
include_subtypes = TRUE
|
||||
k_elasticity = 0 //ALWAYS worth selling orgains
|
||||
|
||||
/datum/export/implant/autodoc
|
||||
cost = 150
|
||||
@@ -60,11 +59,6 @@
|
||||
unit_name = "thrusters set implant"
|
||||
export_types = list(/obj/item/organ/cyberimp/chest/thrusters)
|
||||
|
||||
/datum/export/implant/thrusters
|
||||
cost = 150
|
||||
unit_name = "thrusters set implant"
|
||||
export_types = list(/obj/item/organ/cyberimp/chest/thrusters)
|
||||
|
||||
/datum/export/implant/arm
|
||||
cost = 200
|
||||
unit_name = "arm set implant"
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
include_subtypes = FALSE
|
||||
|
||||
/datum/export/glasswork_lens
|
||||
cost = 1800
|
||||
cost = 1600
|
||||
unit_name = "small glass lens"
|
||||
export_types = list(/obj/item/glasswork/glass_base/lens)
|
||||
|
||||
@@ -133,13 +133,13 @@
|
||||
include_subtypes = FALSE
|
||||
|
||||
/datum/export/glasswork_teaplate
|
||||
cost = 1200
|
||||
cost = 1000
|
||||
unit_name = "tea gear"
|
||||
export_types = list(/obj/item/tea_plate)
|
||||
include_subtypes = FALSE
|
||||
|
||||
/datum/export/glasswork_teacup
|
||||
cost = 1800
|
||||
cost = 1600
|
||||
unit_name = "tea gear"
|
||||
export_types = list(/obj/item/tea_cup)
|
||||
include_subtypes = FALSE
|
||||
|
||||
@@ -120,12 +120,6 @@
|
||||
message = "of cloth"
|
||||
export_types = list(/obj/item/stack/sheet/cloth)
|
||||
|
||||
/datum/export/stack/silk
|
||||
cost = 200 //The new plasma
|
||||
unit_name = "sheets"
|
||||
message = "of silk"
|
||||
export_types = list(/obj/item/stack/sheet/silk)
|
||||
|
||||
/datum/export/stack/duracloth
|
||||
cost = 40
|
||||
unit_name = "sheets"
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/datum/export/toolbox
|
||||
/datum/export/tool
|
||||
k_elasticity = 1/500 //Tool selling almost allways fine a target
|
||||
|
||||
/datum/export/tool/toolbox
|
||||
cost = 6
|
||||
unit_name = "toolbox"
|
||||
export_types = list(/obj/item/storage/toolbox)
|
||||
@@ -29,93 +32,93 @@
|
||||
|
||||
// Lights/Eletronic
|
||||
|
||||
/datum/export/lights
|
||||
/datum/export/tool/lights
|
||||
cost = 10
|
||||
unit_name = "light fixer"
|
||||
export_types = list(/obj/item/wallframe/light_fixture)
|
||||
include_subtypes = TRUE
|
||||
|
||||
/datum/export/apc_board
|
||||
/datum/export/tool/apc_board
|
||||
cost = 5
|
||||
unit_name = "apc electronics"
|
||||
export_types = list(/obj/item/electronics/apc)
|
||||
include_subtypes = TRUE
|
||||
|
||||
/datum/export/apc_frame
|
||||
/datum/export/tool/apc_frame
|
||||
cost = 3
|
||||
unit_name = "apc frame"
|
||||
export_types = list(/obj/item/wallframe/apc)
|
||||
include_subtypes = TRUE
|
||||
|
||||
/datum/export/floodlights
|
||||
/datum/export/tool/floodlights
|
||||
cost = 15
|
||||
unit_name = "floodlight fixer"
|
||||
export_types = list(/obj/structure/floodlight_frame)
|
||||
include_subtypes = TRUE
|
||||
|
||||
/datum/export/bolbstubes
|
||||
/datum/export/tool/bolbstubes
|
||||
cost = 1 //Time
|
||||
unit_name = "light replacement"
|
||||
export_types = list(/obj/item/light/tube, /obj/item/light/bulb)
|
||||
|
||||
/datum/export/lightreplacer
|
||||
/datum/export/tool/lightreplacer
|
||||
cost = 20
|
||||
unit_name = "lightreplacer"
|
||||
export_types = list(/obj/item/lightreplacer)
|
||||
|
||||
// Basic tools
|
||||
/datum/export/basicmining
|
||||
/datum/export/tool/basicmining
|
||||
cost = 30
|
||||
unit_name = "basic mining tool"
|
||||
export_types = list(/obj/item/pickaxe, /obj/item/pickaxe/mini, /obj/item/shovel, /obj/item/resonator)
|
||||
include_subtypes = FALSE
|
||||
|
||||
/datum/export/upgradedmining
|
||||
/datum/export/tool/upgradedmining
|
||||
cost = 80
|
||||
unit_name = "mining tool"
|
||||
export_types = list(/obj/item/pickaxe/silver, /obj/item/pickaxe/drill, /obj/item/gun/energy/plasmacutter, /obj/item/resonator/upgraded)
|
||||
include_subtypes = FALSE
|
||||
|
||||
/datum/export/advdmining
|
||||
/datum/export/tool/advdmining
|
||||
cost = 150
|
||||
unit_name = "advanced mining tool"
|
||||
export_types = list(/obj/item/pickaxe/diamond, /obj/item/pickaxe/drill/diamonddrill, /obj/item/pickaxe/drill/jackhammer, /obj/item/gun/energy/plasmacutter/adv)
|
||||
include_subtypes = FALSE
|
||||
|
||||
/datum/export/screwdriver
|
||||
/datum/export/tool/screwdriver
|
||||
cost = 2
|
||||
unit_name = "screwdriver"
|
||||
export_types = list(/obj/item/screwdriver)
|
||||
include_subtypes = FALSE
|
||||
|
||||
/datum/export/wrench
|
||||
/datum/export/tool/wrench
|
||||
cost = 2
|
||||
unit_name = "wrench"
|
||||
export_types = list(/obj/item/wrench)
|
||||
|
||||
/datum/export/crowbar
|
||||
/datum/export/tool/crowbar
|
||||
cost = 2
|
||||
unit_name = "crowbar"
|
||||
export_types = list(/obj/item/crowbar)
|
||||
|
||||
/datum/export/wirecutters
|
||||
/datum/export/tool/wirecutters
|
||||
cost = 2
|
||||
unit_name = "pair"
|
||||
message = "of wirecutters"
|
||||
export_types = list(/obj/item/wirecutters)
|
||||
|
||||
/datum/export/weldingtool
|
||||
/datum/export/tool/weldingtool
|
||||
cost = 5
|
||||
unit_name = "welding tool"
|
||||
export_types = list(/obj/item/weldingtool)
|
||||
include_subtypes = FALSE
|
||||
|
||||
/datum/export/weldingtool/emergency
|
||||
/datum/export/tool/weldingtool/emergency
|
||||
cost = 2
|
||||
unit_name = "emergency welding tool"
|
||||
export_types = list(/obj/item/weldingtool/mini)
|
||||
|
||||
/datum/export/weldingtool/industrial
|
||||
/datum/export/tool/weldingtool/industrial
|
||||
cost = 10
|
||||
unit_name = "industrial welding tool"
|
||||
export_types = list(/obj/item/weldingtool/largetank, /obj/item/weldingtool/hugetank)
|
||||
@@ -131,23 +134,23 @@
|
||||
unit_name = "pocket fire extinguisher"
|
||||
export_types = list(/obj/item/extinguisher/mini)
|
||||
|
||||
/datum/export/flashlight
|
||||
/datum/export/tool/flashlight
|
||||
cost = 3
|
||||
unit_name = "flashlight"
|
||||
export_types = list(/obj/item/flashlight)
|
||||
include_subtypes = FALSE
|
||||
|
||||
/datum/export/flashlight/flare
|
||||
/datum/export/tool/flashlight/flare
|
||||
cost = 2
|
||||
unit_name = "flare"
|
||||
export_types = list(/obj/item/flashlight/flare)
|
||||
|
||||
/datum/export/flashlight/seclite
|
||||
/datum/export/tool/flashlight/seclite
|
||||
cost = 5
|
||||
unit_name = "seclite"
|
||||
export_types = list(/obj/item/flashlight/seclite)
|
||||
|
||||
/datum/export/analyzer
|
||||
/datum/export/tool/analyzer
|
||||
cost = 5
|
||||
unit_name = "analyzer"
|
||||
export_types = list(/obj/item/analyzer)
|
||||
@@ -163,32 +166,32 @@
|
||||
export_types = list(/obj/item/radio)
|
||||
exclude_types = list(/obj/item/radio/mech)
|
||||
|
||||
/datum/export/rcd
|
||||
/datum/export/tool/rcd
|
||||
cost = 100
|
||||
unit_name = "rapid construction device"
|
||||
export_types = list(/obj/item/construction/rcd)
|
||||
|
||||
/datum/export/rcd_ammo
|
||||
/datum/export/tool/rcd_ammo
|
||||
cost = 60
|
||||
unit_name = "compressed matter cardridge"
|
||||
export_types = list(/obj/item/rcd_ammo)
|
||||
|
||||
/datum/export/rpd
|
||||
/datum/export/tool/rpd
|
||||
cost = 100
|
||||
unit_name = "rapid piping device"
|
||||
export_types = list(/obj/item/pipe_dispenser)
|
||||
|
||||
/datum/export/rld
|
||||
/datum/export/tool/rld
|
||||
cost = 150
|
||||
unit_name = "rapid light device"
|
||||
export_types = list(/obj/item/construction/rld)
|
||||
|
||||
/datum/export/rped
|
||||
/datum/export/tool/rped
|
||||
cost = 100
|
||||
unit_name = "rapid part exchange device"
|
||||
export_types = list(/obj/item/storage/part_replacer)
|
||||
|
||||
/datum/export/bsrped
|
||||
/datum/export/tool/bsrped
|
||||
cost = 200
|
||||
unit_name = "blue space part exchange device"
|
||||
export_types = list(/obj/item/storage/part_replacer/bluespace)
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
name = "gondola"
|
||||
real_name = "gondola"
|
||||
desc = "The silent walker. This one seems to be part of a delivery agency."
|
||||
response_help = "pets"
|
||||
response_disarm = "bops"
|
||||
response_harm = "kicks"
|
||||
response_help_continuous = "pets"
|
||||
response_help_simple = "pet"
|
||||
response_disarm_continuous = "bops"
|
||||
response_disarm_simple = "bop"
|
||||
response_harm_continuous = "kicks"
|
||||
response_harm_simple = "kick"
|
||||
faction = list("gondola")
|
||||
turns_per_move = 10
|
||||
icon = 'icons/mob/gondolapod.dmi'
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
var/special_enabled = FALSE
|
||||
var/DropPodOnly = FALSE //only usable by the Bluespace Drop Pod via the express cargo console
|
||||
var/admin_spawned = FALSE //Can only an admin spawn this crate?
|
||||
var/can_private_buy = TRUE //Can it be purchased privately by each crewmember?
|
||||
|
||||
/datum/supply_pack/proc/generate(atom/A, datum/bank_account/paying_account)
|
||||
var/obj/structure/closet/crate/C
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
group = "Armory"
|
||||
access = ACCESS_ARMORY
|
||||
crate_type = /obj/structure/closet/crate/secure/weapon
|
||||
can_private_buy = FALSE
|
||||
|
||||
/datum/supply_pack/security/armory/bulletarmor
|
||||
name = "Bulletproof Armor Crate"
|
||||
@@ -214,7 +215,7 @@
|
||||
|
||||
/datum/supply_pack/security/armory/wt550ammo
|
||||
name = "WT-550 Semi-Auto SMG Ammo Crate"
|
||||
desc = "Contains four 20-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
|
||||
desc = "Contains four 32-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
|
||||
cost = 1750
|
||||
contains = list(/obj/item/ammo_box/magazine/wt550m9,
|
||||
/obj/item/ammo_box/magazine/wt550m9,
|
||||
@@ -224,7 +225,7 @@
|
||||
|
||||
/datum/supply_pack/security/armory/wt550ammo_nonlethal // Takes around 12 shots to stamcrit someone
|
||||
name = "WT-550 Semi-Auto SMG Non-Lethal Ammo Crate"
|
||||
desc = "Contains four 20-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
|
||||
desc = "Contains four 32-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
|
||||
cost = 1000
|
||||
contains = list(/obj/item/ammo_box/magazine/wt550m9/wtrubber,
|
||||
/obj/item/ammo_box/magazine/wt550m9/wtrubber,
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
crate_name = "supermatter shard crate"
|
||||
crate_type = /obj/structure/closet/crate/secure/engineering
|
||||
dangerous = TRUE
|
||||
|
||||
|
||||
/datum/supply_pack/engine/tesla_coils
|
||||
name = "Tesla Coil Crate"
|
||||
desc = "Whether it's high-voltage executions, creating research points, or just plain old power generation: This pack of four Tesla coils can do it all!"
|
||||
|
||||
@@ -81,32 +81,6 @@
|
||||
contains = list(/obj/item/stack/sheet/mineral/wood/fifty)
|
||||
crate_name = "wood planks crate"
|
||||
|
||||
/datum/supply_pack/materials/rawcotton
|
||||
name = "Raw Cotton Crate"
|
||||
desc = "Plushies have been on the down in the market, and now due to a flood of raw cotton the price of it is so cheap, its a steal! Contains 40 raw cotton sheets."
|
||||
cost = 800 // 100 net cost, 20 x 20 = 400. 300 profit if turned into cloth sheets or more if turned to silk then 10 x 200 = 2000
|
||||
contains = list(/obj/item/stack/sheet/cotton/thirty,
|
||||
/obj/item/stack/sheet/cotton/ten
|
||||
)
|
||||
crate_name = "cotton crate"
|
||||
crate_type = /obj/structure/closet/crate/hydroponics
|
||||
|
||||
/datum/supply_pack/materials/rawcottonbulk
|
||||
name = "Raw Cotton Crate (Bulk)"
|
||||
desc = "We have so much of this stuff we need to get rid of it in -bulk- now. This crate contains 240 raw cotton sheets."
|
||||
cost = 1300 // 600 net cost 20 x 120 = 2400 profit if turned into cloth sheets or if turned into silk 200 x 60 = 12000
|
||||
contains = list(/obj/item/stack/sheet/cotton/thirty,
|
||||
/obj/item/stack/sheet/cotton/thirty,
|
||||
/obj/item/stack/sheet/cotton/thirty,
|
||||
/obj/item/stack/sheet/cotton/thirty,
|
||||
/obj/item/stack/sheet/cotton/thirty,
|
||||
/obj/item/stack/sheet/cotton/thirty,
|
||||
/obj/item/stack/sheet/cotton/thirty,
|
||||
/obj/item/stack/sheet/cotton/thirty,
|
||||
)
|
||||
crate_name = "bulk cotton crate"
|
||||
crate_type = /obj/structure/closet/crate/hydroponics
|
||||
|
||||
/datum/supply_pack/materials/rcdammo
|
||||
name = "Spare RCD ammo"
|
||||
desc = "This crate contains sixteen RCD compressed matter packs, to help with any holes or projects people might be working on."
|
||||
|
||||
@@ -252,6 +252,7 @@
|
||||
crate_name = "virus crate"
|
||||
crate_type = /obj/structure/closet/crate/secure/plasma
|
||||
dangerous = TRUE
|
||||
can_private_buy = FALSE
|
||||
|
||||
/datum/supply_pack/medical/anitvirus
|
||||
name = "Virus Containment Crate"
|
||||
@@ -271,4 +272,4 @@
|
||||
/obj/item/storage/box/syringes,
|
||||
/obj/item/storage/box/beakers)
|
||||
crate_name = "virus containment unit crate"
|
||||
crate_type = /obj/structure/closet/crate/secure/plasma
|
||||
crate_type = /obj/structure/closet/crate/secure/plasma
|
||||
|
||||
@@ -370,22 +370,6 @@
|
||||
/////////////////////////////////// Misc /////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/supply_pack/organic/hunting
|
||||
name = "Hunting Gear"
|
||||
desc = "Even in space, we can find prey to hunt, this crate contains everthing a fine hunter needs to have a sporting time. This crate needs armory access to open. A true huntter only needs a fine bottle of cognac, a nice coat, some good o' cigars, and of cource a hunting shotgun. "
|
||||
cost = 3500
|
||||
contraband = TRUE
|
||||
contains = list(/obj/item/clothing/head/flatcap,
|
||||
/obj/item/clothing/suit/hooded/wintercoat/captain,
|
||||
/obj/item/reagent_containers/food/drinks/bottle/cognac,
|
||||
/obj/item/storage/fancy/cigarettes/cigars/havana,
|
||||
/obj/item/clothing/gloves/color/white,
|
||||
/obj/item/clothing/under/rank/civilian/curator,
|
||||
/obj/item/gun/ballistic/shotgun/lethal)
|
||||
access = ACCESS_ARMORY
|
||||
crate_name = "sporting crate"
|
||||
crate_type = /obj/structure/closet/crate/secure // Would have liked a wooden crate but access >:(
|
||||
|
||||
/datum/supply_pack/organic/party
|
||||
name = "Party Equipment"
|
||||
desc = "Celebrate both life and death on the station with Nanotrasen's Party Essentials(tm)! Contains seven colored glowsticks, four beers, two ales, a drinking shaker, and a bottle of patron & goldschlager!"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
cost = 2500
|
||||
contains = list (/obj/item/reagent_containers/food/snacks/cube/ape)
|
||||
crate_name = "ape cube crate"
|
||||
can_private_buy = FALSE
|
||||
|
||||
/datum/supply_pack/science/beakers
|
||||
name = "Chemistry Beakers Crate"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
group = "Security"
|
||||
access = ACCESS_SECURITY
|
||||
crate_type = /obj/structure/closet/crate/secure/gear
|
||||
can_private_buy = FALSE
|
||||
|
||||
/datum/supply_pack/security/ammo
|
||||
name = "Ammo Crate - General Purpose"
|
||||
@@ -57,6 +58,7 @@
|
||||
/obj/item/toy/crayon/white,
|
||||
/obj/item/clothing/head/fedora/det_hat)
|
||||
crate_name = "forensics crate"
|
||||
can_private_buy = TRUE
|
||||
|
||||
/datum/supply_pack/security/helmets
|
||||
name = "Helmets Crate"
|
||||
@@ -134,6 +136,7 @@
|
||||
/obj/item/grenade/barrier)
|
||||
cost = 2000
|
||||
crate_name = "security barriers crate"
|
||||
can_private_buy = TRUE
|
||||
|
||||
/datum/supply_pack/security/securityclothes
|
||||
name = "Security Clothing Crate"
|
||||
@@ -152,6 +155,7 @@
|
||||
/obj/item/clothing/suit/armor/hos/navyblue,
|
||||
/obj/item/clothing/head/beret/sec/navyhos)
|
||||
crate_name = "security clothing crate"
|
||||
can_private_buy = TRUE
|
||||
|
||||
/datum/supply_pack/security/supplies
|
||||
name = "Security Supplies Crate"
|
||||
@@ -179,6 +183,7 @@
|
||||
contains = list(/obj/item/clothing/head/helmet/justice,
|
||||
/obj/item/clothing/mask/gas/sechailer)
|
||||
crate_name = "security clothing crate"
|
||||
can_private_buy = TRUE
|
||||
|
||||
/datum/supply_pack/security/baton
|
||||
name = "Stun Batons Crate"
|
||||
@@ -207,3 +212,19 @@
|
||||
/obj/item/storage/box/wall_flash,
|
||||
/obj/item/storage/box/wall_flash)
|
||||
crate_name = "wall-mounted flash crate"
|
||||
|
||||
/datum/supply_pack/security/hunting
|
||||
name = "Hunting Gear"
|
||||
desc = "Even in space, we can find prey to hunt, this crate contains everthing a fine hunter needs to have a sporting time. This crate needs armory access to open. A true huntter only needs a fine bottle of cognac, a nice coat, some good o' cigars, and of cource a hunting shotgun. "
|
||||
cost = 3500
|
||||
contraband = TRUE
|
||||
contains = list(/obj/item/clothing/head/flatcap,
|
||||
/obj/item/clothing/suit/hooded/wintercoat/captain,
|
||||
/obj/item/reagent_containers/food/drinks/bottle/cognac,
|
||||
/obj/item/storage/fancy/cigarettes/cigars/havana,
|
||||
/obj/item/clothing/gloves/color/white,
|
||||
/obj/item/clothing/under/rank/civilian/curator,
|
||||
/obj/item/gun/ballistic/shotgun/lethal)
|
||||
access = ACCESS_ARMORY
|
||||
crate_name = "sporting crate"
|
||||
crate_type = /obj/structure/closet/crate/secure // Would have liked a wooden crate but access >:(
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
contains = list(/obj/machinery/vending/security)
|
||||
crate_name = "SecTech supply crate"
|
||||
crate_type = /obj/structure/closet/crate/secure/gear
|
||||
can_private_buy = FALSE
|
||||
|
||||
/datum/supply_pack/vending/snack
|
||||
name = "Snack Supply Crate"
|
||||
|
||||
@@ -80,10 +80,24 @@
|
||||
|
||||
var/list/char_render_holders //Should only be a key-value list of north/south/east/west = obj/screen.
|
||||
|
||||
/// Keys currently held
|
||||
var/list/keys_held = list()
|
||||
/// These next two vars are to apply movement for keypresses and releases made while move delayed.
|
||||
/// Because discarding that input makes the game less responsive.
|
||||
/// On next move, add this dir to the move that would otherwise be done
|
||||
var/next_move_dir_add
|
||||
/// On next move, subtract this dir from the move that would otherwise be done
|
||||
var/next_move_dir_sub
|
||||
/// Amount of keydowns in the last keysend checking interval
|
||||
var/client_keysend_amount = 0
|
||||
/// World tick time where client_keysend_amount will reset
|
||||
var/next_keysend_reset = 0
|
||||
/// World tick time where keysend_tripped will reset back to false
|
||||
var/next_keysend_trip_reset = 0
|
||||
/// When set to true, user will be autokicked if they trip the keysends in a second limit again
|
||||
var/keysend_tripped = FALSE
|
||||
/// custom movement keys for this client
|
||||
var/list/movement_keys = list()
|
||||
|
||||
/// Messages currently seen by this client
|
||||
var/list/seen_messages
|
||||
|
||||
@@ -267,6 +267,9 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
|
||||
else
|
||||
prefs = new /datum/preferences(src)
|
||||
GLOB.preferences_datums[ckey] = prefs
|
||||
if(SSinput.initialized)
|
||||
set_macros()
|
||||
update_movement_keys(prefs)
|
||||
|
||||
prefs.last_ip = address //these are gonna be used for banning
|
||||
prefs.last_id = computer_id //these are gonna be used for banning
|
||||
@@ -330,9 +333,6 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(SSinput.initialized)
|
||||
set_macros()
|
||||
|
||||
chatOutput.start() // Starts the chat
|
||||
|
||||
if(alert_mob_dupe_login)
|
||||
@@ -894,6 +894,23 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
|
||||
y = clamp(y+change, min,max)
|
||||
change_view("[x]x[y]")
|
||||
|
||||
/client/proc/update_movement_keys(datum/preferences/direct_prefs)
|
||||
var/datum/preferences/D = prefs || direct_prefs
|
||||
if(!D?.key_bindings)
|
||||
return
|
||||
movement_keys = list()
|
||||
for(var/key in D.key_bindings)
|
||||
for(var/kb_name in D.key_bindings[key])
|
||||
switch(kb_name)
|
||||
if("North")
|
||||
movement_keys[key] = NORTH
|
||||
if("East")
|
||||
movement_keys[key] = EAST
|
||||
if("West")
|
||||
movement_keys[key] = WEST
|
||||
if("South")
|
||||
movement_keys[key] = SOUTH
|
||||
|
||||
/client/proc/change_view(new_size)
|
||||
if (isnull(new_size))
|
||||
CRASH("change_view called without argument.")
|
||||
@@ -904,23 +921,27 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
|
||||
new_size = "15x15"
|
||||
//END OF CIT CHANGES
|
||||
|
||||
var/list/old_view = getviewsize(view)
|
||||
view = new_size
|
||||
apply_clickcatcher()
|
||||
var/list/actualview = getviewsize(view)
|
||||
apply_clickcatcher(actualview)
|
||||
mob.reload_fullscreen()
|
||||
if (isliving(mob))
|
||||
var/mob/living/M = mob
|
||||
M.update_damage_hud()
|
||||
if (prefs.auto_fit_viewport)
|
||||
fit_viewport()
|
||||
SEND_SIGNAL(mob, COMSIG_MOB_CLIENT_CHANGE_VIEW, src, old_view, actualview)
|
||||
|
||||
/client/proc/generate_clickcatcher()
|
||||
if(!void)
|
||||
void = new()
|
||||
screen += void
|
||||
|
||||
/client/proc/apply_clickcatcher()
|
||||
/client/proc/apply_clickcatcher(list/actualview)
|
||||
generate_clickcatcher()
|
||||
var/list/actualview = getviewsize(view)
|
||||
if(!actualview)
|
||||
actualview = getviewsize(view)
|
||||
void.UpdateGreed(actualview[1],actualview[2])
|
||||
|
||||
/client/proc/AnnouncePR(announcement)
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
/* CAUTION! CAUTION! CAUTION! CAUTION! CAUTION! *\
|
||||
| THIS FILE CONTAINS HOOKS FOR FOR |
|
||||
| CHANGES SPECIFIC TO CITADEL. IF |
|
||||
| YOU'RE FIXING A MERGE CONFLICT |
|
||||
| HERE, PLEASE ASK FOR REVIEW FROM |
|
||||
| ANOTHER MAINTAINER TO ENSURE YOU |
|
||||
| DON'T INTRODUCE REGRESSIONS. |
|
||||
\* */
|
||||
#define DEFAULT_SLOT_AMT 2
|
||||
#define HANDS_SLOT_AMT 2
|
||||
#define BACKPACK_SLOT_AMT 4
|
||||
|
||||
GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
@@ -51,6 +46,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/chat_on_map = TRUE
|
||||
var/max_chat_length = CHAT_MESSAGE_MAX_LENGTH
|
||||
var/see_chat_non_mob = TRUE
|
||||
|
||||
/// Custom Keybindings
|
||||
var/list/key_bindings = list()
|
||||
|
||||
|
||||
var/tgui_fancy = TRUE
|
||||
var/tgui_lock = TRUE
|
||||
var/windowflashing = TRUE
|
||||
@@ -189,9 +189,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
var/uplink_spawn_loc = UPLINK_PDA
|
||||
|
||||
var/sprint_spacebar = FALSE
|
||||
var/sprint_toggle = FALSE
|
||||
|
||||
var/hud_toggle_flash = TRUE
|
||||
var/hud_toggle_color = "#ffffff"
|
||||
|
||||
@@ -204,6 +201,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/vore_flags = 0
|
||||
var/list/belly_prefs = list()
|
||||
var/vore_taste = "nothing in particular"
|
||||
var/toggleeatingnoise = TRUE
|
||||
var/toggledigestionnoise = TRUE
|
||||
var/hound_sleeper = TRUE
|
||||
var/cit_toggles = TOGGLES_CITADEL
|
||||
|
||||
//backgrounds
|
||||
var/mutable_appearance/character_background
|
||||
@@ -214,6 +215,19 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
var/no_tetris_storage = FALSE
|
||||
|
||||
///loadout stuff
|
||||
var/gear_points = 10
|
||||
var/list/gear_categories
|
||||
var/list/chosen_gear = list()
|
||||
var/gear_tab
|
||||
|
||||
var/screenshake = 100
|
||||
var/damagescreenshake = 2
|
||||
var/arousable = TRUE
|
||||
var/widescreenpref = TRUE
|
||||
var/autostand = TRUE
|
||||
var/auto_ooc = FALSE
|
||||
|
||||
/datum/preferences/New(client/C)
|
||||
parent = C
|
||||
|
||||
@@ -233,6 +247,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
return
|
||||
//we couldn't load character data so just randomize the character appearance + name
|
||||
random_character() //let's create a random character then - rather than a fat, bald and naked man.
|
||||
key_bindings = deepCopyList(GLOB.hotkey_keybinding_list_by_key) // give them default keybinds and update their movement keys
|
||||
C?.update_movement_keys(src)
|
||||
real_name = pref_species.random_name(gender,1)
|
||||
if(!loaded_preferences_successfully)
|
||||
save_preferences()
|
||||
@@ -254,6 +270,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<a href='?_src_=prefs;preference=tab;tab=3' [current_tab == 3 ? "class='linkOn'" : ""]>Loadout</a>"
|
||||
dat += "<a href='?_src_=prefs;preference=tab;tab=1' [current_tab == 1 ? "class='linkOn'" : ""]>Game Preferences</a>"
|
||||
dat += "<a href='?_src_=prefs;preference=tab;tab=4' [current_tab == 4 ? "class='linkOn'" : ""]>Content Preferences</a>"
|
||||
dat += "<a href='?_src_=prefs;preference=tab;tab=5' [current_tab == 5 ? "class='linkOn'" : ""]>Keybindings</a>"
|
||||
|
||||
if(!path)
|
||||
dat += "<div class='notice'>Please create an account to save your preferences</div>"
|
||||
@@ -395,7 +412,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
mutant_colors = TRUE
|
||||
|
||||
if (CONFIG_GET(number/body_size_min) != CONFIG_GET(number/body_size_max))
|
||||
dat += "<b>Sprite Size:</b> <a href='?_src_=prefs;preference=body_size;task=input'>[features["body_size"]]%</a><br>"
|
||||
dat += "<b>Sprite Size:</b> <a href='?_src_=prefs;preference=body_size;task=input'>[features["body_size"]*100]%</a><br>"
|
||||
|
||||
if((EYECOLOR in pref_species.species_traits) && !(NOEYES in pref_species.species_traits))
|
||||
|
||||
@@ -843,7 +860,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<b>See Runechat for non-mobs:</b> <a href='?_src_=prefs;preference=see_chat_non_mob'>[see_chat_non_mob ? "Enabled" : "Disabled"]</a><br>"
|
||||
dat += "<br>"
|
||||
dat += "<b>Action Buttons:</b> <a href='?_src_=prefs;preference=action_buttons'>[(buttons_locked) ? "Locked In Place" : "Unlocked"]</a><br>"
|
||||
dat += "<b>Keybindings:</b> <a href='?_src_=prefs;preference=hotkeys'>[(hotkeys) ? "Hotkeys" : "Default"]</a><br>"
|
||||
dat += "<br>"
|
||||
dat += "<b>PDA Color:</b> <span style='border:1px solid #161616; background-color: [pda_color];'> </span> <a href='?_src_=prefs;preference=pda_color;task=input'>Change</a><BR>"
|
||||
dat += "<b>PDA Style:</b> <a href='?_src_=prefs;task=input;preference=pda_style'>[pda_style]</a><br>"
|
||||
@@ -939,8 +955,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "</a><br>"
|
||||
dat += "<b>Ambient Occlusion:</b> <a href='?_src_=prefs;preference=ambientocclusion'>[ambientocclusion ? "Enabled" : "Disabled"]</a><br>"
|
||||
dat += "<b>Fit Viewport:</b> <a href='?_src_=prefs;preference=auto_fit_viewport'>[auto_fit_viewport ? "Auto" : "Manual"]</a><br>"
|
||||
dat += "<b>Sprint Key:</b> <a href='?_src_=prefs;preference=sprint_key'>[sprint_spacebar ? "Space" : "Shift"]</a><br>"
|
||||
dat += "<b>Toggle Sprint:</b> <a href='?_src_=prefs;preference=sprint_toggle'>[sprint_toggle ? "Enabled" : "Disabled"]</a><br>"
|
||||
dat += "<b>HUD Button Flashes:</b> <a href='?_src_=prefs;preference=hud_toggle_flash'>[hud_toggle_flash ? "Enabled" : "Disabled"]</a><br>"
|
||||
dat += "<b>HUD Button Flash Color:</b> <span style='border: 1px solid #161616; background-color: [hud_toggle_color];'> </span> <a href='?_src_=prefs;preference=hud_toggle_color;task=input'>Change</a><br>"
|
||||
|
||||
@@ -1063,6 +1077,56 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<b>Ass Slapping:</b> <a href='?_src_=prefs;preference=ass_slap'>[(cit_toggles & NO_ASS_SLAP) ? "Disallowed" : "Allowed"]</a><br>"
|
||||
dat += "</tr></table>"
|
||||
dat += "<br>"
|
||||
if(5) // Custom keybindings
|
||||
dat += "<b>Keybindings:</b> <a href='?_src_=prefs;preference=hotkeys'>[(hotkeys) ? "Hotkeys" : "Input"]</a><br>"
|
||||
dat += "Keybindings mode controls how the game behaves with tab and map/input focus.<br>If it is on <b>Hotkeys</b>, the game will always attempt to force you to map focus, meaning keypresses are sent \
|
||||
directly to the map instead of the input. You will still be able to use the command bar, but you need to tab to do it every time you click on the game map.<br>\
|
||||
If it is on <b>Input</b>, the game will not force focus away from the input bar, and you can switch focus using TAB between these two modes: If the input bar is pink, that means that you are in non-hotkey mode, sending all keypresses of the normal \
|
||||
alphanumeric characters, punctuation, spacebar, backspace, enter, etc, typing keys into the input bar. If the input bar is white, you are in hotkey mode, meaning all keypresses go into the game's keybind handling system unless you \
|
||||
manually click on the input bar to shift focus there.<br>\
|
||||
Input mode is the closest thing to the old input system.<br>\
|
||||
<b>IMPORTANT:</b> While in input mode's non hotkey setting (tab toggled), Ctrl + KEY will send KEY to the keybind system as the key itself, not as Ctrl + KEY. This means Ctrl + T/W/A/S/D/all your familiar stuff still works, but you \
|
||||
won't be able to access any regular Ctrl binds.<br>"
|
||||
// Create an inverted list of keybindings -> key
|
||||
var/list/user_binds = list()
|
||||
for (var/key in key_bindings)
|
||||
for(var/kb_name in key_bindings[key])
|
||||
user_binds[kb_name] += list(key)
|
||||
|
||||
var/list/kb_categories = list()
|
||||
// Group keybinds by category
|
||||
for (var/name in GLOB.keybindings_by_name)
|
||||
var/datum/keybinding/kb = GLOB.keybindings_by_name[name]
|
||||
kb_categories[kb.category] += list(kb)
|
||||
|
||||
dat += "<style>label { display: inline-block; width: 200px; }</style><body>"
|
||||
|
||||
for (var/category in kb_categories)
|
||||
dat += "<h3>[category]</h3>"
|
||||
for (var/i in kb_categories[category])
|
||||
var/datum/keybinding/kb = i
|
||||
if(!length(user_binds[kb.name]))
|
||||
dat += "<label>[kb.full_name]</label> <a href ='?_src_=prefs;preference=keybindings_capture;keybinding=[kb.name];old_key=["Unbound"]'>Unbound</a>"
|
||||
var/list/default_keys = hotkeys ? kb.hotkey_keys : kb.classic_keys
|
||||
if(LAZYLEN(default_keys))
|
||||
dat += "| Default: [default_keys.Join(", ")]"
|
||||
dat += "<br>"
|
||||
else
|
||||
var/bound_key = user_binds[kb.name][1]
|
||||
dat += "<label>[kb.full_name]</label> <a href ='?_src_=prefs;preference=keybindings_capture;keybinding=[kb.name];old_key=[bound_key]'>[bound_key]</a>"
|
||||
for(var/bound_key_index in 2 to length(user_binds[kb.name]))
|
||||
bound_key = user_binds[kb.name][bound_key_index]
|
||||
dat += " | <a href ='?_src_=prefs;preference=keybindings_capture;keybinding=[kb.name];old_key=[bound_key]'>[bound_key]</a>"
|
||||
if(length(user_binds[kb.name]) < MAX_KEYS_PER_KEYBIND)
|
||||
dat += "| <a href ='?_src_=prefs;preference=keybindings_capture;keybinding=[kb.name]'>Add Secondary</a>"
|
||||
var/list/default_keys = hotkeys ? kb.classic_keys : kb.hotkey_keys
|
||||
if(LAZYLEN(default_keys))
|
||||
dat += "| Default: [default_keys.Join(", ")]"
|
||||
dat += "<br>"
|
||||
|
||||
dat += "<br><br>"
|
||||
dat += "<a href ='?_src_=prefs;preference=keybindings_reset'>\[Reset to default\]</a>"
|
||||
dat += "</body>"
|
||||
|
||||
|
||||
dat += "<hr><center>"
|
||||
@@ -1083,6 +1147,31 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
#undef APPEARANCE_CATEGORY_COLUMN
|
||||
#undef MAX_MUTANT_ROWS
|
||||
|
||||
/datum/preferences/proc/CaptureKeybinding(mob/user, datum/keybinding/kb, var/old_key)
|
||||
var/HTML = {"
|
||||
<div id='focus' style="outline: 0;" tabindex=0>Keybinding: [kb.full_name]<br>[kb.description]<br><br><b>Press any key to change<br>Press ESC to clear</b></div>
|
||||
<script>
|
||||
var deedDone = false;
|
||||
document.onkeyup = function(e) {
|
||||
if(deedDone){ return; }
|
||||
var alt = e.altKey ? 1 : 0;
|
||||
var ctrl = e.ctrlKey ? 1 : 0;
|
||||
var shift = e.shiftKey ? 1 : 0;
|
||||
var numpad = (95 < e.keyCode && e.keyCode < 112) ? 1 : 0;
|
||||
var escPressed = e.keyCode == 27 ? 1 : 0;
|
||||
var url = 'byond://?_src_=prefs;preference=keybindings_set;keybinding=[kb.name];old_key=[old_key];clear_key='+escPressed+';key='+e.key+';alt='+alt+';ctrl='+ctrl+';shift='+shift+';numpad='+numpad+';key_code='+e.keyCode;
|
||||
window.location=url;
|
||||
deedDone = true;
|
||||
}
|
||||
document.getElementById('focus').focus();
|
||||
</script>
|
||||
"}
|
||||
winshow(user, "capturekeypress", TRUE)
|
||||
var/datum/browser/popup = new(user, "capturekeypress", "<div align='center'>Keybindings</div>", 350, 300)
|
||||
popup.set_content(HTML)
|
||||
popup.open(FALSE)
|
||||
onclose(user, "capturekeypress", src)
|
||||
|
||||
/datum/preferences/proc/SetChoices(mob/user, limit = 17, list/splitJobs = list("Chief Engineer"), widthPerColumn = 295, height = 620)
|
||||
if(!SSjob)
|
||||
return
|
||||
@@ -2263,10 +2352,73 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
if("hotkeys")
|
||||
hotkeys = !hotkeys
|
||||
if(hotkeys)
|
||||
winset(user, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED] mainwindow.macro=default")
|
||||
else
|
||||
winset(user, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED] mainwindow.macro=old_default")
|
||||
user.client.set_macros()
|
||||
|
||||
if("keybindings_capture")
|
||||
var/datum/keybinding/kb = GLOB.keybindings_by_name[href_list["keybinding"]]
|
||||
var/old_key = href_list["old_key"]
|
||||
CaptureKeybinding(user, kb, old_key)
|
||||
return
|
||||
|
||||
if("keybindings_set")
|
||||
var/kb_name = href_list["keybinding"]
|
||||
if(!kb_name)
|
||||
user << browse(null, "window=capturekeypress")
|
||||
ShowChoices(user)
|
||||
return
|
||||
|
||||
var/clear_key = text2num(href_list["clear_key"])
|
||||
var/old_key = href_list["old_key"]
|
||||
if(clear_key)
|
||||
if(key_bindings[old_key])
|
||||
key_bindings[old_key] -= kb_name
|
||||
if(!length(key_bindings[old_key]))
|
||||
key_bindings -= old_key
|
||||
user << browse(null, "window=capturekeypress")
|
||||
save_preferences()
|
||||
ShowChoices(user)
|
||||
return
|
||||
|
||||
var/new_key = uppertext(href_list["key"])
|
||||
var/AltMod = text2num(href_list["alt"]) ? "Alt" : ""
|
||||
var/CtrlMod = text2num(href_list["ctrl"]) ? "Ctrl" : ""
|
||||
var/ShiftMod = text2num(href_list["shift"]) ? "Shift" : ""
|
||||
var/numpad = text2num(href_list["numpad"]) ? "Numpad" : ""
|
||||
// var/key_code = text2num(href_list["key_code"])
|
||||
|
||||
if(GLOB._kbMap[new_key])
|
||||
new_key = GLOB._kbMap[new_key]
|
||||
|
||||
var/full_key
|
||||
switch(new_key)
|
||||
if("Alt")
|
||||
full_key = "[new_key][CtrlMod][ShiftMod]"
|
||||
if("Ctrl")
|
||||
full_key = "[AltMod][new_key][ShiftMod]"
|
||||
if("Shift")
|
||||
full_key = "[AltMod][CtrlMod][new_key]"
|
||||
else
|
||||
full_key = "[AltMod][CtrlMod][ShiftMod][numpad][new_key]"
|
||||
if(key_bindings[old_key])
|
||||
key_bindings[old_key] -= kb_name
|
||||
if(!length(key_bindings[old_key]))
|
||||
key_bindings -= old_key
|
||||
key_bindings[full_key] += list(kb_name)
|
||||
key_bindings[full_key] = sortList(key_bindings[full_key])
|
||||
|
||||
user << browse(null, "window=capturekeypress")
|
||||
user.client.update_movement_keys()
|
||||
save_preferences()
|
||||
|
||||
if("keybindings_reset")
|
||||
var/choice = tgalert(user, "Would you prefer 'hotkey' or 'classic' defaults?", "Setup keybindings", "Hotkey", "Classic", "Cancel")
|
||||
if(choice == "Cancel")
|
||||
ShowChoices(user)
|
||||
return
|
||||
hotkeys = (choice == "Hotkey")
|
||||
key_bindings = (hotkeys) ? deepCopyList(GLOB.hotkey_keybinding_list_by_key) : deepCopyList(GLOB.classic_keybinding_list_by_key)
|
||||
user.client.update_movement_keys()
|
||||
|
||||
if("chat_on_map")
|
||||
chat_on_map = !chat_on_map
|
||||
if("see_chat_non_mob")
|
||||
@@ -2385,21 +2537,18 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("ambientocclusion")
|
||||
ambientocclusion = !ambientocclusion
|
||||
if(parent && parent.screen && parent.screen.len)
|
||||
var/obj/screen/plane_master/game_world/PM = locate(/obj/screen/plane_master/game_world) in parent.screen
|
||||
PM.backdrop(parent.mob)
|
||||
var/obj/screen/plane_master/game_world/G = parent.mob.hud_used.plane_masters["[GAME_PLANE]"]
|
||||
var/obj/screen/plane_master/above_wall/A = parent.mob.hud_used.plane_masters["[ABOVE_WALL_PLANE]"]
|
||||
var/obj/screen/plane_master/wall/W = parent.mob.hud_used.plane_masters["[WALL_PLANE]"]
|
||||
G.backdrop(parent.mob)
|
||||
A.backdrop(parent.mob)
|
||||
W.backdrop(parent.mob)
|
||||
|
||||
if("auto_fit_viewport")
|
||||
auto_fit_viewport = !auto_fit_viewport
|
||||
if(auto_fit_viewport && parent)
|
||||
parent.fit_viewport()
|
||||
|
||||
if("sprint_key")
|
||||
sprint_spacebar = !sprint_spacebar
|
||||
|
||||
if("sprint_toggle")
|
||||
sprint_toggle = !sprint_toggle
|
||||
|
||||
|
||||
if("hud_toggle_flash")
|
||||
hud_toggle_flash = !hud_toggle_flash
|
||||
|
||||
@@ -2578,3 +2727,37 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(!cached_holoform_icons[filter_type])
|
||||
cached_holoform_icons[filter_type] = process_holoform_icon_filter(custom_holoform_icon, filter_type)
|
||||
return cached_holoform_icons[filter_type]
|
||||
|
||||
//Used in savefile update 32, can be removed once that is no longer relevant.
|
||||
/datum/preferences/proc/force_reset_keybindings()
|
||||
var/choice = tgalert(parent.mob, "Your basic keybindings need to be reset, emotes will remain as before. Would you prefer 'hotkey' or 'classic' mode?", "Reset keybindings", "Hotkey", "Classic")
|
||||
hotkeys = (choice != "Classic")
|
||||
var/list/oldkeys = key_bindings
|
||||
key_bindings = (hotkeys) ? deepCopyList(GLOB.hotkey_keybinding_list_by_key) : deepCopyList(GLOB.classic_keybinding_list_by_key)
|
||||
|
||||
for(var/key in oldkeys)
|
||||
if(!key_bindings[key])
|
||||
key_bindings[key] = oldkeys[key]
|
||||
parent.update_movement_keys()
|
||||
|
||||
/datum/preferences/proc/is_loadout_slot_available(slot)
|
||||
var/list/L
|
||||
LAZYINITLIST(L)
|
||||
for(var/i in chosen_gear)
|
||||
var/datum/gear/G = i
|
||||
var/occupied_slots = L[slot_to_string(initial(G.category))] ? L[slot_to_string(initial(G.category))] + 1 : 1
|
||||
LAZYSET(L, slot_to_string(initial(G.category)), occupied_slots)
|
||||
switch(slot)
|
||||
if(SLOT_IN_BACKPACK)
|
||||
if(L[slot_to_string(SLOT_IN_BACKPACK)] < BACKPACK_SLOT_AMT)
|
||||
return TRUE
|
||||
if(SLOT_HANDS)
|
||||
if(L[slot_to_string(SLOT_HANDS)] < HANDS_SLOT_AMT)
|
||||
return TRUE
|
||||
else
|
||||
if(L[slot_to_string(slot)] < DEFAULT_SLOT_AMT)
|
||||
return TRUE
|
||||
|
||||
#undef DEFAULT_SLOT_AMT
|
||||
#undef HANDS_SLOT_AMT
|
||||
#undef BACKPACK_SLOT_AMT
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// You do not need to raise this if you are adding new values that have sane defaults.
|
||||
// Only raise this value when changing the meaning/format/name/layout of an existing value
|
||||
// where you would want the updater procs below to run
|
||||
#define SAVEFILE_VERSION_MAX 31
|
||||
#define SAVEFILE_VERSION_MAX 32
|
||||
|
||||
/*
|
||||
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
|
||||
@@ -42,7 +42,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
//if your savefile is 3 months out of date, then 'tough shit'.
|
||||
|
||||
/datum/preferences/proc/update_preferences(current_version, savefile/S)
|
||||
return
|
||||
if(current_version < 32) //If you remove this, remove force_reset_keybindings() too.
|
||||
addtimer(CALLBACK(src, .proc/force_reset_keybindings), 30) //No mob available when this is run, timer allows user choice.
|
||||
|
||||
/datum/preferences/proc/update_character(current_version, savefile/S)
|
||||
if(current_version < 19)
|
||||
@@ -250,8 +251,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["parallax"] >> parallax
|
||||
S["ambientocclusion"] >> ambientocclusion
|
||||
S["auto_fit_viewport"] >> auto_fit_viewport
|
||||
S["sprint_spacebar"] >> sprint_spacebar
|
||||
S["sprint_toggle"] >> sprint_toggle
|
||||
S["hud_toggle_flash"] >> hud_toggle_flash
|
||||
S["hud_toggle_color"] >> hud_toggle_color
|
||||
S["menuoptions"] >> menuoptions
|
||||
@@ -261,6 +260,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["pda_color"] >> pda_color
|
||||
S["pda_skin"] >> pda_skin
|
||||
|
||||
// Custom hotkeys
|
||||
S["key_bindings"] >> key_bindings
|
||||
|
||||
//citadel code
|
||||
S["arousable"] >> arousable
|
||||
S["screenshake"] >> screenshake
|
||||
@@ -295,8 +297,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
parallax = sanitize_integer(parallax, PARALLAX_INSANE, PARALLAX_DISABLE, null)
|
||||
ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion))
|
||||
auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport))
|
||||
sprint_spacebar = sanitize_integer(sprint_spacebar, 0, 1, initial(sprint_spacebar))
|
||||
sprint_toggle = sanitize_integer(sprint_toggle, 0, 1, initial(sprint_toggle))
|
||||
hud_toggle_flash = sanitize_integer(hud_toggle_flash, 0, 1, initial(hud_toggle_flash))
|
||||
hud_toggle_color = sanitize_hexcolor(hud_toggle_color, 6, 1, initial(hud_toggle_color))
|
||||
ghost_form = sanitize_inlist(ghost_form, GLOB.ghost_forms, initial(ghost_form))
|
||||
@@ -315,6 +315,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
cit_toggles = sanitize_integer(cit_toggles, 0, 16777215, initial(cit_toggles))
|
||||
auto_ooc = sanitize_integer(auto_ooc, 0, 1, initial(auto_ooc))
|
||||
no_tetris_storage = sanitize_integer(no_tetris_storage, 0, 1, initial(no_tetris_storage))
|
||||
key_bindings = sanitize_islist(key_bindings, list())
|
||||
|
||||
return 1
|
||||
|
||||
@@ -362,8 +363,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["parallax"], parallax)
|
||||
WRITE_FILE(S["ambientocclusion"], ambientocclusion)
|
||||
WRITE_FILE(S["auto_fit_viewport"], auto_fit_viewport)
|
||||
WRITE_FILE(S["sprint_spacebar"], sprint_spacebar)
|
||||
WRITE_FILE(S["sprint_toggle"], sprint_toggle)
|
||||
WRITE_FILE(S["hud_toggle_flash"], hud_toggle_flash)
|
||||
WRITE_FILE(S["hud_toggle_color"], hud_toggle_color)
|
||||
WRITE_FILE(S["menuoptions"], menuoptions)
|
||||
@@ -372,6 +371,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["pda_style"], pda_style)
|
||||
WRITE_FILE(S["pda_color"], pda_color)
|
||||
WRITE_FILE(S["pda_skin"], pda_skin)
|
||||
WRITE_FILE(S["key_bindings"], key_bindings)
|
||||
|
||||
//citadel code
|
||||
WRITE_FILE(S["screenshake"], screenshake)
|
||||
@@ -465,6 +465,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["feature_insect_wings"] >> features["insect_wings"]
|
||||
S["feature_insect_fluff"] >> features["insect_fluff"]
|
||||
S["feature_insect_markings"] >> features["insect_markings"]
|
||||
S["feature_horns_color"] >> features["horns_color"]
|
||||
S["feature_wings_color"] >> features["wings_color"]
|
||||
|
||||
|
||||
//Custom names
|
||||
for(var/custom_name_id in GLOB.preferences_custom_names)
|
||||
@@ -541,6 +544,21 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["vore_taste"] >> vore_taste
|
||||
S["belly_prefs"] >> belly_prefs
|
||||
|
||||
//gear loadout
|
||||
var/text_to_load
|
||||
S["loadout"] >> text_to_load
|
||||
var/list/saved_loadout_paths = splittext(text_to_load, "|")
|
||||
chosen_gear = list()
|
||||
gear_points = CONFIG_GET(number/initial_gear_points)
|
||||
for(var/i in saved_loadout_paths)
|
||||
var/datum/gear/path = text2path(i)
|
||||
if(path)
|
||||
var/init_cost = initial(path.cost)
|
||||
if(init_cost > gear_points)
|
||||
continue
|
||||
chosen_gear += path
|
||||
gear_points -= init_cost
|
||||
|
||||
//try to fix any outdated data if necessary
|
||||
if(needs_update >= 0)
|
||||
update_character(needs_update, S) //needs_update == savefile_version if we need an update (positive integer)
|
||||
@@ -701,8 +719,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["shirt_color"] , shirt_color)
|
||||
WRITE_FILE(S["socks"] , socks)
|
||||
WRITE_FILE(S["socks_color"] , socks_color)
|
||||
WRITE_FILE(S["horns_color"] , features["horns_color"])
|
||||
WRITE_FILE(S["wings_color"] , features["wings_color"])
|
||||
WRITE_FILE(S["backbag"] , backbag)
|
||||
WRITE_FILE(S["jumpsuit_style"] , jumpsuit_style)
|
||||
WRITE_FILE(S["uplink_loc"] , uplink_spawn_loc)
|
||||
@@ -718,6 +734,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["feature_lizard_body_markings"] , features["body_markings"])
|
||||
WRITE_FILE(S["feature_lizard_legs"] , features["legs"])
|
||||
WRITE_FILE(S["feature_deco_wings"] , features["deco_wings"])
|
||||
WRITE_FILE(S["feature_horns_color"] , features["horns_color"])
|
||||
WRITE_FILE(S["feature_wings_color"] , features["wings_color"])
|
||||
WRITE_FILE(S["feature_insect_wings"] , features["insect_wings"])
|
||||
WRITE_FILE(S["feature_insect_fluff"] , features["insect_fluff"])
|
||||
WRITE_FILE(S["feature_insect_markings"] , features["insect_markings"])
|
||||
@@ -771,6 +789,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["vore_taste"] , vore_taste)
|
||||
WRITE_FILE(S["belly_prefs"] , belly_prefs)
|
||||
|
||||
//gear loadout
|
||||
if(chosen_gear.len)
|
||||
var/text_to_save = chosen_gear.Join("|")
|
||||
S["loadout"] << text_to_save
|
||||
else
|
||||
S["loadout"] << "" //empty string to reset the value
|
||||
|
||||
cit_character_pref_save(S)
|
||||
|
||||
return 1
|
||||
|
||||
@@ -639,7 +639,7 @@
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/ancient/mason
|
||||
name = "M.A.S.O.N RIG"
|
||||
desc = "The Multi-Augmented Severe Operations Networked Resource Integration Gear is an man-portable tank designed for extreme environmental situations. It is excessively bulky, but rated for all but the most atomic of hazards. The specialized armor is surprisingly weak to conventional weaponry. The exo slot can attach most storge bags on to the suit."
|
||||
desc = "The Multi-Augmented Severe Operations Networked Resource Integration Gear is an man-portable tank designed for extreme environmental situations. It is excessively bulky, but rated for all but the most atomic of hazards. The specialized armor is surprisingly weak to conventional weaponry. The exo slot can attach most storage bags on to the suit."
|
||||
icon_state = "hardsuit-ancient"
|
||||
item_state = "anc_hardsuit"
|
||||
armor = list("melee" = 20, "bullet" = 15, "laser" = 15, "energy" = 45, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100)
|
||||
@@ -649,7 +649,6 @@
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | IMMUTABLE_SLOW
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
flags_1 = TESLA_IGNORE_1
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason
|
||||
name = "M.A.S.O.N RIG helmet"
|
||||
@@ -665,7 +664,6 @@
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
flags_1 = TESLA_IGNORE_1
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/Initialize()
|
||||
. = ..()
|
||||
@@ -676,12 +674,14 @@
|
||||
if (slot == SLOT_HEAD)
|
||||
var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC]
|
||||
DHUD.add_hud_to(user)
|
||||
ADD_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "mason_hardsuit")
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/dropped(mob/living/carbon/human/user)
|
||||
..()
|
||||
if (user.head == src)
|
||||
if (HAS_TRAIT_FROM(user, TRAIT_TESLA_SHOCKIMMUNE, "mason_hardsuit"))
|
||||
var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC]
|
||||
DHUD.remove_hud_from(user)
|
||||
REMOVE_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "mason_hardsuit")
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/ancient/proc/on_mob_move()
|
||||
var/mob/living/carbon/human/H = loc
|
||||
@@ -915,8 +915,8 @@
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
|
||||
. = ..()
|
||||
if(!isinhands)
|
||||
var/mutable_appearance/energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", ABOVE_LIGHTING_LAYER)
|
||||
energy_overlay.plane = ABOVE_LIGHTING_LAYER
|
||||
var/mutable_appearance/energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", EMISSIVE_LAYER)
|
||||
energy_overlay.plane = EMISSIVE_PLANE
|
||||
energy_overlay.color = energy_color
|
||||
. += energy_overlay
|
||||
|
||||
@@ -946,8 +946,8 @@
|
||||
/obj/item/clothing/suit/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file, used_state, style_flags = NONE)
|
||||
. = ..()
|
||||
if(!isinhands)
|
||||
var/mutable_appearance/energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", ABOVE_LIGHTING_LAYER)
|
||||
energy_overlay.plane = ABOVE_LIGHTING_LAYER
|
||||
var/mutable_appearance/energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", EMISSIVE_LAYER)
|
||||
energy_overlay.plane = EMISSIVE_PLANE
|
||||
energy_overlay.color = energy_color
|
||||
. += energy_overlay
|
||||
|
||||
|
||||
@@ -395,10 +395,18 @@ Contains:
|
||||
actions_types = list()
|
||||
resistance_flags = FIRE_PROOF
|
||||
mutantrace_variation = NONE
|
||||
var/charges = INFINITY
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize()
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/anti_magic, FALSE, FALSE, TRUE, ITEM_SLOT_HEAD)
|
||||
AddComponent(/datum/component/anti_magic, FALSE, FALSE, TRUE, ITEM_SLOT_HEAD, charges, TRUE, null, CALLBACK(src, .proc/anti_magic_gone))
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/proc/anti_magic_gone()
|
||||
var/mob/M = loc
|
||||
if(!istype(M))
|
||||
return
|
||||
do_sparks(2, TRUE, M)
|
||||
M.show_message("<span class='warning'>\The [src] sparks and fizzles as its psychic wards wane away at last...</span>", MSG_VISUAL)
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/ert/paranormal
|
||||
name = "paranormal response team suit"
|
||||
@@ -408,10 +416,18 @@ Contains:
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
resistance_flags = FIRE_PROOF
|
||||
var/charges = INFINITY
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, ITEM_SLOT_OCLOTHING)
|
||||
AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, ITEM_SLOT_OCLOTHING, charges, TRUE, null, CALLBACK(src, .proc/anti_magic_gone))
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/proc/anti_magic_gone()
|
||||
var/mob/M = loc
|
||||
if(!istype(M))
|
||||
return
|
||||
do_sparks(2, TRUE, M)
|
||||
M.show_message("<span class='warning'>\The [src] sparks and fizzles as its anti magic wards wane away at last...</span>", MSG_VISUAL)
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor
|
||||
name = "inquisitor's hardsuit"
|
||||
@@ -424,6 +440,19 @@ Contains:
|
||||
icon_state = "hardsuit0-inq"
|
||||
item_state = "hardsuit0-inq"
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor/old
|
||||
desc = "Powerful wards are built into this hardsuit, protecting the user from all manner of paranormal threats. Alas, this one looks pretty worn out and rusted."
|
||||
armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60)
|
||||
slowdown = 0.8
|
||||
obj_flags = IMMUTABLE_SLOW //rest in peace rusty joints.
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/old
|
||||
charges = 12
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/old
|
||||
desc = "A helmet worn by those who deal with paranormal threats for a living. Alas, this one looks pretty worn out and rusted."
|
||||
armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60)
|
||||
charges = 12
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker
|
||||
name = "champion's hardsuit"
|
||||
desc = "Voices echo from the hardsuit, driving the user insane."
|
||||
@@ -437,6 +466,19 @@ Contains:
|
||||
icon_state = "hardsuit0-beserker"
|
||||
item_state = "hardsuit0-beserker"
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker/old
|
||||
desc = "Voices echo from the hardsuit, driving the user insane. This one is pretty battle-worn, but still fearsome."
|
||||
armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60)
|
||||
slowdown = 0.8
|
||||
obj_flags = IMMUTABLE_SLOW //rest in peace rusty joints.
|
||||
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/old
|
||||
charges = 6
|
||||
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/beserker/old
|
||||
desc = "Peering into the eyes of the helmet is enough to seal damnation. This one is pretty battle-worn, but still fearsome."
|
||||
armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60)
|
||||
charges = 6
|
||||
|
||||
/obj/item/clothing/head/helmet/space/fragile
|
||||
name = "emergency space helmet"
|
||||
desc = "A bulky, air-tight helmet meant to protect the user during emergency situations. It doesn't look very durable."
|
||||
@@ -477,4 +519,4 @@ Contains:
|
||||
name = "paramedic EVA helmet"
|
||||
desc = "A deep blue space helmet with a large red cross on the faceplate to designate the wearer as trained emergency medical personnel."
|
||||
icon_state = "paramedic-eva-helmet"
|
||||
item_state = "paramedic-eva-helmet"
|
||||
item_state = "paramedic-eva-helmet"
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
icon_state = "dragon"
|
||||
desc = "A suit of armour fashioned from the remains of an ash drake."
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe, /obj/item/twohanded/spear)
|
||||
armor = list("melee" = 70, "bullet" = 30, "laser" = 50, "energy" = 40, "bomb" = 70, "bio" = 60, "rad" = 50, "fire" = 100, "acid" = 100)
|
||||
armor = list("melee" = 70, "bullet" = 20, "laser" = 35, "energy" = 25, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
hoodtype = /obj/item/clothing/head/hooded/cloakhood/drake
|
||||
heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
|
||||
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
|
||||
@@ -87,7 +87,7 @@
|
||||
name = "drake helm"
|
||||
icon_state = "dragon"
|
||||
desc = "The skull of a dragon."
|
||||
armor = list("melee" = 70, "bullet" = 30, "laser" = 50, "energy" = 40, "bomb" = 70, "bio" = 60, "rad" = 50, "fire" = 100, "acid" = 100)
|
||||
armor = list("melee" = 70, "bullet" = 20, "laser" = 35, "energy" = 25, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
|
||||
heat_protection = HEAD
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF | GOLIATH_RESISTANCE
|
||||
|
||||
@@ -164,21 +164,21 @@
|
||||
desc = "An experimental suit of armor with sensitive detectors hooked up to a huge capacitor grid, with emitters strutting out of it. Zap."
|
||||
siemens_coefficient = -1
|
||||
reactivearmor_cooldown_duration = 20
|
||||
var/tesla_power = 25000
|
||||
var/tesla_range = 20
|
||||
var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE
|
||||
var/zap_power = 25000
|
||||
var/zap_range = 20
|
||||
var/zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE
|
||||
var/legacy = FALSE
|
||||
var/legacy_dmg = 30
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/tesla/dropped(mob/user)
|
||||
..()
|
||||
if(istype(user))
|
||||
user.flags_1 &= ~TESLA_IGNORE_1
|
||||
REMOVE_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "reactive_tesla_armor")
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/tesla/equipped(mob/user, slot)
|
||||
..()
|
||||
if(slot_flags & slotdefine2slotbit(slot)) //Was equipped to a valid slot for this item?
|
||||
user.flags_1 |= TESLA_IGNORE_1
|
||||
ADD_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "reactive_tesla_armor")
|
||||
|
||||
/obj/item/clothing/suit/armor/reactive/tesla/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
if(prob(hit_reaction_chance))
|
||||
@@ -190,7 +190,7 @@
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[src] blocks [attack_text], sending out arcs of lightning!</span>")
|
||||
if(!legacy)
|
||||
tesla_zap(owner, tesla_range, tesla_power, tesla_flags)
|
||||
tesla_zap(owner, zap_range, zap_power, zap_flags)
|
||||
else
|
||||
for(var/mob/living/M in view(7, owner))
|
||||
if(M == owner)
|
||||
|
||||
@@ -329,14 +329,14 @@
|
||||
name = "bone talisman"
|
||||
desc = "A hunter's talisman, some say the old gods smile on those who wear it."
|
||||
icon_state = "talisman"
|
||||
armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 20, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25)
|
||||
armor = list("melee" = 5, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25)
|
||||
|
||||
/obj/item/clothing/accessory/skullcodpiece
|
||||
name = "skull codpiece"
|
||||
desc = "A skull shaped ornament, intended to protect the important things in life."
|
||||
icon_state = "skull"
|
||||
above_suit = TRUE
|
||||
armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 20, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25)
|
||||
armor = list("melee" = 5, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25)
|
||||
|
||||
/obj/item/clothing/accessory/skullcodpiece/fake
|
||||
name = "false codpiece"
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
if(!SSmapping.empty_space)
|
||||
SSmapping.empty_space = SSmapping.add_new_zlevel("Empty Area For Pirates", list(ZTRAIT_LINKAGE = SELFLOOPING))
|
||||
|
||||
|
||||
var/datum/map_template/shuttle/pirate/default/ship = new
|
||||
var/x = rand(TRANSITIONEDGE,world.maxx - TRANSITIONEDGE - ship.width)
|
||||
var/y = rand(TRANSITIONEDGE,world.maxy - TRANSITIONEDGE - ship.height)
|
||||
@@ -159,11 +159,12 @@
|
||||
active = FALSE
|
||||
STOP_PROCESSING(SSobj,src)
|
||||
|
||||
/obj/machinery/shuttle_scrambler/update_icon_state()
|
||||
/obj/machinery/shuttle_scrambler/update_overlays()
|
||||
. = ..()
|
||||
if(active)
|
||||
icon_state = "dominator-blue"
|
||||
else
|
||||
icon_state = "dominator"
|
||||
var/mutable_appearance/M = mutable_appearance(icon, "dominator-overlay")
|
||||
M.color = "#00FFFF"
|
||||
. += M
|
||||
|
||||
/obj/machinery/shuttle_scrambler/Destroy()
|
||||
toggle_off()
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
if(turfs.len) //Pick a turf to spawn at if we can
|
||||
var/turf/T = pick(turfs)
|
||||
new /datum/spacevine_controller(T, pick(subtypesof(/datum/spacevine_mutation)), rand(30,100), rand(5,10), src) //spawn a controller at turf with randomized stats and a single random mutation
|
||||
new /datum/spacevine_controller(T, list(pick(subtypesof(/datum/spacevine_mutation))), rand(30,100), rand(5,10), src) //spawn a controller at turf with randomized stats and a single random mutation
|
||||
|
||||
|
||||
|
||||
/datum/spacevine_mutation
|
||||
@@ -416,7 +417,6 @@
|
||||
if(muts && muts.len)
|
||||
for(var/datum/spacevine_mutation/M in muts)
|
||||
M.add_mutation_to_vinepiece(SV)
|
||||
return
|
||||
if(parent)
|
||||
SV.mutations |= parent.mutations
|
||||
var/parentcolor = parent.atom_colours[FIXED_COLOUR_PRIORITY]
|
||||
@@ -541,4 +541,4 @@
|
||||
var/mob/living/M = A
|
||||
if(("vines" in M.faction) || ("plants" in M.faction))
|
||||
return TRUE
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
@@ -679,9 +679,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
var/list/mob/living/carbon/people = list()
|
||||
var/mob/living/carbon/person = null
|
||||
var/datum/language/understood_language = target.get_random_understood_language()
|
||||
for(var/mob/living/carbon/H in view(target))
|
||||
if(H == target)
|
||||
continue
|
||||
for(var/mob/living/carbon/H in view(target) - target)
|
||||
if(!person)
|
||||
person = H
|
||||
else
|
||||
@@ -1064,6 +1062,8 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/hallucination/danger
|
||||
layer = TURF_LAYER
|
||||
plane = FLOOR_PLANE
|
||||
var/image/image
|
||||
|
||||
/obj/effect/hallucination/danger/proc/show_icon()
|
||||
@@ -1087,7 +1087,8 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
name = "lava"
|
||||
|
||||
/obj/effect/hallucination/danger/lava/show_icon()
|
||||
image = image('icons/turf/floors/lava.dmi',src,"smooth",TURF_LAYER)
|
||||
image = image('icons/turf/floors/lava.dmi',src,"smooth",layer)
|
||||
image.plane = plane
|
||||
if(target.client)
|
||||
target.client.images += image
|
||||
|
||||
@@ -1257,7 +1258,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
..()
|
||||
if(!target.halbody)
|
||||
var/list/possible_points = list()
|
||||
for(var/turf/open/floor/F in view(target,world.view))
|
||||
for(var/turf/open/floor/F in target.fov_view(world.view))
|
||||
possible_points += F
|
||||
if(possible_points.len)
|
||||
var/turf/open/floor/husk_point = pick(possible_points)
|
||||
@@ -1288,7 +1289,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
set waitfor = FALSE
|
||||
..()
|
||||
var/list/turf/startlocs = list()
|
||||
for(var/turf/open/T in view(world.view+1,target)-view(world.view,target))
|
||||
for(var/turf/open/T in target.fov_view(world.view+1)-view(world.view,target))
|
||||
startlocs += T
|
||||
if(!startlocs.len)
|
||||
qdel(src)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"Wines",
|
||||
"Beers",
|
||||
"Brands",
|
||||
"Storge",
|
||||
"Storage",
|
||||
)
|
||||
production_animation = "protolathe_n"
|
||||
allowed_buildtypes = AUTOBOTTLER
|
||||
@@ -15,4 +15,4 @@
|
||||
//Brands - This is just export verson of the booze bottles
|
||||
//Storge - Just the bottles not booze inside
|
||||
//Wines - Holds wines later made by Sci nodes
|
||||
//Beers - Holds beers later made by Sci nodes
|
||||
//Beers - Holds beers later made by Sci nodes
|
||||
|
||||
@@ -451,7 +451,7 @@
|
||||
/obj/item/reagent_containers/food/snacks/donkpocket/initialize_cooked_food(obj/item/reagent_containers/food/snacks/donkpocket/S, cooking_efficiency = 1)
|
||||
. = ..()
|
||||
if(istype(S))
|
||||
desc = initial(desc) //reset the desc since will now cool down.
|
||||
S.desc = initial(S.desc) //reset the desc since will now cool down.
|
||||
for(var/R in S.bonus_reagents)
|
||||
LAZYSET(S.cached_reagents_amount, R, S.reagents.get_reagent_amount(R))
|
||||
S.previous_typepath = type
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<span class="ms" id="pingMs">--ms</span>
|
||||
</div>
|
||||
<div id="darkmodething">
|
||||
<a href="#" class="subCell toggle" id="changeColorPreset" title="Change color preset"><i class="fas fa-eye-open"></i></a>
|
||||
<a href="#" class="subCell toggle" id="changeColorPreset" title="Change color preset"><i class="fas fa-eye"></i></a>
|
||||
</div>
|
||||
<div id="audio">
|
||||
<a href="#" class="subCell toggle" id="toggleAudio" title="Audio"><i class="fas fa-volume-up"></i></a>
|
||||
|
||||
@@ -38,8 +38,10 @@
|
||||
health = 25
|
||||
density = FALSE
|
||||
speech_span = "spooky"
|
||||
friendly = "pets"
|
||||
response_help = "chats with"
|
||||
friendly_verb_continuous = "pets"
|
||||
friendly_verb_simple = "pet"
|
||||
response_help_continuous = "chats with"
|
||||
response_help_simple = "chat with"
|
||||
light_range = 3
|
||||
light_color = "#ff9842"
|
||||
var/last_poof
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
speak_chance = 1
|
||||
turns_per_move = 2
|
||||
butcher_results = list()
|
||||
response_help = "pets"
|
||||
response_disarm = "pushes aside"
|
||||
response_harm = "kicks"
|
||||
response_help_continuous = "pets"
|
||||
response_help_simple = "pet"
|
||||
response_disarm_continuous = "pushes aside"
|
||||
response_disarm_simple = "push aside"
|
||||
response_harm_continuous = "kicks"
|
||||
response_harm_simple = "kick"
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
// Finally, peas. Base plant.
|
||||
/obj/item/seeds/peas
|
||||
name = "pack of pea pods"
|
||||
desc = "These seeds grows into vitamin rich peas!"
|
||||
icon_state = "seed-peas"
|
||||
species = "peas"
|
||||
plantname = "Pea Vines"
|
||||
product = /obj/item/reagent_containers/food/snacks/grown/peas
|
||||
maturation = 3
|
||||
potency = 25
|
||||
growthstages = 3
|
||||
growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi'
|
||||
icon_grow = "peas-grow"
|
||||
icon_dead = "peas-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/peas/laugh) // TODO: Add /obj/item/seeds/peas/shoot at a later date, for the peashooter mutation line
|
||||
reagents_add = list (/datum/reagent/consumable/nutriment/vitamin = 0.1, /datum/reagent/consumable/nutriment = 0.05, /datum/reagent/water = 0.05)
|
||||
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/peas
|
||||
seed = /obj/item/seeds/peas
|
||||
name = "peapod"
|
||||
desc = "Finally... peas."
|
||||
icon_state = "peas"
|
||||
filling_color = "#739122"
|
||||
bitesize_mod = 1
|
||||
foodtype = VEGETABLES
|
||||
tastes = list ("peas" = 1, "chalky saltiness" = 1)
|
||||
wine_power = 50
|
||||
wine_flavor = "what is, distressingly, fermented peas."
|
||||
// distill_regeant = /datum/reagent/saltpetre //if allowed, remove wine_power, ya dingus.
|
||||
|
||||
|
||||
// Laughin' Peas
|
||||
/obj/item/seeds/peas/laugh
|
||||
name = "pack of laughin' peas"
|
||||
desc = "These seeds give off a very soft purple glow.. they should grow into Laughin' Peas."
|
||||
icon_state = "seed-laughpeas"
|
||||
species = "laughpeas"
|
||||
plantname = "Laughin' Peas"
|
||||
product = /obj/item/reagent_containers/food/snacks/grown/laugh
|
||||
maturation = 7
|
||||
potency = 10
|
||||
yield = 7
|
||||
production = 5
|
||||
growthstages = 3
|
||||
growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi'
|
||||
icon_grow = "laughpeas-grow"
|
||||
icon_dead = "laughpeas-dead"
|
||||
genes = list (/datum/plant_gene/trait/repeated_harvest, /datum/plant_gene/trait/glow/purple)
|
||||
mutatelist = list (/obj/item/seeds/peas/laugh/peace)
|
||||
reagents_add = list (/datum/reagent/consumable/laughter = 0.05, /datum/reagent/consumable/sugar = 0.05, /datum/reagent/consumable/nutriment = 0.07)
|
||||
rarity = 25 //It actually might make Central Command Officials loosen up a smidge, eh?
|
||||
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/laugh
|
||||
seed = /obj/item/seeds/peas/laugh
|
||||
name = "pod of laughin' peas"
|
||||
desc = "Ridens Cicer, guaranteed to improve your mood dramatically upon consumption!"
|
||||
icon_state = "laughpeas"
|
||||
filling_color = "#ee7bee"
|
||||
bitesize_mod = 2
|
||||
foodtype = VEGETABLES
|
||||
tastes = list ("a prancing rabbit" = 1) //Vib Ribbon sends her regards.. wherever she is.
|
||||
wine_power = 90
|
||||
wine_flavor = "a vector-graphic rabbit dancing on your tongue"
|
||||
|
||||
|
||||
// World Peas - Peace at last, peace at last...
|
||||
/obj/item/seeds/peas/laugh/peace
|
||||
name = "pack of world peas"
|
||||
desc = "These rather large seeds give off a soothing blue glow..."
|
||||
icon_state = "seed-worldpeas"
|
||||
species = "worldpeas"
|
||||
plantname = "World Peas"
|
||||
product = /obj/item/reagent_containers/food/snacks/grown/peace
|
||||
maturation = 20
|
||||
potency = 75
|
||||
yield = 1
|
||||
production = 10
|
||||
growthstages = 3
|
||||
growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi'
|
||||
icon_grow = "worldpeas-grow"
|
||||
icon_dead = "worldpeas-dead"
|
||||
genes = list (/datum/plant_gene/trait/glow/blue)
|
||||
reagents_add = list (/datum/reagent/pax = 0.1, /datum/reagent/drug/happiness = 0.1, /datum/reagent/consumable/nutriment = 0.15)
|
||||
rarity = 50 // This absolutely will make even the most hardened Syndicate Operators relax, and lay down their arms.
|
||||
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/peace
|
||||
seed = /obj/item/seeds/peas/laugh/peace
|
||||
name = "cluster of world peas"
|
||||
desc = "A plant discovered through extensive genetic engineering, and iterative graft work. It's rumored to bring peace to any who consume it. In the wider AgSci community, it's attained the nickname of 'Pax Mundi'." //at last... world peas. I'm not sorry.
|
||||
icon_state = "worldpeas"
|
||||
filling_color = "#0099CC"
|
||||
bitesize_mod = 4
|
||||
foodtype = VEGETABLES
|
||||
tastes = list ("numbing tranquility" = 2, "warmth" = 1)
|
||||
wine_power = 100
|
||||
wine_flavor = "mind-numbing peace and warmth"
|
||||
|
||||
|
||||
@@ -873,3 +873,8 @@
|
||||
pixel_x = -31
|
||||
if(WEST)
|
||||
pixel_x = 31
|
||||
plane = ABOVE_WALL_PLANE
|
||||
|
||||
/obj/item/electronic_assembly/wallmount/Moved(atom/OldLoc, Dir, Forced = FALSE) //reset the plane if moved off the wall.
|
||||
. = ..()
|
||||
plane = GAME_PLANE
|
||||
|
||||
@@ -426,7 +426,7 @@
|
||||
activators = list("compute abs coordinates" = IC_PINTYPE_PULSE_IN, "on convert" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/abs_to_rel_coords/do_work()
|
||||
/obj/item/integrated_circuit/converter/rel_to_abs_coords/do_work()
|
||||
var/x1 = get_pin_data(IC_INPUT, 1)
|
||||
var/y1 = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
activators = list("compute abs coordinates" = IC_PINTYPE_PULSE_IN, "on convert" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/abs_to_rel_coords/do_work()
|
||||
/obj/item/integrated_circuit/converter/adv_rel_to_abs_coords/do_work()
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
if(!T)
|
||||
|
||||
@@ -296,6 +296,7 @@
|
||||
var/x_abs = clamp(T.x + target_x_rel, 0, world.maxx)
|
||||
var/y_abs = clamp(T.y + target_y_rel, 0, world.maxy)
|
||||
var/range = round(clamp(sqrt(target_x_rel*target_x_rel+target_y_rel*target_y_rel),0,8),1)
|
||||
playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 50, 1)
|
||||
assembly.visible_message("<span class='danger'>\The [assembly] has thrown [A]!</span>")
|
||||
log_attack("[assembly] [REF(assembly)] has thrown [A] with lethal force.")
|
||||
A.forceMove(drop_location())
|
||||
|
||||
@@ -69,10 +69,8 @@
|
||||
// How much threat this job is worth in dynamic. Is subtracted if the player's not an antag, added if they are.
|
||||
var/threat = 0
|
||||
|
||||
/// Starting skill levels.
|
||||
var/list/starting_skills
|
||||
/// Skill affinities to set
|
||||
var/list/skill_affinities
|
||||
/// Starting skill modifiers.
|
||||
var/list/starting_modifiers
|
||||
|
||||
//Only override this proc
|
||||
//H is usually a human unless an /equip override transformed it
|
||||
@@ -180,15 +178,10 @@
|
||||
to_chat(M, "<b>Prefix your message with :h to speak on your department's radio. To see other prefixes, look closely at your headset.</b>")
|
||||
|
||||
/datum/job/proc/standard_assign_skills(datum/mind/M)
|
||||
if(!starting_skills)
|
||||
if(!starting_modifiers)
|
||||
return
|
||||
for(var/skill in starting_skills)
|
||||
M.skill_holder.boost_skill_value_to(skill, starting_skills[skill], TRUE) //silent
|
||||
// do wipe affinities though
|
||||
M.skill_holder.skill_affinities = list()
|
||||
for(var/skill in skill_affinities)
|
||||
M.skill_holder.skill_affinities[skill] = skill_affinities[skill]
|
||||
UNSETEMPTY(M.skill_holder.skill_affinities) //if we didn't set any.
|
||||
for(var/mod in starting_modifiers)
|
||||
ADD_SINGLETON_SKILL_MODIFIER(M, mod, null)
|
||||
|
||||
/datum/outfit/job
|
||||
name = "Standard Gear"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
var/do_special_check = TRUE
|
||||
threat = 5
|
||||
|
||||
starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_BASIC))
|
||||
starting_modifiers = list(/datum/skill_modifier/job/level/wiring/basic)
|
||||
|
||||
/datum/job/ai/equip(mob/living/carbon/human/H, visualsOnly, announce, latejoin, datum/outfit/outfit_override, client/preference_source = null)
|
||||
if(visualsOnly)
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
paycheck = PAYCHECK_MEDIUM
|
||||
paycheck_department = ACCOUNT_ENG
|
||||
|
||||
starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_BASIC))
|
||||
skill_affinities = list(/datum/skill/level/job/wiring = STARTING_SKILL_AFFINITY_WIRING_ENGI_ROBO)
|
||||
starting_modifiers = list(/datum/skill_modifier/job/level/wiring/basic, /datum/skill_modifier/job/affinity/wiring)
|
||||
|
||||
display_order = JOB_DISPLAY_ORDER_ATMOSPHERIC_TECHNICIAN
|
||||
threat = 0.5
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
display_order = JOB_DISPLAY_ORDER_CHEMIST
|
||||
threat = 1.5
|
||||
|
||||
starting_skills = list(/datum/skill/numerical/surgery = STARTING_SKILL_SURGERY_MEDICAL)
|
||||
skill_affinities = list(/datum/skill/numerical/surgery = STARTING_SKILL_AFFINITY_SURGERY_MEDICAL)
|
||||
starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery)
|
||||
|
||||
/datum/outfit/job/chemist
|
||||
name = "Chemist"
|
||||
|
||||
@@ -29,8 +29,7 @@
|
||||
paycheck = PAYCHECK_COMMAND
|
||||
paycheck_department = ACCOUNT_ENG
|
||||
|
||||
starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_TRAINED))
|
||||
skill_affinities = list(/datum/skill/level/job/wiring = STARTING_SKILL_AFFINITY_WIRING_ENGI_ROBO)
|
||||
starting_modifiers = list(/datum/skill_modifier/job/level/wiring, /datum/skill_modifier/job/affinity/wiring)
|
||||
|
||||
display_order = JOB_DISPLAY_ORDER_CHIEF_ENGINEER
|
||||
blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/paraplegic, /datum/quirk/insanity)
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity)
|
||||
threat = 2
|
||||
|
||||
starting_skills = list(/datum/skill/numerical/surgery = STARTING_SKILL_SURGERY_MEDICAL)
|
||||
skill_affinities = list(/datum/skill/numerical/surgery = STARTING_SKILL_AFFINITY_SURGERY_MEDICAL)
|
||||
starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery)
|
||||
|
||||
/datum/outfit/job/cmo
|
||||
name = "Chief Medical Officer"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
exp_requirements = 120
|
||||
exp_type = EXP_TYPE_CREW
|
||||
|
||||
starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_BASIC))
|
||||
starting_modifiers = list(/datum/skill_modifier/job/level/wiring/basic)
|
||||
|
||||
display_order = JOB_DISPLAY_ORDER_CYBORG
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
display_order = JOB_DISPLAY_ORDER_GENETICIST
|
||||
threat = 1.5
|
||||
|
||||
starting_skills = list(/datum/skill/numerical/surgery = STARTING_SKILL_SURGERY_MEDICAL)
|
||||
starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery)
|
||||
|
||||
/datum/outfit/job/geneticist
|
||||
name = "Geneticist"
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
display_order = JOB_DISPLAY_ORDER_MEDICAL_DOCTOR
|
||||
threat = 0.5
|
||||
|
||||
starting_skills = list(/datum/skill/numerical/surgery = STARTING_SKILL_SURGERY_MEDICAL)
|
||||
skill_affinities = list(/datum/skill/numerical/surgery = STARTING_SKILL_AFFINITY_SURGERY_MEDICAL)
|
||||
starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery)
|
||||
|
||||
/datum/outfit/job/doctor
|
||||
name = "Medical Doctor"
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
|
||||
threat = 0.5
|
||||
|
||||
starting_skills = list(/datum/skill/numerical/surgery = STARTING_SKILL_SURGERY_MEDICAL)
|
||||
skill_affinities = list(/datum/skill/numerical/surgery = STARTING_SKILL_AFFINITY_SURGERY_MEDICAL)
|
||||
starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery)
|
||||
|
||||
/datum/outfit/job/paramedic
|
||||
name = "Paramedic"
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
paycheck = PAYCHECK_MEDIUM
|
||||
paycheck_department = ACCOUNT_SCI
|
||||
|
||||
starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_TRAINED))
|
||||
skill_affinities = list(/datum/skill/level/job/wiring = STARTING_SKILL_AFFINITY_WIRING_ENGI_ROBO)
|
||||
|
||||
starting_modifiers = list(/datum/skill_modifier/job/level/wiring, /datum/skill_modifier/job/affinity/wiring)
|
||||
|
||||
display_order = JOB_DISPLAY_ORDER_ROBOTICIST
|
||||
threat = 1
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
paycheck = PAYCHECK_MEDIUM
|
||||
paycheck_department = ACCOUNT_ENG
|
||||
|
||||
starting_skills = list(/datum/skill/level/job/wiring = GET_STANDARD_LVL(JOB_SKILL_TRAINED))
|
||||
skill_affinities = list(/datum/skill/level/job/wiring = STARTING_SKILL_AFFINITY_WIRING_ENGI_ROBO)
|
||||
starting_modifiers = list(/datum/skill_modifier/job/level/wiring, /datum/skill_modifier/job/affinity/wiring)
|
||||
|
||||
display_order = JOB_DISPLAY_ORDER_STATION_ENGINEER
|
||||
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
|
||||
threat = 1.5
|
||||
|
||||
starting_skills = list(/datum/skill/numerical/surgery = STARTING_SKILL_SURGERY_MEDICAL)
|
||||
skill_affinities = list(/datum/skill/numerical/surgery = STARTING_SKILL_AFFINITY_SURGERY_MEDICAL)
|
||||
starting_modifiers = list(/datum/skill_modifier/job/surgery, /datum/skill_modifier/job/affinity/surgery)
|
||||
|
||||
/datum/outfit/job/virologist
|
||||
name = "Virologist"
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/datum/admins/key_down(_key, client/user)
|
||||
switch(_key)
|
||||
if("F3")
|
||||
user.get_admin_say()
|
||||
return
|
||||
if("F5")
|
||||
user.admin_ghost()
|
||||
return
|
||||
if("F6")
|
||||
player_panel_new()
|
||||
return
|
||||
if("F7")
|
||||
user.togglebuildmodeself()
|
||||
return
|
||||
if("F8")
|
||||
if(user.keys_held["Ctrl"])
|
||||
user.stealth()
|
||||
else
|
||||
user.invisimin()
|
||||
return
|
||||
if("F10")
|
||||
user.get_dead_say()
|
||||
return
|
||||
..()
|
||||
@@ -5,7 +5,7 @@
|
||||
if(!user.keys_held["Ctrl"])
|
||||
var/movement_dir = NONE
|
||||
for(var/_key in user.keys_held)
|
||||
movement_dir = movement_dir | SSinput.movement_keys[_key]
|
||||
movement_dir = movement_dir | user.movement_keys[_key]
|
||||
if(user.next_move_dir_add)
|
||||
movement_dir |= user.next_move_dir_add
|
||||
if(user.next_move_dir_sub)
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
/mob/living/carbon/key_down(_key, client/user)
|
||||
switch(_key)
|
||||
if("R", "Southwest") // Southwest is End
|
||||
toggle_throw_mode()
|
||||
return
|
||||
if("C")
|
||||
user_toggle_intentional_combat_mode()
|
||||
return
|
||||
return ..()
|
||||
@@ -33,55 +33,69 @@
|
||||
to_chat(src, "<span class='userdanger'>Invalid KeyDown detected! You have been disconnected from the server automatically.</span>")
|
||||
log_admin("Client [ckey] just attempted to send an invalid keypress. Keymessage was over [MAX_KEYPRESS_COMMANDLENGTH] characters, autokicking due to likely abuse.")
|
||||
message_admins("Client [ckey] just attempted to send an invalid keypress. Keymessage was over [MAX_KEYPRESS_COMMANDLENGTH] characters, autokicking due to likely abuse.")
|
||||
QDEL_IN(src, 1)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(_key == "Tab")
|
||||
ForceAllKeysUp() //groan, more hacky kevcode
|
||||
return
|
||||
|
||||
if(length(keys_held) > MAX_HELD_KEYS)
|
||||
keys_held.Cut(1,2)
|
||||
keys_held[_key] = TRUE
|
||||
var/movement = SSinput.movement_keys[_key]
|
||||
var/movement = movement_keys[_key]
|
||||
if(!(next_move_dir_sub & movement) && !keys_held["Ctrl"])
|
||||
next_move_dir_add |= movement
|
||||
|
||||
// Client-level keybindings are ones anyone should be able to do at any time
|
||||
// Things like taking screenshots, hitting tab, and adminhelps.
|
||||
|
||||
var/AltMod = keys_held["Alt"] ? "Alt" : ""
|
||||
var/CtrlMod = keys_held["Ctrl"] ? "Ctrl" : ""
|
||||
var/ShiftMod = keys_held["Shift"] ? "Shift" : ""
|
||||
var/full_key
|
||||
switch(_key)
|
||||
if("F1")
|
||||
if(keys_held["Ctrl"] && keys_held["Shift"]) // Is this command ever used?
|
||||
winset(src, null, "command=.options")
|
||||
else
|
||||
get_adminhelp()
|
||||
return
|
||||
if("F2") // Screenshot. Hold shift to choose a name and location to save in
|
||||
winset(src, null, "command=.screenshot [!keys_held["shift"] ? "auto" : ""]")
|
||||
return
|
||||
if("F12") // Toggles minimal HUD
|
||||
mob.button_pressed_F12()
|
||||
return
|
||||
if("Alt", "Ctrl", "Shift")
|
||||
full_key = "[AltMod][CtrlMod][ShiftMod]"
|
||||
else
|
||||
full_key = "[AltMod][CtrlMod][ShiftMod][_key]"
|
||||
var/keycount = 0
|
||||
for(var/kb_name in prefs.key_bindings[full_key])
|
||||
keycount++
|
||||
var/datum/keybinding/kb = GLOB.keybindings_by_name[kb_name]
|
||||
if(kb.can_use(src) && kb.down(src) && keycount >= MAX_COMMANDS_PER_KEY)
|
||||
break
|
||||
|
||||
if(holder)
|
||||
holder.key_down(_key, src)
|
||||
if(mob.focus)
|
||||
mob.focus.key_down(_key, src)
|
||||
holder?.key_down(_key, src)
|
||||
mob.focus?.key_down(_key, src)
|
||||
|
||||
/// Keyup's all keys held down.
|
||||
/client/proc/ForceAllKeysUp()
|
||||
// simulate a user releasing all keys except for the mod keys. groan. i hate this. thanks, byond. why aren't keyups able to be forced to fire on macro change aoaoaoao.
|
||||
// groan
|
||||
for(var/key in keys_held) // all of these won't be the 3 mod keys.
|
||||
if((key == "Ctrl") || (key == "Alt") || (key == "Shift"))
|
||||
continue
|
||||
keyUp("[key]")
|
||||
|
||||
/client/verb/keyUp(_key as text)
|
||||
set instant = TRUE
|
||||
set hidden = TRUE
|
||||
|
||||
keys_held -= _key
|
||||
var/movement = SSinput.movement_keys[_key]
|
||||
var/movement = movement_keys[_key]
|
||||
if(!(next_move_dir_add & movement))
|
||||
next_move_dir_sub |= movement
|
||||
|
||||
if(holder)
|
||||
holder.key_up(_key, src)
|
||||
if(mob.focus)
|
||||
mob.focus.key_up(_key, src)
|
||||
// We don't do full key for release, because for mod keys you
|
||||
// can hold different keys and releasing any should be handled by the key binding specifically
|
||||
for (var/kb_name in prefs.key_bindings[_key])
|
||||
var/datum/keybinding/kb = GLOB.keybindings_by_name[kb_name]
|
||||
if(kb.can_use(src) && kb.up(src))
|
||||
break
|
||||
holder?.key_up(_key, src)
|
||||
mob.focus?.key_up(_key, src)
|
||||
|
||||
// Called every game tick
|
||||
/client/keyLoop()
|
||||
if(holder)
|
||||
holder.keyLoop(src)
|
||||
if(mob.focus)
|
||||
mob.focus.keyLoop(src)
|
||||
holder?.keyLoop(src)
|
||||
mob.focus?.keyLoop(src)
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/mob/living/carbon/human/key_down(_key, client/user)
|
||||
if(client.keys_held["Shift"])
|
||||
switch(_key)
|
||||
if("E") // Put held thing in belt or take out most recent thing from belt
|
||||
var/obj/item/thing = get_active_held_item()
|
||||
var/obj/item/storage/equipped_belt = get_item_by_slot(SLOT_BELT)
|
||||
if(!equipped_belt) // We also let you equip a belt like this
|
||||
if(!thing)
|
||||
to_chat(user, "<span class='notice'>You have no belt to take something out of.</span>")
|
||||
return
|
||||
equip_to_slot_if_possible(thing, SLOT_BELT)
|
||||
return
|
||||
if(!istype(equipped_belt)) // not a storage item
|
||||
if(!thing)
|
||||
to_chat(user, "<span class='notice'>You have no belt to take something out of.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You can't fit anything in.</span>")
|
||||
return
|
||||
if(thing) // put thing in belt
|
||||
if(!SEND_SIGNAL(equipped_belt, COMSIG_TRY_STORAGE_INSERT, thing, user.mob))
|
||||
to_chat(user, "<span class='notice'>You can't fit anything in.</span>")
|
||||
return
|
||||
if(!equipped_belt.contents.len) // nothing to take out
|
||||
to_chat(user, "<span class='notice'>There's nothing in your belt to take out.</span>")
|
||||
return
|
||||
var/obj/item/stored = equipped_belt.contents[equipped_belt.contents.len]
|
||||
if(!stored || stored.on_found(src))
|
||||
return
|
||||
stored.attack_hand(src) // take out thing from belt
|
||||
return
|
||||
|
||||
if("B") // Put held thing in backpack or take out most recent thing from backpack
|
||||
var/obj/item/thing = get_active_held_item()
|
||||
var/obj/item/storage/equipped_backpack = get_item_by_slot(SLOT_BACK)
|
||||
if(!equipped_backpack) // We also let you equip a backpack like this
|
||||
if(!thing)
|
||||
to_chat(user, "<span class='notice'>You have no backpack to take something out of.</span>")
|
||||
return
|
||||
equip_to_slot_if_possible(thing, SLOT_BACK)
|
||||
return
|
||||
if(!istype(equipped_backpack)) // not a storage item
|
||||
if(!thing)
|
||||
to_chat(user, "<span class='notice'>You have no backpack to take something out of.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You can't fit anything in.</span>")
|
||||
return
|
||||
if(thing) // put thing in backpack
|
||||
if(!SEND_SIGNAL(equipped_backpack, COMSIG_TRY_STORAGE_INSERT, thing, user.mob))
|
||||
to_chat(user, "<span class='notice'>You can't fit anything in.</span>")
|
||||
return
|
||||
if(!equipped_backpack.contents.len) // nothing to take out
|
||||
to_chat(user, "<span class='notice'>There's nothing in your backpack to take out.</span>")
|
||||
return
|
||||
var/obj/item/stored = equipped_backpack.contents[equipped_backpack.contents.len]
|
||||
if(!stored || stored.on_found(src))
|
||||
return
|
||||
stored.attack_hand(src) // take out thing from backpack
|
||||
return
|
||||
switch(_key)
|
||||
if("Shift")
|
||||
if(!user.prefs.sprint_spacebar)
|
||||
user.prefs.sprint_toggle ? default_toggle_sprint() : sprint_hotkey(TRUE) //Yes, this looks hacky. Yes, this works.
|
||||
return
|
||||
if("Space")
|
||||
if(user.prefs.sprint_spacebar)
|
||||
user.prefs.sprint_toggle ? default_toggle_sprint() : sprint_hotkey(TRUE)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/key_up(_key, client/user)
|
||||
switch(_key)
|
||||
if("Shift")
|
||||
if(!user.prefs.sprint_spacebar && !user.prefs.sprint_toggle)
|
||||
sprint_hotkey(FALSE)
|
||||
return
|
||||
if("Space")
|
||||
if(user.prefs.sprint_spacebar && !user.prefs.sprint_toggle)
|
||||
sprint_hotkey(FALSE)
|
||||
return
|
||||
return ..()
|
||||
@@ -1,27 +0,0 @@
|
||||
/mob/living/key_down(_key, client/user)
|
||||
switch(_key)
|
||||
if("B")
|
||||
resist()
|
||||
return
|
||||
if("1")
|
||||
if(possible_a_intents)
|
||||
a_intent_change(INTENT_HELP)
|
||||
return
|
||||
if("2")
|
||||
if(possible_a_intents)
|
||||
a_intent_change(INTENT_DISARM)
|
||||
return
|
||||
if("3")
|
||||
if(possible_a_intents)
|
||||
a_intent_change(INTENT_GRAB)
|
||||
return
|
||||
if("4")
|
||||
if(possible_a_intents)
|
||||
a_intent_change(INTENT_HARM)
|
||||
return
|
||||
if ("V")
|
||||
lay_down()
|
||||
return
|
||||
|
||||
|
||||
return ..()
|
||||
@@ -1,94 +0,0 @@
|
||||
// Technically the client argument is unncessary here since that SHOULD be src.client but let's not assume things
|
||||
// All it takes is one badmin setting their focus to someone else's client to mess things up
|
||||
// Or we can have NPC's send actual keypresses and detect that by seeing no client
|
||||
|
||||
/mob/key_down(_key, client/user)
|
||||
switch(_key)
|
||||
if("Delete", "H")
|
||||
if(!pulling)
|
||||
to_chat(src, "<span class='notice'>You are not pulling anything.</span>")
|
||||
else
|
||||
stop_pulling()
|
||||
return
|
||||
if("Insert", "G")
|
||||
a_intent_change(INTENT_HOTKEY_RIGHT)
|
||||
return
|
||||
if("F")
|
||||
a_intent_change(INTENT_HOTKEY_LEFT)
|
||||
return
|
||||
if("X", "Northeast") // Northeast is Page-up
|
||||
swap_hand()
|
||||
return
|
||||
if("Y", "Z", "Southeast") // Southeast is Page-down
|
||||
mode() // attack_self(). No idea who came up with "mode()"
|
||||
return
|
||||
if("Q", "Northwest") // Northwest is Home
|
||||
var/obj/item/I = get_active_held_item()
|
||||
if(!I)
|
||||
to_chat(src, "<span class='warning'>You have nothing to drop in your hand!</span>")
|
||||
else
|
||||
dropItemToGround(I)
|
||||
return
|
||||
if("E")
|
||||
quick_equip()
|
||||
return
|
||||
if("Alt")
|
||||
toggle_move_intent()
|
||||
return
|
||||
//Bodypart selections
|
||||
if("Numpad8")
|
||||
user.body_toggle_head()
|
||||
return
|
||||
if("Numpad4")
|
||||
user.body_r_arm()
|
||||
return
|
||||
if("Numpad5")
|
||||
user.body_chest()
|
||||
return
|
||||
if("Numpad6")
|
||||
user.body_l_arm()
|
||||
return
|
||||
if("Numpad1")
|
||||
user.body_r_leg()
|
||||
return
|
||||
if("Numpad2")
|
||||
user.body_groin()
|
||||
return
|
||||
if("Numpad3")
|
||||
user.body_l_leg()
|
||||
return
|
||||
|
||||
if(client.keys_held["Ctrl"])
|
||||
switch(SSinput.movement_keys[_key])
|
||||
if(NORTH)
|
||||
if(client.keys_held["Shift"])
|
||||
northshift()
|
||||
else
|
||||
northface()
|
||||
return
|
||||
if(SOUTH)
|
||||
if(client.keys_held["Shift"])
|
||||
southshift()
|
||||
else
|
||||
southface()
|
||||
return
|
||||
if(WEST)
|
||||
if(client.keys_held["Shift"])
|
||||
westshift()
|
||||
else
|
||||
westface()
|
||||
return
|
||||
if(EAST)
|
||||
if(client.keys_held["Shift"])
|
||||
eastshift()
|
||||
else
|
||||
eastface()
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/key_up(_key, client/user)
|
||||
switch(_key)
|
||||
if("Alt")
|
||||
toggle_move_intent()
|
||||
return
|
||||
return ..()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user