* testing, further improvements. Tired.

* FLAK

* Automatic changelog generation for PR #9971 [ci skip]

* Update preferences.dm

* Automatic changelog generation for PR #9736 [ci skip]

* this cannot go wrong

* oop

* Changes required to enable for maintenance protocols

All combat mechs that are special get their internals_access increased so the pilots of the deathsquad / nuke team can fix up their mechs without having to steal a robotics ID. Also removes engineering from being able to access mech internals, seems weird to have if only robotics is allowed to handle mechs, probably remnant of engineering robotics?

* Automatic changelog generation for PR #10115 [ci skip]

* Port boops and handshakes

* Update code/modules/mob/living/carbon/carbon_defense.dm

Co-Authored-By: deathride58 <deathride58@users.noreply.github.com>

* Update code/modules/mob/living/carbon/carbon_defense.dm

Co-Authored-By: deathride58 <deathride58@users.noreply.github.com>

* AAAAA

* Add a nose boop sound

* Add a boop sound effect

* Make the boop louder.

* Fixes pubby wall meds being var-edited snowflakes.

* Commit suggestions

Co-Authored-By: deathride58 <deathride58@users.noreply.github.com>

* Commit suggestions

Co-Authored-By: deathride58 <deathride58@users.noreply.github.com>

* Commit suggestions

Co-Authored-By: deathride58 <deathride58@users.noreply.github.com>

* Commit suggestions

Co-Authored-By: deathride58 <deathride58@users.noreply.github.com>

* Commit suggestions

Co-Authored-By: deathride58 <deathride58@users.noreply.github.com>

* Commit suggestions

Co-Authored-By: deathride58 <deathride58@users.noreply.github.com>

* Fixes AI being unable to talk through the holopad.

* Travis had a stroke.

* ports "Standardize obj/updateicon() and update_icons() to update_icon()"

* Update supply.dm

* Update code/modules/vending/cola.dm

Co-Authored-By: Ghom <42542238+Ghommie@users.noreply.github.com>

* Brings carbon action intent hotkeys down to living.

* Update drink_reagents.dm

* Automatic changelog generation for PR #10180 [ci skip]

* Automatic changelog generation for PR #10181 [ci skip]

* Porting a few martial art code updates.

* Adds gas miners to all maps.

* Compress secK9

* whoops

* Hopefully this won't screw up travis.

* Two slimepeople fixes.

* Automatic changelog generation for PR #10072 [ci skip]

* Automatic changelog generation for PR #10225 [ci skip]

* Update drink_reagents.dm

* Automatic changelog generation for PR #10203 [ci skip]

* Automatic changelog generation for PR #10157 [ci skip]

* Automatic changelog generation for PR #10155 [ci skip]

* Automatic changelog generation for PR #10111 [ci skip]

* Automatic changelog generation for PR #10216 [ci skip]

* Automatic changelog generation for PR #10172 [ci skip]

* Automatic changelog generation for PR #10026 [ci skip]

* Automatic changelog generation for PR #10076 [ci skip]

* Update drinks.dm

* Automatic changelog generation for PR #10153 [ci skip]

* ??

* Update snacks.dm

* oops

* probably fixes only neutral traits existing

* Automatic changelog generation for PR #10227 [ci skip]

* argk

* Chef buffs chef buffs tastier food.

"The strong flavor of" was always in game but someone put it behind an else if statement that would never proc.
Now if there's more than 45% (or 30% if you are a lizzard, hissss) of a reagent in a beaker, you will taste a strong flavor! 
Hurrah!

* Automatic changelog generation for PR #10228 [ci skip]

* fixes the sprites

* Actually hold on

So that not everything in the game now tastes like STRONG FLAVOUR. That'd be annoying.

* Magic number man bad, also all heads can spam CC now

* im baby dumb and removed "a hint of" by accident.

Okay whoops haha there we go now both strong and weak should work.

* oh hey macros.

slightly less ugly ™

* modular man bad.

now mörge this so chefs can make delicious dish, hemk.

* Update carbon.dm

* lolman acctually knows how the stuff work

* AAAAAAAAAAAAAAAAAAAA

* Update flashbang.dm

* thank you based ghomtainer (when)

Co-Authored-By: Ghom <42542238+Ghommie@users.noreply.github.com>

* thank you based ghomtainer (when) 2x how did i not notice this

* Automatic changelog generation for PR #10204 [ci skip]

* Converts the main timsorts file from relative pathing to absolute pathing.

* Ports "Added TRAIT_DISK_VERIFIER, refactors how fake disk checks work slightly"

* wew

* Automatic changelog generation for PR #10090 [ci skip]

* Add the sprite for the landmark

* Make it include my files

* Automatic changelog generation for PR #10067 [ci skip]

* Automatic changelog generation for PR #10160 [ci skip]

* drop

* Automatic changelog generation for PR #10079 [ci skip]

* Automatic changelog generation for PR #10207 [ci skip]

* Automatic changelog generation for PR #10214 [ci skip]

* Update mob.dm

* Update mob.dm

* Redo my changes on Box

Hopefully this will fix the conflict with the fire alarms.

* h

* Automatic changelog generation for PR #10193 [ci skip]

* I'm a god. How can you defeat a god? What a grand and intoxicating innocence, how can you be so naive?

* Automatic changelog generation for PR #10054 [ci skip]

* Automatic changelog generation for PR #10126 [ci skip]

* Automatic changelog generation for PR #10142 [ci skip]

* Automatic changelog generation for PR #10051 [ci skip]

* Automatic changelog generation for PR #9925 [ci skip]

* Automatic changelog generation for PR #9563 [ci skip]

* Atomises out the magicnumber change

* Automatic changelog generation for PR #10231 [ci skip]

* Automatic changelog generation for PR #10235 [ci skip]

* Automatic changelog generation for PR #10200 [ci skip]

* Fix the nose boop.

* Remove extra indentations

* Update inhand_holder.dm

* hhh

* ghom help

* ff

* ff

* Automatic changelog generation for PR #10058 [ci skip]

* Automatic changelog generation for PR #10059 [ci skip]

* Automatic changelog generation for PR #9596 [ci skip]

* Automatic changelog generation for PR #9940 [ci skip]

* Automatic changelog generation for PR #10232 [ci skip]

* Automatic changelog generation for PR #10141 [ci skip]

* Begone crap.

* I gotta go fast.

* QoL Update

Move the Engines to a subfolder to be cleaner when there will be 20 submaps on different maps and change the Tesla Submap to incorporate a few changes I did for the Singulo submap.

* Magic number baaad

* Make things even more organized

* Better safe than sorry.

* Automatic changelog generation for PR #10164 [ci skip]

* Automatic changelog generation for PR #10120 [ci skip]

* Automatic changelog generation for PR #10257 [ci skip]

* typo

* Unnecessary OOC note.

* Is merging someone else's PR you personally fixed considerable as self-merging?

* I'm playing dirty because we have too many PRs to merge anyway.

* Automatic changelog generation for PR #10096 [ci skip]

* Automatic changelog generation for PR #9950 [ci skip]

* Automatic changelog generation for PR #10190 [ci skip]

* Automatic changelog generation for PR #9830 [ci skip]

* Suggestions

* Fix indentation

* lowered to 10 after i struggled to open tickets panel

* FUUUUUUUUUUUCK

* Nerfs fun

* FUUUUUUUUUCK v2

* Automatic changelog generation for PR #10263 [ci skip]

* QoL Update

- Rename the cameras and place two more

- Unanchor the shields generators and emitters because they were bugged and will save more time

- Put more rad closets on the Singulo

- Put more insuls on the Tesla since they protect

- Moved the Engineer clothing locker to Boxstation instead of having it in the Engine

- Added a button to the shutters on the north side of PA

- Added a marker to show where to place the console

- Rewire the power wire to be more in a straight line.

* Forgot a "

* Forgot a button on the Tesla

* Update supply.dm

* readds sprites

* Fills white first aid kits to the brim. Ergo how I was fooled into believing it was a tweak and not a nerf.

* Connect the fuel pipe to somewhere

* no more 40% time dilation

* Update __donator.dm

* Update modular_citadel/code/modules/client/loadout/__donator.dm

Co-Authored-By: Ghom <42542238+Ghommie@users.noreply.github.com>

* Update modular_citadel/code/modules/client/loadout/__donator.dm

Co-Authored-By: Ghom <42542238+Ghommie@users.noreply.github.com>

* Update modular_citadel/code/modules/client/loadout/__donator.dm

Co-Authored-By: Ghom <42542238+Ghommie@users.noreply.github.com>

* Update custom_items.dm

* Automatic changelog generation for PR #10254 [ci skip]

* Fix areas and tiles getting ripped off

* Also give Tesla's emitters R-floors

* Automatic changelog generation for PR #10093 [ci skip]

* Automatic changelog generation for PR #10210 [ci skip]

* Automatic changelog generation for PR #10246 [ci skip]

* Update custom_items.dm

* Automatic changelog generation for PR #10218 [ci skip]

* Automatic changelog generation for PR #10274 [ci skip]

* Add the option to restrict the Engine that spawn

* Revert "Add the option to restrict the Engine that spawn"

This reverts commit e3e1f91635.

* Revert "Revert "Add the option to restrict the Engine that spawn""

This reverts commit d851beea16.

* Add config options

* Move the config up to avoid conflict

* Automatic changelog generation for PR #10245 [ci skip]

Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
Co-authored-by: kevinz000 <2003111+kevinz000@users.noreply.github.com>
Co-authored-by: CitadelStationBot <citadelstationcommunity@gmail.com>
Co-authored-by: Lin <linzolle@gmail.com>
Co-authored-by: kappa-sama <44128284+kappa-sama@users.noreply.github.com>
Co-authored-by: DeltaFire15 <46569814+DeltaFire15@users.noreply.github.com>
Co-authored-by: Useroth <37159550+Useroth@users.noreply.github.com>
Co-authored-by: BlackMajor <henrydyer6@hotmail.com>
Co-authored-by: deathride58 <deathride58@users.noreply.github.com>
Co-authored-by: Putnam3145 <putnam3145@gmail.com>
Co-authored-by: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com>
Co-authored-by: GrayRachnid <Gray_icy@hotmail.com>
Co-authored-by: B1gb3ast <Yeremyrus@live.nl>
Co-authored-by: Seris02 <49109742+Seris02@users.noreply.github.com>
Co-authored-by: lolman360 <22850904+lolman360@users.noreply.github.com>
Co-authored-by: nik707 <38332985+nik707@users.noreply.github.com>
Co-authored-by: LetterJay <9606363+LetterJay@users.noreply.github.com>
This commit is contained in:
r4d6
2019-12-23 13:29:44 -05:00
committed by GitHub
parent 4608b3852d
commit 54b3e3603e
908 changed files with 146032 additions and 135164 deletions
+2 -2
View File
@@ -149,8 +149,8 @@
friend_talk(message)
/mob/camera/imaginary_friend/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
to_chat(src, compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode))
/mob/camera/imaginary_friend/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source)
to_chat(src, compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode, FALSE, source))
/mob/camera/imaginary_friend/proc/friend_talk(message)
message = capitalize(trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)))
+2 -2
View File
@@ -53,7 +53,7 @@
// If you want/expect to be moving the component around between parents, use this to register on the parent for signals
/datum/component/proc/RegisterWithParent()
return
SEND_SIGNAL(src, COMSIG_COMPONENT_REGISTER_PARENT) //CITADEL EDIT
/datum/component/proc/Initialize(...)
return
@@ -85,7 +85,7 @@
UnregisterFromParent()
/datum/component/proc/UnregisterFromParent()
return
SEND_SIGNAL(src, COMSIG_COMPONENT_UNREGISTER_PARENT) //CITADEL EDIT
/datum/proc/RegisterSignal(datum/target, sig_type_or_types, proctype, override = FALSE)
if(QDELETED(src) || QDELETED(target))
+2
View File
@@ -19,12 +19,14 @@
src.damage_multiplier = damage_multiplier
/datum/component/bane/RegisterWithParent()
. = ..()
if(speciestype)
RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/speciesCheck)
else
RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/mobCheck)
/datum/component/bane/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, COMSIG_ITEM_AFTERATTACK)
/datum/component/bane/proc/speciesCheck(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
+2
View File
@@ -21,9 +21,11 @@
RegisterSignal(parent, bounce, .proc/bounce_up)
/datum/component/bouncy/RegisterWithParent()
. = ..()
RegisterSignal(parent, bounce_signals, .proc/bounce_up)
/datum/component/bouncy/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, bounce_signals)
/datum/component/bouncy/proc/bounce_up(datum/source)
+35 -1
View File
@@ -23,17 +23,51 @@
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/onItemAttack)
/datum/component/butchering/proc/onItemAttack(obj/item/source, mob/living/M, mob/living/user)
if(user.a_intent == INTENT_HARM && M.stat == DEAD && (M.butcher_results || M.guaranteed_butcher_results)) //can we butcher it?
if(user.a_intent != INTENT_HARM)
return
if(M.stat == DEAD && (M.butcher_results || M.guaranteed_butcher_results)) //can we butcher it?
if(butchering_enabled && (can_be_blunt || source.get_sharpness()))
INVOKE_ASYNC(src, .proc/startButcher, source, M, user)
return COMPONENT_ITEM_NO_ATTACK
if(ishuman(M) && source.force && source.get_sharpness())
var/mob/living/carbon/human/H = M
if((H.health <= H.crit_threshold || (user.pulling == H && user.grab_state >= GRAB_NECK) || H.IsSleeping()) && user.zone_selected == BODY_ZONE_HEAD) // Only sleeping, neck grabbed, or crit, can be sliced.
if(H.has_status_effect(/datum/status_effect/neck_slice))
user.show_message("<span class='warning'>[H]'s neck has already been already cut, you can't make the bleeding any worse!</span>", 1, \
"<span class='warning'>Their neck has already been already cut, you can't make the bleeding any worse!</span>")
return COMPONENT_ITEM_NO_ATTACK
INVOKE_ASYNC(src, .proc/startNeckSlice, source, H, user)
return COMPONENT_ITEM_NO_ATTACK
/datum/component/butchering/proc/startButcher(obj/item/source, mob/living/M, mob/living/user)
to_chat(user, "<span class='notice'>You begin to butcher [M]...</span>")
playsound(M.loc, butcher_sound, 50, TRUE, -1)
if(do_mob(user, M, speed) && M.Adjacent(source))
Butcher(user, M)
/datum/component/butchering/proc/startNeckSlice(obj/item/source, mob/living/carbon/human/H, mob/living/user)
user.visible_message("<span class='danger'>[user] is slitting [H]'s throat!</span>", \
"<span class='danger'>You start slicing [H]'s throat!</span>", \
"<span class='notice'>You hear a cutting noise!</span>", ignored_mobs = H)
H.show_message("<span class='userdanger'>Your throat is being slit by [user]!</span>", 1, \
"<span class = 'userdanger'>Something is cutting into your neck!</span>", NONE)
log_combat(user, H, "starts slicing the throat of")
playsound(H.loc, butcher_sound, 50, TRUE, -1)
if(do_mob(user, H, CLAMP(500 / source.force, 30, 100)) && H.Adjacent(source))
if(H.has_status_effect(/datum/status_effect/neck_slice))
user.show_message("<span class='warning'>[H]'s neck has already been already cut, you can't make the bleeding any worse!</span>", 1, \
"<span class='warning'>Their neck has already been already cut, you can't make the bleeding any worse!</span>")
return
H.visible_message("<span class='danger'>[user] slits [H]'s throat!</span>", \
"<span class='userdanger'>[user] slits your throat...</span>")
log_combat(user, H, "finishes slicing the throat of")
H.apply_damage(source.force, BRUTE, BODY_ZONE_HEAD)
H.bleed_rate = CLAMP(H.bleed_rate + 20, 0, 30)
H.apply_status_effect(/datum/status_effect/neck_slice)
/datum/component/butchering/proc/Butcher(mob/living/butcher, mob/living/meat)
var/turf/T = meat.drop_location()
var/final_effectiveness = effectiveness - meat.butcher_difficulty
+2
View File
@@ -17,6 +17,7 @@
apply()
/datum/component/decal/RegisterWithParent()
. = ..()
if(first_dir)
RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, .proc/rotate_react)
if(cleanable)
@@ -25,6 +26,7 @@
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
/datum/component/decal/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE))
/datum/component/decal/Destroy()
@@ -30,11 +30,13 @@
return ..()
/datum/component/fantasy/RegisterWithParent()
. = ..()
var/obj/item/master = parent
originalName = master.name
modify()
/datum/component/fantasy/UnregisterFromParent()
. = ..()
unmodify()
/datum/component/fantasy/InheritComponent(datum/component/fantasy/newComp, original, list/arguments)
+2
View File
@@ -9,6 +9,7 @@
src.fire_stacks = fire_stacks
/datum/component/igniter/RegisterWithParent()
. = ..()
if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc
RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit)
else if(isitem(parent))
@@ -17,6 +18,7 @@
RegisterSignal(parent, COMSIG_HOSTILE_ATTACKINGTARGET, .proc/hostile_attackingtarget)
/datum/component/igniter/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT))
/datum/component/igniter/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
+2
View File
@@ -10,6 +10,7 @@
src.throw_anchored = throw_anchored
/datum/component/knockback/RegisterWithParent()
. = ..()
if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc
RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit)
else if(isitem(parent))
@@ -18,6 +19,7 @@
RegisterSignal(parent, COMSIG_HOSTILE_ATTACKINGTARGET, .proc/hostile_attackingtarget)
/datum/component/knockback/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT))
/datum/component/knockback/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
+2
View File
@@ -10,6 +10,7 @@
src.flat_heal = flat_heal
/datum/component/lifesteal/RegisterWithParent()
. = ..()
if(isgun(parent))
RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit)
else if(isitem(parent))
@@ -18,6 +19,7 @@
RegisterSignal(parent, COMSIG_HOSTILE_ATTACKINGTARGET, .proc/hostile_attackingtarget)
/datum/component/lifesteal/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT))
/datum/component/lifesteal/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
-9
View File
@@ -150,15 +150,6 @@
if(9)
setSanity(sanity+0.4, maximum=SANITY_GREAT)
if(HAS_TRAIT(owner, TRAIT_DEPRESSION))
if(prob(0.05))
add_event(null, "depression", /datum/mood_event/depression)
clear_event(null, "jolly")
if(HAS_TRAIT(owner, TRAIT_JOLLY))
if(prob(0.05))
add_event(null, "jolly", /datum/mood_event/jolly)
clear_event(null, "depression")
HandleNutrition(owner)
/datum/component/mood/proc/setSanity(amount, minimum=SANITY_INSANE, maximum=SANITY_NEUTRAL)//I'm sure bunging this in here will have no negative repercussions.
+2
View File
@@ -34,6 +34,7 @@
cloud_sync()
/datum/component/nanites/RegisterWithParent()
. = ..()
RegisterSignal(parent, COMSIG_HAS_NANITES, .proc/confirm_nanites)
RegisterSignal(parent, COMSIG_NANITE_UI_DATA, .proc/nanite_ui_data)
RegisterSignal(parent, COMSIG_NANITE_GET_PROGRAMS, .proc/get_programs)
@@ -57,6 +58,7 @@
RegisterSignal(parent, COMSIG_NANITE_SIGNAL, .proc/receive_signal)
/datum/component/nanites/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_HAS_NANITES,
COMSIG_NANITE_UI_DATA,
COMSIG_NANITE_GET_PROGRAMS,
+2
View File
@@ -20,12 +20,14 @@
begin_orbit(orbiter, radius, clockwise, rotation_speed, rotation_segments, pre_rotation)
/datum/component/orbiter/RegisterWithParent()
. = ..()
var/atom/target = parent
while(ismovableatom(target))
RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/move_react)
target = target.loc
/datum/component/orbiter/UnregisterFromParent()
. = ..()
var/atom/target = parent
while(ismovableatom(target))
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
+1
View File
@@ -106,6 +106,7 @@
if(!can_be_rotated.Invoke(user, rotation) || !can_user_rotate.Invoke(user, rotation))
return
BaseRot(user, rotation)
return TRUE
/datum/component/simple_rotation/proc/WrenchRot(datum/source, obj/item/I, mob/living/user)
if(!can_be_rotated.Invoke(user,default_rotation_direction) || !can_user_rotate.Invoke(user,default_rotation_direction))
+2
View File
@@ -13,10 +13,12 @@
src.override_projectile_range = override_projectile_range
/datum/component/shrapnel/RegisterWithParent()
. = ..()
if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc
RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit)
/datum/component/shrapnel/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_PROJECTILE_ON_HIT))
/datum/component/shrapnel/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle)
+42
View File
@@ -0,0 +1,42 @@
/datum/component/shrink
var/olddens
var/oldopac
dupe_mode = COMPONENT_DUPE_HIGHLANDER
/datum/component/shrink/Initialize(shrink_time)
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
var/atom/parent_atom = parent
parent_atom.transform = parent_atom.transform.Scale(0.5,0.5)
olddens = parent_atom.density
oldopac = parent_atom.opacity
parent_atom.density = 0
parent_atom.opacity = 0
if(isliving(parent_atom))
var/mob/living/L = parent_atom
L.add_movespeed_modifier(MOVESPEED_ID_SHRINK_RAY, update=TRUE, priority=100, multiplicative_slowdown=4)
if(iscarbon(L))
var/mob/living/carbon/C = L
C.unequip_everything()
C.visible_message("<span class='warning'>[C]'s belongings fall off of [C.p_them()] as they shrink down!</span>",
"<span class='userdanger'>Your belongings fall away as everything grows bigger!</span>")
if(ishuman(C))
var/mob/living/carbon/human/H = C
H.physiology.damage_resistance -= 100//carbons take double damage while shrunk
parent_atom.visible_message("<span class='warning'>[parent_atom] shrinks down to a tiny size!</span>",
"<span class='userdanger'>Everything grows bigger!</span>")
QDEL_IN(src, shrink_time)
/datum/component/shrink/Destroy()
var/atom/parent_atom = parent
parent_atom.transform = parent_atom.transform.Scale(2,2)
parent_atom.density = olddens
parent_atom.opacity = oldopac
if(isliving(parent_atom))
var/mob/living/L = parent_atom
L.remove_movespeed_modifier(MOVESPEED_ID_SHRINK_RAY)
if(ishuman(L))
var/mob/living/carbon/human/H = L
H.physiology.damage_resistance += 100
..()
+25
View File
@@ -0,0 +1,25 @@
/datum/component/sizzle
var/mutable_appearance/sizzling
var/sizzlealpha = 0
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
/datum/component/sizzle/Initialize()
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
setup_sizzle()
/datum/component/sizzle/InheritComponent(datum/component/C, i_am_original)
var/atom/food = parent
sizzlealpha += 5
sizzling.alpha = sizzlealpha
food.cut_overlay(sizzling)
food.add_overlay(sizzling)
/datum/component/sizzle/proc/setup_sizzle()
var/atom/food = parent
var/icon/grill_marks = icon(initial(food.icon), initial(food.icon_state)) //we only want to apply grill marks to the initial icon_state for each object
grill_marks.Blend("#fff", ICON_ADD) //fills the icon_state with white (except where it's transparent)
grill_marks.Blend(icon('icons/obj/kitchen.dmi', "grillmarks"), ICON_MULTIPLY) //adds grill marks and the remaining white areas become transparent
sizzling = new(grill_marks)
sizzling.alpha = sizzlealpha
food.add_overlay(sizzling)
+7 -6
View File
@@ -762,7 +762,7 @@
if(!isliving(user) || !user.CanReach(parent))
return
if(check_locked(source, user, TRUE))
return
return TRUE
var/atom/A = parent
if(!quickdraw)
@@ -770,19 +770,20 @@
user_show_to_mob(user)
if(rustle_sound)
playsound(A, "rustle", 50, 1, -5)
return
return TRUE
if(!user.incapacitated())
if(user.can_hold_items() && !user.incapacitated())
var/obj/item/I = locate() in real_location()
if(!I)
return
A.add_fingerprint(user)
remove_from_storage(I, get_turf(user))
if(!user.put_in_hands(I))
to_chat(user, "<span class='notice'>You fumble for [I] and it falls on the floor.</span>")
return
user.visible_message("<span class='warning'>[user] fumbles with the [parent], letting [I] fall on the floor.</span>", \
"<span class='notice'>You fumble with [parent], letting [I] fall on the floor.</span>")
return TRUE
user.visible_message("<span class='warning'>[user] draws [I] from [parent]!</span>", "<span class='notice'>You draw [I] from [parent].</span>")
return
return TRUE
/datum/component/storage/proc/action_trigger(datum/signal_source, datum/action/source)
gather_mode_switch(source.owner)
+2
View File
@@ -24,6 +24,7 @@
src.faction = faction
/datum/component/summoning/RegisterWithParent()
. = ..()
if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc
RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit)
else if(isitem(parent))
@@ -32,6 +33,7 @@
RegisterSignal(parent, COMSIG_HOSTILE_ATTACKINGTARGET, .proc/hostile_attackingtarget)
/datum/component/summoning/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT))
/datum/component/summoning/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters)
+2
View File
@@ -9,10 +9,12 @@
src.allowed_slot = allowed_slot
/datum/component/tactical/RegisterWithParent()
. = ..()
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/modify)
RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/unmodify)
/datum/component/tactical/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED))
unmodify()
+205 -88
View File
@@ -1,128 +1,245 @@
/**
* The virtual reality turned component.
* Originally created to overcome issues of mob polymorphing locking the player inside virtual reality
* and allow for a more "immersive" virtual reality in a virtual reality experience.
* It relies on comically complex order of logic, expect things to break if procs such as mind/transfer_to() are revamped.
* In short, a barebone not so hardcoded VR framework.
* If you plan to add more devices that make use of this component, remember to isolate their code outta here where possible.
*/
/datum/component/virtual_reality
can_transfer = TRUE
var/datum/mind/mastermind // where is my mind t. pixies
//the player's mind (not the parent's), should something happen to them or to their mob.
var/datum/mind/mastermind
//the current mob's mind, which we need to keep track for mind transfer.
var/datum/mind/current_mind
var/obj/machinery/vr_sleeper/vr_sleeper
//the action datum used by the mob to quit the vr session.
var/datum/action/quit_vr/quit_action
//This one's name should be self explainatory, currently used for emags.
var/you_die_in_the_game_you_die_for_real = FALSE
var/datum/component/virtual_reality/inception //The component works on a very fragile link betwixt mind, ckey and death.
//Used to allow people to play recursively playing vr while playing vr without many issues.
var/datum/component/virtual_reality/level_below
var/datum/component/virtual_reality/level_above
//Used to stop the component from executing certain functions that'd cause us some issues otherwise.
//FALSE if there is a connected player, otherwise TRUE.
var/session_paused = TRUE
//Used to stop unwarranted behaviour from happening in cases where the master mind transference is unsupported. Set on Initialize().
var/allow_mastermind_transfer = FALSE
/datum/component/virtual_reality/Initialize(mob/M, obj/machinery/vr_sleeper/gaming_pod, yolo = FALSE, new_char = TRUE)
if(!ismob(parent) || !istype(M))
/datum/component/virtual_reality/Initialize(yolo = FALSE, _allow_mastermind_transfer = FALSE)
var/mob/M = parent
if(!istype(M) || !M.mind)
return COMPONENT_INCOMPATIBLE
var/mob/vr_M = parent
mastermind = M.mind
RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING), .proc/game_over)
RegisterSignal(M, COMSIG_MOB_KEY_CHANGE, .proc/switch_player)
RegisterSignal(mastermind, COMSIG_MIND_TRANSFER, .proc/switch_player)
you_die_in_the_game_you_die_for_real = yolo
quit_action = new()
if(gaming_pod)
vr_sleeper = gaming_pod
RegisterSignal(vr_sleeper, COMSIG_ATOM_EMAG_ACT, .proc/you_only_live_once)
RegisterSignal(vr_sleeper, COMSIG_MACHINE_EJECT_OCCUPANT, .proc/revert_to_reality)
vr_M.ckey = M.ckey
var/datum/component/virtual_reality/clusterfk = M.GetComponent(/datum/component/virtual_reality)
if(clusterfk && !clusterfk.inception)
clusterfk.inception = src
SStgui.close_user_uis(M, src)
allow_mastermind_transfer = _allow_mastermind_transfer
quit_action = new
/datum/component/virtual_reality/Destroy()
QDEL_NULL(quit_action)
if(level_above)
level_above.level_below = null
level_above = null
if(level_below)
level_below.level_above = null
level_below = null
return ..()
/datum/component/virtual_reality/RegisterWithParent()
. = ..()
var/mob/M = parent
current_mind = M.mind
if(!quit_action)
quit_action = new
quit_action.Grant(M)
RegisterSignal(quit_action, COMSIG_ACTION_TRIGGER, .proc/revert_to_reality)
RegisterSignal(quit_action, COMSIG_ACTION_TRIGGER, .proc/action_trigger)
RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING), .proc/game_over)
RegisterSignal(M, COMSIG_MOB_GHOSTIZE, .proc/be_a_quitter)
RegisterSignal(M, COMSIG_MOB_KEY_CHANGE, .proc/pass_me_the_remote)
RegisterSignal(current_mind, COMSIG_MIND_TRANSFER, .proc/pass_me_the_remote)
mastermind.current.audiovisual_redirect = M
if(vr_sleeper)
vr_sleeper.vr_mob = M
RegisterSignal(M, COMSIG_MOB_KEY_CHANGE, .proc/on_player_transfer)
RegisterSignal(current_mind, COMSIG_MIND_TRANSFER, .proc/on_player_transfer)
RegisterSignal(current_mind, COMSIG_PRE_MIND_TRANSFER, .proc/pre_player_transfer)
if(mastermind?.current)
mastermind.current.audiovisual_redirect = M
/datum/component/virtual_reality/UnregisterFromParent()
quit_action.Remove(parent)
. = ..()
if(quit_action)
quit_action.Remove(parent)
UnregisterSignal(quit_action, COMSIG_ACTION_TRIGGER)
UnregisterSignal(parent, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING, COMSIG_MOB_KEY_CHANGE, COMSIG_MOB_GHOSTIZE))
UnregisterSignal(current_mind, COMSIG_MIND_TRANSFER)
UnregisterSignal(quit_action, COMSIG_ACTION_TRIGGER)
UnregisterSignal(current_mind, list(COMSIG_MIND_TRANSFER, COMSIG_PRE_MIND_TRANSFER))
current_mind = null
mastermind.current.audiovisual_redirect = null
if(mastermind?.current)
mastermind.current.audiovisual_redirect = null
/datum/component/virtual_reality/proc/switch_player(datum/source, mob/new_mob, mob/old_mob)
if(vr_sleeper || !new_mob.mind)
// Machineries currently don't deal up with the occupant being polymorphed et similar... Or did something fuck up?
revert_to_reality()
return
old_mob.audiovisual_redirect = null
new_mob.audiovisual_redirect = parent
/datum/component/virtual_reality/proc/action_trigger(datum/signal_source, datum/action/source)
if(source != quit_action)
return COMPONENT_ACTION_BLOCK_TRIGGER
revert_to_reality(signal_source)
/**
* Called when attempting to connect a mob to a virtual reality mob.
* This will return FALSE if the mob is without player or dead. TRUE otherwise
*/
/datum/component/virtual_reality/proc/connect(mob/M)
var/mob/vr_M = parent
if(!M.mind || M.stat == DEAD || !vr_M.mind || vr_M.stat == DEAD)
return FALSE
var/datum/component/virtual_reality/VR = M.GetComponent(/datum/component/virtual_reality)
if(VR)
VR.level_below = src
level_above = VR
M.transfer_ckey(vr_M, FALSE)
mastermind = M.mind
mastermind.current.audiovisual_redirect = parent
RegisterSignal(mastermind, COMSIG_PRE_MIND_TRANSFER, .proc/switch_player)
RegisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING), .proc/game_over)
RegisterSignal(M, COMSIG_MOB_PRE_PLAYER_CHANGE, .proc/player_hijacked)
SStgui.close_user_uis(vr_M, src)
session_paused = FALSE
return TRUE
/**
* emag_act() hook. Makes the game deadlier, killing the mastermind mob too should the parent die.
*/
/datum/component/virtual_reality/proc/you_only_live_once()
if(you_die_in_the_game_you_die_for_real || vr_sleeper?.only_current_user_can_interact)
if(you_die_in_the_game_you_die_for_real)
return FALSE
you_die_in_the_game_you_die_for_real = TRUE
return TRUE
/datum/component/virtual_reality/proc/pass_me_the_remote(datum/source, mob/new_mob)
if(new_mob == mastermind.current)
revert_to_reality(source)
return TRUE
new_mob.TakeComponent(src)
return TRUE
/**
* Called when the mastermind mind is transferred to another mob.
* This is pretty much just going to simply quit the session until machineries support polymorphed occupants etcetera.
*/
/datum/component/virtual_reality/proc/switch_player(datum/source, mob/new_mob, mob/old_mob)
if(session_paused)
return
if(!allow_mastermind_transfer)
quit()
return COMPONENT_STOP_MIND_TRANSFER
UnregisterSignal(old_mob, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING, COMSIG_MOB_PRE_PLAYER_CHANGE))
RegisterSignal(new_mob, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING), .proc/game_over)
RegisterSignal(new_mob, COMSIG_MOB_PRE_PLAYER_CHANGE, .proc/player_hijacked)
old_mob.audiovisual_redirect = null
new_mob.audiovisual_redirect = parent
/**
* Called to stop the player mind from being transferred should the new mob happen to be one of our masterminds'.
* Since the target's mind.current is going to be null'd in the mind transfer process,
* This has to be done in a different signal proc than on_player_transfer(), by then the mastermind.current will be null.
*/
/datum/component/virtual_reality/proc/pre_player_transfer(datum/source, mob/new_mob, mob/old_mob)
if(!mastermind || session_paused)
return
if(new_mob == mastermind.current)
quit()
return COMPONENT_STOP_MIND_TRANSFER
if(!level_above)
return
var/datum/component/virtual_reality/VR = level_above
while(VR)
if(VR.mastermind.current == new_mob)
VR.quit() //this will revert the ckey back to new_mob.
return COMPONENT_STOP_MIND_TRANSFER
VR = VR.level_above
/**
* Called when someone or something else is somewhat about to replace the mastermind's mob key somehow.
* And potentially lock the player in a broken virtual reality plot. Not really something to be proud of.
*/
/datum/component/virtual_reality/proc/player_hijacked(datum/source, mob/our_character, mob/their_character)
if(session_paused)
return
if(!their_character)
quit(cleanup = TRUE)
return
var/will_it_be_handled_in_their_pre_player_transfer = FALSE
var/datum/component/virtual_reality/VR = src
while(VR)
if(VR.parent == their_character)
will_it_be_handled_in_their_pre_player_transfer = TRUE
break
VR = VR.level_below
if(!will_it_be_handled_in_their_pre_player_transfer) //it's not the player playing shenanigeans, abandon all ships.
quit(cleanup = TRUE)
/**
* Takes care of moving the component from a mob to another when their mind or ckey is transferred.
* The very reason this component even exists (else one would be stuck playing as a monky if monkyified)
*/
/datum/component/virtual_reality/proc/on_player_transfer(datum/source, mob/new_mob, mob/old_mob)
new_mob.TakeComponent(src)
/**
* Required for the component to be transferable from mob to mob.
*/
/datum/component/virtual_reality/PostTransfer()
if(!ismob(parent))
return COMPONENT_INCOMPATIBLE
/**
*The following procs simply acts as hooks for quit(), since components do not use callbacks anymore
*/
/datum/component/virtual_reality/proc/action_trigger(datum/signal_source, datum/action/source)
quit()
return COMPONENT_ACTION_BLOCK_TRIGGER
/datum/component/virtual_reality/proc/revert_to_reality(datum/source)
quit_it()
quit()
/datum/component/virtual_reality/proc/game_over(datum/source)
quit_it(TRUE, TRUE)
quit(you_die_in_the_game_you_die_for_real, TRUE)
return COMPONENT_BLOCK_DEATH_BROADCAST
/datum/component/virtual_reality/proc/be_a_quitter(datum/source, can_reenter_corpse)
quit_it()
return COMPONENT_BLOCK_GHOSTING
/datum/component/virtual_reality/proc/be_a_quitter(datum/source, can_reenter_corpse, special = FALSE, penalize = FALSE)
if(!special)
quit()
return COMPONENT_BLOCK_GHOSTING
/datum/component/virtual_reality/proc/virtual_reality_in_a_virtual_reality(mob/player, killme = FALSE, datum/component/virtual_reality/yo_dawg)
/datum/component/virtual_reality/proc/machine_destroyed(datum/source)
quit(cleanup = TRUE)
/**
* Takes care of deleting itself, moving the player back to the mastermind's current and queueing the parent for deletion.
* It supports nested virtual realities by recursively calling vr_in_a_vr(), which in turns calls quit(),
* up to the deepest level, where the ckey will be transferred back to our mastermind's mob instead.
* The above operation is skipped when session_paused is TRUE (ergo no player in control of the current mob).
* vars:
* * deathcheck is used to kill the master, you want this FALSE unless for stuff that doesn't involve emagging.
* * cleanup is used to queue the parent for the next vr_clean_master's run, where they'll be deleted should they be dead.
* * mob/override is used for the recursive virtual reality explained above and shouldn't be used outside of vr_in_a_vr().
*/
/datum/component/virtual_reality/proc/quit(deathcheck = FALSE, cleanup = FALSE, mob/override)
var/mob/M = parent
quit_it(FALSE, killme, player, yo_dawg)
yo_dawg.inception = null
if(killme)
M.death(FALSE)
/datum/component/virtual_reality/proc/quit_it(deathcheck = FALSE, cleanup = FALSE, mob/override)
var/mob/M = parent
var/mob/dreamer = override ? override : mastermind.current
if(!mastermind)
to_chat(M, "<span class='warning'>You feel a dreadful sensation, something terrible happened. You try to wake up, but you find yourself unable to...</span>")
else
var/key_transfer = FALSE
if(inception?.parent)
inception.virtual_reality_in_a_virtual_reality(dreamer, cleanup, src)
if(!session_paused)
session_paused = TRUE
var/mob/dreamer = override || mastermind.current
if(!dreamer) //This shouldn't happen.
stack_trace("virtual reality component quit() called without a mob to transfer the parent ckey to.")
to_chat(M, "<span class='warning'>You feel a dreadful sensation, something terrible happened. You try to wake up, but you find yourself unable to...</span>")
qdel(src)
return
if(level_below?.parent)
level_below.vr_in_a_vr(dreamer, deathcheck, (deathcheck && cleanup))
else
key_transfer = TRUE
if(key_transfer)
M.transfer_ckey(dreamer, FALSE)
dreamer.stop_sound_channel(CHANNEL_HEARTBEAT)
dreamer.audiovisual_redirect = null
if(deathcheck && you_die_in_the_game_you_die_for_real)
to_chat(mastermind, "<span class='warning'>You feel everything fading away...</span>")
dreamer.death(FALSE)
if(cleanup)
var/obj/effect/vr_clean_master/cleanbot = locate() in get_area(M)
if(cleanbot)
LAZYADD(cleanbot.corpse_party, M)
if(vr_sleeper)
vr_sleeper.vr_mob = null
vr_sleeper = null
qdel(src)
if(deathcheck)
to_chat(dreamer, "<span class='warning'>You feel everything fading away...</span>")
dreamer.death(FALSE)
mastermind.current.audiovisual_redirect = null
if(!cleanup)
if(level_above)
level_above.level_below = null
level_above = null
UnregisterSignal(mastermind.current, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING, COMSIG_MOB_PRE_PLAYER_CHANGE))
UnregisterSignal(mastermind, COMSIG_PRE_MIND_TRANSFER)
mastermind = null
if(cleanup)
var/obj/effect/vr_clean_master/cleanbot = locate() in get_area(M)
if(cleanbot)
LAZYOR(cleanbot.corpse_party, M)
qdel(src)
/datum/component/virtual_reality/Destroy()
var/datum/action/quit_vr/delet_me = quit_action
. = ..()
qdel(delet_me)
/**
* Used for recursive virtual realities shenanigeans and should be called only through the above proc.
*/
/datum/component/virtual_reality/proc/vr_in_a_vr(mob/player, deathcheck = FALSE, lethal_cleanup = FALSE)
var/mob/M = parent
quit(deathcheck, lethal_cleanup, player)
M.audiovisual_redirect = null
if(lethal_cleanup)
M.death(FALSE)
+2
View File
@@ -34,10 +34,12 @@
last_process = world.time
/datum/component/wet_floor/RegisterWithParent()
. = ..()
RegisterSignal(parent, COMSIG_TURF_IS_WET, .proc/is_wet)
RegisterSignal(parent, COMSIG_TURF_MAKE_DRY, .proc/dry)
/datum/component/wet_floor/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(COMSIG_TURF_IS_WET, COMSIG_TURF_MAKE_DRY))
/datum/component/wet_floor/Destroy()
+1 -1
View File
@@ -255,7 +255,7 @@
M.fields["alg_d"] = "No allergies have been detected in this patient."
M.fields["cdi"] = "None"
M.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
M.fields["notes"] = "No notes."
M.fields["notes"] = H.get_trait_string(medical)
medical += M
//Security Record
+26
View File
@@ -1398,3 +1398,29 @@
var/mob/living/carbon/human/H = locate(href_list["copyoutfit"]) in GLOB.carbon_list
if(istype(H))
H.copy_outfit()
else if(href_list["modquirks"])
if(!check_rights(R_SPAWN))
return
var/mob/living/carbon/human/H = locate(href_list["modquirks"]) in GLOB.mob_list
if(!istype(H))
to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human")
return
var/list/options = list("Clear"="Clear")
for(var/x in subtypesof(/datum/quirk))
var/datum/quirk/T = x
var/qname = initial(T.name)
options[H.has_quirk(T) ? "[qname] (Remove)" : "[qname] (Add)"] = T
var/result = input(usr, "Choose quirk to add/remove","Quirk Mod") as null|anything in options
if(result)
if(result == "Clear")
for(var/datum/quirk/q in H.roundstart_quirks)
H.remove_quirk(q.type)
else
var/T = options[result]
if(H.has_quirk(T))
H.remove_quirk(T)
else
H.add_quirk(T,TRUE)
-1
View File
@@ -254,7 +254,6 @@
if(icon_update)
update_body()
update_hair()
update_body_parts()
update_mutations_overlay()// no lizard with human hulk overlay please.
+1
View File
@@ -27,6 +27,7 @@ GLOBAL_LIST_INIT(huds, list(
ANTAG_HUD_SOULLESS = new/datum/atom_hud/antag/hidden(),
ANTAG_HUD_CLOCKWORK = new/datum/atom_hud/antag(),
ANTAG_HUD_BROTHER = new/datum/atom_hud/antag/hidden(),
ANTAG_HUD_BLOODSUCKER = new/datum/atom_hud/antag/bloodsucker()
))
/datum/atom_hud
+11 -2
View File
@@ -4,7 +4,7 @@
mid_sounds = list('sound/machines/shower/shower_mid1.ogg'=1,'sound/machines/shower/shower_mid2.ogg'=1,'sound/machines/shower/shower_mid3.ogg'=1)
mid_length = 10
end_sound = 'sound/machines/shower/shower_end.ogg'
volume = 20
volume = 10
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -32,7 +32,7 @@
mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1)
mid_length = 2
end_sound = 'sound/machines/fryer/deep_fryer_emerge.ogg'
volume = 15
volume = 5
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -43,3 +43,12 @@
mid_length = 10
end_sound = 'sound/machines/microwave/microwave-end.ogg'
volume = 90
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/looping_sound/grill
mid_length = 2
mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1)
volume = 10
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+6 -6
View File
@@ -8,9 +8,7 @@
var/deflection_chance = 0 //Chance to deflect projectiles
var/reroute_deflection = FALSE //Delete the bullet, or actually deflect it in some direction?
var/block_chance = 0 //Chance to block melee attacks using items while on throw mode.
var/restraining = 0 //used in cqc's disarm_act to check if the disarmed is being restrained and so whether they should be put in a chokehold or not
var/help_verb
var/no_guns = FALSE
var/pacifism_check = TRUE //are the martial arts combos/attacks unable to be used by pacifist.
var/allow_temp_override = TRUE //if this martial art can be overridden by temporary martial arts
@@ -28,14 +26,16 @@
/datum/martial_art/proc/add_to_streak(element,mob/living/carbon/human/D)
if(D != current_target)
current_target = D
streak = ""
restraining = 0
reset_streak(D)
streak = streak+element
if(length(streak) > max_streak_length)
streak = copytext(streak,2)
return
/datum/martial_art/proc/reset_streak(mob/living/carbon/human/new_target)
current_target = new_target
streak = ""
/datum/martial_art/proc/basic_hit(mob/living/carbon/human/A,mob/living/carbon/human/D)
var/damage = rand(A.dna.species.punchdamagelow, A.dna.species.punchdamagehigh)
@@ -81,7 +81,7 @@
D.forcesay(GLOB.hit_appends)
return 1
/datum/martial_art/proc/teach(mob/living/carbon/human/H,make_temporary=0)
/datum/martial_art/proc/teach(mob/living/carbon/human/H, make_temporary = FALSE)
if(!istype(H) || !H.mind)
return FALSE
if(H.mind.martial_art)
+35 -34
View File
@@ -9,24 +9,13 @@
id = MARTIALART_CQC
help_verb = /mob/living/carbon/human/proc/CQC_help
block_chance = 75
var/just_a_cook = FALSE
var/static/list/areas_under_siege = typecacheof(list(/area/crew_quarters/kitchen,
/area/crew_quarters/cafeteria,
/area/crew_quarters/bar))
var/old_grab_state = null
var/restraining = FALSE
/datum/martial_art/cqc/under_siege
name = "Close Quarters Cooking"
just_a_cook = TRUE
/datum/martial_art/cqc/proc/drop_restraining()
/datum/martial_art/cqc/reset_streak(mob/living/carbon/human/new_target)
. = ..()
restraining = FALSE
/datum/martial_art/cqc/can_use(mob/living/carbon/human/H)
var/area/A = get_area(H)
if(just_a_cook && !(is_type_in_typecache(A, areas_under_siege)))
return FALSE
return ..()
/datum/martial_art/cqc/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!can_use(A))
return FALSE
@@ -75,6 +64,7 @@
D.apply_damage(10, BRUTE)
log_combat(A, D, "kicked (CQC)")
if(D.IsKnockdown() && !D.stat)
log_combat(A, D, "knocked out (Head kick)(CQC)")
D.visible_message("<span class='warning'>[A] kicks [D]'s head, knocking [D.p_them()] out!</span>", \
"<span class='userdanger'>[A] kicks your head, knocking you out!</span>")
playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1)
@@ -85,7 +75,8 @@
/datum/martial_art/cqc/proc/Pressure(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!can_use(A))
return FALSE
D.visible_message("<span class='warning'>[A] forces their arm on [D]'s neck!</span>")
log_combat(A, D, "pressured (CQC)")
D.visible_message("<span class='warning'>[A] punches [D]'s neck!</span>")
D.adjustStaminaLoss(60)
playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
return TRUE
@@ -96,18 +87,20 @@
if(!can_use(A))
return FALSE
if(!D.stat)
log_combat(A, D, "restrained (CQC)")
D.visible_message("<span class='warning'>[A] locks [D] into a restraining position!</span>", \
"<span class='userdanger'>[A] locks you into a restraining position!</span>")
D.adjustStaminaLoss(20)
D.Stun(100)
restraining = TRUE
addtimer(CALLBACK(src, .proc/drop_restraining), 50, TIMER_UNIQUE)
addtimer(VARSET_CALLBACK(src, restraining, FALSE), 50, TIMER_UNIQUE)
return TRUE
/datum/martial_art/cqc/proc/Consecutive(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!can_use(A))
return FALSE
if(!D.stat)
log_combat(A, D, "consecutive CQC'd (CQC)")
D.visible_message("<span class='warning'>[A] strikes [D]'s abdomen, neck and back consecutively</span>", \
"<span class='userdanger'>[A] strikes your abdomen, neck and back consecutively!</span>")
playsound(get_turf(D), 'sound/weapons/cqchit2.ogg', 50, 1, -1)
@@ -119,23 +112,20 @@
return TRUE
/datum/martial_art/cqc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!can_use(A))
return FALSE
add_to_streak("G",D)
if(check_streak(A,D))
return TRUE
if(A == D) // no self grab.
return FALSE
if(A.grab_state >= GRAB_AGGRESSIVE)
if(A.a_intent == INTENT_GRAB && A!=D && can_use(A)) // A!=D prevents grabbing yourself
add_to_streak("G",D)
if(check_streak(A,D)) //if a combo is made no grab upgrade is done
return TRUE
old_grab_state = A.grab_state
D.grabbedby(A, 1)
else
A.start_pulling(D, 1)
if(A.pulling)
D.stop_pulling()
if(old_grab_state == GRAB_PASSIVE)
D.drop_all_held_items()
A.grab_state = GRAB_AGGRESSIVE //Instant agressive grab if on grab intent
log_combat(A, D, "grabbed", addition="aggressively")
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
return TRUE
D.visible_message("<span class='warning'>[A] violently grabs [D]!</span>", \
"<span class='userdanger'>[A] violently grabs you!</span>")
return TRUE
return FALSE
/datum/martial_art/cqc/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!can_use(A))
@@ -190,6 +180,7 @@
playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
log_combat(A, D, "disarmed (CQC)", "[I ? " grabbing \the [I]" : ""]")
if(restraining && A.pulling == D)
log_combat(A, D, "knocked out (Chokehold)(CQC)")
D.visible_message("<span class='danger'>[A] puts [D] into a chokehold!</span>", \
"<span class='userdanger'>[A] puts you into a chokehold!</span>")
D.SetSleeping(400)
@@ -208,9 +199,19 @@
to_chat(usr, "<b><i>You try to remember some of the basics of CQC.</i></b>")
to_chat(usr, "<span class='notice'>Slam</span>: Grab Harm. Slam opponent into the ground, knocking them down.")
to_chat(usr, "<span class='notice'>CQC Kick</span>: Disarm Harm Harm. Knocks opponent away. Knocks out stunned or knocked down opponents.")
to_chat(usr, "<span class='notice'>Restrain</span>: Grab Grab. Locks opponents into a restraining position, disarm to knock them out with a choke hold.")
to_chat(usr, "<span class='notice'>CQC Kick</span>: Harm Harm. Knocks opponent away. Knocks out stunned or knocked down opponents.")
to_chat(usr, "<span class='notice'>Restrain</span>: Grab Grab. Locks opponents into a restraining position, disarm to knock them out with a chokehold.")
to_chat(usr, "<span class='notice'>Pressure</span>: Disarm Grab. Decent stamina damage.")
to_chat(usr, "<span class='notice'>Consecutive CQC</span>: Disarm Disarm Harm. Mainly offensive move, huge damage and decent stamina damage.")
to_chat(usr, "<b><i>In addition, by having your throw mode on when being attacked, you enter an active defense mode where you have a chance to block and sometimes even counter attacks done to you.</i></b>")
///Subtype of CQC. Only used for the chef.
/datum/martial_art/cqc/under_siege
name = "Close Quarters Cooking"
///Prevents use if the cook is not in the kitchen.
/datum/martial_art/cqc/under_siege/can_use(mob/living/carbon/human/H) //this is used to make chef CQC only work in kitchen
if(!istype(get_area(H), /area/crew_quarters/kitchen))
return FALSE
return ..()
+55 -47
View File
@@ -9,35 +9,36 @@
id = MARTIALART_SLEEPINGCARP
deflection_chance = 100
reroute_deflection = TRUE
no_guns = TRUE
allow_temp_override = FALSE
help_verb = /mob/living/carbon/human/proc/sleeping_carp_help
var/old_grab_state = null
/datum/martial_art/the_sleeping_carp/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(findtext(streak,WRIST_WRENCH_COMBO))
streak = ""
wristWrench(A,D)
return 1
return TRUE
if(findtext(streak,BACK_KICK_COMBO))
streak = ""
backKick(A,D)
return 1
return TRUE
if(findtext(streak,STOMACH_KNEE_COMBO))
streak = ""
kneeStomach(A,D)
return 1
return TRUE
if(findtext(streak,HEAD_KICK_COMBO))
streak = ""
headKick(A,D)
return 1
return TRUE
if(findtext(streak,ELBOW_DROP_COMBO))
streak = ""
elbowDrop(A,D)
return 1
return 0
return TRUE
return FALSE
/datum/martial_art/the_sleeping_carp/proc/wristWrench(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.stat && !D.IsStun() && !D.IsKnockdown())
log_combat(A, D, "wrist wrenched (Sleeping Carp)")
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
D.visible_message("<span class='warning'>[A] grabs [D]'s wrist and wrenches it sideways!</span>", \
"<span class='userdanger'>[A] grabs your wrist and violently wrenches it to the side!</span>")
@@ -46,24 +47,29 @@
D.dropItemToGround(D.get_active_held_item())
D.apply_damage(5, BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM))
D.Knockdown(60)//CIT CHANGE - makes sleepingcarp use knockdown() for its stuns instead of stun()
return 1
log_combat(A, D, "wrist wrenched (Sleeping Carp)")
return TRUE
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/backKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(A.dir == D.dir && !D.stat && !D.IsKnockdown())
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
D.visible_message("<span class='warning'>[A] kicks [D] in the back!</span>", \
"<span class='userdanger'>[A] kicks you in the back, making you stumble and fall!</span>")
step_to(D,get_step(D,D.dir),1)
D.Knockdown(80)
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
return 1
log_combat(A, D, "back-kicked (Sleeping Carp)")
if(!D.stat && !D.IsKnockdown())
if(A.dir == D.dir)
log_combat(A, D, "back-kicked (Sleeping Carp)")
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
D.visible_message("<span class='warning'>[A] kicks [D] in the back!</span>", \
"<span class='userdanger'>[A] kicks you in the back, making you stumble and fall!</span>")
step_to(D,get_step(D,D.dir),1)
D.Knockdown(80)
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
return TRUE
else
log_combat(A, D, "missed a back-kick (Sleeping Carp) on")
D.visible_message("<span class='warning'>[A] tries to kick [D] in the back, but misses!</span>", \
"<span class='userdanger'>[A] tries to kick you in the back, but misses!</span>")
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/kneeStomach(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.stat && !D.IsKnockdown())
log_combat(A, D, "stomach kneed (Sleeping Carp)")
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
D.visible_message("<span class='warning'>[A] knees [D] in the stomach!</span>", \
"<span class='userdanger'>[A] winds you with a knee in the stomach!</span>")
@@ -71,12 +77,12 @@
D.losebreath += 3
D.Knockdown(40)//CIT CHANGE - makes sleepingcarp use knockdown() for its stuns instead of stun()
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
return 1
log_combat(A, D, "stomach kneed (Sleeping Carp)")
return TRUE
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/headKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.stat && !D.IsKnockdown())
log_combat(A, D, "head kicked (Sleeping Carp)")
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
D.visible_message("<span class='warning'>[A] kicks [D] in the head!</span>", \
"<span class='userdanger'>[A] kicks you in the jaw!</span>")
@@ -84,12 +90,12 @@
D.drop_all_held_items()
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
D.Knockdown(80)//CIT CHANGE - makes sleepingcarp use knockdown() for its stuns instead of stun()
return 1
log_combat(A, D, "head kicked (Sleeping Carp)")
return TRUE
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/elbowDrop(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(D.IsKnockdown() || D.resting || D.stat)
log_combat(A, D, "elbow dropped (Sleeping Carp)")
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
D.visible_message("<span class='warning'>[A] elbow drops [D]!</span>", \
"<span class='userdanger'>[A] piledrives you with their elbow!</span>")
@@ -97,37 +103,29 @@
D.death() //FINISH HIM!
D.apply_damage(50, BRUTE, BODY_ZONE_CHEST)
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 75, 1, -1)
return 1
log_combat(A, D, "elbow dropped (Sleeping Carp)")
return TRUE
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
add_to_streak("G",D)
if(check_streak(A,D))
return 1
if(A == D) //no self grab stun
return FALSE
if(A.grab_state >= GRAB_AGGRESSIVE)
if(A.a_intent == INTENT_GRAB && A!=D) // A!=D prevents grabbing yourself
add_to_streak("G",D)
if(check_streak(A,D)) //if a combo is made no grab upgrade is done
return TRUE
old_grab_state = A.grab_state
D.grabbedby(A, 1)
else
A.start_pulling(D, 1)
if(A.pulling)
if(old_grab_state == GRAB_PASSIVE)
D.drop_all_held_items()
D.stop_pulling()
if(A.a_intent == INTENT_GRAB)
log_combat(A, D, "grabbed", addition="aggressively")
D.visible_message("<span class='warning'>[A] violently grabs [D]!</span>", \
"<span class='userdanger'>[A] violently grabs you!</span>")
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
else
log_combat(A, D, "grabbed", addition="passively")
A.grab_state = GRAB_PASSIVE
return 1
A.grab_state = GRAB_AGGRESSIVE //Instant agressive grab if on grab intent
log_combat(A, D, "grabbed", addition="aggressively")
D.visible_message("<span class='warning'>[A] violently grabs [D]!</span>", \
"<span class='userdanger'>[A] violently grabs you!</span>")
return TRUE
return FALSE
/datum/martial_art/the_sleeping_carp/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
add_to_streak("H",D)
if(check_streak(A,D))
return 1
return TRUE
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
var/atk_verb = pick("punches", "kicks", "chops", "hits", "slams")
D.visible_message("<span class='danger'>[A] [atk_verb] [D]!</span>", \
@@ -138,15 +136,25 @@
D.visible_message("<span class='warning'>[D] stumbles and falls!</span>", "<span class='userdanger'>The blow sends you to the ground!</span>")
D.Knockdown(80)
log_combat(A, D, "[atk_verb] (Sleeping Carp)")
return 1
return TRUE
/datum/martial_art/the_sleeping_carp/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
add_to_streak("D",D)
if(check_streak(A,D))
return 1
return TRUE
return ..()
/datum/martial_art/the_sleeping_carp/teach(mob/living/carbon/human/H, make_temporary = FALSE)
. = ..()
if(!.)
return
ADD_TRAIT(H, TRAIT_NOGUNS, SLEEPING_CARP_TRAIT)
/datum/martial_art/the_sleeping_carp/on_remove(mob/living/carbon/human/H)
. = ..()
REMOVE_TRAIT(H, TRAIT_NOGUNS, SLEEPING_CARP_TRAIT)
/mob/living/carbon/human/proc/sleeping_carp_help()
set name = "Recall Teachings"
set desc = "Remember the martial techniques of the Sleeping Carp clan."
@@ -233,4 +241,4 @@
/obj/item/twohanded/bostaff/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(wielded)
return ..()
return 0
return FALSE
+5 -1
View File
@@ -88,6 +88,9 @@
/datum/mind/proc/transfer_to(mob/new_character, var/force_key_move = 0)
var/old_character = current
var/signals = SEND_SIGNAL(new_character, COMSIG_MOB_PRE_PLAYER_CHANGE, new_character, old_character) | SEND_SIGNAL(src, COMSIG_PRE_MIND_TRANSFER, new_character, old_character)
if(signals & COMPONENT_STOP_MIND_TRANSFER)
return
if(current) // remove ourself from our old body's mind variable
current.mind = null
SStgui.on_transfer(current, new_character)
@@ -125,7 +128,6 @@
transfer_martial_arts(new_character)
if(active || force_key_move)
new_character.key = key //now transfer the key to link the client to our new body
SEND_SIGNAL(src, COMSIG_MIND_TRANSFER, new_character, old_character)
//CIT CHANGE - makes arousal update when transfering bodies
if(isliving(new_character)) //New humans and such are by default enabled arousal. Let's always use the new mind's prefs.
@@ -134,6 +136,8 @@
L.canbearoused = L.client.prefs.arousable //Technically this should make taking over a character mean the body gain the new minds setting...
L.update_arousal_hud() //Removes the old icon
SEND_SIGNAL(src, COMSIG_MIND_TRANSFER, new_character, old_character)
/datum/mind/proc/store_memory(new_text)
if((length(memory) + length(new_text)) <= MAX_MESSAGE_LEN)
memory += "[new_text]<BR>"
@@ -198,3 +198,48 @@
description = "<span class='nicegreen'>It feels quite cold out here.</span>\n"
mood_change = -2
timeout = 1 MINUTES
/datum/mood_event/vampcandle
description = "<span class='umbra'>Something is making your mind feel... loose...</span>\n"
mood_change = -10
timeout = 1 MINUTES
/datum/mood_event/drankblood_bad
description = "<span class='boldwarning'>I drank the blood of a lesser creature. Disgusting.</span>\n"
mood_change = -4
timeout = 900
/datum/mood_event/drankblood_dead
description = "<span class='boldwarning'>I drank dead blood. I am better than this.</span>\n"
mood_change = -7
timeout = 900
/datum/mood_event/drankblood_synth
description = "<span class='boldwarning'>I drank synthetic blood. What is wrong with me?</span>\n"
mood_change = -7
timeout = 900
/datum/mood_event/drankkilled
description = "<span class='boldwarning'>I drank from my victim until they died. I feel...less human.</span>\n"
mood_change = -12
timeout = 6000
/datum/mood_event/madevamp
description = "<span class='boldwarning'>A soul has been cursed to undeath by my own hand.</span>\n"
mood_change = -10
timeout = 10000
/datum/mood_event/vampatefood
description = "<span class='boldwarning'>Mortal nourishment no longer sustains me. I feel unwell.</span>\n"
mood_change = -6
timeout = 1000
/datum/mood_event/daylight_1
description = "<span class='boldwarning'>I slept poorly in a makeshift coffin during the day.</span>\n"
mood_change = -3
timeout = 1000
/datum/mood_event/daylight_2
description = "<span class='boldwarning'>I have been scorched by the unforgiving rays of the sun.</span>\n"
mood_change = -6
timeout = 1200
@@ -134,6 +134,22 @@
mood_change = 3
timeout = 3000
/datum/mood_event/breakfast
description = "<span class='nicegreen'>Nothing like a hearty breakfast to start the shift.</span>\n"
mood_change = 2
timeout = 15 MINUTES
//Power gamer stuff below
/datum/mood_event/drankblood
description = "<span class='nicegreen'>I have fed greedly from that which nourishes me.</span>\n"
mood_change = 10
timeout = 900
/datum/mood_event/coffinsleep
description = "<span class='nicegreen'>I slept in a coffin during the day. I feel whole again.</span>\n"
mood_change = 8
timeout = 1200
//Cursed stuff below.
/datum/mood_event/orgasm
@@ -148,3 +164,8 @@
/datum/mood_event/fedprey
description = "<span class='nicegreen'>It feels quite cozy in here.</span>\n"
mood_change = 3
/datum/mood_event/hope_lavaland
description = "<span class='nicegreen'>What a peculiar emblem. It makes me feel hopeful for my future.</span>\n"
mood_change = 5
+3 -1
View File
@@ -5,7 +5,7 @@
get_chance = 15
lowest_value = 256 * 12
text_gain_indication = "<span class='notice'>Your muscles hurt!</span>"
species_allowed = list("human") //no skeleton/lizard hulk
species_allowed = list("fly") //no skeleton/lizard hulk
health_req = 25
/datum/mutation/human/hulk/on_acquiring(mob/living/carbon/human/owner)
@@ -13,6 +13,7 @@
return
ADD_TRAIT(owner, TRAIT_STUNIMMUNE, TRAIT_HULK)
ADD_TRAIT(owner, TRAIT_PUSHIMMUNE, TRAIT_HULK)
ADD_TRAIT(owner, TRAIT_CHUNKYFINGERS, TRAIT_HULK)
owner.update_body_parts()
SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "hulk", /datum/mood_event/hulk)
RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech)
@@ -31,6 +32,7 @@
return
REMOVE_TRAIT(owner, TRAIT_STUNIMMUNE, TRAIT_HULK)
REMOVE_TRAIT(owner, TRAIT_PUSHIMMUNE, TRAIT_HULK)
ADD_TRAIT(owner, TRAIT_CHUNKYFINGERS, TRAIT_HULK)
owner.update_body_parts()
SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "hulk")
UnregisterSignal(owner, COMSIG_MOB_SAY)
+1
View File
@@ -95,6 +95,7 @@
message = replacetext(message," ugly "," beautiful ")
message = replacetext(message," douchbag "," nice guy ")
message = replacetext(message," whore "," lady ")
message = replacetext(message," gamer "," intellectual ")
message = replacetext(message," nerd "," smarty pants ")
message = replacetext(message," moron "," fun person ")
message = replacetext(message," IT'S LOOSE "," EVERYTHING IS FINE ")
+10 -1
View File
@@ -229,4 +229,13 @@
id = "puzzle"
description = "Mystery to be solved."
suffix = "lavaland_surface_puzzle.dmm"
cost = 5
cost = 5
/datum/map_template/ruin/lavaland/elite_tumor
name = "Pulsating Tumor"
id = "tumor"
description = "A strange tumor which houses a powerful beast..."
suffix = "lavaland_surface_elite_tumor.dmm"
cost = 5
always_place = TRUE
allow_duplicates = TRUE
+6 -3
View File
@@ -2,17 +2,20 @@
prefix = "_maps/RandomRuins/StationRuins/"
cost = 0
// Boxstation
// Engine
/datum/map_template/ruin/station/box/engine
id = "engine_sm"
suffix = "engine_sm.dmm"
suffix = "Box/Engine/engine_sm.dmm"
name = "Engine SM"
/datum/map_template/ruin/station/box/engine/singulo
id = "engine_singulo"
suffix = "engine_singulo.dmm"
suffix = "Box/Engine/engine_singulo.dmm"
name = "Engine Singulo"
/datum/map_template/ruin/station/box/engine/tesla
id = "engine_tesla"
suffix = "engine_tesla.dmm"
suffix = "Box/Engine/engine_tesla.dmm"
name = "Engine Tesla"
+49 -11
View File
@@ -80,34 +80,55 @@
desc = "You've fallen asleep. Wait a bit and you should wake up. Unless you don't, considering how helpless you are."
icon_state = "asleep"
//TASER
/datum/status_effect/electrode
id = "tased"
/datum/status_effect/no_combat_mode/
id = "no_combat_mode"
blocks_combatmode = TRUE
status_type = STATUS_EFFECT_REPLACE
alert_type = null
status_type = STATUS_EFFECT_REPLACE
/datum/status_effect/electrode/on_creation(mob/living/new_owner, set_duration)
/datum/status_effect/no_combat_mode/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration))
duration = set_duration
. = ..()
if(iscarbon(owner))
var/mob/living/carbon/C = owner
if(C.combatmode)
C.toggle_combat_mode(TRUE)
/datum/status_effect/no_combat_mode/mesmerize
id = "Mesmerize"
alert_type = /obj/screen/alert/status_effect/mesmerized
/obj/screen/alert/status_effect/mesmerized
name = "Mesmerized"
desc = "You cant tear your sight from who is in front of you...Their gaze is simply too enthralling.."
icon = 'icons/mob/actions/bloodsucker.dmi'
icon_state = "power_mez"
/datum/status_effect/no_combat_mode/electrode
id = "tased"
/datum/status_effect/no_combat_mode/electrode/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration)) //TODO, figure out how to grab from subtype
duration = set_duration
. = ..()
if(iscarbon(owner))
var/mob/living/carbon/C = owner
if(C.combatmode)
C.toggle_combat_mode(TRUE)
C.add_movespeed_modifier(MOVESPEED_ID_TASED_STATUS, TRUE, override = TRUE, multiplicative_slowdown = 8)
/datum/status_effect/electrode/on_remove()
/datum/status_effect/no_combat_mode/electrode/on_remove()
if(iscarbon(owner))
var/mob/living/carbon/C = owner
C.remove_movespeed_modifier(MOVESPEED_ID_TASED_STATUS)
. = ..()
/datum/status_effect/electrode/tick()
/datum/status_effect/no_combat_mode/electrode/tick()
if(owner)
owner.adjustStaminaLoss(5) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
/datum/status_effect/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
/datum/status_effect/no_combat_mode/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
return 2
//OTHER DEBUFFS
@@ -388,6 +409,19 @@
else
new /obj/effect/temp_visual/bleed(get_turf(owner))
/datum/status_effect/neck_slice
id = "neck_slice"
status_type = STATUS_EFFECT_UNIQUE
alert_type = null
duration = -1
/datum/status_effect/neck_slice/tick()
var/mob/living/carbon/human/H = owner
if(H.stat == DEAD || H.bleed_rate <= 8)
H.remove_status_effect(/datum/status_effect/neck_slice)
if(prob(10))
H.emote(pick("gasp", "gag", "choke"))
/mob/living/proc/apply_necropolis_curse(set_curse, duration = 10 MINUTES)
var/datum/status_effect/necropolis_curse/C = has_status_effect(STATUS_EFFECT_NECROPOLIS_CURSE)
if(!set_curse)
@@ -481,7 +515,7 @@
deltimer(timerid)
//Kindle: Used by servants of Ratvar. 10-second knockdown, reduced by 1 second per 5 damage taken while the effect is active.
//Kindle: Used by servants of Ratvar. 10-second knockdown, reduced by 1 second per 5 damage taken while the effect is active. Does not take into account Oxy-damage
/datum/status_effect/kindle
id = "kindle"
status_type = STATUS_EFFECT_UNIQUE
@@ -489,6 +523,7 @@
duration = 100
alert_type = /obj/screen/alert/status_effect/kindle
var/old_health
var/old_oxyloss
/datum/status_effect/kindle/tick()
owner.Knockdown(15, TRUE, FALSE, 15)
@@ -498,7 +533,9 @@
C.stuttering = max(5, C.stuttering)
if(!old_health)
old_health = owner.health
var/health_difference = old_health - owner.health
if(!old_oxyloss)
old_oxyloss = owner.getOxyLoss()
var/health_difference = old_health - owner.health - CLAMP(owner.getOxyLoss() - old_oxyloss,0, owner.getOxyLoss())
if(!health_difference)
return
owner.visible_message("<span class='warning'>The light in [owner]'s eyes dims as [owner.p_theyre()] harmed!</span>", \
@@ -506,6 +543,7 @@
health_difference *= 2 //so 10 health difference translates to 20 deciseconds of stun reduction
duration -= health_difference
old_health = owner.health
old_oxyloss = owner.getOxyLoss()
/datum/status_effect/kindle/on_remove()
owner.visible_message("<span class='warning'>The light in [owner]'s eyes fades!</span>", \
@@ -698,4 +736,4 @@ datum/status_effect/pacify
if(LAZYLEN(targets) && I)
to_chat(owner, "<span class='warning'>Your arm spasms!</span>")
owner.log_message("threw [I] due to a Muscle Spasm", LOG_ATTACK)
owner.throw_item(pick(targets))
owner.throw_item(pick(targets))
+32 -15
View File
@@ -8,12 +8,14 @@
mob_trait = TRAIT_ALCOHOL_TOLERANCE
gain_text = "<span class='notice'>You feel like you could drink a whole keg!</span>"
lose_text = "<span class='danger'>You don't feel as resistant to alcohol anymore. Somehow.</span>"
medical_record_text = "Patient demonstrates a high tolerance for alcohol."
/datum/quirk/apathetic
name = "Apathetic"
desc = "You just don't care as much as other people. That's nice to have in a place like this, I guess."
value = 1
mood_quirk = TRUE
medical_record_text = "Patient was administered the Apathy Evaluation Scale but did not bother to complete it."
/datum/quirk/apathetic/add()
var/datum/component/mood/mood = quirk_holder.GetComponent(/datum/component/mood)
@@ -42,6 +44,7 @@
mob_trait = TRAIT_EMPATH
gain_text = "<span class='notice'>You feel in tune with those around you.</span>"
lose_text = "<span class='danger'>You feel isolated from others.</span>"
medical_record_text = "Patient is highly perceptive of and sensitive to social cues, or may possibly have ESP. Further testing needed."
/datum/quirk/freerunning
name = "Freerunning"
@@ -50,6 +53,7 @@
mob_trait = TRAIT_FREERUNNING
gain_text = "<span class='notice'>You feel lithe on your feet!</span>"
lose_text = "<span class='danger'>You feel clumsy again.</span>"
medical_record_text = "Patient scored highly on cardio tests."
/datum/quirk/friendly
name = "Friendly"
@@ -59,6 +63,7 @@
gain_text = "<span class='notice'>You want to hug someone.</span>"
lose_text = "<span class='danger'>You no longer feel compelled to hug others.</span>"
mood_quirk = TRUE
medical_record_text = "Patient demonstrates low-inhibitions for physical contact and well-developed arms. Requesting another doctor take over this case."
/datum/quirk/jolly
name = "Jolly"
@@ -66,6 +71,11 @@
value = 1
mob_trait = TRAIT_JOLLY
mood_quirk = TRUE
medical_record_text = "Patient demonstrates constant euthymia irregular for environment. It's a bit much, to be honest."
/datum/quirk/jolly/on_process()
if(prob(0.05))
SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "jolly", /datum/mood_event/jolly)
/datum/quirk/light_step
name = "Light Step"
@@ -74,6 +84,7 @@
mob_trait = TRAIT_LIGHT_STEP
gain_text = "<span class='notice'>You walk with a little more litheness.</span>"
lose_text = "<span class='danger'>You start tromping around like a barbarian.</span>"
medical_record_text = "Patient's dexterity belies a strong capacity for stealth."
/datum/quirk/quick_step
name = "Quick Step"
@@ -82,6 +93,7 @@
mob_trait = TRAIT_SPEEDY_STEP
gain_text = "<span class='notice'>You feel determined. No time to lose.</span>"
lose_text = "<span class='danger'>You feel less determined. What's the rush, man?</span>"
medical_record_text = "Patient scored highly on racewalking tests."
/datum/quirk/musician
name = "Musician"
@@ -90,6 +102,7 @@
mob_trait = TRAIT_MUSICIAN
gain_text = "<span class='notice'>You know everything about musical instruments.</span>"
lose_text = "<span class='danger'>You forget how musical instruments work.</span>"
medical_record_text = "Patient brain scans show a highly-developed auditory pathway."
/datum/quirk/musician/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
@@ -101,21 +114,6 @@
H.equip_to_slot(musicaltuner, SLOT_IN_BACKPACK)
H.regenerate_icons()
/datum/quirk/night_vision
name = "Night Vision"
desc = "You can see slightly more clearly in full darkness than most people."
value = 1
mob_trait = TRAIT_NIGHT_VISION
gain_text = "<span class='notice'>The shadows seem a little less dark.</span>"
lose_text = "<span class='danger'>Everything seems a little darker.</span>"
/datum/quirk/night_vision/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
var/obj/item/organ/eyes/eyes = H.getorgan(/obj/item/organ/eyes)
if(!eyes || eyes.lighting_alpha)
return
eyes.Insert(H) //refresh their eyesight and vision
/datum/quirk/photographer
name = "Photographer"
desc = "You know how to handle a camera, shortening the delay between each shot."
@@ -123,6 +121,7 @@
mob_trait = TRAIT_PHOTOGRAPHER
gain_text = "<span class='notice'>You know everything about photography.</span>"
lose_text = "<span class='danger'>You forget how photo cameras work.</span>"
medical_record_text = "Patient mentions photography as a stress-relieving hobby."
/datum/quirk/photographer/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
@@ -136,12 +135,14 @@
desc = "You know your body well, and can accurately assess the extent of your wounds."
value = 2
mob_trait = TRAIT_SELF_AWARE
medical_record_text = "Patient demonstrates an uncanny knack for self-diagnosis."
/datum/quirk/skittish
name = "Skittish"
desc = "You can conceal yourself in danger. Ctrl-shift-click a closed locker to jump into it, as long as you have access."
value = 2
mob_trait = TRAIT_SKITTISH
medical_record_text = "Patient demonstrates a high aversion to danger and has described hiding in containers out of fear."
/datum/quirk/spiritual
name = "Spiritual"
@@ -150,6 +151,7 @@
mob_trait = TRAIT_SPIRITUAL
gain_text = "<span class='notice'>You feel a little more faithful to the gods today.</span>"
lose_text = "<span class='danger'>You feel less faithful in the gods.</span>"
medical_record_text = "Patient reports a belief in a higher power."
/datum/quirk/tagger
name = "Tagger"
@@ -158,6 +160,7 @@
mob_trait = TRAIT_TAGGER
gain_text = "<span class='notice'>You know how to tag walls efficiently.</span>"
lose_text = "<span class='danger'>You forget how to tag walls properly.</span>"
medical_record_text = "Patient was recently seen for possible paint huffing incident."
/datum/quirk/tagger/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
@@ -173,6 +176,7 @@
mob_trait = TRAIT_VORACIOUS
gain_text = "<span class='notice'>You feel HONGRY.</span>"
lose_text = "<span class='danger'>You no longer feel HONGRY.</span>"
medical_record_text = "Patient demonstrates a disturbing capacity for eating."
/datum/quirk/trandening
name = "High Luminosity Eyes"
@@ -194,6 +198,7 @@
mob_trait = TRAIT_HIGH_BLOOD
gain_text = "<span class='notice'>You feel full of blood!</span>"
lose_text = "<span class='notice'>You feel like your blood pressure went down.</span>"
medical_record_text = "Patient's blood tests report an abnormal concentration of red blood cells in their bloodstream."
/datum/quirk/bloodpressure/add()
var/mob/living/M = quirk_holder
@@ -203,3 +208,15 @@
/datum/quirk/bloodpressure/remove()
var/mob/living/M = quirk_holder
M.blood_ratio = 1
/datum/quirk/night_vision
name = "Night Vision"
desc = "You can see slightly more clearly in full darkness than most people."
value = 1
mob_trait = TRAIT_NIGHT_VISION
gain_text = "<span class='notice'>The shadows seem a little less dark.</span>"
lose_text = "<span class='danger'>Everything seems a little darker.</span>"
/datum/quirk/night_vision/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
H.update_sight()
+24 -8
View File
@@ -22,14 +22,19 @@
value = -1
gain_text = "<span class='danger'>You start feeling depressed.</span>"
lose_text = "<span class='notice'>You no longer feel depressed.</span>" //if only it were that easy!
medical_record_text = "Patient has a severe mood disorder causing them to experience sudden moments of sadness."
medical_record_text = "Patient has a severe mood disorder, causing them to experience acute episodes of depression."
mood_quirk = TRUE
/datum/quirk/depression/on_process()
if(prob(0.05))
SEND_SIGNAL(quirk_holder, COMSIG_ADD_MOOD_EVENT, "depression", /datum/mood_event/depression)
/datum/quirk/family_heirloom
name = "Family Heirloom"
desc = "You are the current owner of an heirloom, passed down for generations. You have to keep it safe!"
value = -1
mood_quirk = TRUE
medical_record_text = "Patient demonstrates an unnatural attachment to a family heirloom."
var/obj/item/heirloom
var/where
@@ -143,6 +148,7 @@
name = "Nyctophobia"
desc = "As far as you can remember, you've always been afraid of the dark. While in the dark without a light source, you instinctually act careful, and constantly feel a sense of dread."
value = -1
medical_record_text = "Patient demonstrates a fear of the dark. (Seriously?)"
/datum/quirk/nyctophobia/on_process()
var/mob/living/carbon/human/H = quirk_holder
@@ -163,7 +169,8 @@
desc = "Bright lights irritate you. Your eyes start to water, your skin feels itchy against the photon radiation, and your hair gets dry and frizzy. Maybe it's a medical condition. If only Nanotrasen was more considerate of your needs..."
value = -1
gain_text = "<span class='danger'>The safty of light feels off...</span>"
lose_text = "<span class='notice'>Enlighing.</span>"
lose_text = "<span class='notice'>Enlightening.</span>"
medical_record_text = "Despite my warnings, the patient refuses turn on the lights, only to end up rolling down a full flight of stairs and into the cellar."
/datum/quirk/lightless/on_process()
var/turf/T = get_turf(quirk_holder)
@@ -332,16 +339,19 @@
medical_record_text = "Patient has an extreme or irrational fear and aversion to an undefined stimuli."
var/datum/brain_trauma/mild/phobia/phobia
/datum/quirk/phobia/add()
/datum/quirk/phobia/post_add()
var/mob/living/carbon/human/H = quirk_holder
phobia = new
H.gain_trauma(phobia, TRAUMA_RESILIENCE_SURGERY)
H.gain_trauma(phobia, TRAUMA_RESILIENCE_ABSOLUTE)
/datum/quirk/phobia/remove()
var/mob/living/carbon/human/H = quirk_holder
H?.cure_trauma_type(phobia, TRAUMA_RESILIENCE_ABSOLUTE)
/datum/quirk/mute
name = "Mute"
desc = "Due to some accident, medical condition, or simply by choice, you are completely unable to speak."
value = -2 //HALP MAINTS
mob_trait = TRAIT_MUTE
gain_text = "<span class='danger'>You find yourself unable to speak!</span>"
lose_text = "<span class='notice'>You feel a growing strength in your vocal chords.</span>"
medical_record_text = "Functionally mute, patient is unable to use their voice in any capacity."
@@ -350,14 +360,17 @@
/datum/quirk/mute/add()
var/mob/living/carbon/human/H = quirk_holder
mute = new
H.gain_trauma(mute, TRAUMA_RESILIENCE_SURGERY)
H.gain_trauma(mute, TRAUMA_RESILIENCE_ABSOLUTE)
/datum/quirk/mute/remove()
var/mob/living/carbon/human/H = quirk_holder
H?.cure_trauma_type(mute, TRAUMA_RESILIENCE_ABSOLUTE)
/datum/quirk/mute/on_process()
if(quirk_holder.mind && LAZYLEN(quirk_holder.mind.antag_datums))
to_chat(quirk_holder, "<span class='boldannounce'>Your antagonistic nature has caused your voice to be heard.</span>")
qdel(src)
/datum/quirk/unstable
name = "Unstable"
desc = "Due to past troubles, you are unable to recover your sanity if you lose it. Be very careful managing your mood!"
@@ -373,7 +386,7 @@
value = -4
gain_text = "<span class='danger'>You can't see anything.</span>"
lose_text = "<span class='notice'>You miraculously gain back your vision.</span>"
medical_record_text = "Subject has permanent blindness."
medical_record_text = "Patient has permanent blindness."
/datum/quirk/blindness/add()
quirk_holder.become_blind(ROUNDSTART_TRAIT)
@@ -384,3 +397,6 @@
if(!H.equip_to_slot_if_possible(glasses, SLOT_GLASSES, bypass_equip_delay_self = TRUE)) //if you can't put it on the user's eyes, put it in their hands, otherwise put it on their eyes eyes
H.put_in_hands(glasses)
H.regenerate_icons()
/datum/quirk/blindness/remove()
quirk_holder?.cure_blind(ROUNDSTART_TRAIT)
+5 -1
View File
@@ -16,6 +16,7 @@
value = 0
gain_text = "<span class='notice'>You feel an intense craving for pineapple.</span>"
lose_text = "<span class='notice'>Your feelings towards pineapples seem to return to a lukewarm state.</span>"
medical_record_text = "Patient demonstrates a pathological love of pineapple."
/datum/quirk/pineapple_liker/add()
var/mob/living/carbon/human/H = quirk_holder
@@ -34,6 +35,7 @@
value = 0
gain_text = "<span class='notice'>You find yourself pondering what kind of idiot actually enjoys pineapples...</span>"
lose_text = "<span class='notice'>Your feelings towards pineapples seem to return to a lukewarm state.</span>"
medical_record_text = "Patient is correct to think that pineapple is disgusting."
/datum/quirk/pineapple_hater/add()
var/mob/living/carbon/human/H = quirk_holder
@@ -52,6 +54,7 @@
value = 0
gain_text = "<span class='notice'>You start craving something that tastes strange.</span>"
lose_text = "<span class='notice'>You feel like eating normal food again.</span>"
medical_record_text = "Patient demonstrates irregular nutrition preferences."
/datum/quirk/deviant_tastes/add()
var/mob/living/carbon/human/H = quirk_holder
@@ -92,7 +95,7 @@
value = 0
gain_text = "<span class='notice'>You feel more prudish.</span>"
lose_text = "<span class='notice'>You don't feel as prudish as before.</span>"
medical_record_text = "Patient exhibits a special gene that makes them immune to Crocin and Hexacrocin."
medical_record_text = "Patient exhibits a special gene that makes them immune to aphrodisiacs."
/datum/quirk/libido
name = "Nymphomania"
@@ -134,6 +137,7 @@
value = 0
mob_trait = TRAIT_PHARMA
lose_text = "<span class='notice'>Your liver feels different.</span>"
medical_record_text = "Non-invasive tests report that the patient's metabolism is indeed incompatible with a certain \"stimulants\"."
var/active = FALSE
var/power = 0
var/cachedmoveCalc = 1
@@ -22,27 +22,17 @@
target_trait = ZTRAIT_STATION
immunity_type = "rad"
var/radiation_intensity = 100
/datum/weather/rad_storm/telegraph()
..()
status_alarm(TRUE)
/datum/weather/rad_storm/weather_act(mob/living/L)
var/resist = L.getarmor(null, "rad")
if(prob(40))
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.dna && !HAS_TRAIT(H, TRAIT_RADIMMUNE))
if(prob(max(0,100-resist)))
H.randmuti()
if(prob(50))
if(prob(90))
H.randmutb()
else
H.randmutg()
H.domutcheck()
L.rad_act(20)
var/ratio = 1 - (min(resist, 100) / 100)
L.rad_act(radiation_intensity * ratio)
/datum/weather/rad_storm/end()
if(..())