Conflicts galore

This commit is contained in:
Artur
2020-05-21 21:08:12 +03:00
532 changed files with 9131 additions and 5662 deletions
+5
View File
@@ -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)
+1 -1
View File
@@ -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)
+1
View File
@@ -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)
-59
View File
@@ -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
-2
View File
@@ -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")
+52
View File
@@ -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
+8 -4
View File
@@ -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
+2
View File
@@ -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
+2 -1
View File
@@ -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'
+4 -2
View File
@@ -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
+1 -1
View File
@@ -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)
+7 -4
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -1,5 +1,6 @@
/datum/export/gear
include_subtypes = FALSE
k_elasticity = 0 //We always want clothing/gear
//blanket
/datum/export/gear/hat
+1 -1
View File
@@ -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"
+3 -3
View File
@@ -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
-6
View File
@@ -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"
+30 -27
View File
@@ -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)
+6 -3
View File
@@ -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'
+1
View File
@@ -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
+3 -2
View File
@@ -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,
+1 -1
View File
@@ -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!"
-26
View File
@@ -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."
+2 -1
View File
@@ -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
-16
View File
@@ -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!"
+1
View File
@@ -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"
+21
View File
@@ -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 >:(
+1
View File
@@ -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"
+14
View File
@@ -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
+27 -6
View File
@@ -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)
+211 -28
View File
@@ -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];'>&nbsp;&nbsp;&nbsp;</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];'>&nbsp;&nbsp;&nbsp;</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
+35 -10
View File
@@ -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
+8 -8
View File
@@ -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"
+2 -2
View File
@@ -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)
+2 -2
View File
@@ -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"
+6 -5
View File
@@ -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()
+3 -3
View File
@@ -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
+7 -6
View File
@@ -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)
+2 -2
View File
@@ -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>
+4 -2
View File
@@ -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
+6 -3
View File
@@ -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"
+102
View File
@@ -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())
+5 -12
View File
@@ -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"
+1 -1
View File
@@ -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
+1 -2
View File
@@ -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"
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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"
+1 -2
View File
@@ -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"
+1 -3
View File
@@ -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
+1 -2
View File
@@ -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
..()
+1 -1
View File
@@ -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 ..()
+42 -28
View File
@@ -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 ..()
-94
View File
@@ -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