Merge remote-tracking branch 'citadel/master' into combat_rework

This commit is contained in:
kevinz000
2020-04-08 04:04:45 -07:00
919 changed files with 148968 additions and 10144 deletions
+1 -11
View File
@@ -302,16 +302,6 @@
name = "Toggle Friendly Fire \[ON\]"
..()
/datum/action/item_action/synthswitch
name = "Change Synthesizer Instrument"
desc = "Change the type of instrument your synthesizer is playing as."
/datum/action/item_action/synthswitch/Trigger()
if(istype(target, /obj/item/instrument/piano_synth))
var/obj/item/instrument/piano_synth/synth = target
return synth.selectInstrument()
return ..()
/datum/action/item_action/vortex_recall
name = "Vortex Recall"
desc = "Recall yourself, and anyone nearby, to an attuned hierophant beacon at any time.<br>If the beacon is still attached, will detach it."
@@ -659,7 +649,7 @@
return FALSE
var/obj/effect/proc_holder/spell/S = target
if(owner)
return S.can_cast(owner)
return S.can_cast(owner, FALSE, TRUE)
return FALSE
/datum/action/spell_action/alien
+17 -11
View File
@@ -9,8 +9,8 @@
var/max_distance = 0
var/sleep_time = 3
var/finished = 0
var/target_oldloc = null
var/origin_oldloc = null
var/turf/target_oldloc
var/turf/origin_oldloc
var/static_beam = 0
var/beam_type = /obj/effect/ebeam //must be subtype
var/timing_id = null
@@ -23,13 +23,13 @@
target_oldloc = get_turf(target)
sleep_time = beam_sleep_time
if(origin_oldloc == origin && target_oldloc == target)
static_beam = 1
static_beam = TRUE
max_distance = maxdistance
base_icon = new(beam_icon,beam_icon_state)
icon = beam_icon
icon_state = beam_icon_state
beam_type = btype
if(time < INFINITY)
if(time < INFINITY)
addtimer(CALLBACK(src,.proc/End), time)
/datum/beam/proc/Start()
@@ -42,10 +42,14 @@
return
recalculating = TRUE
timing_id = null
if(origin && target && get_dist(origin,target)<max_distance && origin.z == target.z)
var/origin_turf = get_turf(origin)
var/target_turf = get_turf(target)
if(!static_beam && (origin_turf != origin_oldloc || target_turf != target_oldloc))
var/turf/origin_turf
if(origin)
origin_turf = get_turf(origin)
var/turf/target_turf
if(target)
target_turf = get_turf(target)
if(origin_turf && target_turf && (get_dist(origin_turf, target_turf) < max_distance) && (origin_turf.z == target_turf.z))
if(!static_beam && ((origin_turf != origin_oldloc) || (target_turf != target_oldloc)))
origin_oldloc = origin_turf //so we don't keep checking against their initial positions, leading to endless Reset()+Draw() calls
target_oldloc = target_turf
Reset()
@@ -90,13 +94,15 @@
return ..()
/datum/beam/proc/Draw()
var/Angle = round(Get_Angle(origin,target))
if(!origin_oldloc || !target_oldloc)
return
var/Angle = round(Get_Angle(origin_oldloc,target_oldloc))
var/matrix/rot_matrix = matrix()
rot_matrix.Turn(Angle)
//Translation vector for origin and target
var/DX = (32*target.x+target.pixel_x)-(32*origin.x+origin.pixel_x)
var/DY = (32*target.y+target.pixel_y)-(32*origin.y+origin.pixel_y)
var/DX = (32*target_oldloc.x+target_oldloc.pixel_x)-(32*origin_oldloc.x+origin_oldloc.pixel_x)
var/DY = (32*target_oldloc.y+target_oldloc.pixel_y)-(32*origin_oldloc.y+origin_oldloc.pixel_y)
var/N = 0
var/length = round(sqrt((DX)**2+(DY)**2)) //hypotenuse of the triangle formed by target and origin's displacement
+9 -12
View File
@@ -20,6 +20,7 @@
..()
make_backseats()
get_ghost()
RegisterSignal(M, COMSIG_MOB_DEATH, .proc/revert_to_normal)
/datum/brain_trauma/severe/split_personality/proc/make_backseats()
stranger_backseat = new(owner, src)
@@ -37,23 +38,23 @@
qdel(src)
/datum/brain_trauma/severe/split_personality/on_life()
if(owner.stat == DEAD)
if(current_controller != OWNER)
switch_personalities()
qdel(src)
else if(prob(3))
if(prob(3))
switch_personalities()
..()
/datum/brain_trauma/severe/split_personality/on_lose()
if(current_controller != OWNER) //it would be funny to cure a guy only to be left with the other personality, but it seems too cruel
switch_personalities()
switch_personalities(TRUE)
QDEL_NULL(stranger_backseat)
QDEL_NULL(owner_backseat)
UnregisterSignal(owner, COMSIG_MOB_DEATH)
..()
/datum/brain_trauma/severe/split_personality/proc/switch_personalities()
if(QDELETED(owner) || owner.stat == DEAD || QDELETED(stranger_backseat) || QDELETED(owner_backseat))
/datum/brain_trauma/severe/split_personality/proc/revert_to_normal()
qdel(src)
/datum/brain_trauma/severe/split_personality/proc/switch_personalities(forced = FALSE)
if(QDELETED(owner) || (owner.stat == DEAD && !forced) || QDELETED(stranger_backseat) || QDELETED(owner_backseat))
return
var/mob/living/split_personality/current_backseat
@@ -126,10 +127,6 @@
if(QDELETED(body))
qdel(src) //in case trauma deletion doesn't already do it
if((body.stat == DEAD && trauma.owner_backseat == src))
trauma.switch_personalities()
qdel(trauma)
//if one of the two ghosts, the other one stays permanently
if(!body.client && trauma.initialized)
trauma.switch_personalities()
+2 -2
View File
@@ -72,9 +72,9 @@
return {"<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
[head_content]
</head>
<body scroll=auto>
+2
View File
@@ -8,6 +8,8 @@
var/obj/screen/craft/C = new()
C.icon = H.ui_style
H.static_inventory += C
if(!CL.prefs.widescreenpref)
C.screen_loc = ui_boxcraft
CL.screen += C
RegisterSignal(C, COMSIG_CLICK, .proc/component_ui_interact)
@@ -33,6 +33,13 @@
/obj/item/organ/ears/cat = 1)
category = CAT_CLOTHING
/datum/crafting_recipe/papermask
name = "Paper Mask"
result = /obj/item/clothing/mask/paper
time = 10
reqs = list(/obj/item/paper = 20)
category = CAT_CLOTHING
////////
//Huds//
////////
+12 -4
View File
@@ -191,20 +191,28 @@
///////Yes, I said humans. No, this won't end well...//////////
/datum/component/riding/human
var/fireman_carrying = FALSE
/datum/component/riding/human/Initialize()
. = ..()
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
H.remove_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING)
. = ..()
var/mob/living/carbon/human/H = parent
if(!length(H.buckled_mobs))
H.remove_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING)
if(!fireman_carrying)
M.Daze(25)
REMOVE_TRAIT(M, TRAIT_MOBILITY_NOUSE, src)
/datum/component/riding/human/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE)
. = ..()
var/mob/living/carbon/human/H = parent
H.add_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING, multiplicative_slowdown = HUMAN_CARRY_SLOWDOWN)
if(length(H.buckled_mobs))
H.add_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING, multiplicative_slowdown = fireman_carrying? FIREMAN_CARRY_SLOWDOWN : PIGGYBACK_CARRY_SLOWDOWN)
if(fireman_carrying)
ADD_TRAIT(M, TRAIT_MOBILITY_NOUSE, src)
/datum/component/riding/human/proc/on_host_unarmed_melee(atom/target)
var/mob/living/carbon/human/H = parent
@@ -236,11 +244,11 @@
else
return list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(-6, 4), TEXT_WEST = list( 6, 4))
/datum/component/riding/human/force_dismount(mob/living/user)
var/atom/movable/AM = parent
AM.unbuckle_mob(user)
user.DefaultCombatKnockdown(60)
user.Daze(50)
user.visible_message("<span class='warning'>[AM] pushes [user] off of [AM.p_them()]!</span>")
/datum/component/riding/cyborg
+17 -2
View File
@@ -27,6 +27,8 @@ GLOBAL_LIST_EMPTY(uplinks)
var/datum/ui_state/checkstate
var/compact_mode = FALSE
var/debug = FALSE
var/saved_player_population = 0
var/list/filters = list()
/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20, datum/ui_state/_checkstate, datum/traitor_class/traitor_class)
if(!isitem(parent))
@@ -47,7 +49,6 @@ GLOBAL_LIST_EMPTY(uplinks)
RegisterSignal(parent, COMSIG_PEN_ROTATED, .proc/pen_rotation)
GLOB.uplinks += src
var/list/filters = list()
if(istype(traitor_class))
filters = traitor_class.uplink_filters
starting_tc = traitor_class.TC
@@ -68,6 +69,7 @@ GLOBAL_LIST_EMPTY(uplinks)
if(!lockable)
active = TRUE
locked = FALSE
saved_player_population = GLOB.joined_player_list.len
/datum/component/uplink/InheritComponent(datum/component/uplink/U)
lockable |= U.lockable
@@ -117,7 +119,18 @@ GLOBAL_LIST_EMPTY(uplinks)
return
active = TRUE
if(user)
//update the saved population
var/previous_player_population = saved_player_population
saved_player_population = GLOB.joined_player_list.len
//if population has changed, update uplink items
if(saved_player_population != previous_player_population)
//make sure discounts are not rerolled
var/old_discounts = uplink_items["Discounted Gear"]
uplink_items = get_uplink_items(gamemode, FALSE, allow_restricted, filters)
if(old_discounts)
uplink_items["Discounted Gear"] = old_discounts
ui_interact(user)
// an unlocked uplink blocks also opening the PDA or headset menu
return COMPONENT_NO_INTERACT
@@ -190,7 +203,9 @@ GLOBAL_LIST_EMPTY(uplinks)
if(item in buyable_items)
var/datum/uplink_item/I = buyable_items[item]
MakePurchase(usr, I)
//check to make sure people cannot buy items when the player pop is below the requirement
if(GLOB.joined_player_list.len >= I.player_minimum)
MakePurchase(usr, I)
. = TRUE
if("lock")
active = FALSE
+2
View File
@@ -109,6 +109,8 @@
UnregisterSignal(target, signal_procs[target])
//END: ECS SHIT
SSsounds.free_datum_channels(src)
return QDEL_HINT_QUEUE
#ifdef DATUMVAR_DEBUGGING_MODE
+23 -1378
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -412,13 +412,13 @@
switch(deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 4))
if(G_MALE)
set_gender(MALE, TRUE)
set_gender(MALE, TRUE, forced = TRUE)
if(G_FEMALE)
set_gender(FEMALE, TRUE)
set_gender(FEMALE, TRUE, forced = TRUE)
if(G_PLURAL)
set_gender(PLURAL, TRUE)
set_gender(PLURAL, TRUE, forced = TRUE)
else
set_gender(NEUTER, TRUE)
set_gender(NEUTER, TRUE, forced = TRUE)
/mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
..()
+12 -2
View File
@@ -72,7 +72,7 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
var/atom/target = locate(href_list["show_flavor"])
var/text = texts_by_atom[target]
if(text)
usr << browse("<HTML><HEAD><TITLE>[target.name]</TITLE></HEAD><BODY><TT>[replacetext(texts_by_atom[target], "\n", "<BR>")]</TT></BODY></HTML>", "window=[target.name];size=500x200")
usr << browse("<HTML><HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><TITLE>[target.name]</TITLE></HEAD><BODY><TT>[replacetext(texts_by_atom[target], "\n", "<BR>")]</TT></BODY></HTML>", "window=[target.name];size=500x200")
onclose(usr, "[target.name]")
return TRUE
@@ -114,6 +114,9 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
//subtypes with additional hooks for DNA and preferences.
/datum/element/flavor_text/carbon
//list of antagonists etcetera that should have nothing to do with people's snowflakes.
var/static/list/i_dont_even_know_who_you_are = typecacheof(list(/datum/antagonist/abductor, /datum/antagonist/ert,
/datum/antagonist/nukeop, /datum/antagonist/wizard))
/datum/element/flavor_text/carbon/Attach(datum/target, text = "", _name = "Flavor Text", _addendum, _max_len = MAX_FLAVOR_LEN, _always_show = FALSE, _edit = TRUE)
if(!iscarbon(target))
@@ -122,6 +125,7 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
if(. == ELEMENT_INCOMPATIBLE)
return
RegisterSignal(target, COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, .proc/update_dna_flavor_text)
RegisterSignal(target, COMSIG_MOB_ANTAG_ON_GAIN, .proc/on_antag_gain)
if(ishuman(target))
RegisterSignal(target, COMSIG_HUMAN_PREFS_COPIED_TO, .proc/update_prefs_flavor_text)
RegisterSignal(target, COMSIG_HUMAN_HARDSET_DNA, .proc/update_dna_flavor_text)
@@ -129,7 +133,7 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
/datum/element/flavor_text/carbon/Detach(mob/living/carbon/C)
. = ..()
UnregisterSignal(C, list(COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, COMSIG_HUMAN_PREFS_COPIED_TO, COMSIG_HUMAN_HARDSET_DNA, COMSIG_HUMAN_ON_RANDOMIZE))
UnregisterSignal(C, list(COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, COMSIG_MOB_ANTAG_ON_GAIN, COMSIG_HUMAN_PREFS_COPIED_TO, COMSIG_HUMAN_HARDSET_DNA, COMSIG_HUMAN_ON_RANDOMIZE))
/datum/element/flavor_text/carbon/proc/update_dna_flavor_text(mob/living/carbon/C)
texts_by_atom[C] = C.dna.features["flavor_text"]
@@ -144,3 +148,9 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
/datum/element/flavor_text/carbon/proc/unset_flavor(mob/living/carbon/user)
texts_by_atom[user] = ""
/datum/element/flavor_text/carbon/proc/on_antag_gain(mob/living/carbon/user, datum/antagonist/antag)
if(is_type_in_typecache(antag, i_dont_even_know_who_you_are))
texts_by_atom[user] = ""
if(user.dna)
user.dna.features["flavor_text"] = ""
+17 -2
View File
@@ -1,15 +1,21 @@
/datum/element/ghost_role_eligibility
element_flags = ELEMENT_DETACH
element_flags = ELEMENT_DETACH | ELEMENT_BESPOKE
id_arg_index = 3
var/list/timeouts = list()
var/list/mob/eligible_mobs = list()
var/penalizing = FALSE
var/free_ghost = FALSE
/datum/element/ghost_role_eligibility/Attach(datum/target,penalize = FALSE)
/datum/element/ghost_role_eligibility/Attach(datum/target,penalize = FALSE,free_ghosting = FALSE, penalize_on_ghost = FALSE)
. = ..()
if(!ismob(target))
return ELEMENT_INCOMPATIBLE
penalizing = penalize_on_ghost
free_ghost = free_ghosting
var/mob/M = target
if(!(M in eligible_mobs))
eligible_mobs += M
RegisterSignal(M, COMSIG_MOB_GHOSTIZE, .proc/get_ghost_flags)
if(penalize) //penalizing them from making a ghost role / midround antag comeback right away.
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
@@ -32,6 +38,7 @@
. = ..()
if(M in eligible_mobs)
eligible_mobs -= M
UnregisterSignal(M, COMSIG_MOB_GHOSTIZE)
/datum/element/ghost_role_eligibility/proc/get_all_ghost_role_eligible(silent = FALSE)
var/list/candidates = list()
@@ -56,3 +63,11 @@
if(!silent && M.client)
to_chat(M, "<span class='warning'>You are unable to reenter the round[timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(timeout - world.realtime)]" : ""].</span>")
return FALSE
/datum/element/ghost_role_eligibility/proc/get_ghost_flags()
. = 0
if(!penalizing)
. |= COMPONENT_DO_NOT_PENALIZE_GHOSTING
if(free_ghost)
. |= COMPONENT_FREE_GHOSTING
return .
+6
View File
@@ -76,6 +76,7 @@
lefthand_file = 'icons/mob/animals_held_lh.dmi'
icon_state = ""
w_class = WEIGHT_CLASS_BULKY
dynamic_hair_suffix = ""
var/mob/living/held_mob
/obj/item/clothing/head/mob_holder/Initialize(mapload, mob/living/target, worn_state, alt_worn, right_hand, left_hand, slots = NONE)
@@ -162,6 +163,11 @@
L.visible_message("<span class='warning'>[held_mob] escapes from [L]!</span>", "<span class='warning'>[held_mob] escapes your grip!</span>")
release()
/obj/item/clothing/head/mob_holder/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
if(!ishuman(M)) //monkeys holding monkeys holding monkeys...
return FALSE
return ..()
/obj/item/clothing/head/mob_holder/assume_air(datum/gas_mixture/env)
var/atom/location = loc
if(!loc)
+54
View File
@@ -0,0 +1,54 @@
/datum/element/spellcasting //allows to cast certain spells or skip requirements.
element_flags = ELEMENT_BESPOKE|ELEMENT_DETACH
id_arg_index = 2
var/cast_flags
var/cast_slots
var/list/users_by_item = list()
var/list/stacked_spellcasting_by_user = list()
/datum/element/spellcasting/Attach(datum/target, _flags, _slots)
. = ..()
if(isitem(target))
RegisterSignal(target, COMSIG_ITEM_EQUIPPED, .proc/on_equip)
RegisterSignal(target, COMSIG_ITEM_DROPPED, .proc/on_drop)
else if(ismob(target))
RegisterSignal(target, COMSIG_MOB_SPELL_CAST_CHECK, .proc/on_cast)
stacked_spellcasting_by_user[target]++
else
return ELEMENT_INCOMPATIBLE
cast_flags = _flags
cast_slots = _slots
/datum/element/spellcasting/Detach(datum/target)
. = ..()
UnregisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED, COMSIG_MOB_SPELL_CAST_CHECK))
if(users_by_item[target])
var/mob/user = users_by_item[target]
stacked_spellcasting_by_user[user]--
if(!stacked_spellcasting_by_user[user])
stacked_spellcasting_by_user -= user
UnregisterSignal(user, COMSIG_MOB_SPELL_CAST_CHECK)
else if(ismob(target))
stacked_spellcasting_by_user[target]--
if(!stacked_spellcasting_by_user[target])
stacked_spellcasting_by_user -= target
/datum/element/spellcasting/proc/on_equip(datum/source, mob/equipper, slot)
if(!(slot in cast_slots))
return
users_by_item[source] = equipper
if(!stacked_spellcasting_by_user[equipper])
RegisterSignal(equipper, COMSIG_MOB_SPELL_CAST_CHECK, .proc/on_cast)
stacked_spellcasting_by_user[equipper]++
/datum/element/spellcasting/proc/on_drop(datum/source, mob/user)
if(!users_by_item[source])
return
users_by_item -= source
stacked_spellcasting_by_user[user]--
if(!stacked_spellcasting_by_user[user])
stacked_spellcasting_by_user -= user
UnregisterSignal(user, COMSIG_MOB_SPELL_CAST_CHECK)
/datum/element/spellcasting/proc/on_cast(mob/caster, obj/effect/proc_holder/spell)
return cast_flags
+1 -1
View File
@@ -15,4 +15,4 @@
/datum/element/sword_point/proc/point(datum/source, atom/target, mob/user, proximity_flag, params)
if(!proximity_flag && ismob(target))
user.visible_message("<span class='notice'>[user] points the tip of [source] at [target].</span>", "<span class='notice'>You point the tip of [src] at [target].</span>")
user.visible_message("<span class='notice'>[user] points the tip of [source] at [target].</span>", "<span class='notice'>You point the tip of [source] at [target].</span>")
+1 -1
View File
@@ -73,7 +73,7 @@
var/list/atoms_cache = output_atoms
var/sound/S = sound(soundfile)
if(direct)
S.channel = open_sound_channel()
S.channel = SSsounds.random_available_channel()
S.volume = volume
for(var/i in 1 to atoms_cache.len)
var/atom/thing = atoms_cache[i]
+1 -1
View File
@@ -37,7 +37,7 @@
D.apply_damage(damage, STAMINA, affecting, armor_block)
log_combat(A, D, "punched (boxing) ")
if(D.getStaminaLoss() > 100)
if(D.getStaminaLoss() > 100 && istype(D.mind?.martial_art, /datum/martial_art/boxing))
var/knockout_prob = (D.getStaminaLoss() + rand(-15,15))*0.75
if((D.stat != DEAD) && prob(knockout_prob))
D.visible_message("<span class='danger'>[A] has knocked [D] out with a haymaker!</span>", \
+2 -2
View File
@@ -63,11 +63,11 @@
playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, TRUE, -1)
if((D.mobility_flags & MOBILITY_STAND))
D.apply_damage(10, BRUTE, BODY_ZONE_HEAD)
D.DefaultCombatKnockdown(50)
D.DefaultCombatKnockdown(50, override_hardstun = 0.01, override_stamdmg = 0)
D.adjustStaminaLoss(40) //A cit specific change form the tg port to really punish anyone who tries to stand up
D.visible_message("<span class='warning'>[A] kicks [D] in the head, sending them face first into the floor!</span>", \
"<span class='userdanger'>You are kicked in the head by [A], sending you crashing to the floor!</span>", "<span class='hear'>You hear a sickening sound of flesh hitting flesh!</span>", COMBAT_MESSAGE_RANGE, A)
if(!(D.mobility_flags & MOBILITY_STAND))
else if(!(D.mobility_flags & MOBILITY_STAND))
D.apply_damage(5, BRUTE, BODY_ZONE_HEAD)
D.adjustStaminaLoss(40)
D.drop_all_held_items()
+20
View File
@@ -18,6 +18,8 @@
var/datum/action/drop/drop = new/datum/action/drop()
/datum/martial_art/wrestling/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
if(!can_use(A, D))
return 0
switch(streak)
if("drop")
streak = ""
@@ -448,6 +450,8 @@
/datum/martial_art/wrestling/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(check_streak(A,D))
return 1
if(!can_use(A,D))
return ..()
if(A.pulling == D || A == D) // don't stun grab yoursel
return FALSE
A.start_pulling(D)
@@ -476,3 +480,19 @@
if(H.get_item_by_slot(SLOT_BELT) == src)
style.remove(H)
return
//Subtype of wrestling, reserved for the wrestling belts found in the holodeck
/datum/martial_art/wrestling/holodeck
name = "Holodeck Wrestling"
/obj/item/storage/belt/champion/wrestling/holodeck
name = "Holodeck Wrestling Belt"
style = new /datum/martial_art/wrestling/holodeck
//Make sure that moves can only be used on people wearing the holodeck belt
/datum/martial_art/wrestling/holodeck/can_use(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
if(!(istype(D.mind?.martial_art, /datum/martial_art/wrestling/holodeck)))
return 0
else
return ..()
-1
View File
@@ -470,7 +470,6 @@
/datum/objective/steal,
/datum/objective/download,
/datum/objective/nuclear,
/datum/objective/capture,
/datum/objective/absorb,
/datum/objective/custom
)
+9
View File
@@ -31,6 +31,7 @@
//MUT_EXTRA - A mutation that is in the mutations tab, and can be given and taken away through though the DNA console. Has a 0 before it's name in the mutation section of the dna console
//MUT_OTHER Cannot be interacted with by players through normal means. I.E. wizards mutate
var/list/conflicts //any mutations that might conflict. put mutation typepath defines in here. make sure to enter it both ways (so that A conflicts with B, and B with A)
var/can_chromosome = CHROMOSOME_NONE //can we take chromosomes? 0: CHROMOSOME_NEVER never, 1:CHROMOSOME_NONE yeah, 2: CHROMOSOME_USED no, already have one
var/chromosome_name //purely cosmetic
var/modified = FALSE //ugly but we really don't want chromosomes and on_acquiring to overlap and apply double the powers
@@ -60,6 +61,14 @@
return TRUE
if(limb_req && !H.get_bodypart(limb_req))
return TRUE
for(var/M in H.dna.mutations)//check for conflicting powers
var/datum/mutation/human/mewtayshun = M
if(LAZYLEN(mewtayshun.conflicts))
for(var/cons in mewtayshun.conflicts)
var/datum/mutation/human/conflicter = cons
if(conflicter == type)
to_chat(H, "<span class='warning'>You feel your genes resisting something.</span>")
return TRUE
owner = H
dna = H.dna
dna.mutations += src
+7 -10
View File
@@ -41,7 +41,7 @@
desc = "You can breathe fire at a target."
school = "evocation"
charge_max = 600
clothes_req = FALSE
clothes_req = NONE
range = 20
base_icon_state = "fireball"
action_icon_state = "fireball0"
@@ -121,7 +121,7 @@
name = "Convoke Void" //magic the gathering joke here
desc = "A rare genome that attracts odd forces not usually observed. May sometimes pull you in randomly."
school = "evocation"
clothes_req = FALSE
clothes_req = NONE
charge_max = 600
invocation = "DOOOOOOOOOOOOOOOOOOOOM!!!"
invocation_type = "shout"
@@ -155,7 +155,7 @@
dropmessage = "You let the electricity from your hand dissipate."
hand_path = /obj/item/melee/touch_attack/shock
charge_max = 400
clothes_req = FALSE
clothes_req = NONE
action_icon_state = "zap"
/obj/item/melee/touch_attack/shock
@@ -211,7 +211,7 @@
name = "Remember the Scent"
desc = "Get a scent off of the item you're currently holding to track it. With an empty hand, you'll track the scent you've remembered."
charge_max = 100
clothes_req = FALSE
clothes_req = NONE
range = -1
include_user = TRUE
action_icon_state = "nose"
@@ -289,8 +289,7 @@
/obj/effect/proc_holder/spell/self/self_amputation
name = "Drop a limb"
desc = "Concentrate to make a random limb pop right off your body."
clothes_req = FALSE
human_req = FALSE
clothes_req = NONE
charge_max = 100
action_icon_state = "autotomy"
@@ -327,8 +326,7 @@
/obj/effect/proc_holder/spell/self/lay_genetic_web
name = "Lay Web"
desc = "Drops a web. Only you will be able to traverse your web easily, making it pretty good for keeping you safe."
clothes_req = FALSE
human_req = FALSE
clothes_req = NONE
charge_max = 4 SECONDS //the same time to lay a web
action_icon = 'icons/mob/actions/actions_genetic.dmi'
action_icon_state = "lay_web"
@@ -369,8 +367,7 @@
/obj/effect/proc_holder/spell/self/tongue_spike
name = "Launch spike"
desc = "Shoot your tongue out in the direction you're facing, embedding it and dealing damage until they remove it."
clothes_req = FALSE
human_req = TRUE
clothes_req = NONE
charge_max = 100
action_icon = 'icons/mob/actions/actions_genetic.dmi'
action_icon_state = "spike"
+4 -2
View File
@@ -75,20 +75,21 @@
quality = POSITIVE
difficulty = 16
instability = 5
conflicts = list(GIGANTISM)
locked = TRUE // Default intert species for now, so locked from regular pool.
/datum/mutation/human/dwarfism/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.transform = owner.transform.Scale(1, 0.8)
owner.pass_flags |= PASSTABLE
passtable_on(owner, GENETIC_MUTATION)
owner.visible_message("<span class='danger'>[owner] suddenly shrinks!</span>", "<span class='notice'>Everything around you seems to grow..</span>")
/datum/mutation/human/dwarfism/on_losing(mob/living/carbon/human/owner)
if(..())
return
owner.transform = owner.transform.Scale(1, 1.25)
owner.pass_flags &= ~PASSTABLE
passtable_off(owner, GENETIC_MUTATION)
owner.visible_message("<span class='danger'>[owner] suddenly grows!</span>", "<span class='notice'>Everything around you seems to shrink..</span>")
@@ -333,6 +334,7 @@
desc = "The cells within the subject spread out to cover more area, making the subject appear larger."
quality = MINOR_NEGATIVE
difficulty = 12
conflicts = list(DWARFISM)
/datum/mutation/human/gigantism/on_acquiring(mob/living/carbon/human/owner)
if(..())
+5 -3
View File
@@ -18,7 +18,6 @@
name = "Asteroid 1"
description = "I-spy with my little eye, something beginning with R."
/datum/map_template/ruin/space/asteroid2
id = "asteroid2"
suffix = "asteroid2.dmm"
@@ -187,6 +186,7 @@
name = "Abandoned Teleporter"
description = "In space construction the teleporter is often the first system brought online. \
This lonely half built teleporter is a sign of a proposed structure that for one reason or another just never got built."
always_place = TRUE
/datum/map_template/ruin/space/crashedclownship
id = "crashedclownship"
@@ -268,6 +268,7 @@
suffix = "whiteshipdock.dmm"
name = "Whiteship Dock"
description = "An abandoned but functional vessel parked in deep space, ripe for the taking."
always_place = TRUE
/datum/map_template/ruin/space/cat_experiments
id = "meow"
@@ -287,6 +288,7 @@
suffix = "hilbertshoteltestingsite.dmm"
name = "Hilbert Research Facility"
description = "A research facility of great bluespace discoveries. Long since abandoned, willingly or not..."
/datum/map_template/ruin/space/augmentation
id = "augmentationfacility"
suffix = "augmentationfacility.dmm"
@@ -376,13 +378,13 @@
id = "roid8"
suffix = "roid8.dmm"
name = "Dead wizard Roid"
description = "Mineral asteroid. Ft. Dead wizard and toilet paradox bag."
description = "Mineral asteroid. Ft. Dead wizard and toilet wand."
/datum/map_template/ruin/spacenearstation/roid9
id = "roid9"
suffix = "roid9.dmm"
name = "Monitoring Roid"
description = "Mineral asteroid. Ft. Station monitoring, syndie toolbox and erp."
description = "Mineral asteroid. Ft. Station monitoring, toolbox and erp."
/datum/map_template/ruin/spacenearstation/roid10
id = "roid10"
+1
View File
@@ -90,6 +90,7 @@
/datum/status_effect/staggered
id = "staggered"
blocks_sprint = TRUE
alert_type = null
/datum/status_effect/staggered/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration))
-8
View File
@@ -88,14 +88,6 @@
if(quirk_holder)
quirk_holder.remove_client_colour(/datum/client_colour/monochrome)
/datum/quirk/libido
name = "Nymphomania"
desc = "You're always feeling a bit in heat. Also, you get aroused faster than usual."
value = 0
mob_trait = TRAIT_PERMABONER
gain_text = "<span class='notice'>You are feeling extra wild.</span>"
lose_text = "<span class='notice'>You don't feel that burning sensation anymore.</span>"
/datum/quirk/maso
name = "Masochism"
desc = "You are aroused by pain."