Merge branch 'master' into upstream-merge-37597

This commit is contained in:
LetterJay
2018-05-22 07:21:53 -05:00
committed by GitHub
661 changed files with 12019 additions and 10559 deletions
+1 -1
View File
@@ -480,7 +480,7 @@
H.attack_self(owner)
return
var/obj/item/I = target
if(owner.can_equip(I, slot_hands))
if(owner.can_equip(I, SLOT_HANDS))
owner.temporarilyRemoveItemFromInventory(I)
owner.put_in_hands(I)
I.attack_self(owner)
+1 -1
View File
@@ -160,7 +160,7 @@
to_chat(owner, "<span class='warning'>You feel really lonely...</span>")
else
to_chat(owner, "<span class='warning'>You're going mad with loneliness!</span>")
owner.hallucination += 20
owner.hallucination += 30
if(5)
if(!high_stress)
+78
View File
@@ -0,0 +1,78 @@
/datum/component/armor_plate
var/amount = 0
var/maxamount = 3
var/upgrade_item = /obj/item/stack/sheet/animalhide/goliath_hide
var/datum/armor/added_armor = list("melee" = 10)
var/upgrade_name
/datum/component/armor_plate/Initialize(_maxamount,obj/item/_upgrade_item,datum/armor/_added_armor)
if(!isobj(parent))
return COMPONENT_INCOMPATIBLE
RegisterSignal(COMSIG_PARENT_EXAMINE, .proc/examine)
RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/applyplate)
RegisterSignal(COMSIG_PARENT_PREQDELETED, .proc/dropplates)
if(_maxamount)
maxamount = _maxamount
if(_upgrade_item)
upgrade_item = _upgrade_item
if(_added_armor)
if(islist(_added_armor))
added_armor = getArmor(arglist(_added_armor))
else if (istype(_added_armor, /datum/armor))
added_armor = _added_armor
else
stack_trace("Invalid type [_added_armor.type] passed as _armor_item argument to armorplate component")
else
added_armor = getArmor(arglist(added_armor))
var/obj/item/typecast = upgrade_item
upgrade_name = initial(typecast.name)
/datum/component/armor_plate/proc/examine(mob/user)
//upgrade_item could also be typecast here instead
if(ismecha(parent))
if(amount)
if(amount < maxamount)
to_chat(user, "<span class='notice'>Its armor is enhanced with [amount] [upgrade_name].</span>")
else
to_chat(user, "<span class='notice'>It's wearing a fearsome carapace entirely composed of [upgrade_name] - its pilot must be an experienced monster hunter.</span>")
else
to_chat(user, "<span class='notice'>It has attachment points for strapping monster hide on for added protection.</span>")
else
if(amount)
to_chat(user, "<span class='notice'>It has been strengthened with [amount]/[maxamount] [upgrade_name].</span>")
else
to_chat(user, "<span class='notice'>It can be strengthened with up to [maxamount] [upgrade_name].</span>")
/datum/component/armor_plate/proc/applyplate(obj/item/I, mob/user, params)
if(!istype(I,upgrade_item))
return
if(amount >= maxamount)
to_chat(user, "<span class='warning'>You can't improve [parent] any further!</span>")
return
if(istype(I,/obj/item/stack))
I.use(1)
else
if(length(I.contents))
to_chat(user, "<span class='warning'>[I] cannot be used for armoring while there's something inside!</span>")
return
qdel(I)
var/obj/O = parent
amount++
O.armor = O.armor.attachArmor(added_armor)
if(ismecha(O))
var/obj/mecha/R = O
R.update_icon()
to_chat(user, "<span class='info'>You strengthen [R], improving its resistance against melee, bullet and laser damage.</span>")
else
to_chat(user, "<span class='info'>You strengthen [O], improving its resistance against melee attacks.</span>")
/datum/component/armor_plate/proc/dropplates(force)
if(ismecha(parent)) //items didn't drop the plates before and it causes erroneous behavior for the time being with collapsible helmets
for(var/i in 1 to amount)
new upgrade_item(get_turf(parent))
+11 -6
View File
@@ -15,16 +15,18 @@
var/sheet_type
var/list/materials
var/show_on_examine
var/disable_attackby
var/list/allowed_typecache
var/last_inserted_id
var/precise_insertion = FALSE
var/datum/callback/precondition
var/datum/callback/after_insert
/datum/component/material_container/Initialize(list/mat_list, max_amt = 0, _show_on_examine = FALSE, list/allowed_types, datum/callback/_precondition, datum/callback/_after_insert)
/datum/component/material_container/Initialize(list/mat_list, max_amt = 0, _show_on_examine = FALSE, list/allowed_types, datum/callback/_precondition, datum/callback/_after_insert, _disable_attackby)
materials = list()
max_amount = max(0, max_amt)
show_on_examine = _show_on_examine
disable_attackby = _disable_attackby
if(allowed_types)
allowed_typecache = typecacheof(allowed_types)
precondition = _precondition
@@ -43,14 +45,17 @@
materials[id] = new mat_path()
/datum/component/material_container/proc/OnExamine(mob/user)
for(var/I in materials)
var/datum/material/M = materials[I]
var/amt = amount(M.id)
if(amt)
to_chat(user, "<span class='notice'>It has [amt] units of [lowertext(M.name)] stored.</span>")
if(show_on_examine)
for(var/I in materials)
var/datum/material/M = materials[I]
var/amt = amount(M.id)
if(amt)
to_chat(user, "<span class='notice'>It has [amt] units of [lowertext(M.name)] stored.</span>")
/datum/component/material_container/proc/OnAttackBy(obj/item/I, mob/living/user)
var/list/tc = allowed_typecache
if(disable_attackby)
return
if(user.a_intent != INTENT_HELP)
return
if((I.flags_1 & HOLOGRAM_1) || (I.item_flags & NO_MAT_REDEMPTION) || (tc && !is_type_in_typecache(I, tc)))
+6 -1
View File
@@ -1,9 +1,14 @@
/datum/component/redirect
dupe_mode = COMPONENT_DUPE_ALLOWED
/datum/component/redirect/Initialize(list/signals, datum/callback/_callback)
/datum/component/redirect/Initialize(list/signals, datum/callback/_callback, flags=NONE)
//It's not our job to verify the right signals are registered here, just do it.
if(!LAZYLEN(signals) || !istype(_callback))
warning("signals are [list2params(signals)], callback is [_callback]]")
return COMPONENT_INCOMPATIBLE
if(flags & REDIRECT_TRANSFER_WITH_TURF && isturf(parent))
RegisterSignal(COMSIG_TURF_CHANGE, .proc/turf_change)
RegisterSignal(signals, _callback)
/datum/component/redirect/proc/turf_change(path, new_baseturfs, flags, list/transfers)
transfers += src
+1 -7
View File
@@ -28,13 +28,7 @@
CRASH("Unable to find a blobstart landmark")
var/atom/movable/AM = parent
if(ismob(AM.loc))
var/mob/M = AM.loc
M.transferItemToLoc(AM, targetturf, TRUE) //nodrops disks when?
else if(AM.loc.SendSignal(COMSIG_CONTAINS_STORAGE))
AM.loc.SendSignal(COMSIG_TRY_STORAGE_TAKE, src, targetturf, TRUE)
else
AM.forceMove(targetturf)
AM.forceMove(targetturf)
// move the disc, so ghosts remain orbiting it even if it's "destroyed"
return targetturf
@@ -73,6 +73,8 @@
slave.refresh_mob_views()
/datum/component/storage/concrete/emp_act(severity)
if(emp_shielded)
return
var/atom/real_location = real_location()
for(var/i in real_location)
var/atom/A = i
+24 -16
View File
@@ -87,7 +87,8 @@
RegisterSignal(COMSIG_ATOM_ATTACK_PAW, .proc/on_attack_hand)
RegisterSignal(COMSIG_ATOM_EMP_ACT, .proc/emp_act)
RegisterSignal(COMSIG_ATOM_ATTACK_GHOST, .proc/show_to_ghost)
RegisterSignal(COMSIG_ATOM_EXITED, .proc/_removal_reset)
RegisterSignal(COMSIG_ATOM_ENTERED, .proc/refresh_mob_views)
RegisterSignal(COMSIG_ATOM_EXITED, .proc/_remove_and_refresh)
RegisterSignal(COMSIG_ITEM_PRE_ATTACK, .proc/preattack_intercept)
RegisterSignal(COMSIG_ITEM_ATTACK_SELF, .proc/attack_self)
@@ -232,13 +233,15 @@
stoplag(1)
qdel(progress)
/datum/component/storage/proc/mass_remove_from_storage(atom/target, list/things, datum/progressbar/progress)
/datum/component/storage/proc/mass_remove_from_storage(atom/target, list/things, datum/progressbar/progress, trigger_on_found = TRUE)
var/atom/real_location = real_location()
for(var/obj/item/I in things)
things -= I
if(I.loc != real_location)
continue
remove_from_storage(I, target)
if(trigger_on_found && I.on_found())
return FALSE
if(TICK_CHECK)
progress.update(progress.goal - length(things))
return TRUE
@@ -367,10 +370,10 @@
. = TRUE //returns TRUE if any mobs actually got a close(M) call
/datum/component/storage/proc/emp_act(severity)
var/atom/A = parent
if(!isliving(A.loc) && !emp_shielded)
var/datum/component/storage/concrete/master = master()
master.emp_act(severity)
if(emp_shielded)
return
var/datum/component/storage/concrete/master = master()
master.emp_act(severity)
//This proc draws out the inventory and places the items on it. tx and ty are the upper left tile and mx, my are the bottm right.
//The numbers are calculated from the bottom-left The bottom-left slot being 1,1.
@@ -400,6 +403,10 @@
return FALSE
return master._removal_reset(thing)
/datum/component/storage/proc/_remove_and_refresh(atom/movable/thing)
_removal_reset(thing)
refresh_mob_views()
//Call this proc to handle the removal of an item from the storage item. The item will be moved to the new_location target, if that is null it's being deleted
/datum/component/storage/proc/remove_from_storage(atom/movable/AM, atom/new_location)
if(!istype(AM))
@@ -453,23 +460,24 @@
return FALSE
handle_item_insertion(I, FALSE, M)
/datum/component/storage/proc/return_inv()
. = list()
. += contents()
for(var/i in contents())
var/atom/a = i
GET_COMPONENT_FROM(STR, /datum/component/storage, a)
if(STR)
. += STR.return_inv()
/datum/component/storage/proc/return_inv(recursive)
var/list/ret = list()
ret |= contents()
if(recursive)
for(var/i in ret.Copy())
var/atom/A = i
A.SendSignal(COMSIG_TRY_STORAGE_RETURN_INVENTORY, ret, TRUE)
return ret
/datum/component/storage/proc/contents() //ONLY USE IF YOU NEED TO COPY CONTENTS OF REAL LOCATION, COPYING IS NOT AS FAST AS DIRECT ACCESS!
var/atom/real_location = real_location()
return real_location.contents.Copy()
/datum/component/storage/proc/signal_return_inv(list/interface)
//Abuses the fact that lists are just references, or something like that.
/datum/component/storage/proc/signal_return_inv(list/interface, recursive = TRUE)
if(!islist(interface))
return FALSE
interface |= return_inv()
interface |= return_inv(recursive)
return TRUE
/datum/component/storage/proc/mousedrop_onto(atom/over_object, mob/M)
+3
View File
@@ -1,3 +1,6 @@
/datum/proc/CanProcCall(procname)
return TRUE
/datum/proc/can_vv_get(var_name)
return TRUE
+2 -2
View File
@@ -79,8 +79,8 @@
if(isobj(H.wear_suit))
Cl = H.wear_suit
passed = prob((Cl.permeability_coefficient*100) - 1)
if(passed && isobj(slot_w_uniform))
Cl = slot_w_uniform
if(passed && isobj(SLOT_W_UNIFORM))
Cl = SLOT_W_UNIFORM
passed = prob((Cl.permeability_coefficient*100) - 1)
if(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)
if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered&HANDS)
@@ -55,7 +55,7 @@ Bonus
switch(A.stage)
if(1, 2, 3, 4)
if(prob(base_message_chance) && !suppress_warning)
to_chat(M, "<span class='warning'>[pick("You feel nauseous.", "You feel like you're going to throw up!")]</span>")
to_chat(M, "<span class='warning'>[pick("You feel nauseated.", "You feel like you're going to throw up!")]</span>")
else
vomit(M)
+1 -1
View File
@@ -34,7 +34,7 @@
to_chat(H, "<span class='warning'>You feel dizzy.</span>")
H.confused += 6
if(prob(3))
to_chat(H, "<span class='warning'>You feel [pick("full", "nauseous", "sweaty", "weak", "tired", "short on breath", "uneasy")].</span>")
to_chat(H, "<span class='warning'>You feel [pick("full", "nauseated", "sweaty", "weak", "tired", "short on breath", "uneasy")].</span>")
if(3 to 4)
if(!sound)
H.playsound_local(H, 'sound/health/slowbeat.ogg',40,0, channel = CHANNEL_HEARTBEAT)
-1
View File
@@ -9,7 +9,6 @@
viable_mobtypes = list(/mob/living/carbon/human)
permeability_mod = 1
severity = DISEASE_SEVERITY_BIOHAZARD
process_dead = TRUE
/datum/disease/rhumba_beat/stage_act()
..()
+3 -3
View File
@@ -61,19 +61,19 @@ STI KALY - blind
if(!istype(H.head, /obj/item/clothing/head/wizard))
if(!H.dropItemToGround(H.head))
qdel(H.head)
H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(H), SLOT_HEAD)
return
if(prob(chance))
if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe))
if(!H.dropItemToGround(H.wear_suit))
qdel(H.wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(H), SLOT_WEAR_SUIT)
return
if(prob(chance))
if(!istype(H.shoes, /obj/item/clothing/shoes/sandal/magic))
if(!H.dropItemToGround(H.shoes))
qdel(H.shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(H), SLOT_SHOES)
return
else
var/mob/living/carbon/H = affected_mob
+10 -9
View File
@@ -5,7 +5,7 @@
var/date
/datum/getrev/New()
testmerge = SERVER_TOOLS_PR_LIST
testmerge = world.TgsTestMerges()
log_world("Running /tg/ revision:")
var/list/logs = world.file2list(".git/logs/HEAD")
if(logs)
@@ -21,7 +21,8 @@
log_world(commit)
for(var/line in testmerge)
if(line)
var/tmcommit = testmerge[line]["commit"]
var/datum/tgs_revision_information/test_merge/tm = line
var/tmcommit = tm.commit
log_world("Test merge active of PR #[line] commit [tmcommit]")
SSblackbox.record_feedback("nested tally", "testmerged_prs", 1, list("[line]", "[tmcommit]"))
if(originmastercommit)
@@ -34,11 +35,12 @@
return ""
. = header ? "The following pull requests are currently test merged:<br>" : ""
for(var/line in testmerge)
var/cm = testmerge[line]["commit"]
var/details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["author"]) + " at commit " + html_encode(copytext(cm, 1, min(length(cm), 7)))
var/datum/tgs_revision_information/test_merge/tm = line
var/cm = tm.pull_request_commit
var/details = ": '" + html_encode(tm.title) + "' by " + html_encode(tm.author) + " at commit " + html_encode(copytext(cm, 1, min(length(cm), 11)))
if(details && findtext(details, "\[s\]") && (!usr || !usr.client.holder))
continue
. += "<a href=\"[CONFIG_GET(string/githuburl)]/pull/[line]\">#[line][details]</a><br>"
. += "<a href=\"[CONFIG_GET(string/githuburl)]/pull/[tm.number]\">#[tm.number][details]</a><br>"
/client/verb/showrevinfo()
set category = "OOC"
@@ -54,13 +56,12 @@
to_chat(src, GLOB.revdata.GetTestMergeInfo())
prefix = "Based off origin/master commit: "
var/pc = GLOB.revdata.originmastercommit
to_chat(src, "[prefix]<a href=\"[CONFIG_GET(string/githuburl)]/commit/[pc]\">[copytext(pc, 1, min(length(pc), 7))]</a>")
to_chat(src, "[prefix]<a href=\"[CONFIG_GET(string/githuburl)]/commit/[pc]\">[copytext(pc, 1, min(length(pc), 11))]</a>")
else
to_chat(src, "Master revision unknown")
to_chat(src, "Revision: [GLOB.revdata.commit]")
if(SERVER_TOOLS_PRESENT)
to_chat(src, "Server tools version: [SERVER_TOOLS_VERSION]")
to_chat(src, "Server tools API version: [SERVER_TOOLS_API_VERSION]")
if(world.TgsAvailable())
to_chat(src, "Server tools version: [world.TgsVersion()]")
to_chat(src, "<b>Current Informational Settings:</b>")
to_chat(src, "Protect Authority Roles From Traitor: [CONFIG_GET(flag/protect_roles_from_antagonist)]")
to_chat(src, "Protect Assistant Role From Traitor: [CONFIG_GET(flag/protect_assistant_from_antagonist)]")
+2 -2
View File
@@ -53,7 +53,7 @@
/obj/item/clothing/gloves/boxing/equipped(mob/user, slot)
if(!ishuman(user))
return
if(slot == slot_gloves)
if(slot == SLOT_GLOVES)
var/mob/living/carbon/human/H = user
style.teach(H,1)
return
@@ -62,6 +62,6 @@
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
if(H.get_item_by_slot(slot_gloves) == src)
if(H.get_item_by_slot(SLOT_GLOVES) == src)
style.remove(H)
return
+2 -2
View File
@@ -170,7 +170,7 @@
/obj/item/clothing/gloves/krav_maga/equipped(mob/user, slot)
if(!ishuman(user))
return
if(slot == slot_gloves)
if(slot == SLOT_GLOVES)
var/mob/living/carbon/human/H = user
style.teach(H,1)
@@ -178,7 +178,7 @@
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
if(H.get_item_by_slot(slot_gloves) == src)
if(H.get_item_by_slot(SLOT_GLOVES) == src)
style.remove(H)
/obj/item/clothing/gloves/krav_maga/sec//more obviously named, given to sec
+1 -1
View File
@@ -161,7 +161,7 @@
desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts. Can be wielded to both kill and incapacitate."
force = 10
w_class = WEIGHT_CLASS_BULKY
slot_flags = SLOT_BACK
slot_flags = ITEM_SLOT_BACK
force_unwielded = 10
force_wielded = 24
throwforce = 20
+2 -2
View File
@@ -448,7 +448,7 @@
/obj/item/storage/belt/champion/wrestling/equipped(mob/user, slot)
if(!ishuman(user))
return
if(slot == slot_belt)
if(slot == SLOT_BELT)
var/mob/living/carbon/human/H = user
style.teach(H,1)
return
@@ -457,6 +457,6 @@
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
if(H.get_item_by_slot(slot_belt) == src)
if(H.get_item_by_slot(SLOT_BELT) == src)
style.remove(H)
return
+16 -16
View File
@@ -39,31 +39,31 @@
//Start with uniform,suit,backpack for additional slots
if(uniform)
H.equip_to_slot_or_del(new uniform(H),slot_w_uniform)
H.equip_to_slot_or_del(new uniform(H),SLOT_W_UNIFORM)
if(suit)
H.equip_to_slot_or_del(new suit(H),slot_wear_suit)
H.equip_to_slot_or_del(new suit(H),SLOT_WEAR_SUIT)
if(back)
H.equip_to_slot_or_del(new back(H),slot_back)
H.equip_to_slot_or_del(new back(H),SLOT_BACK)
if(belt)
H.equip_to_slot_or_del(new belt(H),slot_belt)
H.equip_to_slot_or_del(new belt(H),SLOT_BELT)
if(gloves)
H.equip_to_slot_or_del(new gloves(H),slot_gloves)
H.equip_to_slot_or_del(new gloves(H),SLOT_GLOVES)
if(shoes)
H.equip_to_slot_or_del(new shoes(H),slot_shoes)
H.equip_to_slot_or_del(new shoes(H),SLOT_SHOES)
if(head)
H.equip_to_slot_or_del(new head(H),slot_head)
H.equip_to_slot_or_del(new head(H),SLOT_HEAD)
if(mask)
H.equip_to_slot_or_del(new mask(H),slot_wear_mask)
H.equip_to_slot_or_del(new mask(H),SLOT_WEAR_MASK)
if(neck)
H.equip_to_slot_or_del(new neck(H),slot_neck)
H.equip_to_slot_or_del(new neck(H),SLOT_NECK)
if(ears)
H.equip_to_slot_or_del(new ears(H),slot_ears)
H.equip_to_slot_or_del(new ears(H),SLOT_EARS)
if(glasses)
H.equip_to_slot_or_del(new glasses(H),slot_glasses)
H.equip_to_slot_or_del(new glasses(H),SLOT_GLASSES)
if(id)
H.equip_to_slot_or_del(new id(H),slot_wear_id)
H.equip_to_slot_or_del(new id(H),SLOT_WEAR_ID)
if(suit_store)
H.equip_to_slot_or_del(new suit_store(H),slot_s_store)
H.equip_to_slot_or_del(new suit_store(H),SLOT_S_STORE)
if(accessory)
var/obj/item/clothing/under/U = H.w_uniform
@@ -79,16 +79,16 @@
if(!visualsOnly) // Items in pockets or backpack don't show up on mob's icon.
if(l_pocket)
H.equip_to_slot_or_del(new l_pocket(H),slot_l_store)
H.equip_to_slot_or_del(new l_pocket(H),SLOT_L_STORE)
if(r_pocket)
H.equip_to_slot_or_del(new r_pocket(H),slot_r_store)
H.equip_to_slot_or_del(new r_pocket(H),SLOT_R_STORE)
if(backpack_contents)
for(var/path in backpack_contents)
var/number = backpack_contents[path]
if(!isnum(number))//Default to 1
number = 1
for(var/i in 1 to number)
H.equip_to_slot_or_del(new path(H),slot_in_backpack)
H.equip_to_slot_or_del(new path(H),SLOT_IN_BACKPACK)
if(!H.head && toggle_helmet && istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit))
var/obj/item/clothing/suit/space/hardsuit/HS = H.wear_suit
+3
View File
@@ -29,6 +29,9 @@
/datum/radiation_wave/process()
master_turf = get_step(master_turf, move_dir)
if(!master_turf)
qdel(src)
return
steps++
var/list/atoms = get_rad_atoms()
@@ -1,94 +1,94 @@
//every trait in this folder should be coded around being applied on spawn
//these are NOT "mob traits" like GOTTAGOFAST, but exist as a medium to apply them and other different effects
/datum/trait
var/name = "Test Trait"
var/desc = "This is a test trait."
//every quirk in this folder should be coded around being applied on spawn
//these are NOT "mob quirks" like GOTTAGOFAST, but exist as a medium to apply them and other different effects
/datum/quirk
var/name = "Test Quirk"
var/desc = "This is a test quirk."
var/value = 0
var/human_only = TRUE
var/gain_text
var/lose_text
var/medical_record_text //This text will appear on medical records for the trait. Not yet implemented
var/mood_trait = FALSE //if true, this trait affects mood and is unavailable if moodlets are disabled
var/mood_quirk = FALSE //if true, this quirk affects mood and is unavailable if moodlets are disabled
var/mob_trait //if applicable, apply and remove this mob trait
var/mob/living/trait_holder
var/mob/living/quirk_holder
/datum/trait/New(mob/living/trait_mob, spawn_effects)
/datum/quirk/New(mob/living/quirk_mob, spawn_effects)
..()
if(!trait_mob || (human_only && !ishuman(trait_mob)) || trait_mob.has_trait_datum(type))
if(!quirk_mob || (human_only && !ishuman(quirk_mob)) || quirk_mob.has_quirk(type))
qdel(src)
trait_holder = trait_mob
SStraits.trait_objects += src
to_chat(trait_holder, gain_text)
trait_holder.roundstart_traits += src
quirk_holder = quirk_mob
SSquirks.quirk_objects += src
to_chat(quirk_holder, gain_text)
quirk_holder.roundstart_quirks += src
if(mob_trait)
trait_holder.add_trait(mob_trait, ROUNDSTART_TRAIT)
START_PROCESSING(SStraits, src)
quirk_holder.add_trait(mob_trait, ROUNDSTART_TRAIT)
START_PROCESSING(SSquirks, src)
add()
if(spawn_effects)
on_spawn()
addtimer(CALLBACK(src, .proc/post_add), 30)
/datum/trait/Destroy()
STOP_PROCESSING(SStraits, src)
/datum/quirk/Destroy()
STOP_PROCESSING(SSquirks, src)
remove()
if(trait_holder)
to_chat(trait_holder, lose_text)
trait_holder.roundstart_traits -= src
if(quirk_holder)
to_chat(quirk_holder, lose_text)
quirk_holder.roundstart_quirks -= src
if(mob_trait)
trait_holder.remove_trait(mob_trait, ROUNDSTART_TRAIT, TRUE)
SStraits.trait_objects -= src
quirk_holder.remove_trait(mob_trait, ROUNDSTART_TRAIT, TRUE)
SSquirks.quirk_objects -= src
return ..()
/datum/trait/proc/transfer_mob(mob/living/to_mob)
trait_holder.roundstart_traits -= src
to_mob.roundstart_traits += src
/datum/quirk/proc/transfer_mob(mob/living/to_mob)
quirk_holder.roundstart_quirks -= src
to_mob.roundstart_quirks += src
if(mob_trait)
trait_holder.remove_trait(mob_trait, ROUNDSTART_TRAIT)
quirk_holder.remove_trait(mob_trait, ROUNDSTART_TRAIT)
to_mob.add_trait(mob_trait, ROUNDSTART_TRAIT)
trait_holder = to_mob
quirk_holder = to_mob
on_transfer()
/datum/trait/proc/add() //special "on add" effects
/datum/trait/proc/on_spawn() //these should only trigger when the character is being created for the first time, i.e. roundstart/latejoin
/datum/trait/proc/remove() //special "on remove" effects
/datum/trait/proc/on_process() //process() has some special checks, so this is the actual process
/datum/trait/proc/post_add() //for text, disclaimers etc. given after you spawn in with the trait
/datum/trait/proc/on_transfer() //code called when the trait is transferred to a new mob
/datum/quirk/proc/add() //special "on add" effects
/datum/quirk/proc/on_spawn() //these should only trigger when the character is being created for the first time, i.e. roundstart/latejoin
/datum/quirk/proc/remove() //special "on remove" effects
/datum/quirk/proc/on_process() //process() has some special checks, so this is the actual process
/datum/quirk/proc/post_add() //for text, disclaimers etc. given after you spawn in with the trait
/datum/quirk/proc/on_transfer() //code called when the trait is transferred to a new mob
/datum/trait/process()
if(QDELETED(trait_holder))
trait_holder = null
/datum/quirk/process()
if(QDELETED(quirk_holder))
quirk_holder = null
qdel(src)
return
if(trait_holder.stat == DEAD)
if(quirk_holder.stat == DEAD)
return
on_process()
/mob/living/proc/get_trait_string(medical) //helper string. gets a string of all the traits the mob has
var/list/dat = list()
if(!medical)
for(var/V in roundstart_traits)
var/datum/trait/T = V
for(var/V in roundstart_quirks)
var/datum/quirk/T = V
dat += T.name
if(!dat.len)
return "None"
return dat.Join(", ")
else
for(var/V in roundstart_traits)
var/datum/trait/T = V
for(var/V in roundstart_quirks)
var/datum/quirk/T = V
dat += T.medical_record_text
if(!dat.len)
return "None"
return dat.Join("<br>")
/mob/living/proc/cleanse_trait_datums() //removes all trait datums
for(var/V in roundstart_traits)
var/datum/trait/T = V
for(var/V in roundstart_quirks)
var/datum/quirk/T = V
qdel(T)
/mob/living/proc/transfer_trait_datums(mob/living/to_mob)
for(var/V in roundstart_traits)
var/datum/trait/T = V
for(var/V in roundstart_quirks)
var/datum/quirk/T = V
T.transfer_mob(to_mob)
/*
@@ -96,7 +96,7 @@
Commented version of Nearsighted to help you add your own traits
Use this as a guideline
/datum/trait/nearsighted
/datum/quirk/nearsighted
name = "Nearsighted"
///The trait's name
@@ -116,11 +116,11 @@ Use this as a guideline
medical_record_text = "Subject has permanent nearsightedness."
///These three are self-explanatory
/datum/trait/nearsighted/on_spawn()
var/mob/living/carbon/human/H = trait_holder
/datum/quirk/nearsighted/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
var/obj/item/clothing/glasses/regular/glasses = new(get_turf(H))
H.put_in_hands(glasses)
H.equip_to_slot(glasses, slot_glasses)
H.equip_to_slot(glasses, SLOT_GLASSES)
H.regenerate_icons()
//This whole proc is called automatically
@@ -130,3 +130,5 @@ Use this as a guideline
//If you don't need any special effects like spawning glasses, then you don't need an add()
*/
+18 -18
View File
@@ -1,7 +1,7 @@
//predominantly positive traits
//this file is named weirdly so that positive traits are listed above negative ones
/datum/trait/alcohol_tolerance
/datum/quirk/alcohol_tolerance
name = "Alcohol Tolerance"
desc = "You become drunk more slowly and suffer fewer drawbacks from alcohol."
value = 1
@@ -11,25 +11,25 @@
/datum/trait/apathetic
/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_trait = TRUE
mood_quirk = TRUE
/datum/trait/apathetic/add()
GET_COMPONENT_FROM(mood, /datum/component/mood, trait_holder)
/datum/quirk/apathetic/add()
GET_COMPONENT_FROM(mood, /datum/component/mood, quirk_holder)
if(mood)
mood.mood_modifier = 0.8
/datum/trait/apathetic/remove()
GET_COMPONENT_FROM(mood, /datum/component/mood, trait_holder)
/datum/quirk/apathetic/remove()
GET_COMPONENT_FROM(mood, /datum/component/mood, quirk_holder)
if(mood)
mood.mood_modifier = 1 //Change this once/if species get their own mood modifiers.
/datum/trait/freerunning
/datum/quirk/freerunning
name = "Freerunning"
desc = "You're great at quick moves! You can climb tables more quickly."
value = 2
@@ -39,16 +39,16 @@
/datum/trait/jolly
/datum/quirk/jolly
name = "Jolly"
desc = "You sometimes just feel happy, for no reason at all."
value = 1
mob_trait = TRAIT_JOLLY
mood_trait = TRUE
mood_quirk = TRUE
/datum/trait/light_step
/datum/quirk/light_step
name = "Light Step"
desc = "You walk with a gentle step, making stepping on sharp objects quieter and less painful."
value = 1
@@ -58,7 +58,7 @@
/datum/trait/night_vision
/datum/quirk/night_vision
name = "Night Vision"
desc = "You can see slightly more clearly in full darkness than most people."
value = 1
@@ -66,8 +66,8 @@
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/trait/night_vision/on_spawn()
var/mob/living/carbon/human/H = trait_holder
/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
@@ -75,7 +75,7 @@
/datum/trait/selfaware
/datum/quirk/selfaware
name = "Self-Aware"
desc = "You know your body well, and can accurately assess the extent of your wounds."
value = 2
@@ -83,7 +83,7 @@
/datum/trait/skittish
/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
@@ -91,7 +91,7 @@
/datum/trait/spiritual
/datum/quirk/spiritual
name = "Spiritual"
desc = "You're in tune with the gods, and your prayers may be more likely to be heard. Or not."
value = 1
@@ -101,7 +101,7 @@
/datum/trait/voracious
/datum/quirk/voracious
name = "Voracious"
desc = "Nothing gets between you and your food. You eat twice as fast as everyone else!"
value = 1
+74 -81
View File
@@ -1,6 +1,6 @@
//predominantly negative traits
/datum/trait/blooddeficiency
/datum/quirk/blooddeficiency
name = "Acute Blood Deficiency"
desc = "Your body can't produce enough blood to sustain itself."
value = -2
@@ -8,12 +8,12 @@
lose_text = "<span class='notice'>You feel vigorous again.</span>"
medical_record_text = "Patient requires regular treatment for blood loss due to low production of blood."
/datum/trait/blooddeficiency/on_process()
trait_holder.blood_volume -= 0.275
/datum/quirk/blooddeficiency/on_process()
quirk_holder.blood_volume -= 0.275
/datum/trait/depression
/datum/quirk/depression
name = "Depression"
desc = "You sometimes just hate life."
mob_trait = TRAIT_DEPRESSION
@@ -21,22 +21,22 @@
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."
mood_trait = TRUE
mood_quirk = TRUE
/datum/trait/family_heirloom
/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_trait = TRUE
mood_quirk = TRUE
var/obj/item/heirloom
var/where_text
/datum/trait/family_heirloom/on_spawn()
var/mob/living/carbon/human/H = trait_holder
/datum/quirk/family_heirloom/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
var/obj/item/heirloom_type
switch(trait_holder.mind.assigned_role)
switch(quirk_holder.mind.assigned_role)
if("Clown")
heirloom_type = /obj/item/bikehorn/golden
if("Mime")
@@ -56,35 +56,35 @@
/obj/item/toy/cards/deck,
/obj/item/lighter,
/obj/item/dice/d20)
heirloom = new heirloom_type(get_turf(trait_holder))
heirloom = new heirloom_type(get_turf(quirk_holder))
var/list/slots = list(
"in your backpack" = slot_in_backpack,
"in your left pocket" = slot_l_store,
"in your right pocket" = slot_r_store
"in your backpack" = SLOT_IN_BACKPACK,
"in your left pocket" = SLOT_L_STORE,
"in your right pocket" = SLOT_R_STORE
)
var/where = H.equip_in_one_of_slots(heirloom, slots)
if(!where)
where = "at your feet"
if(where == "in your backpack")
H.back.SendSignal(COMSIG_TRY_STORAGE_SHOW, H)
else if(where == "in your backpack")
H.back.SendSignal(COMSIG_TRY_STORAGE_SHOW, H)
where_text = "<span class='boldnotice'>There is a precious family [heirloom.name] [where], passed down from generation to generation. Keep it safe!</span>"
/datum/trait/family_heirloom/post_add()
to_chat(trait_holder, where_text)
var/list/family_name = splittext(trait_holder.real_name, " ")
/datum/quirk/family_heirloom/post_add()
to_chat(quirk_holder, where_text)
var/list/family_name = splittext(quirk_holder.real_name, " ")
heirloom.name = "\improper [family_name[family_name.len]] family [heirloom.name]"
/datum/trait/family_heirloom/on_process()
if(heirloom in trait_holder.GetAllContents())
trait_holder.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "family_heirloom_missing")
trait_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "family_heirloom", /datum/mood_event/family_heirloom)
/datum/quirk/family_heirloom/on_process()
if(heirloom in quirk_holder.GetAllContents())
quirk_holder.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "family_heirloom_missing")
quirk_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "family_heirloom", /datum/mood_event/family_heirloom)
else
trait_holder.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "family_heirloom")
trait_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "family_heirloom_missing", /datum/mood_event/family_heirloom_missing)
quirk_holder.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "family_heirloom")
quirk_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "family_heirloom_missing", /datum/mood_event/family_heirloom_missing)
/datum/trait/heavy_sleeper
/datum/quirk/heavy_sleeper
name = "Heavy Sleeper"
desc = "You sleep like a rock! Whenever you're put to sleep, you sleep for a little bit longer."
value = -1
@@ -93,20 +93,20 @@
lose_text = "<span class='notice'>You feel awake again.</span>"
medical_record_text = "Patient has abnormal sleep study results and is difficult to wake up."
/datum/trait/brainproblems
/datum/quirk/brainproblems
name = "Brain Tumor"
desc = "You have a little friend in your brain that is slowly destroying it. Better bring some mannitol!"
value = -2
value = -3
gain_text = "<span class='danger'>You feel smooth.</span>"
lose_text = "<span class='notice'>You feel wrinkled again.</span>"
medical_record_text = "Patient has a tumor in their brain that is slowly driving them to brain death."
/datum/trait/brainproblems/on_process()
trait_holder.adjustBrainLoss(0.2)
/datum/quirk/brainproblems/on_process()
quirk_holder.adjustBrainLoss(0.2)
/datum/trait/nearsighted //t. errorage
/datum/quirk/nearsighted //t. errorage
name = "Nearsighted"
desc = "You are nearsighted without prescription glasses, but spawn with a pair."
value = -1
@@ -114,40 +114,40 @@
lose_text = "<span class='notice'>You start seeing faraway things normally again.</span>"
medical_record_text = "Patient requires prescription glasses in order to counteract nearsightedness."
/datum/trait/nearsighted/add()
trait_holder.become_nearsighted(ROUNDSTART_TRAIT)
/datum/quirk/nearsighted/add()
quirk_holder.become_nearsighted(ROUNDSTART_TRAIT)
/datum/trait/nearsighted/on_spawn()
var/mob/living/carbon/human/H = trait_holder
/datum/quirk/nearsighted/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
var/obj/item/clothing/glasses/regular/glasses = new(get_turf(H))
H.put_in_hands(glasses)
H.equip_to_slot(glasses, slot_glasses)
H.equip_to_slot(glasses, SLOT_GLASSES)
H.regenerate_icons() //this is to remove the inhand icon, which persists even if it's not in their hands
/datum/trait/nyctophobia
/datum/quirk/nyctophobia
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
/datum/trait/nyctophobia/on_process()
var/mob/living/carbon/human/H = trait_holder
/datum/quirk/nyctophobia/on_process()
var/mob/living/carbon/human/H = quirk_holder
if(H.dna.species.id in list("shadow", "nightmare"))
return //we're tied with the dark, so we don't get scared of it; don't cleanse outright to avoid cheese
var/turf/T = get_turf(trait_holder)
var/turf/T = get_turf(quirk_holder)
var/lums = T.get_lumcount()
if(lums <= 0.2)
if(trait_holder.m_intent == MOVE_INTENT_RUN)
to_chat(trait_holder, "<span class='warning'>Easy, easy, take it slow... you're in the dark...</span>")
trait_holder.toggle_move_intent()
trait_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "nyctophobia", /datum/mood_event/nyctophobia)
if(quirk_holder.m_intent == MOVE_INTENT_RUN)
to_chat(quirk_holder, "<span class='warning'>Easy, easy, take it slow... you're in the dark...</span>")
quirk_holder.toggle_move_intent()
quirk_holder.SendSignal(COMSIG_ADD_MOOD_EVENT, "nyctophobia", /datum/mood_event/nyctophobia)
else
trait_holder.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "nyctophobia")
quirk_holder.SendSignal(COMSIG_CLEAR_MOOD_EVENT, "nyctophobia")
/datum/trait/nonviolent
/datum/quirk/nonviolent
name = "Pacifist"
desc = "The thought of violence makes you sick. So much so, in fact, that you can't hurt anyone."
value = -2
@@ -156,14 +156,14 @@
lose_text = "<span class='notice'>You think you can defend yourself again.</span>"
medical_record_text = "Patient is unusually pacifistic and cannot bring themselves to cause physical harm."
/datum/trait/nonviolent/on_process()
if(trait_holder.mind && LAZYLEN(trait_holder.mind.antag_datums))
to_chat(trait_holder, "<span class='boldannounce'>Your antagonistic nature has caused you to renounce your pacifism.</span>")
/datum/quirk/nonviolent/on_process()
if(quirk_holder.mind && LAZYLEN(quirk_holder.mind.antag_datums))
to_chat(quirk_holder, "<span class='boldannounce'>Your antagonistic nature has caused you to renounce your pacifism.</span>")
qdel(src)
/datum/trait/poor_aim
/datum/quirk/poor_aim
name = "Poor Aim"
desc = "You're terrible with guns and can't line up a straight shot to save your life. Dual-wielding is right out."
value = -1
@@ -172,7 +172,7 @@
/datum/trait/prosopagnosia
/datum/quirk/prosopagnosia
name = "Prosopagnosia"
desc = "You have a mental disorder that prevents you from being able to recognize faces at all."
value = -1
@@ -181,41 +181,41 @@
/datum/trait/prosthetic_limb
/datum/quirk/prosthetic_limb
name = "Prosthetic Limb"
desc = "An accident caused you to lose one of your limbs. Because of this, you now have a random prosthetic!"
value = -1
var/slot_string = "limb"
/datum/trait/prosthetic_limb/on_spawn()
/datum/quirk/prosthetic_limb/on_spawn()
var/limb_slot = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
var/mob/living/carbon/human/H = trait_holder
var/mob/living/carbon/human/H = quirk_holder
var/obj/item/bodypart/old_part = H.get_bodypart(limb_slot)
var/obj/item/bodypart/prosthetic
switch(limb_slot)
if(BODY_ZONE_L_ARM)
prosthetic = new/obj/item/bodypart/l_arm/robot/surplus(trait_holder)
prosthetic = new/obj/item/bodypart/l_arm/robot/surplus(quirk_holder)
slot_string = "left arm"
if(BODY_ZONE_R_ARM)
prosthetic = new/obj/item/bodypart/r_arm/robot/surplus(trait_holder)
prosthetic = new/obj/item/bodypart/r_arm/robot/surplus(quirk_holder)
slot_string = "right arm"
if(BODY_ZONE_L_LEG)
prosthetic = new/obj/item/bodypart/l_leg/robot/surplus(trait_holder)
prosthetic = new/obj/item/bodypart/l_leg/robot/surplus(quirk_holder)
slot_string = "left leg"
if(BODY_ZONE_R_LEG)
prosthetic = new/obj/item/bodypart/r_leg/robot/surplus(trait_holder)
prosthetic = new/obj/item/bodypart/r_leg/robot/surplus(quirk_holder)
slot_string = "right leg"
prosthetic.replace_limb(H)
qdel(old_part)
H.regenerate_icons()
/datum/trait/prosthetic_limb/post_add()
to_chat(trait_holder, "<span class='boldannounce'>Your [slot_string] has been replaced with a surplus prosthetic. It is fragile and will easily come apart under duress. Additionally, \
/datum/quirk/prosthetic_limb/post_add()
to_chat(quirk_holder, "<span class='boldannounce'>Your [slot_string] has been replaced with a surplus prosthetic. It is fragile and will easily come apart under duress. Additionally, \
you need to use a welding tool and cables to repair it, instead of bruise packs and ointment.</span>")
/datum/trait/insanity
/datum/quirk/insanity
name = "Reality Dissociation Syndrome"
desc = "You suffer from a severe disorder that causes very vivid hallucinations. Mindbreaker toxin can suppress its effects, and you are immune to mindbreaker's hallucinogenic properties. <b>This is not a license to grief.</b>"
value = -2
@@ -224,32 +224,25 @@
lose_text = "<span class='notice'>You feel in tune with the world again.</span>"
medical_record_text = "Patient suffers from acute Reality Dissociation Syndrome and experiences vivid hallucinations."
/datum/trait/insanity/on_process()
if(trait_holder.reagents.has_reagent("mindbreaker"))
trait_holder.hallucination = 0
/datum/quirk/insanity/on_process()
if(quirk_holder.reagents.has_reagent("mindbreaker"))
quirk_holder.hallucination = 0
return
if(prob(2)) //we'll all be mad soon enough
madness()
/datum/quirk/insanity/proc/madness()
quirk_holder.hallucination += rand(10, 25)
/datum/trait/insanity/proc/madness(mad_fools)
set waitfor = FALSE
if(!mad_fools)
mad_fools = prob(20)
if(mad_fools)
var/hallucination_type = pick(subtypesof(/datum/hallucination/rds))
new hallucination_type (trait_holder, FALSE)
else
trait_holder.hallucination += rand(10, 50)
/datum/trait/insanity/post_add() //I don't /think/ we'll need this but for newbies who think "roleplay as insane" = "license to kill" it's probably a good thing to have
if(!trait_holder.mind || trait_holder.mind.special_role)
/datum/quirk/insanity/post_add() //I don't /think/ we'll need this but for newbies who think "roleplay as insane" = "license to kill" it's probably a good thing to have
if(!quirk_holder.mind || quirk_holder.mind.special_role)
return
to_chat(trait_holder, "<span class='big bold info'>Please note that your dissociation syndrome does NOT give you the right to attack people or otherwise cause any interference to \
to_chat(quirk_holder, "<span class='big bold info'>Please note that your dissociation syndrome does NOT give you the right to attack people or otherwise cause any interference to \
the round. You are not an antagonist, and the rules will treat you the same as other crewmembers.</span>")
/datum/trait/social_anxiety
/datum/quirk/social_anxiety
name = "Social Anxiety"
desc = "Talking to people is very difficult for you, and you often stutter or even lock up."
value = -1
@@ -258,12 +251,12 @@
medical_record_text = "Patient is usually anxious in social encounters and prefers to avoid them."
var/dumb_thing = TRUE
/datum/trait/social_anxiety/on_process()
/datum/quirk/social_anxiety/on_process()
var/nearby_people = 0
for(var/mob/living/carbon/human/H in view(5, trait_holder))
for(var/mob/living/carbon/human/H in view(5, quirk_holder))
if(H.client)
nearby_people++
var/mob/living/carbon/human/H = trait_holder
var/mob/living/carbon/human/H = quirk_holder
if(prob(2 + nearby_people))
H.stuttering = max(3, H.stuttering)
else if(prob(min(3, nearby_people)) && !H.silent)
+25 -25
View File
@@ -1,7 +1,7 @@
//traits with no real impact that can be taken freely
//MAKE SURE THESE DO NOT MAJORLY IMPACT GAMEPLAY. those should be positive or negative traits.
/datum/trait/no_taste
/datum/quirk/no_taste
name = "Ageusia"
desc = "You can't taste anything! Toxic food will still poison you."
value = 0
@@ -12,75 +12,75 @@
/datum/trait/pineapple_liker
/datum/quirk/pineapple_liker
name = "Ananas Affinity"
desc = "You find yourself greatly enjoying fruits of the ananas genus. You can't seem to ever get enough of their sweet goodness!"
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>"
/datum/trait/pineapple_liker/add()
var/mob/living/carbon/human/H = trait_holder
/datum/quirk/pineapple_liker/add()
var/mob/living/carbon/human/H = quirk_holder
var/datum/species/species = H.dna.species
species.liked_food |= PINEAPPLE
/datum/trait/pineapple_liker/remove()
var/mob/living/carbon/human/H = trait_holder
/datum/quirk/pineapple_liker/remove()
var/mob/living/carbon/human/H = quirk_holder
var/datum/species/species = H.dna.species
species.liked_food &= ~PINEAPPLE
/datum/trait/pineapple_hater
/datum/quirk/pineapple_hater
name = "Ananas Aversion"
desc = "You find yourself greatly detesting fruits of the ananas genus. Serious, how the hell can anyone say these things are good? And what kind of madman would even dare putting it on a pizza!?"
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>"
/datum/trait/pineapple_hater/add()
var/mob/living/carbon/human/H = trait_holder
/datum/quirk/pineapple_hater/add()
var/mob/living/carbon/human/H = quirk_holder
var/datum/species/species = H.dna.species
species.disliked_food |= PINEAPPLE
/datum/trait/pineapple_hater/remove()
var/mob/living/carbon/human/H = trait_holder
/datum/quirk/pineapple_hater/remove()
var/mob/living/carbon/human/H = quirk_holder
var/datum/species/species = H.dna.species
species.disliked_food &= ~PINEAPPLE
/datum/trait/deviant_tastes
/datum/quirk/deviant_tastes
name = "Deviant Tastes"
desc = "You dislike food that most people enjoy, and find delicious what they don't."
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>"
/datum/trait/deviant_tastes/add()
var/mob/living/carbon/human/H = trait_holder
/datum/quirk/deviant_tastes/add()
var/mob/living/carbon/human/H = quirk_holder
var/datum/species/species = H.dna.species
var/liked = species.liked_food
species.liked_food = species.disliked_food
species.disliked_food = liked
/datum/trait/deviant_tastes/remove()
var/mob/living/carbon/human/H = trait_holder
/datum/quirk/deviant_tastes/remove()
var/mob/living/carbon/human/H = quirk_holder
var/datum/species/species = H.dna.species
species.liked_food = initial(species.liked_food)
species.disliked_food = initial(species.disliked_food)
/datum/trait/monochromatic
/datum/quirk/monochromatic
name = "Monochromacy"
desc = "You suffer from full colorblindness, and perceive nearly the entire world in blacks and whites."
value = 0
medical_record_text = "Patient is afflicted with almost complete color blindness."
/datum/trait/monochromatic/add()
trait_holder.add_client_colour(/datum/client_colour/monochrome)
/datum/quirk/monochromatic/add()
quirk_holder.add_client_colour(/datum/client_colour/monochrome)
/datum/trait/monochromatic/post_add()
if(trait_holder.mind.assigned_role == "Detective")
to_chat(trait_holder, "<span class='boldannounce'>Mmm. Nothing's ever clear on this station. It's all shades of gray...</span>")
trait_holder.playsound_local(trait_holder, 'sound/ambience/ambidet1.ogg', 50, FALSE)
/datum/quirk/monochromatic/post_add()
if(quirk_holder.mind.assigned_role == "Detective")
to_chat(quirk_holder, "<span class='boldannounce'>Mmm. Nothing's ever clear on this station. It's all shades of gray...</span>")
quirk_holder.playsound_local(quirk_holder, 'sound/ambience/ambidet1.ogg', 50, FALSE)
/datum/trait/monochromatic/remove()
trait_holder.remove_client_colour(/datum/client_colour/monochrome)
/datum/quirk/monochromatic/remove()
quirk_holder.remove_client_colour(/datum/client_colour/monochrome)
+102 -102
View File
@@ -1,102 +1,102 @@
/datum/verbs
var/name
var/list/children
var/datum/verbs/parent
var/list/verblist
var/abstract = FALSE
//returns the master list for verbs of a type
/datum/verbs/proc/GetList()
CRASH("Abstract verblist for [type]")
//do things for each entry in Generate_list
//return value sets Generate_list[verbpath]
/datum/verbs/proc/HandleVerb(list/entry, atom/verb/verbpath, ...)
return entry
/datum/verbs/New()
var/mainlist = GetList()
var/ourentry = mainlist[type]
children = list()
verblist = list()
if (ourentry)
if (!islist(ourentry)) //some of our childern already loaded
qdel(src)
CRASH("Verb double load: [type]")
Add_children(ourentry)
mainlist[type] = src
Load_verbs(type, typesof("[type]/verb"))
var/datum/verbs/parent = mainlist[parent_type]
if (!parent)
mainlist[parent_type] = list(src)
else if (islist(parent))
parent += src
else
parent.Add_children(list(src))
/datum/verbs/proc/Set_parent(datum/verbs/_parent)
parent = _parent
if (abstract)
parent.Add_children(children)
var/list/verblistoftypes = list()
for(var/thing in verblist)
LAZYADD(verblistoftypes[verblist[thing]], thing)
for(var/verbparenttype in verblistoftypes)
parent.Load_verbs(verbparenttype, verblistoftypes[verbparenttype])
/datum/verbs/proc/Add_children(list/kids)
if (abstract && parent)
parent.Add_children(kids)
return
for(var/thing in kids)
var/datum/verbs/item = thing
item.Set_parent(src)
if (!item.abstract)
children += item
/datum/verbs/proc/Load_verbs(verb_parent_type, list/verbs)
if (abstract && parent)
parent.Load_verbs(verb_parent_type, verbs)
return
for (var/verbpath in verbs)
verblist[verbpath] = verb_parent_type
/datum/verbs/proc/Generate_list(...)
. = list()
if (length(children))
for (var/thing in children)
var/datum/verbs/child = thing
var/list/childlist = child.Generate_list(arglist(args))
if (childlist)
var/childname = "[child]"
if (childname == "[child.type]")
var/list/tree = splittext(childname, "/")
childname = tree[tree.len]
.[child.type] = "parent=[url_encode(type)];name=[url_encode(childname)]"
. += childlist
for (var/thing in verblist)
var/atom/verb/verbpath = thing
if (!verbpath)
stack_trace("Bad VERB in [type] verblist: [english_list(verblist)]")
var/list/entry = list()
entry["parent"] = "[type]"
entry["name"] = verbpath.desc
if (copytext(verbpath.name,1,2) == "@")
entry["command"] = copytext(verbpath.name,2)
else
entry["command"] = replacetext(verbpath.name, " ", "-")
.[verbpath] = HandleVerb(arglist(list(entry, verbpath) + args))
/world/proc/LoadVerbs(verb_type)
if(!ispath(verb_type, /datum/verbs) || verb_type == /datum/verbs)
CRASH("Invalid verb_type: [verb_type]")
for (var/typepath in subtypesof(verb_type))
new typepath()
/datum/verbs
var/name
var/list/children
var/datum/verbs/parent
var/list/verblist
var/abstract = FALSE
//returns the master list for verbs of a type
/datum/verbs/proc/GetList()
CRASH("Abstract verblist for [type]")
//do things for each entry in Generate_list
//return value sets Generate_list[verbpath]
/datum/verbs/proc/HandleVerb(list/entry, atom/verb/verbpath, ...)
return entry
/datum/verbs/New()
var/mainlist = GetList()
var/ourentry = mainlist[type]
children = list()
verblist = list()
if (ourentry)
if (!islist(ourentry)) //some of our childern already loaded
qdel(src)
CRASH("Verb double load: [type]")
Add_children(ourentry)
mainlist[type] = src
Load_verbs(type, typesof("[type]/verb"))
var/datum/verbs/parent = mainlist[parent_type]
if (!parent)
mainlist[parent_type] = list(src)
else if (islist(parent))
parent += src
else
parent.Add_children(list(src))
/datum/verbs/proc/Set_parent(datum/verbs/_parent)
parent = _parent
if (abstract)
parent.Add_children(children)
var/list/verblistoftypes = list()
for(var/thing in verblist)
LAZYADD(verblistoftypes[verblist[thing]], thing)
for(var/verbparenttype in verblistoftypes)
parent.Load_verbs(verbparenttype, verblistoftypes[verbparenttype])
/datum/verbs/proc/Add_children(list/kids)
if (abstract && parent)
parent.Add_children(kids)
return
for(var/thing in kids)
var/datum/verbs/item = thing
item.Set_parent(src)
if (!item.abstract)
children += item
/datum/verbs/proc/Load_verbs(verb_parent_type, list/verbs)
if (abstract && parent)
parent.Load_verbs(verb_parent_type, verbs)
return
for (var/verbpath in verbs)
verblist[verbpath] = verb_parent_type
/datum/verbs/proc/Generate_list(...)
. = list()
if (length(children))
for (var/thing in children)
var/datum/verbs/child = thing
var/list/childlist = child.Generate_list(arglist(args))
if (childlist)
var/childname = "[child]"
if (childname == "[child.type]")
var/list/tree = splittext(childname, "/")
childname = tree[tree.len]
.[child.type] = "parent=[url_encode(type)];name=[childname]"
. += childlist
for (var/thing in verblist)
var/atom/verb/verbpath = thing
if (!verbpath)
stack_trace("Bad VERB in [type] verblist: [english_list(verblist)]")
var/list/entry = list()
entry["parent"] = "[type]"
entry["name"] = verbpath.desc
if (copytext(verbpath.name,1,2) == "@")
entry["command"] = copytext(verbpath.name,2)
else
entry["command"] = replacetext(verbpath.name, " ", "-")
.[verbpath] = HandleVerb(arglist(list(entry, verbpath) + args))
/world/proc/LoadVerbs(verb_type)
if(!ispath(verb_type, /datum/verbs) || verb_type == /datum/verbs)
CRASH("Invalid verb_type: [verb_type]")
for (var/typepath in subtypesof(verb_type))
new typepath()
@@ -25,8 +25,10 @@
/datum/weather/floor_is_lava/weather_act(mob/living/L)
if(issilicon(L))
return
if(istype(L.buckled, /obj/structure/bed))
return
for(var/obj/structure/O in L.loc)
if(O.density || (L in O.buckled_mobs && istype(O, /obj/structure/bed)))
if(O.density)
return
if(L.loc.density)
return
+14 -3
View File
@@ -120,8 +120,12 @@
require_comms_key = TRUE
/datum/world_topic/namecheck/Run(list/input)
var/datum/server_tools_command/namecheck/NC = new
return NC.Run(input["sender"], input["namecheck"])
//Oh this is a hack, someone refactor the functionality out of the chat command PLS
var/datum/tgs_chat_command/namecheck/NC = new
var/datum/tgs_chat_user/user = new
user.friendly_name = input["sender"]
user.mention = user.friendly_name
return NC.Run(user, input["namecheck"])
/datum/world_topic/adminwho
keyword = "adminwho"
@@ -136,7 +140,7 @@
/datum/world_topic/status/Run(list/input)
. = list()
.["version"] = GLOB.game_version
.["mode"] = GLOB.master_mode
.["mode"] = "hidden" //CIT CHANGE - hides the gamemode in topic() calls to prevent meta'ing the gamemode
.["respawn"] = config ? !CONFIG_GET(flag/norespawn) : FALSE
.["enter"] = GLOB.enter_allowed
.["vote"] = CONFIG_GET(flag/allow_vote_mode)
@@ -164,9 +168,16 @@
.["security_level"] = get_security_level()
.["round_duration"] = SSticker ? round((world.time-SSticker.round_start_time)/10) : 0
// Amount of world's ticks in seconds, useful for calculating round duration
//Time dilation stats.
.["time_dilation_current"] = SStime_track.time_dilation_current
.["time_dilation_avg"] = SStime_track.time_dilation_avg
.["time_dilation_avg_slow"] = SStime_track.time_dilation_avg_slow
.["time_dilation_avg_fast"] = SStime_track.time_dilation_avg_fast
if(SSshuttle && SSshuttle.emergency)
.["shuttle_mode"] = SSshuttle.emergency.mode
// Shuttle status, see /__DEFINES/stat.dm
.["shuttle_timer"] = SSshuttle.emergency.timeLeft()
// Shuttle timer, in seconds