mirror of
https://github.com/quotefox/Hyper-Station-13.git
synced 2026-08-24 05:06:14 +01:00
Merge branch 'master' into fairylights
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
//A spooky element, this can be added to pretty much anything, take your pick. It is effectively harmless however.
|
||||
//target.AddElement(/datum/element/spooky) for example.
|
||||
|
||||
/datum/element/spooky
|
||||
element_flags = ELEMENT_DETACH
|
||||
var/datum/C
|
||||
|
||||
/datum/element/spooky/Attach(datum/target)
|
||||
. = ..()
|
||||
/*
|
||||
if(!iscarbon(target))
|
||||
return ELEMENT_INCOMPATIBLE //keeping this uncommented would make it so it only works with carbons, which is not really needed unless one adds procs that require the user to be a carbon in the future.
|
||||
*/
|
||||
C = target
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/datum/element/spooky/Detach(datum/source, force)
|
||||
. = ..()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/datum/element/spooky/process()
|
||||
var/spookythings = rand(120)
|
||||
switch(spookythings)
|
||||
if(119 to 120) //Plays a spooky ambient sound as long as one hasn't been played in a while.
|
||||
var/sound = pick(SPOOKY)
|
||||
for(var/mob/living/carbon/L in view(6, C))
|
||||
if(L.client && !L.client.played)
|
||||
SEND_SOUND(L, sound(sound, repeat = 0, wait = 0, volume = 35, channel = CHANNEL_AMBIENCE))
|
||||
L.client.played = TRUE
|
||||
addtimer(CALLBACK(L.client, /client/proc/ResetAmbiencePlayed), 600)
|
||||
if(65 to 70) //Lights flicker.
|
||||
var/obj/machinery/light/L = locate(/obj/machinery/light) in view(4, C)
|
||||
if(L)
|
||||
L.flicker()
|
||||
if(1 to 5) //Very small chance to cause an unburnt tile to change to its burnt sprite.
|
||||
var/turf/open/floor/T = locate(/turf/open/floor) in view(4, C)
|
||||
if(T && prob(5) && !isplatingturf(T) && !istype(T, /turf/open/floor/engine/cult) && !T.burnt)
|
||||
T.burn_tile()
|
||||
@@ -0,0 +1,464 @@
|
||||
/*
|
||||
* cards rework; uses TGUI and allows in-depth manipulation of cards, such as
|
||||
* angles, flip states, drawing a number of cards at once, peeking, etc.
|
||||
*
|
||||
* sarcoph march 2022
|
||||
*/
|
||||
|
||||
#define CARD_ROTATION_UP "upright"
|
||||
#define CARD_ROTATION_SIDE "sideways"
|
||||
#define CARD_ROTATION_DOWN "reversed"
|
||||
|
||||
// ================================= GENERAL CARDS =================================
|
||||
|
||||
/obj/item/toy/cards
|
||||
var/face_up = FALSE
|
||||
var/rotation = CARD_ROTATION_UP
|
||||
var/merge_rank = 0
|
||||
|
||||
/obj/item/toy/cards/proc/GetAngle(_dir)
|
||||
var/_angle = 0
|
||||
switch(_dir)
|
||||
if(CARD_ROTATION_UP)
|
||||
_angle = 0
|
||||
if(CARD_ROTATION_SIDE)
|
||||
_angle = 90
|
||||
if(CARD_ROTATION_DOWN)
|
||||
_angle = 180
|
||||
return _angle
|
||||
|
||||
/obj/item/toy/cards/proc/GetNextAngle(angle)
|
||||
var/list/_rotations = list(CARD_ROTATION_UP, CARD_ROTATION_SIDE, CARD_ROTATION_DOWN)
|
||||
var/list/_indexof = _rotations.Find(rotation)
|
||||
return _rotations[_indexof%3 + 1]
|
||||
|
||||
|
||||
/obj/item/toy/cards/proc/RotateCards(angle)
|
||||
if(angle)
|
||||
rotation = angle
|
||||
else
|
||||
rotation = GetNextAngle(angle)
|
||||
update_icon()
|
||||
|
||||
/obj/item/toy/cards/proc/FlipCards(side)
|
||||
if(side != null) face_up = side
|
||||
else face_up = !face_up
|
||||
update_icon()
|
||||
|
||||
|
||||
/**
|
||||
* Handles functionality for merging different types of cards.
|
||||
*
|
||||
* Arguments:
|
||||
* * target - The "greater" card item that this object is going to merge into.
|
||||
* * user - The mob that is performing this merge.
|
||||
*
|
||||
* Returns:
|
||||
* * TRUE/FALSE: Whether or not this logic is considered "processed" - i.e., a merge
|
||||
* was actually attempted.
|
||||
*/
|
||||
/obj/item/toy/cards/proc/MergeInto(obj/item/toy/cards/target, mob/living/user)
|
||||
if(target.parentdeck != src && src.parentdeck != target && src.parentdeck != target.parentdeck)
|
||||
to_chat(user, "<span class='warning'>You can't mix cards from other decks!</span>")
|
||||
return TRUE
|
||||
if(!user.temporarilyRemoveItemFromInventory(src))
|
||||
to_chat(user, "<span class='warning'>\The [src] is stuck to your hand, you can't add it to \the [target]!</span>")
|
||||
return TRUE
|
||||
return FALSE
|
||||
// unimplemented
|
||||
|
||||
/**
|
||||
* Announces card(s) being added to a deck, and then deletes the card(s).
|
||||
*/
|
||||
/obj/item/toy/cards/proc/FinishMergingCards(obj/item/toy/cards/target, mob/living/user)
|
||||
return FALSE // unimplemented
|
||||
|
||||
/obj/item/toy/cards/attackby(obj/item/I, mob/living/user, params)
|
||||
if(istype(I, /obj/item/toy/cards))
|
||||
var/obj/item/toy/cards/C = I
|
||||
var/obj/item/toy/cards/greater = merge_rank > C.merge_rank ? src : C
|
||||
var/obj/item/toy/cards/lesser = greater == src ? C : src
|
||||
if(lesser.MergeInto(greater, user)) return
|
||||
else
|
||||
return ..()
|
||||
|
||||
// ================================= DECK OF CARDS =================================
|
||||
|
||||
/obj/item/toy/cards/deck
|
||||
var/peeking = FALSE
|
||||
var/dealing = FALSE
|
||||
merge_rank = 3
|
||||
|
||||
/**
|
||||
* Randomizes positions of all cards in a deck, plays a nice sound,
|
||||
* and announces this to the `user`'s surroundings. There is a small
|
||||
* cooldown.
|
||||
*
|
||||
* Arguments:
|
||||
* * user - The `mob` shuffling this deck of cards.
|
||||
*/
|
||||
/obj/item/toy/cards/deck/proc/ShuffleCards(mob/user)
|
||||
if(cooldown < world.time - 5 SECONDS)
|
||||
cards = shuffle(cards)
|
||||
playsound(src, 'sound/items/cardshuffle.ogg', 50, 1)
|
||||
user.visible_message("[user] shuffles the deck.", "<span class='notice'>You shuffle the deck.</span>")
|
||||
cooldown = world.time
|
||||
|
||||
/**
|
||||
* Draws cards into a new hand from a list of indices, turning those new
|
||||
* cards into a hand.
|
||||
*
|
||||
* Arguments:
|
||||
* * card_indices - The `list` of card indices to remove from `cards`.
|
||||
*
|
||||
* Returns:
|
||||
* * /obj/item/toy/cards/cardhand - A new hand containing the removed cards.
|
||||
* OR
|
||||
* * /obj/item/toy/cards/singlecard - A single card, if there is only one index.
|
||||
*/
|
||||
/obj/item/toy/cards/deck/proc/DrawCards(list/card_indices)
|
||||
if(card_indices.len == 1) return DrawOneCard(card_indices)
|
||||
var/obj/item/toy/cards/cardhand/H = new/obj/item/toy/cards/cardhand(usr.loc)
|
||||
var/list/cards_to_remove = list()
|
||||
for(var/C in card_indices)
|
||||
var/card_to_add = cards[C]
|
||||
card_to_add["rotation"] = rotation
|
||||
card_to_add["face_up"] = face_up
|
||||
H.currenthand += list(card_to_add)
|
||||
cards_to_remove += list(card_to_add)
|
||||
cards -= cards_to_remove
|
||||
H.parentdeck = src
|
||||
H.apply_card_vars(H,src)
|
||||
update_icon()
|
||||
return H
|
||||
|
||||
/obj/item/toy/cards/deck/proc/DrawOneCard(list/card_indices)
|
||||
var/obj/item/toy/cards/singlecard/S = new/obj/item/toy/cards/singlecard(usr.loc)
|
||||
var/_card = cards[card_indices[1]]
|
||||
_card["rotation"] = rotation
|
||||
_card["face_up"] = face_up
|
||||
S.card = _card
|
||||
S.rotation = _card["rotation"]
|
||||
S.face_up = _card["face_up"]
|
||||
S.parentdeck = src
|
||||
S.apply_card_vars(S,src)
|
||||
cards -= list(_card)
|
||||
return S
|
||||
|
||||
/obj/item/toy/cards/deck/FinishMergingCards(obj/item/toy/cards/target, mob/living/user)
|
||||
var/message = "[user] adds \the [target] to the bottom of \the [src]."
|
||||
var/self_message = "<span class='notice'>You add \the [target] to the bottom of \the [src].</span>"
|
||||
user.visible_message(message, self_message)
|
||||
qdel(target)
|
||||
update_icon()
|
||||
|
||||
/obj/item/toy/cards/deck/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Alt-Click to quick-draw a card.</span>"
|
||||
|
||||
/obj/item/toy/cards/deck/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(!ishuman(usr) || !usr.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
var/obj/item/toy/cards/drawn = DrawCards(list(1))
|
||||
drawn.pickup(user)
|
||||
user.put_in_hands(drawn)
|
||||
to_chat(user, "<span class='notice'>You draw \a [drawn] from \the [src].</span>")
|
||||
|
||||
|
||||
// =================== TGUI stuff ===================
|
||||
|
||||
/obj/item/toy/cards/deck/ui_interact(mob/user, ui_key, datum/tgui/ui, force_open, datum/tgui/master_ui, datum/tgui_state/state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "CardsDeck", name, 300, 400, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/item/toy/cards/deck/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
var/list/targets = list(usr, src)
|
||||
switch(action)
|
||||
if("deal")
|
||||
var/n_cards = text2num(params["count"])
|
||||
var/n_hands = text2num(params["hands"])
|
||||
if(dealing) return FALSE
|
||||
if(!n_cards || !n_hands) return FALSE
|
||||
if(n_cards * n_hands > cards.len)
|
||||
to_chat(usr, "<span class='warning'>You can't deal more cards than there are in the deck!</span>")
|
||||
return FALSE
|
||||
dealing = TRUE
|
||||
to_chat(usr, "<span class='notice'>You get ready to deal cards...</span>")
|
||||
if(do_after_mob(usr, targets, 1 SECONDS, progress=TRUE))
|
||||
visible_message("[usr] begins dealing cards.")
|
||||
var/list/holder = list()
|
||||
var/broken = FALSE
|
||||
for(var/C = 1, C <= n_cards, C++) holder += C // card indices placeholder
|
||||
for(var/H = 1, H <= n_hands, H++)
|
||||
if(do_after_mob(usr, targets, 0.5 SECONDS, progress=TRUE) && dealing)
|
||||
var/obj/item/toy/cards/hand = DrawCards(holder)
|
||||
step(hand, GLOB.alldirs[H])
|
||||
else
|
||||
broken = TRUE
|
||||
break
|
||||
if(broken)
|
||||
visible_message("<span class='danger'>[usr] stops in the middle of dealing cards!</span>")
|
||||
dealing = FALSE
|
||||
if("draw")
|
||||
if(!params["cards"]) return FALSE
|
||||
var/list/P = splittext(params["cards"], ",")
|
||||
var/list/P_cards = list()
|
||||
for(var/T in P)
|
||||
P_cards += text2num(T) + 1
|
||||
var/obj/item/toy/cards/H = DrawCards(P_cards)
|
||||
H.pickup(usr)
|
||||
usr.put_in_hands(H)
|
||||
if("flip")
|
||||
var/P_side = params["side"]
|
||||
var/flip_side = null
|
||||
if(P_side)
|
||||
flip_side = P_side == "face_down" ? FALSE : P_side == "face_up" ? TRUE : null
|
||||
FlipCards(flip_side)
|
||||
return TRUE
|
||||
if("peek")
|
||||
visible_message("<span class='warning'>[usr] is peeking in \the [name]!</span>")
|
||||
if(do_after_mob(usr, targets, 3 SECONDS, progress=TRUE))
|
||||
to_chat(usr, "<span class='notice'>You peek into \the [name].</span>")
|
||||
peeking = TRUE
|
||||
if("rotate")
|
||||
RotateCards(params["angle"])
|
||||
return TRUE
|
||||
if("shuffle")
|
||||
peeking = FALSE
|
||||
ShuffleCards(usr)
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/cards/deck/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["face_up"] = face_up
|
||||
data["rotation"] = rotation
|
||||
data["cards"] = cards
|
||||
data["name"] = name
|
||||
data["peeking"] = peeking
|
||||
return data
|
||||
|
||||
/obj/item/toy/cards/deck/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["possible_rotations"] = list(CARD_ROTATION_UP, CARD_ROTATION_SIDE, CARD_ROTATION_DOWN)
|
||||
return data
|
||||
|
||||
/obj/item/toy/cards/deck/ui_close()
|
||||
dealing = FALSE
|
||||
peeking = FALSE
|
||||
|
||||
|
||||
// ================================= HAND OF CARDS =================================
|
||||
|
||||
/obj/item/toy/cards/cardhand
|
||||
merge_rank = 2
|
||||
face_up = TRUE
|
||||
|
||||
/obj/item/toy/cards/cardhand/proc/QuickAnnounce(mob/living/user)
|
||||
if(!user.is_holding(src))
|
||||
to_chat(user, "<span class='warning'>You need to be holding \the [src] to show it!</span>")
|
||||
return
|
||||
if(user.stat || user.restrained())
|
||||
return
|
||||
var/list/temp_cards = list()
|
||||
var/facedown = 0
|
||||
for(var/C in currenthand)
|
||||
var/_flipped = C["face_up"] || face_up
|
||||
var/_angle = C["rotation"] || rotation
|
||||
if(_flipped)
|
||||
if(is_all_same_direction())
|
||||
temp_cards += "\a [C["name"]]"
|
||||
else
|
||||
temp_cards += "\a [_angle] [C["name"]]"
|
||||
else
|
||||
facedown++
|
||||
if(facedown > 0)
|
||||
temp_cards += "[facedown] unrevealed card\s"
|
||||
visible_message("<span class='notice'>[user] shows [user.p_their()] hand: [english_list(temp_cards)].</span>")
|
||||
|
||||
/obj/item/toy/cards/cardhand/proc/is_all_same_direction()
|
||||
var/compare_orient = currenthand[1]["rotation"]
|
||||
for(var/list/C in currenthand)
|
||||
var/_rotation = C["rotation"] || rotation
|
||||
if(_rotation != compare_orient) return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/cards/cardhand/proc/DrawOneCard(list/card_indices)
|
||||
var/obj/item/toy/cards/singlecard/S = new/obj/item/toy/cards/singlecard(usr.loc)
|
||||
var/_card = currenthand[card_indices[1]]
|
||||
S.card = _card
|
||||
S.rotation = _card["rotation"]
|
||||
S.face_up = _card["face_up"]
|
||||
S.parentdeck = src.parentdeck
|
||||
S.apply_card_vars(S,src)
|
||||
currenthand -= list(_card)
|
||||
S.update_icon()
|
||||
update_icon()
|
||||
return S
|
||||
|
||||
/obj/item/toy/cards/cardhand/MergeInto(obj/item/toy/cards/target, mob/living/user)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(istype(target, /obj/item/toy/cards/deck))
|
||||
var/obj/item/toy/cards/deck/C = target
|
||||
for(var/_card = 1, _card < currenthand.len, _card++)
|
||||
currenthand[_card]["rotation"] = null
|
||||
currenthand[_card]["face_up"] = null
|
||||
C.cards += currenthand
|
||||
C.FinishMergingCards(src, user)
|
||||
else if(istype(target, /obj/item/toy/cards/cardhand))
|
||||
if(do_after_mob(user, list(user,src,target), 0.5 SECONDS))
|
||||
var/obj/item/toy/cards/cardhand/C = target
|
||||
C.currenthand += currenthand
|
||||
C.FinishMergingCards(src, user)
|
||||
else
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/cards/cardhand/FinishMergingCards(obj/item/toy/cards/target, mob/living/user)
|
||||
user.visible_message("[user] combines \the [target] into [user.p_their()] hand.",\
|
||||
"<span class='notice'>You combine \the [target] into the [src].</span>")
|
||||
qdel(target)
|
||||
update_icon()
|
||||
|
||||
/obj/item/toy/cards/cardhand/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Alt-Click to quick-announce your deck.</span>"
|
||||
|
||||
/obj/item/toy/cards/cardhand/AltClick(mob/user)
|
||||
. = ..()
|
||||
QuickAnnounce(user)
|
||||
|
||||
|
||||
// =================== TGUI stuff ===================
|
||||
|
||||
/obj/item/toy/cards/cardhand/ui_interact(mob/user, ui_key, datum/tgui/ui, force_open, datum/tgui/master_ui, datum/tgui_state/state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "CardsHand", name, 300, 400, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/item/toy/cards/cardhand/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("draw")
|
||||
if(!params["cards"]) return FALSE
|
||||
var/list/P = splittext(params["cards"], ",")
|
||||
var/list/P_cards = list()
|
||||
for(var/T in P)
|
||||
P_cards += text2num(T) + 1
|
||||
var/obj/item/toy/cards/H = DrawOneCard(P_cards)
|
||||
H.pickup(usr)
|
||||
usr.put_in_hands(H)
|
||||
if("flip")
|
||||
if(!params["card"]) return FALSE
|
||||
var/card = currenthand[text2num(params["card"]) + 1]
|
||||
card["face_up"] = !card["face_up"]
|
||||
if("rotate")
|
||||
if(!params["card"]) return FALSE
|
||||
var/card = currenthand[text2num(params["card"]) + 1]
|
||||
if(params["angle"])
|
||||
card["rotation"] = params["angle"]
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/cards/cardhand/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["cards"] = currenthand
|
||||
data["name"] = name
|
||||
return data
|
||||
|
||||
/obj/item/toy/cards/cardhand/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["possible_rotations"] = list(CARD_ROTATION_UP, CARD_ROTATION_SIDE, CARD_ROTATION_DOWN)
|
||||
return data
|
||||
|
||||
|
||||
// ================================= SINGLE CARDS =================================
|
||||
|
||||
/obj/item/toy/cards/singlecard
|
||||
merge_rank = 1
|
||||
|
||||
/obj/item/toy/cards/singlecard/MergeInto(obj/item/toy/cards/target, mob/living/user)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(istype(target, /obj/item/toy/cards/deck))
|
||||
var/obj/item/toy/cards/deck/C = target
|
||||
card["rotation"] = null
|
||||
card["face_up"] = null
|
||||
C.cards += list(card)
|
||||
C.FinishMergingCards(src, user)
|
||||
else if(istype(target, /obj/item/toy/cards/cardhand))
|
||||
var/obj/item/toy/cards/cardhand/C = target
|
||||
C.currenthand += list(card)
|
||||
C.FinishMergingCards(src, user)
|
||||
else if(istype(target, /obj/item/toy/cards/singlecard))
|
||||
var/obj/item/toy/cards/singlecard/C = target
|
||||
var/obj/item/toy/cards/cardhand/H = new/obj/item/toy/cards/cardhand(user.loc)
|
||||
H.currenthand += list(C.card)
|
||||
H.currenthand += list(src.card)
|
||||
H.parentdeck = C.parentdeck
|
||||
H.apply_card_vars(H,C)
|
||||
H.pickup(user)
|
||||
user.put_in_hands(H)
|
||||
C.FinishMergingCards(src, user)
|
||||
else
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/toy/cards/singlecard/proc/FlipCard(mob/user)
|
||||
if(!ishuman(usr) || !usr.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
FlipCards()
|
||||
to_chat(user, "<span class='notice'>You flip \the [src] [(face_up ? "face-up" : "face-down")]</span>.")
|
||||
|
||||
/obj/item/toy/cards/singlecard/proc/RotateCard(mob/user, var/rotation_angle)
|
||||
if(!ishuman(usr) || !usr.canUseTopic(src, BE_CLOSE))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You turn \the [src] to \a [rotation_angle] position.</span>")
|
||||
RotateCards(rotation_angle)
|
||||
|
||||
|
||||
/obj/item/toy/cards/singlecard/FinishMergingCards(obj/item/toy/cards/singlecard/target, mob/living/user)
|
||||
to_chat(user, "<span class='notice'>You combine the [target.card["name"]] and the [src.card["name"]] into a hand.</span>")
|
||||
qdel(target)
|
||||
qdel(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/toy/cards/singlecard/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Click to flip. Alt-Click to rotate.</span>"
|
||||
|
||||
/obj/item/toy/cards/singlecard/attack_self(mob/user)
|
||||
. = ..()
|
||||
FlipCard(user)
|
||||
|
||||
/obj/item/toy/cards/singlecard/AltClick(mob/user)
|
||||
. = ..()
|
||||
RotateCard(user, GetNextAngle(rotation))
|
||||
|
||||
/obj/item/toy/cards/singlecard/update_icon()
|
||||
. = ..()
|
||||
var/matrix/rot_matrix = matrix()
|
||||
rot_matrix.Turn(GetAngle(rotation))
|
||||
transform = rot_matrix
|
||||
|
||||
var/rotation_name = (rotation == CARD_ROTATION_UP ? "" : rotation + " ")
|
||||
if(face_up)
|
||||
if(card)
|
||||
src.icon_state = "sc_[card["icon_state"] || card["name"]]_[deckstyle]"
|
||||
src.name = rotation_name + src.card["name"]
|
||||
else
|
||||
src.icon_state = "sc_aceofspades_[deckstyle]"
|
||||
src.name = "What Card"
|
||||
src.pixel_x = 5
|
||||
else
|
||||
src.icon_state = "singlecard_down_[deckstyle]"
|
||||
src.name = rotation_name + "card"
|
||||
src.pixel_x = -5
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
lover's dice: based off a really funny yakuza gif i saw on tumblr years ago
|
||||
these give suggestions for sex acts to perform. it's stupid but fun.
|
||||
|
||||
sarcoph mar 2022
|
||||
*/
|
||||
|
||||
// dice bag
|
||||
|
||||
/obj/item/storage/pill_bottle/lovedice
|
||||
name = "bag of love dice"
|
||||
desc = "Contains all the intimate ideas you'll ever need. A game that everyone wins!"
|
||||
icon = 'hyperstation/icons/obj/toy.dmi'
|
||||
icon_state = "lovedicebag"
|
||||
price = 1
|
||||
|
||||
/obj/item/storage/pill_bottle/lovedice/Initialize()
|
||||
. = ..()
|
||||
new /obj/item/dice/lover/d6_gesture(src)
|
||||
new /obj/item/dice/lover/d6_location(src)
|
||||
new /obj/item/dice/lover/d6_action(src)
|
||||
new /obj/item/dice/lover/d6_bodypart(src)
|
||||
|
||||
|
||||
// dice
|
||||
|
||||
/obj/item/dice/lover
|
||||
desc = "A die with six sides to inspire some bedroom action."
|
||||
icon = 'hyperstation/icons/obj/toy.dmi'
|
||||
sides = 6
|
||||
|
||||
/obj/item/dice/lover/update_icon()
|
||||
return // override the dice proc for this, there is no overlay
|
||||
|
||||
/obj/item/dice/lover/examine(mob/user)
|
||||
. = ..() // again, no overlays
|
||||
. += "<span class='notice'>The top reads [result].</span>"
|
||||
|
||||
|
||||
// actual dice
|
||||
|
||||
/obj/item/dice/lover/d6_gesture
|
||||
name = "lover's d6 (v1)"
|
||||
desc = "A die with six sides to inspire some bedroom action. This one has intimate gestures."
|
||||
icon_state = "loved6_1"
|
||||
special_faces = list(
|
||||
"Let's hug",
|
||||
"Let's kiss",
|
||||
"Let's play",
|
||||
"Let's fuck", // it actually says "let's do it" on the irl ones lol
|
||||
"Let's wrestle",
|
||||
"Let's ?"
|
||||
)
|
||||
|
||||
/obj/item/dice/lover/d6_location
|
||||
name = "lover's d6 (v2)"
|
||||
desc = "A die with six sides to inspire some bedroom action. This one has different locations."
|
||||
icon_state = "loved6_2"
|
||||
special_faces = list(
|
||||
"On a chair",
|
||||
"On the bed",
|
||||
"On the floor",
|
||||
"In the closet",
|
||||
"In the bathtub",
|
||||
"In the ?"
|
||||
)
|
||||
|
||||
/obj/item/dice/lover/d6_action
|
||||
name = "lover's d6 (v3)"
|
||||
desc = "A die with six sides to inspire some bedroom action. This one has different actions."
|
||||
icon_state = "loved6_3"
|
||||
special_faces = list(
|
||||
"Caress my",
|
||||
"Kiss my",
|
||||
"Grab my",
|
||||
"Rub my",
|
||||
"Tickle my",
|
||||
"Surprise!"
|
||||
)
|
||||
|
||||
/obj/item/dice/lover/d6_bodypart
|
||||
name = "lover's d6 (v4)"
|
||||
desc = "A die with six sides to inspire some bedroom action. This one has body parts."
|
||||
icon_state = "loved6_4"
|
||||
special_faces = list(
|
||||
"Back",
|
||||
"Chest",
|
||||
"Face",
|
||||
"Ass",
|
||||
"Genitals",
|
||||
"Surprise!"
|
||||
)
|
||||
@@ -151,15 +151,18 @@
|
||||
|
||||
usr.visible_message("<span class='warning'>[user] starts climbing onto \the [src]!</span>")
|
||||
|
||||
if(!do_after(user, 20))
|
||||
if(!do_after(user, 15, src))
|
||||
return
|
||||
|
||||
if(get_turf(user) == get_turf(src))
|
||||
usr.dir = get_dir(usr.loc, get_step(src, src.dir))//turn and face railing
|
||||
usr.forceMove(get_step(src, src.dir))
|
||||
else
|
||||
usr.dir = get_dir(usr.loc, loc)//turn and face railing
|
||||
usr.forceMove(get_turf(src))
|
||||
|
||||
usr.visible_message("<span class='warning'>[user] climbed over \the [src]!</span>")
|
||||
usr.do_twist(targetangle = 45, timer = 8)
|
||||
|
||||
/obj/structure/railing/handrail
|
||||
name = "handrail"
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
icon_state = "crystal"
|
||||
icon_living = "crystal"
|
||||
icon_dead = "crystal"
|
||||
mob_biotypes = MOB_BEAST
|
||||
gender = NEUTER
|
||||
mob_biotypes = MOB_INORGANIC
|
||||
speak_chance = 0
|
||||
turns_per_move = 10
|
||||
response_help = "touches"
|
||||
@@ -29,6 +30,7 @@
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
maxbodytemp = 3500
|
||||
blood_volume = 0 //It's a fucking rock
|
||||
faction = list("carp")
|
||||
movement_type = FLYING
|
||||
pressure_resistance = 500
|
||||
|
||||
@@ -211,13 +211,7 @@
|
||||
return
|
||||
|
||||
if(href_list["shrink_belly"])
|
||||
var/obj/item/organ/genital/belly/E = usr.getorganslot("belly")
|
||||
if(E.size > 0)
|
||||
to_chat(usr, "<span class='userlove'>You feel your belly diminish.</span>")
|
||||
E.size -= 1
|
||||
H.update_genitals()
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Your belly is already at the minimum size! </span>")
|
||||
H.shrink_belly(1)
|
||||
|
||||
if(href_list["removecondom"])
|
||||
H.menuremovecondom()
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/mob/living/carbon/proc/expand_belly(expansion = 1)
|
||||
var/obj/item/organ/genital/belly/_belly = getorganslot("belly")
|
||||
if(!expansion || !_belly || !_belly.inflatable)
|
||||
return
|
||||
var/original_size = _belly.size
|
||||
_belly.size = clamp(_belly.size + expansion, BELLY_MIN_SIZE, BELLY_MAX_SIZE)
|
||||
if(_belly.size == original_size)
|
||||
return
|
||||
var/_verb = "expand"
|
||||
switch(_belly.size)
|
||||
if(BELLY_MAX_SIZE to INFINITY)
|
||||
_verb = "stretch to its limit"
|
||||
if(BELLY_STRETCH_SIZE to BELLY_MAX_SIZE)
|
||||
_verb = "stretch"
|
||||
if(BELLY_STRAIN_SIZE to BELLY_STRETCH_SIZE)
|
||||
_verb = "strain"
|
||||
to_chat(src, "<span class='userlove'>You feel your belly [_verb].</span>")
|
||||
_belly.update()
|
||||
|
||||
|
||||
/mob/living/carbon/proc/shrink_belly(shrinkage = 1)
|
||||
var/obj/item/organ/genital/belly/_belly = getorganslot("belly")
|
||||
if(!shrinkage ||!_belly || !_belly.inflatable)
|
||||
return
|
||||
var/original_size = _belly.size
|
||||
_belly.size = clamp(_belly.size - shrinkage, BELLY_MIN_SIZE, BELLY_MAX_SIZE)
|
||||
if(_belly.size == original_size)
|
||||
return
|
||||
var/_verb = "diminish"
|
||||
var/_class = "userlove"
|
||||
if(_belly.size == BELLY_MIN_SIZE)
|
||||
_verb = "can't shrink anymore"
|
||||
_class = "warning"
|
||||
to_chat(src, "<span class='[_class]'>You feel your belly [_verb].</span>")
|
||||
_belly.update()
|
||||
@@ -0,0 +1,11 @@
|
||||
/datum/gear/syntech/ring
|
||||
name = "Normalizer Ring"
|
||||
category = SLOT_GLOVES
|
||||
path = /obj/item/clothing/gloves/ring/syntech
|
||||
cost = 6
|
||||
|
||||
/datum/gear/syntech/band
|
||||
name = "Normalizer Band"
|
||||
category = SLOT_GLOVES
|
||||
path = /obj/item/clothing/gloves/ring/syntech/band
|
||||
cost = 6
|
||||
@@ -0,0 +1,5 @@
|
||||
/datum/gear/gasmask
|
||||
name = "gas mask"
|
||||
category = SLOT_WEAR_MASK
|
||||
path = /obj/item/clothing/mask/gas
|
||||
cost = 3
|
||||
@@ -0,0 +1,17 @@
|
||||
/datum/gear/syntech/pendant
|
||||
name = "Normalizer Pendant"
|
||||
category = SLOT_NECK
|
||||
path = /obj/item/clothing/neck/syntech
|
||||
cost = 6
|
||||
|
||||
/datum/gear/syntech/choker
|
||||
name = "Normalizer Choker"
|
||||
category = SLOT_NECK
|
||||
path = /obj/item/clothing/neck/syntech/choker
|
||||
cost = 6
|
||||
|
||||
/datum/gear/syntech/collar
|
||||
name = "Normalizer Collar"
|
||||
category = SLOT_NECK
|
||||
path = /obj/item/clothing/neck/syntech/collar
|
||||
cost = 6
|
||||
@@ -0,0 +1,115 @@
|
||||
//Clothing vars and procs
|
||||
/obj/item/clothing
|
||||
var/normalize_size = RESIZE_NORMAL //This number is used as the "normal" height people will be given when wearing one of these accessories
|
||||
var/natural_size = null //The value of the wearer's body_size var in prefs. Unused for now.
|
||||
var/recorded_size = null //the user's height prior to equipping
|
||||
|
||||
//For applying a normalization
|
||||
/obj/item/clothing/proc/normalize_mob_size(mob/living/carbon/human/H)
|
||||
if(H.normalized) //First we make a check to see if they're already normalized, from wearing another article of SynTech jewelry
|
||||
to_chat(H, "<span class='warning'>This accessory buzzes, being overwritten by another.</span>")
|
||||
playsound(H, 'sound/machines/buzz-sigh.ogg', 50, 1)
|
||||
return
|
||||
recorded_size = H.get_effective_size() //If not, grab their current size
|
||||
playsound(H, 'sound/effects/magic.ogg', 50, 1)
|
||||
flash_lighting_fx(3, 3, LIGHT_COLOR_PURPLE)
|
||||
H.visible_message("<span class='warning'>A flash of purple light engulfs [H], before they change to normal!</span>","<span class='notice'>You feel warm for a moment, before everything scales to your size...</span>")
|
||||
H.resize(normalize_size) //Then apply the size
|
||||
H.normalized = TRUE //And set normalization
|
||||
|
||||
//For removing a normalization, and reverting back to normal
|
||||
/obj/item/clothing/proc/denormalize_mob_size(mob/living/carbon/human/H)
|
||||
if(H.normalized) //sanity check
|
||||
playsound(H,'sound/weapons/emitter2.ogg', 50, 1)
|
||||
flash_lighting_fx(3, 3, LIGHT_COLOR_YELLOW)
|
||||
H.visible_message("<span class='warning'>Golden light engulfs [H], and they shoot back to their default height!</span>","<span class='notice'>Energy rushes through your body, and you return to normal.</span>")
|
||||
H.resize(recorded_size)
|
||||
H.normalized = FALSE
|
||||
|
||||
|
||||
//For storing normalization on mobs
|
||||
/mob/living
|
||||
var/normalized = FALSE
|
||||
//normalized is a check for instances where more than one accessory of jewelry is worn. For all intensive purposes, only the first worn accessory stores the user's size.
|
||||
//Anything else is just extra.
|
||||
|
||||
//Clothing below. Code could be compressed more, but until I make jewelry slots, this will do. -Dahl
|
||||
|
||||
//GLOVE SLOT ITEMS...
|
||||
//SynTech ring
|
||||
/obj/item/clothing/gloves/ring/syntech
|
||||
name = "normalizer ring"
|
||||
desc = "An expensive, shimmering SynTech ring gilded with golden Kinaris markings. It will 'normalize' the size of the user to a specified height approved for work-conditions, as long as it is equipped. The artificial violet gem inside twinkles ominously."
|
||||
icon = 'hyperstation/icons/obj/clothing/sizeaccessories.dmi'
|
||||
icon_state = "ring"
|
||||
item_state = "sring" //No use in a unique sprite since it's just one pixel
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
body_parts_covered = 0
|
||||
transfer_prints = TRUE
|
||||
strip_delay = 40
|
||||
//These are already defined under the parent ring, but I wanna leave em here for reference purposes
|
||||
|
||||
//For glove slots
|
||||
/obj/item/clothing/gloves/ring/syntech/equipped(mob/living/user, slot)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/human_target = user
|
||||
if(slot == SLOT_GLOVES)
|
||||
|
||||
if(human_target.custom_body_size)
|
||||
normalize_mob_size(human_target)
|
||||
|
||||
/obj/item/clothing/gloves/ring/syntech/dropped(mob/living/user, slot)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/human_target = user
|
||||
|
||||
if(human_target.normalized)
|
||||
denormalize_mob_size(human_target)
|
||||
|
||||
|
||||
|
||||
//SynTech Wristband
|
||||
/obj/item/clothing/gloves/ring/syntech/band
|
||||
name = "normalizer wristband"
|
||||
desc = "An expensive technological wristband cast in SynTech purples with shimmering Kinaris golds. It will 'normalize' the size of the user to a specified height for approved work-conditions, as long as it is equipped. There is a small screen buzzing with information."
|
||||
icon_state = "wristband"
|
||||
item_state = "syntechband"
|
||||
|
||||
|
||||
//NECK SLOT ITEMS...
|
||||
//Syntech Pendant
|
||||
/obj/item/clothing/neck/syntech
|
||||
name = "normalizer pendant"
|
||||
desc = "A vibrant violet jewel cast in silvery-gold metals, sporting the elegance of Kinaris with SynTech prowess. It will 'normalize' the size of the user to a specified height for approved work-conditions, as long as it is equipped. The artificial violet gem inside twinkles ominously."
|
||||
icon = 'hyperstation/icons/obj/clothing/sizeaccessories.dmi'
|
||||
icon_state = "pendant"
|
||||
item_state = "pendant"
|
||||
|
||||
//For neck items
|
||||
/obj/item/clothing/neck/syntech/equipped(mob/living/user, slot)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/human_target = user
|
||||
if(slot == SLOT_NECK)
|
||||
|
||||
if(human_target.custom_body_size)
|
||||
normalize_mob_size(human_target)
|
||||
|
||||
/obj/item/clothing/neck/syntech/dropped(mob/living/user, slot)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/human_target = user
|
||||
|
||||
if(human_target.normalized)
|
||||
denormalize_mob_size(human_target)
|
||||
|
||||
//Syntech Choker
|
||||
/obj/item/clothing/neck/syntech/choker
|
||||
name = "normalizer choker"
|
||||
desc = "A sleek, tight-fitting choker embezzled with silver to gold, adorned with vibrant purple studs; combined technology of Kinaris and SynTech. It will 'normalize' the size of the user to a specified height for approved work-conditions, as long as it is equipped. There is a small screen buzzing with information."
|
||||
icon_state = "choker"
|
||||
item_state = "collar"
|
||||
|
||||
//Syntech Collar
|
||||
/obj/item/clothing/neck/syntech/collar
|
||||
name = "normalizer collar"
|
||||
desc = "A cute pet collar, technologically designed with vibrant purples and smooth silvers. There is a small gem bordered by gold at the front, reading 'SYNTECH' engraved within the metal. It will 'normalize' the size of the user to a specified height for approved work-conditions, as long as it is equipped. The artificial violet gem inside twinkles ominously."
|
||||
icon_state = "collar"
|
||||
item_state = "collar"
|
||||
@@ -3,3 +3,9 @@
|
||||
id = /datum/reagent/consumable/pilk
|
||||
results = list(/datum/reagent/consumable/pilk = 2)
|
||||
required_reagents = list(/datum/reagent/consumable/milk = 1, /datum/reagent/consumable/space_cola = 1)
|
||||
|
||||
/datum/chemical_reaction/javelin
|
||||
name = "Javelin"
|
||||
id = /datum/reagent/consumable/ethanol/javelin
|
||||
results = list(/datum/reagent/consumable/ethanol/javelin = 5)
|
||||
required_reagents = list(/datum/reagent/consumable/kalynajuice = 1, /datum/reagent/consumable/ethanol/whiskey = 2, /datum/reagent/consumable/ethanol/vodka = 2)
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// Kalyna Berries
|
||||
/obj/item/seeds/kalyna
|
||||
name = "pack of kalyna berry seeds"
|
||||
desc = "Seeds that grow into Kalyna plants. Take that Red Kalyna and rise it up."
|
||||
icon = 'hyperstation/icons/obj/hydroponics/seeds.dmi'
|
||||
icon_state = "seed-kalyna"
|
||||
species = "kalyna"
|
||||
plantname = "Kalyna Shrub Tree"
|
||||
product = /obj/item/reagent_containers/food/snacks/grown/kalyna
|
||||
lifespan = 20
|
||||
maturation = 5
|
||||
production = 5
|
||||
growthstages = 5
|
||||
yield = 4
|
||||
growing_icon = 'hyperstation/icons/obj/hydroponics/growing_fruits.dmi'
|
||||
icon_grow = "kalyna-grow"
|
||||
icon_dead = "kalyna-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
reagents_add = list(/datum/reagent/consumable/nutriment/vitamin = 0.04, /datum/reagent/consumable/nutriment = 0.1)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/kalyna
|
||||
seed = /obj/item/seeds/kalyna
|
||||
name = "branch of kalyna"
|
||||
desc = "Red berries, attached to a branch. Just looking at it makes you feel an aura of unity."
|
||||
icon = 'hyperstation/icons/obj/hydroponics/harvest.dmi'
|
||||
icon_state = "kalynaberries"
|
||||
gender = PLURAL
|
||||
filling_color = "#FF0000"
|
||||
bitesize_mod = 2
|
||||
foodtype = FRUIT
|
||||
juice_results = list(/datum/reagent/consumable/kalynajuice = 1)
|
||||
tastes = list("sweet cranberries" = 1)
|
||||
distill_reagent = /datum/reagent/consumable/ethanol/gin
|
||||
|
||||
//For those of you wondering, yes, this is very much an addition in support of Ukraine. I decided to make these after a distant Ukranian relative of mine sent me Go_A's 'Kalyna' song.
|
||||
//Our future as a free world could very well depend on the heroism of the people of glorious Ukraine. We owe our freedom to them.
|
||||
//I know that this game should be for escapism, but there's only so much we should escape from. When people's lives are being upturned-- Or taken by a brutal invasive reigime, perhaps then it's when we should take a stand.
|
||||
//And for those that oppose the freedom of the people of Ukraine, Russia, and Belarus; Prykhyl'nyk Putina, idy na khuy. And show some basic empathy for once, it's not that hard.
|
||||
//Glory to Ukraine, Glory to the Heroes!
|
||||
// - Arctaisia, Hyperstation developer and spriter, 23/04/2022 #StandWithUkraine
|
||||
@@ -67,6 +67,35 @@ SNOUTS
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/easterndragon
|
||||
name = "Eastern Dragon (Hyper)"
|
||||
icon_state = "easterndw"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/feasterndragon
|
||||
name = "Eastern Dragon (Top) (Hyper)"
|
||||
icon_state = "feasterndw"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/easterndragonnowhiskers
|
||||
name = "Eastern Dragon - No Whiskers (Hyper)"
|
||||
icon_state = "easterndnw"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/feasterndragonnowhiskers
|
||||
name = "Eastern Dragon - No Whiskers (Top) (Hyper)"
|
||||
icon_state = "feasterndnw"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/fchemlight
|
||||
name = "RadDog (Top) (Hyper)"
|
||||
icon_state = "fchemlight"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/chemlight
|
||||
name = "RadDog (Hyper)"
|
||||
icon_state = "chemlight"
|
||||
icon = 'hyperstation/icons/mob/char_snouts.dmi'
|
||||
|
||||
/*
|
||||
EARS
|
||||
@@ -109,6 +138,15 @@ EARS
|
||||
icon = 'hyperstation/icons/mob/char_ears.dmi'
|
||||
recommended_species = list("insect")
|
||||
|
||||
/datum/sprite_accessory/mam_ears/easterndragon
|
||||
name = "Eastern Dragon (Hyper)"
|
||||
icon_state = "easternd"
|
||||
icon = 'hyperstation/icons/mob/char_ears.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_ears/chemlight
|
||||
name = "RadDog (Hyper)"
|
||||
icon_state = "chemlight"
|
||||
icon = 'hyperstation/icons/mob/char_ears.dmi'
|
||||
|
||||
/*
|
||||
WINGS
|
||||
@@ -276,6 +314,26 @@ TAILS + ANIMATED TAILS
|
||||
icon_state = "swallowstriped"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails/easterndragon //Pulled base from Virgo, seriously love the server and love you guys, stay lovely.
|
||||
name = "Eastern Dragon (Hyper)"
|
||||
icon_state = "easternd"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/easterndragon
|
||||
name = "Eastern Dragon (Hyper)"
|
||||
icon_state = "easternd"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails/chemlight
|
||||
name = "RadDog (Hyper)"
|
||||
icon_state = "chemlight"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/chemlight
|
||||
name = "RadDog (Hyper)"
|
||||
icon_state = "chemlight"
|
||||
icon = 'hyperstation/icons/mob/char_tails.dmi'
|
||||
|
||||
|
||||
/*
|
||||
BODY MARKINGS
|
||||
@@ -335,6 +393,22 @@ from modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm:
|
||||
icon = 'hyperstation/icons/mob/char_markings.dmi'
|
||||
recommended_species = list("avian")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/easterndragon
|
||||
name = "Eastern Dragon (Hyper)"
|
||||
icon_state = "easternd"
|
||||
icon = 'hyperstation/icons/mob/char_markings.dmi'
|
||||
|
||||
//doged was here
|
||||
/datum/sprite_accessory/mam_body_markings/chemlight
|
||||
name = "RadDog (Hyper)"
|
||||
icon_state = "chemlight"
|
||||
icon = 'hyperstation/icons/mob/char_markings.dmi'
|
||||
|
||||
//racc do a code maybe it won't explode
|
||||
/datum/sprite_accessory/mam_body_markings/raccalt
|
||||
name = "RaccAlt (Hyper)"
|
||||
icon_state = "raccalt"
|
||||
icon = 'hyperstation/icons/mob/char_markings.dmi'
|
||||
|
||||
/*
|
||||
TAUR BODIES
|
||||
@@ -355,7 +429,17 @@ from modular_citadel/code/modules/mob/dead/new_player/sprite_accessories.dm:
|
||||
color_src = MATRIXED
|
||||
recommended_species = list("human", "lizard", "insect", "mammal", "xeno", "jelly", "slimeperson", "podweak", "avian", "aquatic")
|
||||
*/
|
||||
/datum/sprite_accessory/taur/chemnaga //Chemlight experimental sprites for future spriting
|
||||
name = "RadDog Naga (Hyper)"
|
||||
icon_state = "chemnaga"
|
||||
taur_mode = SNEK_TAURIC
|
||||
ckeys_allowed = list("chemlight")
|
||||
|
||||
/datum/sprite_accessory/taur/chemlight
|
||||
name = "RadDog Taur (Hyper)"
|
||||
icon_state = "chemlight"
|
||||
taur_mode = PAW_TAURIC
|
||||
ckeys_allowed = list("chemlight")
|
||||
|
||||
/*
|
||||
HAIRSTYLES
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
stuttering += 3 //stutter words
|
||||
|
||||
//if they are asleep, this wont trigger.
|
||||
if (total_pain > 110 && stat == 0) //taking 77 all damage at once from full health, will put you into shock and kill you. This cant be achived with chip damage (or fist fights), because youll die before you reach this pain level.
|
||||
if (total_pain > 120 && stat == 0) //taking 130 all damage at once from full health, will put you into shock and kill you. This cant be achived with chip damage (or fist fights), because youll die before you reach this pain level.
|
||||
if(prob(50))
|
||||
emote("scream")//scream
|
||||
to_chat(src, "<span class='big warning'>You give into the pain...</span>")
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
/mob/living/simple_animal/
|
||||
var/happiness = 50 //how happy they are.
|
||||
|
||||
|
||||
|
||||
/////////////
|
||||
//////////////// CHICKEN /////////////////
|
||||
/////////////
|
||||
|
||||
/mob/living/simple_animal/chick
|
||||
icon = 'hyperstation/icons/mob/chickens.dmi'
|
||||
name = "\improper chick"
|
||||
desc = "Adorable! They make such a racket though."
|
||||
icon_state = "chick"
|
||||
icon_living = "chick"
|
||||
icon_dead = "chick_dead"
|
||||
icon_gib = "chick_gib"
|
||||
gender = FEMALE
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
speak = list("Cherp.","Cherp?","Chirrup.","Cheep!")
|
||||
speak_emote = list("cheeps")
|
||||
emote_hear = list("cheeps.")
|
||||
emote_see = list("pecks at the ground.","flaps its tiny wings.")
|
||||
density = FALSE
|
||||
speak_chance = 2
|
||||
turns_per_move = 2
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/chicken = 1)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
attacktext = "kicks"
|
||||
health = 3
|
||||
maxHealth = 3
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
var/amount_grown = 0
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
mob_size = MOB_SIZE_TINY
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
|
||||
do_footstep = TRUE
|
||||
|
||||
/mob/living/simple_animal/chick/Initialize()
|
||||
. = ..()
|
||||
pixel_x = rand(-6, 6)
|
||||
pixel_y = rand(0, 10)
|
||||
|
||||
/mob/living/simple_animal/chick/Life()
|
||||
. =..()
|
||||
if(!.)
|
||||
return
|
||||
if(!stat && !ckey)
|
||||
amount_grown += rand(1,2)
|
||||
if(amount_grown >= 100)
|
||||
new /mob/living/simple_animal/chicken(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_animal/chick/holo/Life()
|
||||
..()
|
||||
amount_grown = 0
|
||||
|
||||
/mob/living/simple_animal/chicken
|
||||
icon = 'hyperstation/icons/mob/chickens.dmi'
|
||||
name = "\improper chicken"
|
||||
desc = "Hopefully the eggs are good this season."
|
||||
gender = FEMALE
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
icon_state = "chicken_brown"
|
||||
icon_living = "chicken_brown"
|
||||
icon_dead = "chicken_brown_dead"
|
||||
speak = list("Cluck!","BWAAAAARK BWAK BWAK BWAK!","Bwaak bwak.")
|
||||
speak_emote = list("clucks","croons")
|
||||
emote_hear = list("clucks.")
|
||||
emote_see = list("pecks at the ground.","flaps its wings viciously.")
|
||||
density = FALSE
|
||||
speak_chance = 2
|
||||
turns_per_move = 3
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/chicken = 2)
|
||||
var/egg_type = /obj/item/reagent_containers/food/snacks/egg
|
||||
var/food_type = /obj/item/reagent_containers/food/snacks/grown/wheat
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
attacktext = "kicks"
|
||||
health = 15
|
||||
maxHealth = 15
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
var/eggsleft = 0
|
||||
var/eggsFertile = FALSE
|
||||
var/body_color
|
||||
var/icon_prefix = "chicken"
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
var/list/feedMessages = list("It clucks happily.","It clucks happily.")
|
||||
var/list/layMessage = EGG_LAYING_MESSAGES
|
||||
var/list/validColors = list("brown","black","white")
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
var/static/chicken_count = 0
|
||||
|
||||
var/partner //for the sex.
|
||||
var/egglay_timer = 0
|
||||
var/obj/structure/nestbox/nest_target
|
||||
|
||||
var/last_egg
|
||||
var/force_gender //for map loading
|
||||
|
||||
|
||||
do_footstep = TRUE
|
||||
|
||||
/mob/living/simple_animal/chicken/Initialize()
|
||||
. = ..()
|
||||
if((prob(30) && !force_gender) || force_gender == "male") //30% of a male. or setup if already male.
|
||||
gender = MALE
|
||||
name = "rooster"
|
||||
|
||||
if(!body_color)
|
||||
body_color = pick(validColors)
|
||||
icon_state = "[icon_prefix]_[body_color]"
|
||||
icon_living = "[icon_prefix]_[body_color]"
|
||||
icon_dead = "[icon_prefix]_[body_color]_dead"
|
||||
pixel_x = rand(-6, 6)
|
||||
pixel_y = rand(0, 10)
|
||||
++chicken_count
|
||||
|
||||
/mob/living/simple_animal/chicken/Destroy()
|
||||
--chicken_count
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/chicken/attackby(obj/item/O, mob/user, params)
|
||||
if(istype(O, food_type)) //feedin' dem chickens
|
||||
if(!stat && eggsleft < 2)
|
||||
var/feedmsg = "[user] feeds [O] to [name]! [pick(feedMessages)]"
|
||||
user.visible_message(feedmsg)
|
||||
qdel(O)
|
||||
eggsleft += 1
|
||||
egglay_timer = 0
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[name] doesn't seem hungry!</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/chicken/Life()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if (istype(get_turf(src), /turf/open/floor))
|
||||
var/turf/open/floor/turfon = get_turf(src)
|
||||
if (turfon.farm_quality > happiness)
|
||||
happiness ++
|
||||
if (prob(5))
|
||||
visible_message("[src] pecks happily at the ground.") //CLUCK CLUCK CLUCK
|
||||
else
|
||||
happiness --
|
||||
else
|
||||
happiness --
|
||||
|
||||
happiness = clamp(happiness,0,100) //clamp
|
||||
|
||||
|
||||
if (!(gender == FEMALE)) //only females lay eggs and do the rest of the code.
|
||||
return
|
||||
|
||||
|
||||
//Breeding.
|
||||
if (gender == FEMALE && eggsFertile == 0 && eggsleft > 0)
|
||||
for(var/mob/living/simple_animal/chicken/C in view(2,src)) //look for a male near them, or on them.
|
||||
if(C)
|
||||
if(C.gender == MALE) //rooster
|
||||
eggsFertile = 1 //they had sex, just go with it.
|
||||
partner = C //you know who the partner is.
|
||||
//EEGGGG TIME
|
||||
|
||||
//after 10mins, lay a egg regardless.
|
||||
if(world.time > (last_egg+600 SECONDS) && !eggsleft)
|
||||
if(prob(15)) //just to offset
|
||||
eggsleft ++
|
||||
last_egg = world.time
|
||||
|
||||
|
||||
if((!stat && eggsleft > 0) && egg_type)
|
||||
egglay_timer ++
|
||||
else
|
||||
egglay_timer = 0
|
||||
|
||||
|
||||
//chance to lay egg on their own.
|
||||
|
||||
|
||||
//look for nest!
|
||||
|
||||
//We have found a nest, override movement
|
||||
if(nest_target) //if alive and we have a target.
|
||||
stop_automated_movement = 1
|
||||
walk_to(src,nest_target,0,8)
|
||||
else
|
||||
stop_automated_movement = 0
|
||||
walk_to(src,0) //reset walk_to
|
||||
|
||||
if (egglay_timer > 10 && !stat) //time to lay a egg and not dead.
|
||||
if((!stat && eggsleft > 0) && egg_type)
|
||||
if (!nest_target)
|
||||
for(var/obj/structure/nestbox/N in view(3,src)) // look for a eggbox if you dont have one already
|
||||
nest_target = N
|
||||
break
|
||||
|
||||
//We are at the nest we have chosen.
|
||||
if (nest_target)
|
||||
for(var/obj/structure/nestbox/B in get_turf(src))
|
||||
if((prob(25) && eggsleft > 0) && egg_type)
|
||||
visible_message("<span class='alertalien'>[src] [pick(layMessage)]</span>")
|
||||
eggsleft--
|
||||
var/obj/item/E = new egg_type(get_turf(src))
|
||||
E.pixel_x = rand(-6,6)
|
||||
E.pixel_y = rand(-6,6)
|
||||
egglay_timer = 0 //set timer
|
||||
nest_target = null //layed the egg, time to move on
|
||||
if(eggsFertile && partner)
|
||||
if(chicken_count < MAX_CHICKENS && prob(happiness))
|
||||
START_PROCESSING(SSobj, E)
|
||||
eggsFertile = 0 //youve layed your fertile egg.
|
||||
E.name = "fertile egg"
|
||||
partner = null
|
||||
last_egg = world.time
|
||||
break
|
||||
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/egg/var/amount_grown = 0
|
||||
/obj/item/reagent_containers/food/snacks/egg/process()
|
||||
if(isturf(loc))
|
||||
for(var/obj/structure/nestbox/B in get_turf(src)) //can only hatch in a nestbox or incubator
|
||||
amount_grown += rand(1,2)
|
||||
if(amount_grown >= 100)
|
||||
visible_message("[src] hatches with a quiet cracking sound.")
|
||||
new /mob/living/simple_animal/chick(get_turf(src))
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
qdel(src)
|
||||
break
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
|
||||
/mob/living/simple_animal/chicken/examine()
|
||||
. = ..()
|
||||
. += "this one is [gender]."
|
||||
if(happiness<20)
|
||||
. += "<span class='warning'>It looks stressed.</span>"
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
This is a pre-destroyed nuclear reactor for the sake of mapping special fluff stuff.
|
||||
Not actually a reactor, just uses the icon and irradiates the surrounding area a bit.
|
||||
Nowhere else to really put this.
|
||||
*/
|
||||
|
||||
/obj/structure/fluff/destroyed_nuclear_reactor
|
||||
name = "Destroyed Nuclear Reactor"
|
||||
desc = "What in the hell happened here?"
|
||||
icon = 'hyperstation/icons/obj/machinery/rbmk.dmi'
|
||||
icon_state = "reactor_slagged"
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
dir = 8 //Less headache inducing :))
|
||||
|
||||
/obj/structure/fluff/destroyed_nuclear_reactor/Initialize()
|
||||
. = ..()
|
||||
set_light(3)
|
||||
AddComponent(/datum/component/radioactive, 15000 , src)
|
||||
@@ -0,0 +1,11 @@
|
||||
//Hope you're not a Russian T-90
|
||||
/datum/reagent/consumable/ethanol/javelin
|
||||
name = "Javelin Cocktail"
|
||||
boozepwr = 80
|
||||
color = "#F54F10"
|
||||
quality = DRINK_FANTASTIC
|
||||
taste_description = "explosive fireballs"
|
||||
glass_icon_state = "javelin"
|
||||
shot_glass_icon_state = "javelin_warhead"
|
||||
glass_name = "Javelin Cocktail"
|
||||
glass_desc = "A man-portable, delicious glass of justice."
|
||||
@@ -21,3 +21,13 @@
|
||||
if(holder.has_reagent(/datum/reagent/consumable/capsaicin))
|
||||
holder.remove_reagent(/datum/reagent/consumable/capsaicin, 1)
|
||||
..()
|
||||
|
||||
/datum/reagent/consumable/kalynajuice
|
||||
name = "Red Kalyna Juice"
|
||||
description = "Juice from Kalyna plants."
|
||||
color = "#E90501" // rgb: 233, 5, 1
|
||||
taste_description = "sweet cranberries"
|
||||
glass_icon_state = "kalyna"
|
||||
glass_name = "glass of red kalyna juice"
|
||||
glass_desc = "A vibrantly red juice!"
|
||||
hydration = 4
|
||||
|
||||
@@ -12,6 +12,7 @@ var/const/RESIZE_MICRO = 0.25
|
||||
/mob/living
|
||||
var/size_multiplier = 1 //multiplier for the mob's icon size atm
|
||||
var/previous_size = 1
|
||||
var/small_speech = FALSE
|
||||
|
||||
//Cyanosis - Action that resizes the sprite for the client but nobody else. Say goodbye to attacking yourself when someone's above you lmao
|
||||
var/datum/action/sizecode_resize/small_sprite
|
||||
@@ -237,8 +238,14 @@ mob/living/get_effective_size()
|
||||
|
||||
//Proc for changing mob_size to be grabbed for item weight classes
|
||||
/mob/living/proc/update_mobsize(var/mob/living/tmob)
|
||||
if(small_speech == TRUE) //if they have small speech reset it.
|
||||
small_speech = FALSE
|
||||
UnregisterSignal(src, COMSIG_MOB_SAY)
|
||||
|
||||
if(size_multiplier <= 0.50)
|
||||
mob_size = 0
|
||||
RegisterSignal(src, COMSIG_MOB_SAY, .proc/handle_small_speech)
|
||||
small_speech = TRUE
|
||||
if(size_multiplier < 1)
|
||||
mob_size = 1
|
||||
if(size_multiplier == 1)
|
||||
@@ -246,6 +253,9 @@ mob/living/get_effective_size()
|
||||
if(size_multiplier > 1)
|
||||
mob_size = 3
|
||||
|
||||
/mob/living/proc/handle_small_speech(owner, list/speech_args) //for making peoples text small
|
||||
speech_args[SPEECH_SPANS] |= SPAN_SMALL
|
||||
|
||||
//Proc for instantly grabbing valid size difference. Code optimizations soon(TM)
|
||||
/*
|
||||
/mob/living/proc/sizeinteractioncheck(var/mob/living/tmob)
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/obj/item/reagent_containers/food/snacks/grown/wheat/
|
||||
var stacktype = /obj/item/stack/tile/hay
|
||||
var/tile_coefficient = 0.02 // same as grass
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/wheat/attack_self(mob/user)
|
||||
to_chat(user, "<span class='notice'>You prepare the hay bedding.</span>")
|
||||
var/grassAmt = 1 + round(seed.potency * tile_coefficient) // The grass we're holding
|
||||
for(var/obj/item/reagent_containers/food/snacks/grown/wheat/G in user.loc) // The grass on the floor
|
||||
if(G.type != type)
|
||||
continue
|
||||
grassAmt += 1 + round(G.seed.potency * tile_coefficient)
|
||||
qdel(G)
|
||||
new stacktype(user.drop_location(), grassAmt)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/structure/nestbox
|
||||
name = "nest box"
|
||||
icon = 'hyperstation/icons/obj/hydroponics/farming.dmi'
|
||||
icon_state = "nestbox"
|
||||
desc = "A little nest box, for collecting eggs"
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
|
||||
/obj/structure/nestbox/wrench_act(mob/living/user, obj/item/I)
|
||||
user.visible_message("<span class='warning'>[user] disassembles [src].</span>",
|
||||
"<span class='notice'>You start to disassemble [src]...</span>", "You hear clanking and banging noises.")
|
||||
if(I.use_tool(src, user, 20, volume=50))
|
||||
new /obj/item/stack/sheet/mineral/wood (loc, 4)
|
||||
qdel(src)
|
||||
@@ -0,0 +1,44 @@
|
||||
/obj/structure/jacuzzi
|
||||
name = "jacuzzi"
|
||||
icon = 'hyperstation/icons/obj/jacuzzi.dmi'
|
||||
icon_state = "tub"
|
||||
desc = "A luxurious pool, but with bubbles!"
|
||||
var/filled = TRUE
|
||||
density = FALSE
|
||||
var/mutable_appearance/waterlower
|
||||
var/mutable_appearance/water
|
||||
var/mutable_appearance/top
|
||||
var/mutable_appearance/mist
|
||||
anchored = TRUE
|
||||
|
||||
//Dont move, it goes in walls and is shit.
|
||||
///obj/structure/jacuzzi/attackby(obj/item/W, mob/user, params)
|
||||
// if(istype(W, /obj/item/wrench))
|
||||
// W.play_tool_sound(src)
|
||||
// anchored = !anchored
|
||||
|
||||
/obj/structure/jacuzzi/Initialize()
|
||||
. = ..()
|
||||
top = mutable_appearance('hyperstation/icons/obj/jacuzzi.dmi', "tub_top")
|
||||
top.layer = 5
|
||||
add_overlay(top)
|
||||
|
||||
/obj/structure/jacuzzi/attack_hand(mob/user)
|
||||
. = ..()
|
||||
filled = !filled
|
||||
if(!filled)
|
||||
cut_overlay(waterlower)
|
||||
cut_overlay(water)
|
||||
cut_overlay(mist)
|
||||
else
|
||||
waterlower = mutable_appearance('hyperstation/icons/obj/jacuzzi.dmi', "water")
|
||||
water = mutable_appearance('hyperstation/icons/obj/jacuzzi.dmi', "over_water")
|
||||
mist = mutable_appearance('hyperstation/icons/obj/jacuzzi.dmi', "mist")
|
||||
waterlower.layer = 3
|
||||
water.layer = 10
|
||||
mist.layer = 11
|
||||
mist.pixel_y = 5
|
||||
add_overlay(waterlower)
|
||||
add_overlay(water)
|
||||
add_overlay(mist)
|
||||
|
||||
@@ -129,3 +129,72 @@ obj/item/clothing/neck/stole/black
|
||||
max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
|
||||
heat_protection = CHEST|GROIN|ARMS
|
||||
armor = list("melee" = 60, "bullet" = 80, "laser" = 80, "energy" = 90, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
|
||||
|
||||
/obj/item/clothing/under/raccveralls
|
||||
name = "form fitting overalls"
|
||||
desc = "A tight form fitting pair of overalls."
|
||||
icon = 'hyperstation/icons/obj/clothing/uniforms.dmi'
|
||||
icon_state = "raccveralls"
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/uniforms.dmi'
|
||||
item_state = "raccveralls"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/officesexy
|
||||
name = "Revealing office uniform"
|
||||
desc = "A sexy office uniform, that has a low cropped front to show off some chest, or bra. And a tall dress that covers the stomach, complete with a set of buttons."
|
||||
icon = 'hyperstation/icons/obj/clothing/uniforms.dmi'
|
||||
icon_state = "office_revealing"
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/uniforms.dmi'
|
||||
item_state = "office_revealing"
|
||||
can_adjust = FALSE
|
||||
mutantrace_variation = NO_MUTANTRACE_VARIATION
|
||||
|
||||
/obj/item/clothing/under/vaultsuit
|
||||
name = "vault suit"
|
||||
desc = "A tight form fitting Vault-Tec standard issue Vault Jumpsuit! Snazzy!"
|
||||
icon = 'hyperstation/icons/obj/clothing/uniforms.dmi'
|
||||
icon_state = "vaultsuit"
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/uniforms.dmi'
|
||||
item_state = "b_suit"
|
||||
can_adjust = FALSE
|
||||
var/firstpickup = TRUE
|
||||
var/pickupsound = TRUE
|
||||
|
||||
/obj/item/clothing/under/vaultsuit/no_sound
|
||||
pickupsound = FALSE
|
||||
|
||||
/obj/item/clothing/under/vaultsuit/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(!pickupsound)
|
||||
return
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot == SLOT_W_UNIFORM)
|
||||
if(!firstpickup)
|
||||
SEND_SOUND(user, sound('hyperstation/sound/effects/vaultsuit/FalloutEXPUp.ogg', volume = 50))
|
||||
else
|
||||
firstpickup = FALSE
|
||||
SEND_SOUND(user, sound('hyperstation/sound/effects/vaultsuit/FalloutLevelUp.ogg', volume = 50))
|
||||
SEND_SOUND(user, sound('hyperstation/sound/effects/vaultsuit/InkSpotsSting.ogg', volume = 60))
|
||||
return
|
||||
|
||||
/obj/item/clothing/suit/tunnelfox
|
||||
name = "tunnel fox jacket"
|
||||
desc = "Tunnel Foxes Rule!"
|
||||
icon = 'hyperstation/icons/obj/clothing/suits.dmi'
|
||||
icon_state = "tunnelfox"
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/suits.dmi'
|
||||
item_state = "tunnelfox"
|
||||
body_parts_covered = CHEST|LEGS|ARMS
|
||||
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
|
||||
|
||||
/obj/item/clothing/suit/tunnelfox_t
|
||||
name = "opened tunnel fox jacket"
|
||||
desc = "Tunnel Foxes Rule!"
|
||||
icon = 'hyperstation/icons/obj/clothing/suits.dmi'
|
||||
icon_state = "tunnelfox_t"
|
||||
alternate_worn_icon = 'hyperstation/icons/mobs/suits.dmi'
|
||||
item_state = "tunnelfox_t"
|
||||
body_parts_covered = CHEST|LEGS|ARMS
|
||||
min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT
|
||||
|
||||
|
||||
Reference in New Issue
Block a user