This commit is contained in:
Ghommie
2020-05-10 22:36:04 +02:00
105 changed files with 1079 additions and 1039 deletions
File diff suppressed because it is too large Load Diff
+17 -3
View File
@@ -35,9 +35,9 @@
/// Default combat flags for those affected by ((stamina combat))
#define COMBAT_FLAGS_DEFAULT NONE
/// Default combat flags for everyone else (so literally everyone but humans)
#define COMBAT_FLAGS_STAMSYSTEM_EXEMPT (COMBAT_FLAG_SPRINT_ACTIVE | COMBAT_FLAG_COMBAT_ACTIVE | COMBAT_FLAG_SPRINT_TOGGLED | COMBAT_FLAG_COMBAT_TOGGLED)
#define COMBAT_FLAGS_STAMSYSTEM_EXEMPT (COMBAT_FLAG_SPRINT_ACTIVE | COMBAT_FLAG_COMBAT_ACTIVE | COMBAT_FLAG_SPRINT_TOGGLED | COMBAT_FLAG_COMBAT_TOGGLED | COMBAT_FLAG_SPRINT_FORCED | COMBAT_FLAG_COMBAT_FORCED)
/// Default combat flags for those only affected by sprint (so just silicons)
#define COMBAT_FLAGS_STAMEXEMPT_YESSPRINT (COMBAT_FLAG_COMBAT_ACTIVE | COMBAT_FLAG_COMBAT_TOGGLED)
#define COMBAT_FLAGS_STAMEXEMPT_YESSPRINT (COMBAT_FLAG_COMBAT_ACTIVE | COMBAT_FLAG_COMBAT_TOGGLED | COMBAT_FLAG_COMBAT_FORCED)
/// The user wants combat mode on
#define COMBAT_FLAG_COMBAT_TOGGLED (1<<0)
@@ -57,6 +57,10 @@
#define COMBAT_FLAG_INTENTIONALLY_RESTING (1<<7)
/// Currently stamcritted but not as violently
#define COMBAT_FLAG_SOFT_STAMCRIT (1<<8)
/// Force combat mode on at all times, overrides everything including combat disable traits.
#define COMBAT_FLAG_COMBAT_FORCED (1<<9)
/// Force sprint mode on at all times, overrides everything including sprint disable traits.
#define COMBAT_FLAG_SPRINT_FORCED (1<<10)
// Helpers for getting someone's stamcrit state. Cast to living.
#define NOT_STAMCRIT 0
@@ -263,7 +267,17 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
#define BULLET_ACT_FORCE_PIERCE "PIERCE" //It pierces through the object regardless of the bullet being piercing by default.
#define BULLET_ACT_TURF "TURF" //It hit us but it should hit something on the same turf too. Usually used for turfs.
/// Bitflags for check_block() and handle_block(). Meant to be combined. You can be hit and still reflect, for example, if you do not use BLOCK_SUCCESS.
/// Check whether or not we can block, without "triggering" a block. Basically run checks without effects like depleting shields.
/// Wrapper for do_run_block(). The arguments on that means the same as for this.
#define mob_check_block(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list)\
do_run_block(FALSE, object, damage, attack_text, attack_type, armour_penetration, attacker, check_zone(def_zone), return_list)
/// Runs a block "sequence", effectively checking and then doing effects if necessary.
/// Wrapper for do_run_block(). The arguments on that means the same as for this.
#define mob_run_block(object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list)\
do_run_block(TRUE, object, damage, attack_text, attack_type, armour_penetration, attacker, check_zone(def_zone), return_list)
/// Bitflags for check_block() and run_block(). Meant to be combined. You can be hit and still reflect, for example, if you do not use BLOCK_SUCCESS.
/// Attack was not blocked
#define BLOCK_NONE NONE
/// Attack was blocked, do not do damage. THIS FLAG MUST BE THERE FOR DAMAGE/EFFECT PREVENTION!
+3 -3
View File
@@ -131,7 +131,7 @@
/mob/living/attacked_by(obj/item/I, mob/living/user)
var/totitemdamage = pre_attacked_by(I, user)
if((user != src) && run_block(I, totitemdamage, "the [I.name]", ATTACK_TYPE_MELEE, I.armour_penetration, user) & BLOCK_SUCCESS)
if((user != src) && mob_run_block(I, totitemdamage, "the [I.name]", ATTACK_TYPE_MELEE, I.armour_penetration, user, null, null) & BLOCK_SUCCESS)
return FALSE
send_item_attack_message(I, user)
I.do_stagger_action(src, user, totitemdamage)
@@ -163,7 +163,7 @@
if(!user.mind || !I.used_skills)
return
if(.)
. = user.mind.skill_holder.item_action_skills_mod(., I.skill_difficulty, SKILL_ATTACK_MOB, bad_flag)
. = user.mind.skill_holder.item_action_skills_mod(I, ., I.skill_difficulty, SKILL_ATTACK_MOB, bad_flag)
for(var/skill in I.used_skills)
if(!(I.used_skills[skill] & SKILL_TRAIN_ATTACK_MOB))
continue
@@ -216,7 +216,7 @@
. *= STAM_COST_NO_COMBAT_MULT
bad_flag |= SKILL_COMBAT_MODE
if(used_skills && user.mind)
. = user.mind.skill_holder.item_action_skills_mod(., skill_difficulty, flags, bad_flag, FALSE)
. = user.mind.skill_holder.item_action_skills_mod(src, ., skill_difficulty, flags, bad_flag, FALSE)
/// How long this staggers for. 0 and negatives supported.
/obj/item/proc/melee_stagger_duration(force_override)
@@ -35,6 +35,13 @@
/datum/config_entry/keyed_list/midround_antag/ValidateListEntry(key_name, key_value)
return key_name in config.modes
/datum/config_entry/keyed_list/force_antag_count
key_mode = KEY_MODE_TEXT
value_mode = VALUE_MODE_FLAG
/datum/config_entry/keyed_list/force_antag_count/ValidateListEntry(key_name, key_value)
return key_name in config.modes
/datum/config_entry/keyed_list/policy
key_mode = KEY_MODE_TEXT
value_mode = VALUE_MODE_TEXT
@@ -117,7 +117,7 @@
/datum/crafting_recipe/upgraded_gauze
name = "Improved Gauze"
result = /obj/item/stack/medical/gauze/adv
result = /obj/item/stack/medical/gauze/adv/one
time = 1
reqs = list(/obj/item/stack/medical/gauze = 1,
/datum/reagent/space_cleaner/sterilizine = 10)
@@ -126,7 +126,7 @@
/datum/crafting_recipe/bruise_pack
name = "Bruise Pack"
result = /obj/item/stack/medical/bruise_pack
result = /obj/item/stack/medical/bruise_pack/one
time = 1
reqs = list(/obj/item/stack/medical/gauze = 1,
/datum/reagent/medicine/styptic_powder = 10)
@@ -134,8 +134,8 @@
subcategory = CAT_TOOL
/datum/crafting_recipe/burn_pack
name = "Brun Ointment"
result = /obj/item/stack/medical/ointment
name = "Burn Ointment"
result = /obj/item/stack/medical/ointment/one
time = 1
reqs = list(/obj/item/stack/medical/gauze = 1,
/datum/reagent/medicine/silver_sulfadiazine = 10)
+6 -4
View File
@@ -1,3 +1,4 @@
#define SLIGHT_INSANITY_PEN 1
#define MINOR_INSANITY_PEN 5
#define MAJOR_INSANITY_PEN 10
#define MOOD_INSANITY_MALUS 0.0054 // per point of sanity below SANITY_DISTURBED, a 40% debuff to skills at rock bottom depression.
@@ -183,7 +184,7 @@
master.add_movespeed_modifier(/datum/movespeed_modifier/sanity/crazy)
sanity_level = 5
if(SANITY_UNSTABLE to SANITY_DISTURBED)
setInsanityEffect(0)
setInsanityEffect(SLIGHT_INSANITY_PEN)
master.add_movespeed_modifier(/datum/movespeed_modifier/sanity/disturbed)
sanity_level = 4
if(SANITY_DISTURBED to SANITY_NEUTRAL)
@@ -211,12 +212,12 @@
return
//var/mob/living/master = parent
//master.crit_threshold = (master.crit_threshold - insanity_effect) + newval
insanity_effect = newval
if(insanity_effect)
if(!insanity_effect && newval)
RegisterSignal(parent, COMSIG_MOB_ACTION_SKILL_MOD, .proc/on_mob_action_skill_mod)
RegisterSignal(parent, COMSIG_MOB_ITEM_ACTION_SKILLS_MOD, .proc/on_item_action_skills_mod)
else
else if(insanity_effect && !newval)
UnregisterSignal(parent, list(COMSIG_MOB_ACTION_SKILL_MOD, COMSIG_MOB_ITEM_ACTION_SKILLS_MOD))
insanity_effect = newval
/datum/component/mood/proc/modify_sanity(datum/source, amount, minimum = SANITY_INSANE, maximum = SANITY_AMAZING)
setSanity(sanity + amount, minimum, maximum)
@@ -333,6 +334,7 @@
return
return_value[1] *= SKILL_AFFINITY_MOOD_BONUS
#undef SLIGHT_INSANITY_PEN
#undef MINOR_INSANITY_PEN
#undef MAJOR_INSANITY_PEN
#undef MOOD_INSANITY_MALUS
+1 -1
View File
@@ -208,13 +208,13 @@
RegisterSignal(parent, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, .proc/on_host_unarmed_melee)
/datum/component/riding/human/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE)
. = ..()
var/mob/living/carbon/human/H = parent
if(!length(H.buckled_mobs))
H.remove_movespeed_modifier(/datum/movespeed_modifier/human_carry)
if(!fireman_carrying)
M.Daze(25)
REMOVE_TRAIT(M, TRAIT_MOBILITY_NOUSE, src)
return ..()
/datum/component/riding/human/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE)
. = ..()
@@ -58,7 +58,7 @@
var/mob/living/carbon/C = M
if(prob(10))
if(trauma_heal_severe)
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_LOBOTOMY)
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_SURGERY)
else
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC)
+3 -1
View File
@@ -76,7 +76,9 @@ GLOBAL_LIST_EMPTY(explosions)
//I would make this not ex_act the thing that triggered the explosion,
//but everything that explodes gives us their loc or a get_turf()
//and somethings expect us to ex_act them so they can qdel()
stoplag() //tldr, let the calling proc call qdel(src) before we explode
//stoplag() //tldr, let the calling proc call qdel(src) before we explode
// no - use sleep. stoplag() results in quirky things like explosions taking too long to process and hanging mid-air for no reason.
sleep(0)
EX_PREPROCESS_EXIT_CHECK
+1 -1
View File
@@ -417,7 +417,7 @@
if(player.assigned_role == job)
candidates -= player
if(candidates.len < recommended_enemies)
if(candidates.len < recommended_enemies && CONFIG_GET(keyed_list/force_antag_count)[config_tag])
for(var/mob/dead/new_player/player in players)
if(player.client && player.ready == PLAYER_READY_TO_PLAY)
if(!(role in player.client.prefs.be_special)) // We don't have enough people who want to be antagonist, make a separate list of people who don't want to be one
-1
View File
@@ -114,7 +114,6 @@
add_fingerprint(user)
if(charging)
charging.update_icon()
charging.forceMove(drop_location())
user.put_in_hands(charging)
/obj/machinery/recharger/attack_tk(mob/user)
@@ -3,6 +3,46 @@
////////////////////////////////
/datum/component/construction/mecha
var/base_icon
var/looky_helpy = TRUE
/datum/component/construction/mecha/examine(mob/user)
. = ..()
if(looky_helpy)
switch(steps[index]["key"])
if(TOOL_WRENCH)
. += "<span class='notice'>The mech could be <b>wrenched</b> into place.</span>"
if(TOOL_SCREWDRIVER)
. += "<span class='notice'>The mech could be <b>screwed</b> into place.</span>"
if(TOOL_WIRECUTTER)
. += "<span class='notice'>The mech wires could be <b>trimmed</b> into place.</span>"
if(/obj/item/stack/cable_coil)
. += "<span class='notice'>The mech could use some <b>wiring</b>.</span>"
if(/obj/item/circuitboard)
. += "<span class='notice'>The mech could use a type of<b>circuitboard</b>.</span>"
if(/obj/item/stock_parts/scanning_module)
. += "<span class='notice'>The mech could use a <b>scanning stock part</b>.</span>"
if(/obj/item/stock_parts/capacitor)
. += "<span class='notice'>The mech could use a <b>power based stock part</b>.</span>"
if(/obj/item/stock_parts/cell)
. += "<span class='notice'>The mech could use a <b>power source</b>.</span>"
if(/obj/item/stack/sheet/metal)
. += "<span class='notice'>The mech could use some <b>sheets of metal</b>.</span>"
if(/obj/item/stack/sheet/plasteel)
. += "<span class='notice'>The mech could use some <b>sheets of strong steel</b>.</span>"
if(/obj/item/bikehorn)
. += "<span class='notice'>HONK IT!.</span>"
if(/obj/item/clothing/mask/gas/clown_hat)
. += "<span class='notice'>GIVE IT CLOWN MAKEUP HONK!.</span>"
if(/obj/item/clothing/shoes/clown_shoes)
. += "<span class='notice'>GIVE IT GOOFY SHOES HONK HONK!.</span>"
if(/obj/item/mecha_parts/part)
. += "<span class='notice'>The mech could use a mech <b>part</b>.</span>"
if(/obj/item/stack/ore/bluespace_crystal)
. += "<span class='notice'>The mech could use a <b>crystal</b> of sorts.</span>"
if(/obj/item/assembly/signaler/anomaly)
. += "<span class='notice'>The mech could use a <b>anomaly</b> of sorts.</span>"
else
return
/datum/component/construction/mecha/spawn_result()
if(!result)
+11 -12
View File
@@ -118,7 +118,7 @@
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
custom_materials = list(/datum/material/iron=150, /datum/material/glass=75)
breakouttime = 300 //Deciseconds = 30s
cuffsound = 'sound/weapons/cablecuff.ogg'
cuffsound = 'sound/weapons/cablecuff.ogg'
/obj/item/restraints/handcuffs/cable/attack_self(mob/user)
to_chat(user, "<span class='notice'>You start unwinding the cable restraints back into coil</span>")
@@ -130,7 +130,7 @@
user.put_in_hands(coil)
coil.color = color
to_chat(user, "<span class='notice'>You unwind the cable restraints back into coil</span>")
/obj/item/restraints/handcuffs/cable/red
color = "#ff0000"
@@ -225,7 +225,6 @@
/obj/item/restraints/handcuffs/fake/kinky
name = "kinky handcuffs"
desc = "Fake handcuffs meant for erotic roleplay."
icon = 'modular_citadel/icons/obj/items_and_weapons.dmi'
icon_state = "handcuffgag"
item_state = "kinkycuff"
@@ -252,7 +251,7 @@
throw_range = 1
icon_state = "beartrap"
desc = "A trap used to catch bears and other legged creatures."
var/armed = 0
var/armed = FALSE
var/trap_damage = 20
/obj/item/restraints/legcuffs/beartrap/Initialize()
@@ -275,14 +274,14 @@
if(armed && isturf(src.loc))
if(isliving(AM))
var/mob/living/L = AM
var/snap = 0
var/snap = FALSE
var/def_zone = BODY_ZONE_CHEST
if(iscarbon(L))
var/mob/living/carbon/C = L
snap = 1
if(!C.lying)
def_zone = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
if(!C.legcuffed && C.get_num_legs(FALSE) >= 2) //beartrap can't cuff your leg if there's already a beartrap or legcuffs, or you don't have two legs.
snap = TRUE
C.legcuffed = src
forceMove(C)
C.update_equipment_speed_mods()
@@ -291,21 +290,21 @@
else if(isanimal(L))
var/mob/living/simple_animal/SA = L
if(SA.mob_size > MOB_SIZE_TINY)
snap = 1
if(L.movement_type & FLYING)
snap = 0
snap = TRUE
if(L.movement_type & (FLYING | FLOATING))
snap = FALSE
if(snap)
armed = 0
armed = FALSE
icon_state = "[initial(icon_state)][armed]"
playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
L.visible_message("<span class='danger'>[L] triggers \the [src].</span>", \
"<span class='userdanger'>You trigger \the [src]!</span>")
L.apply_damage(trap_damage,BRUTE, def_zone)
L.apply_damage(trap_damage, BRUTE, def_zone)
..()
/obj/item/restraints/legcuffs/beartrap/energy
name = "energy snare"
armed = 1
armed = TRUE
icon_state = "e_snare"
trap_damage = 0
item_flags = DROPDEL
+1 -1
View File
@@ -304,7 +304,7 @@
return
else
if(cooldown_check < world.time)
if(target.run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user) & BLOCK_SUCCESS)
if(target.mob_run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user, null, null) & BLOCK_SUCCESS)
playsound(target, 'sound/weapons/genhit.ogg', 50, 1)
return
if(ishuman(target))
+1 -1
View File
@@ -11,7 +11,7 @@
var/charge_cost = 30
/obj/item/borg/stun/attack(mob/living/M, mob/living/user)
if(M.run_block(src, 0, "[M]'s [name]", ATTACK_TYPE_MELEE, 0, user, ran_zone(user.zone_selected)) & BLOCK_SUCCESS)
if(M.mob_run_block(src, 0, "[M]'s [name]", ATTACK_TYPE_MELEE, 0, user, ran_zone(user.zone_selected), null) & BLOCK_SUCCESS)
playsound(M, 'sound/weapons/genhit.ogg', 50, 1)
return FALSE
if(iscyborg(user))
@@ -59,6 +59,9 @@
self_delay = 20
grind_results = list(/datum/reagent/medicine/styptic_powder = 10)
/obj/item/stack/medical/bruise_pack/one
amount = 1
/obj/item/stack/medical/bruise_pack/heal(mob/living/M, mob/user)
if(M.stat == DEAD)
to_chat(user, "<span class='notice'> [M] is dead. You can not help [M.p_them()]!</span>")
@@ -134,6 +137,9 @@
singular_name = "sterilized medical gauze"
self_delay = 5
/obj/item/stack/medical/gauze/adv/one
amount = 1
/obj/item/stack/medical/gauze/cyborg
custom_materials = null
is_cyborg = 1
@@ -151,6 +157,9 @@
self_delay = 20
grind_results = list(/datum/reagent/medicine/silver_sulfadiazine = 10)
/obj/item/stack/medical/ointment/one
amount = 1
/obj/item/stack/medical/ointment/heal(mob/living/M, mob/user)
if(M.stat == DEAD)
to_chat(user, "<span class='notice'> [M] is dead. You can not help [M.p_them()]!</span>")
+1 -4
View File
@@ -170,7 +170,7 @@
return disarming || (user.a_intent != INTENT_HARM)
/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/user, disarming = FALSE)
if(L.run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user) & BLOCK_SUCCESS) //No message; check_shields() handles that
if(L.mob_run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user, null, null) & BLOCK_SUCCESS) //No message; check_shields() handles that
playsound(L, 'sound/weapons/genhit.ogg', 50, 1)
return FALSE
var/stunpwr = stamforce
@@ -232,11 +232,8 @@
/obj/item/melee/baton/stunsword
name = "stunsword"
desc = "not actually sharp, this sword is functionally identical to a stunbaton"
icon = 'modular_citadel/icons/obj/stunsword.dmi'
icon_state = "stunsword"
item_state = "sword"
lefthand_file = 'modular_citadel/icons/mob/inhands/stunsword_left.dmi'
righthand_file = 'modular_citadel/icons/mob/inhands/stunsword_right.dmi'
/obj/item/melee/baton/stunsword/get_belt_overlay()
if(istype(loc, /obj/item/storage/belt/sabre))
+1 -1
View File
@@ -1182,7 +1182,7 @@
if(iscyborg(target))
..()
return
if(target.run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user) & BLOCK_SUCCESS) //No message; run_block() handles that
if(target.mob_run_block(src, 0, "[user]'s [name]", ATTACK_TYPE_MELEE, 0, user, null, null) & BLOCK_SUCCESS) //No message; run_block() handles that
playsound(target, 'sound/weapons/genhit.ogg', 50, 1)
return FALSE
if(user.a_intent != INTENT_HARM)
@@ -492,7 +492,7 @@
user.do_attack_animation(L)
if(L.run_block(src, 0, "[user]'s [src]", ATTACK_TYPE_MELEE, 0, user, check_zone(user.zone_selected)) & BLOCK_SUCCESS)
if(L.mob_run_block(src, 0, "[user]'s [src]", ATTACK_TYPE_MELEE, 0, user, check_zone(user.zone_selected), null) & BLOCK_SUCCESS)
playsound(L, 'sound/weapons/genhit.ogg', 50, TRUE)
return FALSE
@@ -10,9 +10,9 @@
/obj/item/organ/heart/gland/trauma/activate()
to_chat(owner, "<span class='warning'>You feel a spike of pain in your head.</span>")
if(prob(33))
owner.gain_trauma_type(BRAIN_TRAUMA_SPECIAL, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_LOBOTOMY))
owner.gain_trauma_type(BRAIN_TRAUMA_SPECIAL, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_SURGERY))
else
if(prob(20))
owner.gain_trauma_type(BRAIN_TRAUMA_SEVERE, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_LOBOTOMY))
owner.gain_trauma_type(BRAIN_TRAUMA_SEVERE, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_SURGERY))
else
owner.gain_trauma_type(BRAIN_TRAUMA_MILD, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_LOBOTOMY))
owner.gain_trauma_type(BRAIN_TRAUMA_MILD, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_SURGERY))
@@ -13,5 +13,5 @@
//Recover from stuns.
/obj/effect/proc_holder/changeling/adrenaline/sting_action(mob/living/user)
user.do_adrenaline(0, FALSE, 70, 0, TRUE, list(/datum/reagent/medicine/epinephrine = 3, /datum/reagent/drug/methamphetamine/changeling = 10, /datum/reagent/medicine/mannitol = 10, /datum/reagent/medicine/regen_jelly = 10, /datum/reagent/medicine/changelingadrenaline = 5), "<span class='notice'>Energy rushes through us.</span>", 0, 0.75, 0)
return TRUE
user.do_adrenaline(0, FALSE, 70, 0, TRUE, list(/datum/reagent/medicine/epinephrine = 3, /datum/reagent/drug/methamphetamine/changeling = 10, /datum/reagent/medicine/changelingadrenaline = 5), "<span class='notice'>Energy rushes through us.</span>", 0, 0.75, 0)
return TRUE
@@ -27,12 +27,12 @@
var/obj/item/organ/eyes/E = user.getorganslot(ORGAN_SLOT_EYES)
if(E)
if(!active)
E.sight_flags |= SEE_MOBS | SEE_OBJS | SEE_TURFS //Add sight flags to the user's eyes
ADD_TRAIT(user, TRAIT_THERMAL_VISION, CHANGELING_TRAIT)
E.flash_protect = -1 //Adjust the user's eyes' flash protection
to_chat(user, "We adjust our eyes to sense prey through walls.")
active = TRUE //Defined in code/modules/spells/spell.dm
else
E.sight_flags ^= SEE_MOBS | SEE_OBJS | SEE_TURFS //Remove sight flags from the user's eyes
REMOVE_TRAIT(user, TRAIT_THERMAL_VISION, CHANGELING_TRAIT)
E.flash_protect = 2 //Adjust the user's eyes' flash protection
to_chat(user, "We adjust our eyes to protect them from bright lights.")
active = FALSE
@@ -47,10 +47,8 @@
/obj/effect/proc_holder/changeling/augmented_eyesight/on_refund(mob/user) //Get rid of X-ray vision and flash protection when the user refunds this ability
action.Remove(user)
REMOVE_TRAIT(user, TRAIT_THERMAL_VISION, CHANGELING_TRAIT)
var/obj/item/organ/eyes/E = user.getorganslot(ORGAN_SLOT_EYES)
if(E)
if (active)
E.sight_flags ^= SEE_MOBS | SEE_OBJS | SEE_TURFS
else
E.flash_protect = 0
user.update_sight()
E.flash_protect = initial(E.flash_protect)
user.update_sight()
@@ -2,7 +2,7 @@
name = "Biodegrade"
desc = "Dissolves restraints or other objects preventing free movement."
helptext = "This is obvious to nearby people, and can destroy standard restraints and closets. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat."
chemical_cost = 30 //High cost to prevent spam
chemical_cost = 15 //High cost to prevent spam
loudness = 1
dna_cost = 2
req_human = 1
@@ -3,7 +3,6 @@
desc = "Our skin pigmentation rapidly changes to suit our current environment."
helptext = "Allows us to become invisible after a few seconds of standing still. Can be toggled on and off."
dna_cost = 2
chemical_cost = 25
req_human = 1
action_icon = 'icons/mob/actions/actions_changeling.dmi'
action_icon_state = "ling_camouflage"
@@ -23,4 +22,4 @@
action.Remove(user)
if(user.has_dna())
var/mob/living/carbon/C = user
C.dna.remove_mutation(CHAMELEON)
C.dna.remove_mutation(CHAMELEON)
@@ -1,8 +1,9 @@
/obj/effect/proc_holder/changeling/fleshmend
name = "Fleshmend"
desc = "Our flesh rapidly regenerates, healing our burns, bruises, and shortness of breath. Functions while unconscious."
desc = "Our flesh rapidly regenerates, healing our burns, bruises, and shortness of breath. Functions while unconscious. This ability is loud, and might cause our blood to react violently to heat."
helptext = "If we are on fire, the healing effect will not function. Does not regrow limbs or restore lost blood."
chemical_cost = 20
loudness = 2
dna_cost = 2
req_stat = UNCONSCIOUS
action_icon = 'icons/mob/actions/actions_changeling.dmi'
@@ -137,7 +137,7 @@
name = "Arm Blade"
desc = "We reform one of our arms into a deadly blade."
helptext = "We may retract our armblade in the same manner as we form it. Cannot be used while in lesser form. This ability is loud, and might cause our blood to react violently to heat."
chemical_cost = 20
chemical_cost = 10
dna_cost = 2
loudness = 2
req_human = 1
@@ -410,7 +410,7 @@
desc = "We reform one of our arms into a hard shield."
helptext = "Organic tissue cannot resist damage forever; the shield will break after it is hit too much. The more genomes we absorb, the stronger it is. Cannot be used while in lesser form. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat."
chemical_cost = 20
dna_cost = 1
dna_cost = 2
loudness = 1
req_human = 1
action_icon = 'icons/mob/actions/actions_changeling.dmi'
@@ -522,12 +522,12 @@
/obj/effect/proc_holder/changeling/suit/armor
name = "Chitinous Armor"
desc = "We turn our skin into tough chitin to protect us from damage."
helptext = "Upkeep of the armor requires a low expenditure of chemicals. The armor is strong against brute force, but does not provide much protection from lasers. Cannot be used in lesser form. This ability is loud, and might cause our blood to react violently to heat."
helptext = "Upkeep of the armor requires a constant expenditure of chemicals, resulting in a reduced chemical generation. The armor is strong against brute force, but does not provide much protection from lasers. Cannot be used in lesser form. This ability is loud, and might cause our blood to react violently to heat."
chemical_cost = 20
dna_cost = 1
loudness = 2
req_human = 1
recharge_slowdown = 0.25
recharge_slowdown = 0.5
action_icon = 'icons/mob/actions/actions_changeling.dmi'
action_icon_state = "ling_armor"
action_background_icon_state = "bg_ling"
@@ -543,7 +543,7 @@
icon_state = "lingarmor"
item_flags = DROPDEL
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 90, "acid" = 90)
armor = list("melee" = 70, "bullet" = 60, "laser" = 30, "energy" = 40, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 50, "acid" = 90)
flags_inv = HIDEJUMPSUIT
cold_protection = 0
heat_protection = 0
@@ -559,7 +559,7 @@
desc = "A tough, hard covering of black chitin with transparent chitin in front."
icon_state = "lingarmorhelmet"
item_flags = DROPDEL
armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 90, "acid" = 90)
armor = list("melee" = 70, "bullet" = 60, "laser" = 30, "energy" = 40, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 50, "acid" = 90)
flags_inv = HIDEEARS|HIDEHAIR|HIDEEYES|HIDEFACIALHAIR|HIDEFACE
/obj/item/clothing/head/helmet/changeling/Initialize()
@@ -3,7 +3,7 @@
desc = "Our lungs and vocal cords shift, allowing us to briefly emit a noise that deafens and confuses the weak-minded."
helptext = "Emits a high-frequency sound that confuses and deafens humans, blows out nearby lights and overloads cyborg sensors. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat."
chemical_cost = 20
dna_cost = 1
dna_cost = 2
loudness = 1
req_human = 1
action_icon = 'icons/mob/actions/actions_changeling.dmi'
@@ -37,7 +37,7 @@
desc = "We shift our vocal cords to release a high-frequency sound that overloads nearby electronics."
helptext = "Emits a high-frequency sound that overloads nearby electronics. This ability is somewhat loud, and carries a small risk of our blood gaining violent sensitivity to heat."
chemical_cost = 20
dna_cost = 1
dna_cost = 2
loudness = 1
action_icon = 'icons/mob/actions/actions_changeling.dmi'
action_icon_state = "ling_dissonant"
@@ -5,7 +5,6 @@
name = "Strained Muscles"
desc = "We evolve the ability to reduce the acid buildup in our muscles, allowing us to move much faster."
helptext = "The strain will make us tired, and we will rapidly become fatigued. Standard weight restrictions, like hardsuits, still apply. Cannot be used in lesser form."
chemical_cost = 15
dna_cost = 1
req_human = 1
var/stacks = 0 //Increments every 5 seconds; damage increases over time
@@ -15,16 +14,13 @@
action_background_icon_state = "bg_ling"
/obj/effect/proc_holder/changeling/strained_muscles/sting_action(mob/living/carbon/user)
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
active = !active
if(active)
to_chat(user, "<span class='notice'>Our muscles tense and strengthen.</span>")
changeling.chem_recharge_slowdown += 0.5
else
user.remove_movespeed_modifier(/datum/movespeed_modifier/strained_muscles)
to_chat(user, "<span class='notice'>Our muscles relax.</span>")
changeling.chem_recharge_slowdown -= 0.5
if(stacks >= 20)
if(stacks >= 10)
to_chat(user, "<span class='danger'>We collapse in exhaustion.</span>")
user.DefaultCombatKnockdown(60)
user.emote("gasp")
@@ -34,7 +30,6 @@
return TRUE
/obj/effect/proc_holder/changeling/strained_muscles/proc/muscle_loop(mob/living/carbon/user)
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
while(active)
user.add_movespeed_modifier(/datum/movespeed_modifier/strained_muscles)
if(user.stat != CONSCIOUS || user.staminaloss >= 90)
@@ -42,18 +37,17 @@
to_chat(user, "<span class='notice'>Our muscles relax without the energy to strengthen them.</span>")
user.DefaultCombatKnockdown(40)
user.remove_movespeed_modifier(/datum/movespeed_modifier/strained_muscles)
changeling.chem_recharge_slowdown -= 0.5
break
stacks++
//user.take_bodypart_damage(stacks * 0.03, 0)
user.adjustStaminaLoss(stacks*1.3) //At first the changeling may regenerate stamina fast enough to nullify fatigue, but it will stack
user.adjustStaminaLoss(stacks*1.5) //At first the changeling may regenerate stamina fast enough to nullify fatigue, but it will stack
if(stacks == 10) //Warning message that the stacks are getting too high
if(stacks == 5) //Warning message that the stacks are getting too high
to_chat(user, "<span class='warning'>Our legs are really starting to hurt...</span>")
sleep(40)
while(!active && stacks) //Damage stacks decrease fairly rapidly while not in sanic mode
while(!active && stacks) //Damage stacks decrease slowly while not in sanic mode
stacks--
sleep(20)
sleep(100)
@@ -9,7 +9,7 @@
//DICKS,COCKS,PENISES,WHATEVER YOU WANT TO CALL THEM
/datum/sprite_accessory/penis
icon = 'modular_citadel/icons/obj/genitals/penis_onmob.dmi'
icon = 'icons/obj/genitals/penis_onmob.dmi'
name = "penis" //the preview name of the accessory
color_src = "cock_color"
alt_aroused = TRUE
@@ -22,13 +22,13 @@
/datum/sprite_accessory/penis/knotted
icon_state = "knotted"
name = "Knotted"
taur_icon = 'modular_citadel/icons/obj/genitals/taur_penis_onmob.dmi'
taur_icon = 'icons/obj/genitals/taur_penis_onmob.dmi'
taur_dimension_x = 64
/datum/sprite_accessory/penis/flared
icon_state = "flared"
name = "Flared"
taur_icon = 'modular_citadel/icons/obj/genitals/taur_penis_onmob.dmi'
taur_icon = 'icons/obj/genitals/taur_penis_onmob.dmi'
taur_dimension_x = 64
/datum/sprite_accessory/penis/barbknot
@@ -38,7 +38,7 @@
/datum/sprite_accessory/penis/tapered
icon_state = "tapered"
name = "Tapered"
taur_icon = 'modular_citadel/icons/obj/genitals/taur_penis_onmob.dmi'
taur_icon = 'icons/obj/genitals/taur_penis_onmob.dmi'
taur_dimension_x = 64
/datum/sprite_accessory/penis/tentacle
@@ -55,7 +55,7 @@
//Testicles
/datum/sprite_accessory/testicles
icon = 'modular_citadel/icons/obj/genitals/testicles_onmob.dmi'
icon = 'icons/obj/genitals/testicles_onmob.dmi'
icon_state = "testicle"
name = "testicle" //the preview name of the accessory
color_src = "balls_color"
@@ -66,7 +66,7 @@
//Vaginas
/datum/sprite_accessory/vagina
icon = 'modular_citadel/icons/obj/genitals/vagina_onmob.dmi'
icon = 'icons/obj/genitals/vagina_onmob.dmi'
name = "vagina"
color_src = "vag_color"
alt_aroused = TRUE
@@ -104,7 +104,7 @@
//BREASTS BE HERE
/datum/sprite_accessory/breasts
icon = 'modular_citadel/icons/obj/genitals/breasts_onmob.dmi'
icon = 'icons/obj/genitals/breasts_onmob.dmi'
name = "breasts"
color_src = "breasts_color"
@@ -5,7 +5,7 @@
name = "breasts"
desc = "Female milk producing organs."
icon_state = "breasts"
icon = 'modular_citadel/icons/obj/genitals/breasts.dmi'
icon = 'icons/obj/genitals/breasts.dmi'
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_BREASTS
size = BREASTS_SIZE_DEF // "c". Refer to the breast_values static list below for the cups associated number values
@@ -2,7 +2,7 @@
name = "penis"
desc = "A male reproductive organ."
icon_state = "penis"
icon = 'modular_citadel/icons/obj/genitals/penis.dmi'
icon = 'icons/obj/genitals/penis.dmi'
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_PENIS
masturbation_verb = "stroke"
@@ -2,7 +2,7 @@
name = "testicles"
desc = "A male reproductive organ."
icon_state = "testicles"
icon = 'modular_citadel/icons/obj/genitals/testicles.dmi'
icon = 'icons/obj/genitals/testicles.dmi'
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_TESTICLES
size = BALLS_SIZE_MIN
@@ -1,7 +1,7 @@
/obj/item/organ/genital/vagina
name = "vagina"
desc = "A female reproductive organ."
icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
icon = 'icons/obj/genitals/vagina.dmi'
icon_state = ORGAN_SLOT_VAGINA
zone = BODY_ZONE_PRECISE_GROIN
slot = "vagina"
@@ -1,7 +1,7 @@
/obj/item/organ/genital/womb
name = "womb"
desc = "A female reproductive organ."
icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
icon = 'icons/obj/genitals/vagina.dmi'
icon_state = "womb"
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_WOMB
@@ -4,7 +4,7 @@
/obj/item/dildo
name = "dildo"
desc = "Floppy!"
icon = 'modular_citadel/icons/obj/genitals/dildo.dmi'
icon = 'icons/obj/genitals/dildo.dmi'
force = 0
hitsound = 'sound/weapons/tap.ogg'
throwforce = 0
@@ -42,6 +42,7 @@
desc = "You put the cake on your head. Brilliant."
icon_state = "hardhat0_cakehat"
item_state = "hardhat0_cakehat"
hat_type = "cakehat"
hitsound = 'sound/weapons/tap.ogg'
flags_inv = HIDEEARS|HIDEHAIR
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
@@ -57,7 +57,6 @@
/obj/item/reagent_containers/food/snacks/sushi_basic
name = "funa hosomaki"
desc = "A small cylindrical kudzu skin, filled with rice and fish."
icon = 'modular_citadel/icons/obj/food/food.dmi'
icon_state = "sushie_basic"
bonus_reagents = list(/datum/reagent/consumable/nutriment/vitamin = 2)
list_reagents = list(/datum/reagent/consumable/nutriment = 4)
@@ -69,7 +68,6 @@
/obj/item/reagent_containers/food/snacks/sushi_adv
name = "funa nigiri"
desc = "A peace of carp lightly placed on some rice."
icon = 'modular_citadel/icons/obj/food/food.dmi'
icon_state = "sushie_adv"
bonus_reagents = list(/datum/reagent/consumable/nutriment/vitamin = 2)
list_reagents = list(/datum/reagent/consumable/nutriment = 6)
@@ -81,7 +79,6 @@
/obj/item/reagent_containers/food/snacks/sushi_pro
name = "funa nigiri"
desc = "A well prepared peace of the best of the carp fillet placed on rice. Looks fancy and fresh!"
icon = 'modular_citadel/icons/obj/food/food.dmi'
icon_state = "sushie_pro"
bonus_reagents = list(/datum/reagent/consumable/nutriment = 2, /datum/reagent/consumable/nutriment/vitamin = 2)
list_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/vitamin = 2)
@@ -215,7 +215,6 @@
/obj/item/reagent_containers/food/snacks/tobiko
name = "tobiko"
desc = "Spider eggs wrapped in a thin salted Kudzu pod"
icon = 'modular_citadel/icons/obj/food/food.dmi'
icon_state = "sushie_egg"
list_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/nutriment/vitamin = 2)
filling_color = "#FF3333" // R225 G051 B051
@@ -558,7 +557,6 @@
/obj/item/reagent_containers/food/snacks/riceball
name = "onigiri"
desc = "A ball of rice with some light salt and a wrap of Kudzu skin."
icon = 'modular_citadel/icons/obj/food/food.dmi'
icon_state = "riceball"
list_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/sodiumchloride = 2)
tastes = list("rice" = 3, "salt" = 1)
@@ -136,7 +136,6 @@
/obj/item/reagent_containers/food/snacks/tuna_sandwich
name = "tuna sandwich"
desc = "Both a salad and a sandwich in one."
icon = 'modular_citadel/icons/obj/food/food.dmi'
icon_state = "tunasandwich"
trash = /obj/item/trash/plate
bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 3)
@@ -3,7 +3,6 @@
/obj/item/reagent_containers/food/snacks/sushi_rice
name = "Sushi Rice"
desc = "A bowl of sticky rice for making sushi."
icon = 'modular_citadel/icons/obj/food/food.dmi'
icon_state = "sushi_rice"
list_reagents = list(/datum/reagent/consumable/sodiumchloride = 5)
tastes = list("rice" = 5, "salt" = 1)
@@ -12,7 +11,6 @@
/obj/item/reagent_containers/food/snacks/sea_weed
name = "Sea Weed Sheet"
desc = "A thin, light salt sheet of plant mater. This is commenly used in sushi recipes,"
icon = 'modular_citadel/icons/obj/food/food.dmi'
icon_state = "sea_weed"
list_reagents = list(/datum/reagent/consumable/sodiumchloride = 2)
tastes = list("plants" = 2, "salt" = 1)
@@ -21,7 +19,6 @@
/obj/item/reagent_containers/food/snacks/tuna
name = "Canned Tuna"
desc = "A small can of tuna fish beloved by felines."
icon = 'modular_citadel/icons/obj/food/food.dmi'
icon_state = "tuna_can"
//trash = /obj/item/trash/tuna_used //I dont know if I like this idea - A Masked Cat
list_reagents = list(/datum/reagent/consumable/sodiumchloride = 5, /datum/reagent/mercury = 2)
@@ -32,7 +29,6 @@
/obj/item/reagent_containers/food/snacks/sushie_basic
name = "Funa Hosomaki"
desc = "A small cylindrical filled with rice and fish."
icon = 'modular_citadel/icons/obj/food/food.dmi'
icon_state = "sushie_basic"
bonus_reagents = list(/datum/reagent/consumable/nutriment/vitamin = 2)
list_reagents = list(/datum/reagent/consumable/nutriment = 1)
@@ -44,7 +40,6 @@
/obj/item/reagent_containers/food/snacks/sushie_adv
name = "Funa Nigiri"
desc = "A pice of carp lightly placed on some rice."
icon = 'modular_citadel/icons/obj/food/food.dmi'
icon_state = "sushie_adv"
bonus_reagents = list(/datum/reagent/consumable/nutriment/vitamin = 2)
list_reagents = list(/datum/reagent/consumable/nutriment = 2)
@@ -56,7 +51,6 @@
/obj/item/reagent_containers/food/snacks/sushie_pro
name = "Funa Nigiri"
desc = "A well prepared pice of the best of the carp fillet placed on rice. Looks fancy and fresh!"
icon = 'modular_citadel/icons/obj/food/food.dmi'
icon_state = "sushie_pro"
bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 2)
list_reagents = list(/datum/reagent/consumable/nutriment = 8, /datum/reagent/consumable/nutriment/vitamin = 1)
@@ -68,7 +62,6 @@
/obj/item/reagent_containers/food/snacks/tobiko
name = "Tobiko"
desc = "Spider eggs wrapped in a thin salted Kudzu pod"
icon = 'modular_citadel/icons/obj/food/food.dmi'
icon_state = "sushie_egg"
list_reagents = list(/datum/reagent/consumable/nutriment = 3, /datum/reagent/consumable/nutriment/vitamin = 2)
filling_color = "#FF3333" // R225 G051 B051
@@ -78,7 +71,6 @@
/obj/item/reagent_containers/food/snacks/riceball
name = "Onigiri"
desc = "A ball of rice with some light salt and a wrap of Kudzu skin."
icon = 'modular_citadel/icons/obj/food/food.dmi'
icon_state = "riceball"
list_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/sodiumchloride = 2)
tastes = list("rice" = 4, "salt" = 1)
@@ -66,6 +66,11 @@
/obj/item/instrument/proc/is_tuned()
return tune_time_left > 0
/obj/item/instrument/dropped(mob/user)
. = ..()
if((loc != user) && (user.machine == src))
user.set_machine(null)
/obj/item/instrument/interact(mob/user)
ui_interact(user)
+11 -5
View File
@@ -222,7 +222,9 @@
tempo = sanitize_tempo(600 / bpm)
/// Updates the window for our user. Override in subtypes.
/datum/song/proc/updateDialog(mob/user)
/datum/song/proc/updateDialog(mob/user = usr)
if(user.machine != src)
return
ui_interact(user)
/datum/song/process(wait)
@@ -277,8 +279,10 @@
// subtype for handheld instruments, like violin
/datum/song/handheld
/datum/song/handheld/updateDialog(mob/user)
parent.ui_interact(user || usr)
/datum/song/handheld/updateDialog(mob/user = usr)
if(user.machine != src)
return
parent.ui_interact(user)
/datum/song/handheld/should_stop_playing(mob/user)
. = ..()
@@ -290,8 +294,10 @@
// subtype for stationary structures, like pianos
/datum/song/stationary
/datum/song/stationary/updateDialog(mob/user)
parent.ui_interact(user || usr)
/datum/song/stationary/updateDialog(mob/user = usr)
if(user.machine != src)
return
parent.ui_interact(user)
/datum/song/stationary/should_stop_playing(mob/user)
. = ..()
+73 -43
View File
@@ -1,6 +1,12 @@
///////////////////////////////////////////////////////////////
//SS13 Optimized Map loader
//////////////////////////////////////////////////////////////
/*
* Notes:
* This does NOT support map files where more than one Z is in each grid set, as defined in the file.
* MultiZ map files ARE supported (however very much discouraged), as long as each gridset only contains one z.
* This assumes that for the most part, map files are properly formed, either DMM or TGM standard formats. If you feed it bad data, expect to crash.
*/
#define SPACE_KEY "space"
/datum/grid_set
@@ -9,6 +15,12 @@
var/zcrd
var/gridLines
/datum/grid_set/proc/height(key_len)
return length(gridLines)
/datum/grid_set/proc/width(key_len)
return gridLines[1] / key_len
/datum/parsed_map
var/original_path
var/key_len = 0
@@ -43,7 +55,7 @@
/// - `cropMap`: When true, the map will be cropped to fit the existing world dimensions (Optional).
/// - `measureOnly`: When true, no changes will be made to the world (Optional).
/// - `no_changeturf`: When true, [turf/AfterChange] won't be called on loaded turfs
/// - `x_lower`, `x_upper`, `y_lower`, `y_upper`: Coordinates (relative to the map) to crop to (Optional).
/// - `x_lower`, `x_upper`, `y_lower`, `y_upper`: Coordinates (relative to the game world) to crop to (Optional).
/// - `placeOnTop`: Whether to use [turf/PlaceOnTop] rather than [turf/ChangeTurf] (Optional).
/proc/load_map(
dmm_file as file,
@@ -60,25 +72,37 @@
placeOnTop = FALSE as num,
orientation = SOUTH as num,
annihilate_tiles = FALSE,
z_lower = -INFINITY as num,
z_upper = INFINITY as num
crop_relative_to_game_world = TRUE
)
var/datum/parsed_map/parsed = new(dmm_file, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, measureOnly)
var/datum/parsed_map/parsed = new(dmm_file, measureOnly = measureOnly)
if(parsed.bounds && !measureOnly)
parsed.load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, orientation, annihilate_tiles)
return parsed
/// Parse a map, possibly cropping it.
//WHY THE HECK DO WE EVEN SUPPORT NEGATIVE COORDINATES, ALL IT IS IS A WASTE OF TIME AND CPU!!!???
//DO NOT USE THIS TO TRIM MAPS UNLESS STRICTLY NEEDED! IT IS EXTREMELY EXPENSIVE TO DO SO!
/**
* Parse a map, possibly cropping it.
* Do not use the crop function unless strictly necessary.
* WARNING: Crop function crops based on the tiles you'd see in the map editor. If you're planning to load it in in a different orientation later, you better have done the math.
* It's recommended that you do not crop using this at all.
*/
/datum/parsed_map/New(tfile, x_lower = -INFINITY, x_upper = INFINITY, y_lower = -INFINITY, y_upper = INFINITY, z_lower = -INFINITY, z_upper = INFINITY, measureOnly = FALSE)
_parse(tfile, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, measureOnly)
/datum/parsed_map/proc/_parse(tfile, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, measureOnly)
var/static/parsing = FALSE
UNTIL(!parsing)
// do not multithread this or bad things happen
parsing = TRUE
_do_parse(tfile, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, measureOnly)
parsing = FALSE
/datum/parsed_map/proc/_do_parse(tfile, x_lower, x_upper, y_lower, y_upper, z_lower, z_upper, measureOnly)
if(isfile(tfile))
original_path = "[tfile]"
tfile = file2text(tfile)
else if(isnull(tfile))
// create a new datum without loading a map
return
bounds = parsed_bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF)
ASSERT(x_upper >= x_lower)
ASSERT(y_upper >= y_lower)
@@ -107,12 +131,13 @@
if(!key_len)
CRASH("Coords before model definition in DMM")
// NOTE: We are assuming each coordset only contains one z.
var/curr_z = text2num(dmmRegex.group[5])
if(curr_z < z_lower || curr_z > z_upper)
continue
var/curr_x = text2num(dmmRegex.group[3])
var/curr_y = text2num(dmmRegex.group[4])
var/curr_z = text2num(dmmRegex.group[5])
if(curr_x < x_lower || curr_y < y_lower || curr_z < z_lower || curr_z > z_upper)
continue
var/datum/grid_set/gridSet = new
@@ -120,12 +145,6 @@
gridSet.ycrd = curr_y
gridSet.zcrd = curr_z
bounds[MAP_MINX] = min(bounds[MAP_MINX], curr_x) //since down is up for y/gridlines, we now know the lower left corner.
bounds[MAP_MINY] = min(bounds[MAP_MINY], curr_y)
bounds[MAP_MINZ] = min(bounds[MAP_MINZ], curr_z)
bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], curr_z) //we know max z now
var/list/gridLines = splittext(dmmRegex.group[6], "\n")
gridSet.gridLines = gridLines
@@ -134,31 +153,36 @@
if(leadingBlanks > 1)
gridLines.Cut(1, leadingBlanks) // Remove all leading blank lines.
gridSets += gridSet
var/lines = length(gridLines)
if(lines)
if(gridLines[gridLines.len] == "")
gridLines.Cut(gridLines.len) // Remove only one blank line at the end.
var/right_length = y_upper - curr_y + 1
if(lines > right_length)
gridLines.len = right_length //this can't be negative due to our ASSERTions above, hopefully.
if(!gridLines.len) // Skip it if there's no content.
if(lines && gridLines[lines] == "")
// remove one trailing blank line
gridLines.len--
lines--
// y crop
var/right_length = y_upper - curr_y + 1
if(lines > right_length)
lines = gridLines.len = right_length
if(!lines) // blank
continue
//do not use curr_y after this point, ycrd has changed. use it before because local var.
gridSet.ycrd += gridLines.len - 1 // Start at the top and work down
bounds[MAP_MAXY] = max(bounds[MAP_MAXY], gridSet.ycrd) //we know max y now
var/width = length(gridLines[1]) / key_len
// x crop
var/right_width = x_upper - curr_x + 1
if(width > right_width)
for(var/i in 1 to lines)
gridLines[i] = copytext(gridLines[i], 1, key_len * right_width)
// during the actual load we're starting at the top and working our way down
gridSet.ycrd += lines - 1
var/linelength = length(gridLines[1]) //yes it only samples the first line, this is why you use TGM instead of DMM!
var/xlength = linelength / key_len
var/maxx = gridSet.xcrd + xlength - 1
if(maxx > x_upper)
for(var/i in 1 to length(gridLines))
gridLines[i] = copytext(gridLines[i], 1, key_len * (x_upper - curr_x + 1))
bounds[MAP_MAXX] = max(bounds[MAP_MAXX], maxx)
// Safe to proceed, commit gridset to list and record coords.
gridSets += gridSet
bounds[MAP_MINX] = min(bounds[MAP_MINX], curr_x)
bounds[MAP_MAXX] = max(bounds[MAP_MAXX], curr_x + width - 1)
bounds[MAP_MINY] = min(bounds[MAP_MINY], curr_y)
bounds[MAP_MAXY] = max(bounds[MAP_MAXY], curr_y + lines - 1)
bounds[MAP_MINZ] = min(bounds[MAP_MINZ], curr_z)
bounds[MAP_MAXZ] = max(bounds[MAP_MAXZ], curr_z)
CHECK_TICK
// Indicate failure to parse any coordinates by nulling bounds
@@ -172,7 +196,8 @@
/datum/parsed_map/Destroy()
if(template_host && template_host.cached_map == src)
template_host.cached_map = null
return ..()
. = ..()
return QDEL_HINT_HARDDEL_NOW
/// Load the parsed map into the world. See [/proc/load_map] for arguments.
/datum/parsed_map/proc/load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop, orientation, annihilate_tiles, datum/map_orientation_pattern/forced_pattern)
@@ -197,6 +222,8 @@
var/yi = mode.yi
var/turn_angle = round(SIMPLIFY_DEGREES(mode.turn_angle), 90)
var/delta_swap = x_offset - y_offset
// less checks later
var/do_crop = x_lower > -INFINITY || x_upper < INFINITY || y_lower > -INFINITY || y_upper < INFINITY
for(var/__I in gridSets)
var/datum/grid_set/gridset = __I
@@ -221,6 +248,8 @@
for(var/pos = 1 to (length(line) - key_len + 1) step key_len)
var/placement_x = swap_xy? (actual_y + delta_swap) : actual_x
var/placement_y = swap_xy? (actual_x - delta_swap) : actual_y
if(do_crop && ((placement_x < x_lower) || (placement_x > x_upper) || (placement_y < y_lower) || (placement_y > y_upper)))
continue
if(placement_x > world.maxx)
if(cropMap)
actual_x += xi
@@ -532,6 +561,7 @@
// fallback: string
return text
/datum/parsed_map/Destroy()
..()
return QDEL_HINT_HARDDEL_NOW
/datum/parsed_map/vv_edit_var(var_name, var_value)
if(var_name == NAMEOF(src, dmmRegex) || var_name == NAMEOF(src, trimQuotesRegex) || var_name == NAMEOF(src, trimRegex))
return FALSE
return ..()
+1
View File
@@ -53,6 +53,7 @@
new /datum/data/mining_equipment("Spare Suit Voucher", /obj/item/suit_voucher, 2000),
new /datum/data/mining_equipment("Super Resonator", /obj/item/resonator/upgraded, 2500),
new /datum/data/mining_equipment("Jump Boots", /obj/item/clothing/shoes/bhop, 2500),
new /datum/data/mining_equipment("Ice hiking boots", /obj/item/clothing/shoes/winterboots/ice_boots, 2500),
new /datum/data/mining_equipment("Luxury Shelter Capsule", /obj/item/survivalcapsule/luxury, 3000),
new /datum/data/mining_equipment("Luxury Bar Capsule", /obj/item/survivalcapsule/luxuryelite, 10000),
new /datum/data/mining_equipment("Nanotrasen Minebot", /mob/living/simple_animal/hostile/mining_drone, 800),
@@ -66,7 +66,7 @@
if(hit_atom)
if(isliving(hit_atom))
var/mob/living/L = hit_atom
if(L.run_block(src, 0, "the [name]", ATTACK_TYPE_TACKLE, 0, src) & BLOCK_SUCCESS)
if(L.mob_run_block(src, 0, "the [name]", ATTACK_TYPE_TACKLE, 0, src, null, null) & BLOCK_SUCCESS)
DefaultCombatKnockdown(40, 1, 1)
else
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
@@ -85,7 +85,7 @@
if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
totitemdamage *= 1.5
var/impacting_zone = (user == src)? check_zone(user.zone_selected) : ran_zone(user.zone_selected)
if((user != src) && (run_block(I, totitemdamage, "the [I]", ATTACK_TYPE_MELEE, I.armour_penetration, user, impacting_zone) & BLOCK_SUCCESS))
if((user != src) && (mob_run_block(I, totitemdamage, "the [I]", ATTACK_TYPE_MELEE, I.armour_penetration, user, impacting_zone, null) & BLOCK_SUCCESS))
return FALSE
var/obj/item/bodypart/affecting = get_bodypart(impacting_zone)
if(!affecting) //missing limb? we select the first bodypart (you can never have zero, because of chest)
@@ -273,7 +273,7 @@
if(health >= 0 && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
var/friendly_check = FALSE
if(run_block(M, 0, M.name, ATTACK_TYPE_UNARMED))
if(mob_run_block(M, 0, M.name, ATTACK_TYPE_UNARMED, 0, null, null, null))
return
if(lying)
if(buckled)
@@ -43,5 +43,6 @@ GLOBAL_LIST_EMPTY(dummy_mob_list)
return
var/mob/living/carbon/human/dummy/D = GLOB.human_dummy_list[slotnumber]
if(istype(D))
D.set_species(/datum/species/human,icon_update = TRUE, pref_load = TRUE) //for some fucking reason, if you don't change the species every time, some species will dafault certain things when it's their own species on the mannequin two times in a row, like lizards losing spines and tails setting to smooth. If you can find a fix for this that isn't this, good on you
D.wipe_state()
D.in_use = FALSE
@@ -1536,9 +1536,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(IS_STAMCRIT(user))
to_chat(user, "<span class='warning'>You're too exhausted!</span>")
return FALSE
else if(target.check_block())
target.visible_message("<span class='warning'>[target] blocks [user]'s disarm attempt!</span>")
return FALSE
else if(aim_for_mouth && ( target_on_help || target_restrained || target_aiming_for_mouth))
playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1)
@@ -1671,7 +1668,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/totitemdamage = H.pre_attacked_by(I, user)
// Allows you to put in item-specific reactions based on species
if(user != H)
if(H.run_block(I, totitemdamage, "the [I.name]", ATTACK_TYPE_MELEE, I.armour_penetration, user, affecting.body_zone) & BLOCK_SUCCESS)
if(H.mob_run_block(I, totitemdamage, "the [I.name]", ATTACK_TYPE_MELEE, I.armour_penetration, user, affecting.body_zone, null) & BLOCK_SUCCESS)
return 0
if(H.check_martial_melee_block())
H.visible_message("<span class='warning'>[H] blocks [I]!</span>")
@@ -1779,7 +1776,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
return TRUE
if(M.mind)
attacker_style = M.mind.martial_art
if((M != H) && M.a_intent != INTENT_HELP && (H.run_block(M, 0, "[M]", ATTACK_TYPE_UNARMED, 0, M, M.zone_selected) & BLOCK_SUCCESS))
if((M != H) && M.a_intent != INTENT_HELP && (H.mob_run_block(M, 0, "[M]", ATTACK_TYPE_UNARMED, 0, M, M.zone_selected, null) & BLOCK_SUCCESS))
log_combat(M, H, "attempted to touch")
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>")
return TRUE
+5 -10
View File
@@ -1,7 +1,10 @@
// This file has a weird name, but it's for anything related to the checks for shields, blocking, dodging, and similar "stop this attack before it actually impacts the target" as opposed to "defend once it has hit".
// This file has a weird name, but it's for anything related to the checks for shields, blocking, dodging,
// and similar "stop this attack before it actually impacts the target" as opposed to "defend once it has hit".
/*
/// Bitflags for check_block() and handle_block(). Meant to be combined. You can be hit and still reflect, for example, if you do not use BLOCK_SUCCESS.
/// You can find the mob_check_block() and mob_run_block() macros in __DEFINES/combat.dm
/// Bitflags for check_block() and run_block(). Meant to be combined. You can be hit and still reflect, for example, if you do not use BLOCK_SUCCESS.
/// Attack was not blocked
#define BLOCK_NONE NONE
/// Attack was blocked, do not do damage. THIS FLAG MUST BE THERE FOR DAMAGE/EFFECT PREVENTION!
@@ -23,14 +26,6 @@
#define BLOCK_TARGET_DODGED (1<<7)
*/
///Check whether or not we can block, without "triggering" a block. Basically run checks without effects like depleting shields. Wrapper for do_run_block(). The arguments on that means the same as for this.
/mob/living/proc/check_block(atom/object, damage, attack_text = "the attack", attack_type, armour_penetration, mob/attacker, def_zone, list/return_list)
return do_run_block(FALSE, object, damage, attack_text, attack_type, armour_penetration, attacker, check_zone(def_zone), return_list)
/// Runs a block "sequence", effectively checking and then doing effects if necessary. Wrapper for do_run_block(). The arguments on that means the same as for this.
/mob/living/proc/run_block(atom/object, damage, attack_text = "the attack", attack_type, armour_penetration, mob/attacker, def_zone, list/return_list)
return do_run_block(TRUE, object, damage, attack_text, attack_type, armour_penetration, attacker, check_zone(def_zone), return_list)
/** The actual proc for block checks. DO NOT USE THIS DIRECTLY UNLESS YOU HAVE VERY GOOD REASON TO. To reduce copypaste for differences between handling for real attacks and virtual checks.
* Automatically checks all held items for /obj/item/proc/run_block() with the same parameters.
* @params
+6 -1
View File
@@ -17,7 +17,7 @@
update_combat_mode_icon()
/mob/living/proc/disable_combat_mode(silent = TRUE, was_forced = FALSE, visible = FALSE, update_icon = TRUE)
if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) || (combat_flags & COMBAT_FLAG_COMBAT_FORCED))
return
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_ACTIVE)
SEND_SIGNAL(src, COMSIG_LIVING_COMBAT_DISABLED, was_forced)
@@ -60,6 +60,8 @@
/mob/living/proc/disable_intentional_combat_mode(silent = TRUE, visible = FALSE)
if(!(combat_flags & COMBAT_FLAG_COMBAT_TOGGLED) && !(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
return
if(combat_flags & COMBAT_FLAG_COMBAT_FORCED)
return
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_TOGGLED)
if(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)
disable_combat_mode(silent, FALSE, visible, FALSE)
@@ -71,6 +73,9 @@
/mob/living/proc/user_toggle_intentional_combat_mode(visible = TRUE)
var/old = (combat_flags & COMBAT_FLAG_COMBAT_TOGGLED)
if(old)
if(combat_flags & COMBAT_FLAG_COMBAT_FORCED)
to_chat(src, "<span class='warning'>You are unable to relax your muscles.</span>")
return
disable_intentional_combat_mode()
playsound_local(src, 'sound/misc/ui_toggleoff.ogg', 50, FALSE, pressure_affected = FALSE) //Slightly modified version of the above!
else if(CAN_TOGGLE_COMBAT_MODE(src))
+9 -9
View File
@@ -68,7 +68,7 @@
/mob/living/bullet_act(obj/item/projectile/P, def_zone)
if(P.original != src || P.firer != src) //try to block or reflect the bullet, can't do so when shooting oneself
var/list/returnlist = list()
var/returned = run_block(P, P.damage, "the [P.name]", ATTACK_TYPE_PROJECTILE, P.armour_penetration, P.firer, def_zone, returnlist)
var/returned = mob_run_block(P, P.damage, "the [P.name]", ATTACK_TYPE_PROJECTILE, P.armour_penetration, P.firer, def_zone, returnlist)
if(returned & BLOCK_SHOULD_REDIRECT)
handle_projectile_attack_redirection(P, returnlist[BLOCK_RETURN_REDIRECT_METHOD])
if(returned & BLOCK_REDIRECTED)
@@ -111,7 +111,7 @@
I = AM
throwpower = I.throwforce
var/impacting_zone = ran_zone(BODY_ZONE_CHEST, 65)//Hits a random part of the body, geared towards the chest
if(run_block(AM, throwpower, "\the [AM.name]", ATTACK_TYPE_THROWN, 0, throwingdatum?.thrower, impacting_zone) & BLOCK_SUCCESS)
if(mob_run_block(AM, throwpower, "\the [AM.name]", ATTACK_TYPE_THROWN, 0, throwingdatum?.thrower, impacting_zone, null) & BLOCK_SUCCESS)
hitpush = FALSE
skipcatch = TRUE
blocked = TRUE
@@ -270,7 +270,7 @@
/mob/living/attack_hand(mob/user)
..() //Ignoring parent return value here.
SEND_SIGNAL(src, COMSIG_MOB_ATTACK_HAND, user)
if((user != src) && user.a_intent != INTENT_HELP && (run_block(user, 0, user.name, ATTACK_TYPE_UNARMED | ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected)) & BLOCK_SUCCESS))
if((user != src) && user.a_intent != INTENT_HELP && (mob_run_block(user, 0, user.name, ATTACK_TYPE_UNARMED | ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected), null) & BLOCK_SUCCESS))
log_combat(user, src, "attempted to touch")
visible_message("<span class='warning'>[user] attempted to touch [src]!</span>")
return TRUE
@@ -281,7 +281,7 @@
to_chat(user, "<span class='notice'>You don't want to hurt [src]!</span>")
return TRUE
var/hulk_verb = pick("smash","pummel")
if(user != src && (run_block(user, 15, "the [hulk_verb]ing", ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected)) & BLOCK_SUCCESS))
if(user != src && (mob_run_block(user, 15, "the [hulk_verb]ing", ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected), null) & BLOCK_SUCCESS))
return TRUE
..()
return FALSE
@@ -303,7 +303,7 @@
var/damage = rand(5, 35)
if(M.is_adult)
damage = rand(20, 40)
if(run_block(M, damage, "the [M.name]", ATTACK_TYPE_MELEE, null, M, check_zone(M.zone_selected)) & BLOCK_SUCCESS)
if(mob_run_block(M, damage, "the [M.name]", ATTACK_TYPE_MELEE, null, M, check_zone(M.zone_selected), null) & BLOCK_SUCCESS)
return FALSE
if (stat != DEAD)
@@ -322,7 +322,7 @@
if(HAS_TRAIT(M, TRAIT_PACIFISM))
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
return FALSE
if(run_block(M, rand(M.melee_damage_lower, M.melee_damage_upper), "the [M.name]", ATTACK_TYPE_MELEE, M.armour_penetration, M, check_zone(M.zone_selected)) & BLOCK_SUCCESS)
if(mob_run_block(M, rand(M.melee_damage_lower, M.melee_damage_upper), "the [M.name]", ATTACK_TYPE_MELEE, M.armour_penetration, M, check_zone(M.zone_selected), null) & BLOCK_SUCCESS)
return FALSE
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
@@ -340,7 +340,7 @@
if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
to_chat(M, "<span class='warning'>You can't bite with your mouth covered!</span>")
return FALSE
if(run_block(M, 0, "the [M.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, M, check_zone(M.zone_selected)) & BLOCK_SUCCESS)
if(mob_run_block(M, 0, "the [M.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, 0, M, check_zone(M.zone_selected), null) & BLOCK_SUCCESS)
return FALSE
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
if (prob(75))
@@ -364,7 +364,7 @@
if(HAS_TRAIT(L, TRAIT_PACIFISM))
to_chat(L, "<span class='notice'>You don't want to hurt anyone!</span>")
return FALSE
if(L != src && (run_block(L, rand(1, 3), "the [L.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, L, check_zone(L.zone_selected)) & BLOCK_SUCCESS))
if(L != src && (mob_run_block(L, rand(1, 3), "the [L.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, 0, L, check_zone(L.zone_selected), null) & BLOCK_SUCCESS))
return FALSE
L.do_attack_animation(src)
if(prob(90))
@@ -378,7 +378,7 @@
"<span class='userdanger'>[L.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
if((M != src) && M.a_intent != INTENT_HELP && (run_block(M, 0, "the [M.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, M, check_zone(M.zone_selected)) & BLOCK_SUCCESS))
if((M != src) && M.a_intent != INTENT_HELP && (mob_run_block(M, 0, "the [M.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, 0, M, check_zone(M.zone_selected), null) & BLOCK_SUCCESS))
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
return FALSE
switch(M.a_intent)
+6 -1
View File
@@ -33,7 +33,7 @@
update_sprint_icon()
/mob/living/proc/disable_sprint_mode(update_icon = TRUE)
if(!(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
if(!(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) || (combat_flags & COMBAT_FLAG_SPRINT_FORCED))
return
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_ACTIVE)
if(update_icon)
@@ -51,6 +51,8 @@
/mob/living/proc/disable_intentional_sprint_mode()
if(!(combat_flags & COMBAT_FLAG_SPRINT_TOGGLED) && !(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
return
if(combat_flags & COMBAT_FLAG_SPRINT_FORCED)
return
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_TOGGLED)
if(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE)
disable_sprint_mode(FALSE)
@@ -59,6 +61,9 @@
/mob/living/proc/user_toggle_intentional_sprint_mode()
var/old = (combat_flags & COMBAT_FLAG_SPRINT_TOGGLED)
if(old)
if(combat_flags & COMBAT_FLAG_SPRINT_FORCED)
to_chat(src, "<span class='warning'>You are unable to stop sprinting!</span>")
return
disable_intentional_sprint_mode()
if((m_intent == MOVE_INTENT_RUN) && CHECK_ALL_MOBILITY(src, MOBILITY_STAND|MOBILITY_MOVE))
playsound_local(src, 'sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
@@ -115,7 +115,7 @@
/mob/living/silicon/bullet_act(obj/item/projectile/P, def_zone)
if(P.original != src || P.firer != src) //try to block or reflect the bullet, can't do so when shooting oneself
var/list/returnlist = list()
var/returned = run_block(P, P.damage, "the [P.name]", ATTACK_TYPE_PROJECTILE, P.armour_penetration, P.firer, def_zone, returnlist)
var/returned = mob_run_block(P, P.damage, "the [P.name]", ATTACK_TYPE_PROJECTILE, P.armour_penetration, P.firer, def_zone, returnlist)
if(returned & BLOCK_SHOULD_REDIRECT)
handle_projectile_attack_redirection(P, returnlist[BLOCK_RETURN_REDIRECT_METHOD])
if(returned & BLOCK_REDIRECTED)
@@ -54,7 +54,7 @@
var/blocked = FALSE
if(hasmatchingsummoner(hit_atom)) //if the summoner matches don't hurt them
blocked = TRUE
if(L.run_block(src, 90, "[name]", ATTACK_TYPE_TACKLE, 0, src) & BLOCK_SUCCESS)
if(L.mob_run_block(src, 90, "[name]", ATTACK_TYPE_TACKLE, 0, src, null, null) & BLOCK_SUCCESS)
blocked = TRUE
if(!blocked)
L.drop_all_held_items()
@@ -9,7 +9,7 @@
mob_biotypes = MOB_ORGANIC|MOB_BEAST
mouse_opacity = MOUSE_OPACITY_ICON
speak_emote = list("telepathically cries")
speed = 2
speed = 1
move_to_delay = 2
projectiletype = /obj/item/projectile/temp/basilisk/ice
projectilesound = 'sound/weapons/pierce.ogg'
@@ -25,8 +25,8 @@
melee_damage_upper = 15
attacktext = "slices"
attack_sound = 'sound/weapons/bladeslice.ogg'
vision_range = 9
aggro_vision_range = 9
vision_range = 7
aggro_vision_range = 7
move_force = MOVE_FORCE_VERY_STRONG
move_resist = MOVE_FORCE_VERY_STRONG
pull_force = MOVE_FORCE_VERY_STRONG
+11 -9
View File
@@ -192,7 +192,7 @@
var/on = FALSE // 1 if on, 0 if off
var/on_gs = FALSE
var/static_power_used = 0
var/brightness = 11 // luminosity when on, also used in power calculation
var/brightness = 9 // luminosity when on, also used in power calculation
var/bulb_power = 0.75 // basically the alpha of the emitted light source
var/bulb_colour = "#FFF6ED" // befault colour of the light.
var/status = LIGHT_OK // LIGHT_OK, _EMPTY, _BURNED or _BROKEN
@@ -231,7 +231,8 @@
icon_state = "bulb"
base_state = "bulb"
fitting = "bulb"
brightness = 6
brightness = 5
nightshift_brightness = 4
bulb_colour = "#FFDDBB"
desc = "A small lighting fixture."
light_type = /obj/item/light/bulb
@@ -273,11 +274,11 @@
spawn(2)
switch(fitting)
if("tube")
brightness = 11
brightness = 9
if(prob(2))
break_light_tube(1)
if("bulb")
brightness = 6
brightness = 5
if(prob(5))
break_light_tube(1)
spawn(1)
@@ -360,11 +361,11 @@
set_light(0)
update_icon()
active_power_usage = (brightness * 7.2)
active_power_usage = (brightness * 10)
if(on != on_gs)
on_gs = on
if(on)
static_power_used = brightness * 14.4 * (hijacked ? 2 : 1) //20W per unit luminosity
static_power_used = brightness * 20 * (hijacked ? 2 : 1) //20W per unit luminosity
addStaticPower(static_power_used, STATIC_LIGHT)
else
removeStaticPower(static_power_used, STATIC_LIGHT)
@@ -747,7 +748,7 @@
icon_state = "ltube"
base_state = "ltube"
item_state = "c_tube"
brightness = 11
brightness = 9
/obj/item/light/tube/broken
status = LIGHT_BROKEN
@@ -760,7 +761,7 @@
item_state = "contvapour"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
brightness = 6
brightness = 5
/obj/item/light/bulb/broken
status = LIGHT_BROKEN
@@ -829,7 +830,8 @@
icon = 'icons/obj/lighting.dmi'
base_state = "floor" // base description and icon_state
icon_state = "floor"
brightness = 6
brightness = 5
nightshift_brightness = 4
layer = 2.5
light_type = /obj/item/light/bulb
fitting = "bulb"
@@ -119,14 +119,13 @@
/obj/singularity/Bump(atom/A)
set waitfor = FALSE
consume(A)
return
/obj/singularity/Bumped(atom/movable/AM)
set waitfor = FALSE
consume(AM)
/obj/singularity/process()
if(current_size >= STAGE_TWO)
move()
@@ -268,6 +267,7 @@
/obj/singularity/proc/eat()
set waitfor = FALSE
for(var/tile in spiral_range_turfs(grav_pull, src))
var/turf/T = tile
if(!T || !isturf(loc))
@@ -284,8 +284,6 @@
else
consume(X)
CHECK_TICK
return
/obj/singularity/proc/consume(atom/A)
var/gain = A.singularity_act(current_size, src)
@@ -295,8 +293,6 @@
name = "supermatter-charged [initial(name)]"
consumedSupermatter = 1
set_light(10)
return
/obj/singularity/proc/move(force_move = 0)
if(!move_self)
@@ -26,8 +26,8 @@
var/z_offset = SSmapping.station_start
var/list/bounds
for (var/path in SSmapping.config.GetFullMapPaths())
var/datum/parsed_map/parsed = load_map(file(path), 1, 1, z_offset, measureOnly = FALSE, no_changeturf = FALSE, cropMap=TRUE, x_lower = mother1.x_low, y_lower = mother1.y_low, x_upper = mother1.x_high, y_upper = mother1.y_high)
bounds = parsed?.bounds
var/datum/parsed_map/parsed = load_map(file(path), 1, 1, z_offset, orientation = SSmapping.config.orientation, cropMap = TRUE, x_lower = mother1.x_low, y_lower = mother1.y_low, x_upper = mother1.x_high, y_upper = mother1.y_high)
bounds = parsed.bounds
z_offset += bounds[MAP_MAXZ] - bounds[MAP_MINZ] + 1
var/list/obj/machinery/atmospherics/atmos_machines = list()
@@ -113,7 +113,7 @@
/obj/item/ammo_box/update_icon()
. = ..()
desc = "[initial(desc)] There are [stored_ammo.len] shell\s left!"
desc = "[initial(desc)] There [stored_ammo.len == 1 ? "is" : "are"] [stored_ammo.len] shell\s left!"
for (var/material in bullet_cost)
var/material_amount = bullet_cost[material]
material_amount = (material_amount*stored_ammo.len) + base_cost[material]
@@ -121,3 +121,51 @@
icon_state = "foambox_riot"
ammo_type = /obj/item/ammo_casing/caseless/foam_dart/riot
custom_materials = list(/datum/material/iron = 50000)
//Shotgun clips
/obj/item/ammo_box/shotgun
name = "stripper clip (shotgun shells)"
desc = "A stripper clip, designed to help with loading a shotgun slightly faster."
icon = 'icons/obj/ammo.dmi'
icon_state = "shotgunclip"
caliber = "shotgun" // slapped in to allow shell mix n match
ammo_type = /obj/item/ammo_casing/shotgun
max_ammo = 4
var/pixeloffsetx = 4
start_empty = TRUE
/obj/item/ammo_box/shotgun/update_overlays()
. = ..()
if(stored_ammo.len)
var/offset = -4
for(var/A in stored_ammo)
var/obj/item/ammo_casing/shotgun/C = A
offset += pixeloffsetx
var/mutable_appearance/shell_overlay = mutable_appearance(icon, "[initial(C.icon_state)]-clip")
shell_overlay.pixel_x += offset
shell_overlay.appearance_flags = RESET_COLOR
. += shell_overlay
/obj/item/ammo_box/shotgun/loaded
start_empty = FALSE
/obj/item/ammo_box/shotgun/loaded/rubbershot
ammo_type = /obj/item/ammo_casing/shotgun/rubbershot
/obj/item/ammo_box/shotgun/loaded/buckshot
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
/obj/item/ammo_box/shotgun/loaded/beanbag
ammo_type = /obj/item/ammo_casing/shotgun/beanbag
/obj/item/ammo_box/shotgun/loaded/stunslug
ammo_type = /obj/item/ammo_casing/shotgun/stunslug
/obj/item/ammo_box/shotgun/loaded/techshell
ammo_type = /obj/item/ammo_casing/shotgun/techshell
/obj/item/ammo_box/shotgun/loaded/incendiary
ammo_type = /obj/item/ammo_casing/shotgun/incendiary
/obj/item/ammo_box/shotgun/loaded/dart
ammo_type = /obj/item/ammo_casing/shotgun/dart
+13 -2
View File
@@ -38,6 +38,8 @@
var/trajectory_ignore_forcemove = FALSE //instructs forceMove to NOT reset our trajectory to the new location!
var/speed = 0.8 //Amount of deciseconds it takes for projectile to travel
/// "leftover" ticks and stuff yeah. hey when are we rewriting projectiles for the eighth time to do something smarter like incrementing x pixels until it meets a goal instead of for(var/i in 1 to required_moves)?
var/tick_moves_leftover = 0
var/Angle = 0
var/original_angle = 0 //Angle at firing
var/nondirectional_sprite = FALSE //Set TRUE to prevent projectiles from having their sprites rotated based on firing angle
@@ -350,13 +352,22 @@
/obj/item/projectile/Process_Spacemove(movement_dir = 0)
return TRUE //Bullets don't drift in space
/obj/item/projectile/process()
/obj/item/projectile/process(wait)
if(!loc || !fired || !trajectory)
fired = FALSE
return PROCESS_KILL
if(paused || !isturf(loc))
return
pixel_move(1, FALSE)
var/ds = (SSprojectiles.flags & SS_TICKER)? (wait * world.tick_lag) : wait
var/required_moves = ds / speed
var/leftover = MODULUS(required_moves, 1)
tick_moves_leftover += leftover
required_moves = round(required_moves)
if(tick_moves_leftover > 1)
required_moves += round(tick_moves_leftover)
tick_moves_leftover = MODULUS(tick_moves_leftover, 1)
for(var/i in 1 to required_moves)
pixel_move(1, FALSE)
/obj/item/projectile/proc/fire(angle, atom/direct_target)
if(fired_from)
@@ -575,9 +575,7 @@
/datum/reagent/consumable/ethanol/alexander,
/datum/reagent/consumable/clownstears,
/datum/reagent/toxin/minttoxin,
/datum/reagent/consumable/ethanol/atomicbomb,
/datum/reagent/drug/aphrodisiac,
/datum/reagent/drug/aphrodisiacplus
/datum/reagent/consumable/ethanol/atomicbomb
)
/obj/machinery/chem_dispenser/drinks/beer/fullupgrade //fully ugpraded stock parts, emagged
@@ -211,7 +211,6 @@
/obj/structure/reagent_dispensers/keg
name = "keg"
desc = "A keg."
icon = 'modular_citadel/icons/obj/objects.dmi'
icon_state = "keg"
/obj/structure/reagent_dispensers/keg/mead
@@ -135,6 +135,15 @@
//Ammo Shells/
//////////////
/datum/design/shell_clip
name = "stripper clip (shotgun shells)"
id = "sec_shellclip"
build_type = PROTOLATHE
materials = list(/datum/material/iron = 5000)
build_path = /obj/item/ammo_box/shotgun
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
/datum/design/beanbag_slug/sec
id = "sec_beanbag"
build_type = PROTOLATHE
@@ -166,7 +175,7 @@
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
/datum/design/incendiary_slug/sec
id = "sec_Islug"
id = "sec_islug"
build_type = PROTOLATHE
category = list("Ammo")
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+11 -11
View File
@@ -4,7 +4,7 @@
layer = BELOW_OBJ_LAYER
var/consoleless_interface = TRUE //Whether it can be used without a console.
var/offstation_security_levels = TRUE
var/efficiency_coeff = 1 //Materials needed / coeff = actual.
var/print_cost_coeff = 1 //Materials needed * coeff = actual.
var/list/categories = list()
var/datum/component/remote_materials/materials
var/allowed_department_flags = ALL
@@ -76,13 +76,13 @@
for(var/obj/item/stock_parts/manipulator/M in component_parts)
total_manip_rating += M.rating
manips++
efficiency_coeff = STANDARD_PART_LEVEL_LATHE_COEFFICIENT(total_manip_rating / (manips? manips : 1))
print_cost_coeff = STANDARD_PART_LEVEL_LATHE_COEFFICIENT(total_manip_rating / (manips? manips : 1))
/obj/machinery/rnd/production/examine(mob/user)
. = ..()
var/datum/component/remote_materials/materials = GetComponent(/datum/component/remote_materials)
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Storing up to <b>[materials.local_size]</b> material units locally.<br>Material usage efficiency at <b>[efficiency_coeff*100]%</b>.</span>"
. += "<span class='notice'>The status display reads: Storing up to <b>[materials.local_size]</b> material units locally.<br>Material usage cost at <b>[print_cost_coeff*100]%</b>.</span>"
//we eject the materials upon deconstruction.
/obj/machinery/rnd/production/on_deconstruction()
@@ -112,7 +112,7 @@
// these types don't have their .materials set in do_print, so don't allow
// them to be constructed efficiently
var/ef = efficient_with(being_built.build_path) ? efficiency_coeff : 1
var/ef = efficient_with(being_built.build_path) ? print_cost_coeff : 1
return round(A / max(1, all_materials[mat] * ef))
/obj/machinery/rnd/production/proc/efficient_with(path)
@@ -152,7 +152,7 @@
power += round(D.materials[M] * amount / 35)
power = min(3000, power)
use_power(power)
var/coeff = efficient_with(D.build_path) ? efficiency_coeff : 1
var/coeff = efficient_with(D.build_path) ? print_cost_coeff : 1
var/list/efficient_mats = list()
for(var/MAT in D.materials)
efficient_mats[MAT] = D.materials[MAT] * coeff
@@ -170,7 +170,7 @@
busy = TRUE
if(production_animation)
flick(production_animation, src)
var/timecoeff = D.lathe_time_factor * efficiency_coeff
var/timecoeff = D.lathe_time_factor * print_cost_coeff
addtimer(CALLBACK(src, .proc/reset_busy), (20 * timecoeff * amount) ** 0.5)
addtimer(CALLBACK(src, .proc/do_print, D.build_path, amount, efficient_mats, D.dangerous_construction, usr), (20 * timecoeff * amount) ** 0.5)
return TRUE
@@ -247,7 +247,7 @@
/obj/machinery/rnd/production/proc/ui_screen_search()
var/list/l = list()
var/coeff = efficiency_coeff
var/coeff = print_cost_coeff
l += "<h2>Search Results:</h2>"
l += "<form name='search' action='?src=[REF(src)]'>\
<input type='hidden' name='src' value='[REF(src)]'>\
@@ -264,7 +264,7 @@
if(!istype(D))
return
if(!coeff)
coeff = efficiency_coeff
coeff = print_cost_coeff
if(!efficient_with(D.build_path))
coeff = 1
var/list/l = list()
@@ -276,9 +276,9 @@
t = check_mat(D, M)
temp_material += " | "
if (t < 1)
temp_material += "<span class='bad'>[all_materials[M]/coeff] [CallMaterialName(M)]</span>"
temp_material += "<span class='bad'>[all_materials[M] * coeff] [CallMaterialName(M)]</span>"
else
temp_material += " [all_materials[M]/coeff] [CallMaterialName(M)]"
temp_material += " [all_materials[M] * coeff] [CallMaterialName(M)]"
c = min(c,t)
var/clearance = !(obj_flags & EMAGGED) && (offstation_security_levels || is_station_level(z))
@@ -366,7 +366,7 @@
return ui_screen_main()
var/list/l = list()
l += "<div class='statusDisplay'><h3>Browsing [selected_category]:</h3>"
var/coeff = efficiency_coeff
var/coeff = print_cost_coeff
for(var/v in stored_research.researched_designs)
var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(!(selected_category in D.category)|| !(D.build_type & allowed_buildtypes))
@@ -25,11 +25,6 @@
/obj/machinery/rnd/production/circuit_imprinter/calculate_efficiency()
. = ..()
var/total_rating = 0
for(var/obj/item/stock_parts/manipulator/M in component_parts)
total_rating += M.rating * 2 //There is only one.
total_rating = max(1, total_rating)
efficiency_coeff = total_rating
var/obj/item/circuitboard/machine/circuit_imprinter/C = circuit
offstation_security_levels = C.offstation_security_levels
@@ -76,7 +76,8 @@
var/problems = FALSE
if(iscarbon(host_mob))
var/mob/living/carbon/C = host_mob
if(length(C.get_traumas()))
var/obj/item/organ/brain/B = C.getorganslot(ORGAN_SLOT_BRAIN)
if(length(B?.get_traumas_type(TRAUMA_RESILIENCE_BASIC)))
problems = TRUE
if(host_mob.getOrganLoss(ORGAN_SLOT_BRAIN) > 0)
problems = TRUE
@@ -198,7 +199,8 @@
var/problems = FALSE
if(iscarbon(host_mob))
var/mob/living/carbon/C = host_mob
if(length(C.get_traumas()))
var/obj/item/organ/brain/B = C.getorganslot(ORGAN_SLOT_BRAIN)
if(length(B?.get_traumas_type(TRAUMA_RESILIENCE_SURGERY)))
problems = TRUE
if(host_mob.getOrganLoss(ORGAN_SLOT_BRAIN) > 0)
problems = TRUE
@@ -208,7 +210,7 @@
host_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2)
if(iscarbon(host_mob) && prob(10))
var/mob/living/carbon/C = host_mob
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_LOBOTOMY)
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_SURGERY)
/datum/nanite_program/defib
name = "Defibrillation"
+12 -12
View File
@@ -290,7 +290,7 @@ Nothing else in the console has ID requirements.
continue
var/temp_material
var/c = 50
var/coeff = linked_lathe.efficiency_coeff
var/coeff = linked_lathe.print_cost_coeff
if(!linked_lathe.efficient_with(D.build_path))
coeff = 1
@@ -299,9 +299,9 @@ Nothing else in the console has ID requirements.
var/t = linked_lathe.check_mat(D, M)
temp_material += " | "
if (t < 1)
temp_material += "<span class='bad'>[all_materials[M]/coeff] [CallMaterialName(M)]</span>"
temp_material += "<span class='bad'>[all_materials[M] * coeff] [CallMaterialName(M)]</span>"
else
temp_material += " [all_materials[M]/coeff] [CallMaterialName(M)]"
temp_material += " [all_materials[M] * coeff] [CallMaterialName(M)]"
c = min(c,t)
var/clearance = !(linked_lathe.obj_flags & EMAGGED) && (linked_lathe.offstation_security_levels || is_station_level(linked_lathe.z))
@@ -356,16 +356,16 @@ Nothing else in the console has ID requirements.
var/temp_material
var/c = 50
var/all_materials = D.materials + D.reagents_list
var/coeff = linked_lathe.efficiency_coeff
var/coeff = linked_lathe.print_cost_coeff
if(!linked_lathe.efficient_with(D.build_path))
coeff = 1
for(var/M in all_materials)
var/t = linked_lathe.check_mat(D, M)
temp_material += " | "
if (t < 1)
temp_material += "<span class='bad'>[all_materials[M]/coeff] [CallMaterialName(M)]</span>"
temp_material += "<span class='bad'>[all_materials[M] * coeff] [CallMaterialName(M)]</span>"
else
temp_material += " [all_materials[M]/coeff] [CallMaterialName(M)]"
temp_material += " [all_materials[M] * coeff] [CallMaterialName(M)]"
c = min(c,t)
if (c >= 1)
@@ -457,7 +457,7 @@ Nothing else in the console has ID requirements.
var/check_materials = TRUE
var/all_materials = D.materials + D.reagents_list
var/coeff = linked_imprinter.efficiency_coeff
var/coeff = linked_imprinter.print_cost_coeff
if(!linked_imprinter.efficient_with(D.build_path))
coeff = 1
@@ -465,9 +465,9 @@ Nothing else in the console has ID requirements.
temp_materials += " | "
if (!linked_imprinter.check_mat(D, M))
check_materials = FALSE
temp_materials += " <span class='bad'>[all_materials[M]/coeff] [CallMaterialName(M)]</span>"
temp_materials += " <span class='bad'>[all_materials[M] * coeff] [CallMaterialName(M)]</span>"
else
temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]"
temp_materials += " [all_materials[M] * coeff] [CallMaterialName(M)]"
if (check_materials)
l += "<A href='?src=[REF(src)];imprint=[D.id]'>[D.name]</A>[temp_materials]"
else
@@ -488,16 +488,16 @@ Nothing else in the console has ID requirements.
var/temp_materials
var/check_materials = TRUE
var/all_materials = D.materials + D.reagents_list
var/coeff = linked_imprinter.efficiency_coeff
var/coeff = linked_imprinter.print_cost_coeff
if(!linked_imprinter.efficient_with(D.build_path))
coeff = 1
for(var/M in all_materials)
temp_materials += " | "
if (!linked_imprinter.check_mat(D, M))
check_materials = FALSE
temp_materials += " <span class='bad'>[all_materials[M]/coeff] [CallMaterialName(M)]</span>"
temp_materials += " <span class='bad'>[all_materials[M] * coeff] [CallMaterialName(M)]</span>"
else
temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]"
temp_materials += " [all_materials[M] * coeff] [CallMaterialName(M)]"
if (check_materials)
l += "<A href='?src=[REF(src)];imprint=[D.id]'>[D.name]</A>[temp_materials]"
else
+1 -1
View File
@@ -10,7 +10,7 @@
// Default research tech, prevents bricking
design_ids = list("basic_matter_bin", "basic_cell", "basic_scanning", "basic_capacitor", "basic_micro_laser", "micro_mani", "desttagger", "handlabel", "packagewrap",
"destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab",
"space_heater", "beaker", "large_beaker", "bucket", "xlarge_beaker", "sec_beanbag", "sec_rshot", "sec_bshot", "sec_slug", "sec_Islug", "sec_dart", "sec_38", "sec_38lethal",
"space_heater", "beaker", "large_beaker", "bucket", "xlarge_beaker", "sec_shellclip", "sec_beanbag", "sec_rshot", "sec_bshot", "sec_slug", "sec_islug", "sec_dart", "sec_38", "sec_38lethal",
"rglass","plasteel","plastitanium","plasmaglass","plasmareinforcedglass","titaniumglass","plastitaniumglass")
/datum/techweb_node/mmi
+1 -1
View File
@@ -41,7 +41,7 @@
target.cure_all_traumas(TRAUMA_RESILIENCE_LOBOTOMY)
if(target.mind && target.mind.has_antag_datum(/datum/antagonist/brainwashed))
target.mind.remove_antag_datum(/datum/antagonist/brainwashed)
switch(rand(1,4))//Now let's see what hopefully-not-important part of the brain we cut off
switch(rand(1,6))//Now let's see what hopefully-not-important part of the brain we cut off
if(1)
target.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_MAGIC)
if(2)
@@ -201,10 +201,9 @@
/datum/uplink_item/device_tools/stimpack
name = "Stimpack"
desc = "Stimpacks, the tool of many great heroes, make you nearly immune to stuns and knockdowns for about \
5 minutes after fully injecting yourself. Can inject yourself, or others, 5 times and through hardsuits. \
Each injection will gives around a minute of stimulants."
item = /obj/item/reagent_containers/hypospray/medipen/stimulants
cost = 5
5 minutes after injection."
item = /obj/item/reagent_containers/syringe/stimulants
cost = 3
surplus = 90
/datum/uplink_item/device_tools/medkit
+14
View File
@@ -139,6 +139,20 @@ MIDROUND_ANTAG CHANGELING
MIDROUND_ANTAG WIZARD
#MIDROUND_ANTAG MONKEY
## Toggles for whether this mode should force antags even if not enough players have it enabled.
## If it's off, it just won't roll as many antags.
#FORCE_ANTAG_COUNT TRAITOR
#FORCE_ANTAG_COUNT TRAITORBRO
#FORCE_ANTAG_COUNT TRAITORCHAN
#FORCE_ANTAG_COUNT INTERNAL_AFFAIRS
FORCE_ANTAG_COUNT NUCLEAR
FORCE_ANTAG_COUNT REVOLUTION
FORCE_ANTAG_COUNT CULT
FORCE_ANTAG_COUNT CLOCKWORK_CULT
#FORCE_ANTAG_COUNT CHANGELING
#FORCE_ANTAG_COUNT WIZARD
#FORCE_ANTAG_COUNT MONKEY
## Uncomment these for overrides of the minimum / maximum number of players in a round type.
## If you set any of these occasionally check to see if you still need them as the modes
## will still be actively rebalanced around the SUGGESTED populations, not your overrides.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Before

Width:  |  Height:  |  Size: 668 B

After

Width:  |  Height:  |  Size: 668 B

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Before

Width:  |  Height:  |  Size: 377 B

After

Width:  |  Height:  |  Size: 377 B

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Before

Width:  |  Height:  |  Size: 561 B

After

Width:  |  Height:  |  Size: 561 B

Before

Width:  |  Height:  |  Size: 546 B

After

Width:  |  Height:  |  Size: 546 B

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 KiB

After

Width:  |  Height:  |  Size: 310 KiB

@@ -28,7 +28,7 @@
gender = PLURAL
density = 0
layer = ABOVE_NORMAL_TURF_LAYER
icon = 'modular_citadel/icons/obj/genitals/effects.dmi'
icon = 'icons/obj/genitals/effects.dmi'
icon_state = "semen1"
random_icon_states = list("semen1", "semen2", "semen3", "semen4")
@@ -59,7 +59,7 @@
gender = PLURAL
density = 0
layer = ABOVE_NORMAL_TURF_LAYER
icon = 'modular_citadel/icons/obj/genitals/effects.dmi'
icon = 'icons/obj/genitals/effects.dmi'
icon_state = "fem1"
random_icon_states = list("fem1", "fem2", "fem3", "fem4")
blood_state = null
@@ -92,8 +92,7 @@
/datum/reagent/drug/aphrodisiac
name = "Crocin"
description = "Naturally found in the crocus and gardenia flowers, this drug acts as a natural and safe aphrodisiac."
taste_description = "strawberry roofies"
taste_mult = 2 //Hide the roofies in stronger flavors
taste_description = "strawberries"
color = "#FFADFF"//PINK, rgb(255, 173, 255)
can_synth = FALSE
Binary file not shown.

Before

Width:  |  Height:  |  Size: 570 B

After

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 553 B

After

Width:  |  Height:  |  Size: 400 B

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