Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit740
@@ -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!
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
. = ..()
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 35 KiB |
|
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 |
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
|
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
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 570 B After Width: | Height: | Size: 403 B |
|
Before Width: | Height: | Size: 553 B After Width: | Height: | Size: 400 B |