replaces BANG_PROTECT_2 with a component, also kills OMNITONGUE_2 and flags_2

This commit is contained in:
vuonojenmustaturska
2018-05-02 21:13:41 +03:00
committed by CitadelStationBot
parent e42cce26da
commit 0958d35b26
27 changed files with 890 additions and 41 deletions

View File

@@ -86,6 +86,13 @@
#define COMSIG_MOVABLE_UNBUCKLE "unbuckle" //from base of atom/movable/unbuckle_mob(): (mob, force)
#define COMSIG_MOVABLE_THROW "movable_throw" //from base of atom/movable/throw_at(): (datum/thrownthing, spin)
#define COMSIG_MOVABLE_Z_CHANGED "movable_ztransit" //from base of atom/movable/onTransitZ(): (old_z, new_z)
<<<<<<< HEAD
=======
// /mob/living/carbon signals
#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity))
>>>>>>> fd4c753... replaces BANG_PROTECT_2 with a component, also kills OMNITONGUE_2 and flags_2 (#37597)
// /obj signals
#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct" //from base of obj/deconstruct(): (disassembled)

View File

@@ -16,15 +16,28 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define NODROP_1 (1<<1) // This flag makes it so that an item literally cannot be removed at all, or at least that's how it should be. Only deleted.
#define NOBLUDGEON_1 (1<<2) // when an item has this it produces no "X has been hit by Y with Z" message in the default attackby()
<<<<<<< HEAD
#define MASKINTERNALS_1 (1<<3) // mask allows internals
#define HEAR_1 (1<<4) // This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not.
#define CHECK_RICOCHET_1 (1<<5) // Projectiels will check ricochet on things impacted that have this.
#define CONDUCT_1 (1<<6) // conducts electricity (metal etc.)
#define ABSTRACT_1 (1<<7) // for all things that are technically items but used for various different stuff, made it 128 because it could conflict with other flags other way
=======
#define HEAR_1 (1<<3) // This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not.
#define CHECK_RICOCHET_1 (1<<4) // Projectiels will check ricochet on things impacted that have this.
#define CONDUCT_1 (1<<5) // conducts electricity (metal etc.)
#define ABSTRACT_1 (1<<6) // for all things that are technically items but used for various different stuff, made it 128 because it could conflict with other flags other way
>>>>>>> fd4c753... replaces BANG_PROTECT_2 with a component, also kills OMNITONGUE_2 and flags_2 (#37597)
#define NODECONSTRUCT_1 (1<<7) // For machines and structures that should not break into parts, eg, holodeck stuff
#define OVERLAY_QUEUED_1 (1<<8) // atom queued to SSoverlay
#define ON_BORDER_1 (1<<9) // item has priority to check when entering or leaving
#define DROPDEL_1 (1<<10) // When dropped, it calls qdel on itself
#define PREVENT_CLICK_UNDER_1 (1<<11) //Prevent clicking things below it on the same turf eg. doors/ fulltile windows
#define NO_EMP_WIRES_1 (1<<12)
#define HOLOGRAM_1 (1<<13)
#define TESLA_IGNORE_1 (1<<14) // TESLA_IGNORE grants immunity from being targeted by tesla-style electricity
<<<<<<< HEAD
#define NOSLIP_1 (1<<10) //prevents from slipping on wet floors, in space etc
// BLOCK_GAS_SMOKE_EFFECT_1 only used in masks at the moment.
@@ -53,6 +66,8 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
// TESLA_IGNORE grants immunity from being targeted by tesla-style electricity
#define TESLA_IGNORE_2 (1<<9)
=======
>>>>>>> fd4c753... replaces BANG_PROTECT_2 with a component, also kills OMNITONGUE_2 and flags_2 (#37597)
// Stops you from putting things like an RCD or other items into an ORM or protolathe for materials.
#define NO_MAT_REDEMPTION_2 (1<<10)
@@ -67,7 +82,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define NO_DEATHRATTLE_1 (1<<4) // Do not notify deadchat about any deaths that occur on this turf.
#define NO_RUINS_1 (1<<5) //Blocks ruins spawning on the turf
#define NO_LAVA_GEN_1 (1<<6) //Blocks lava rivers being generated on the turf
//#define CHECK_RICOCHET_1 32 //Same thing as atom flag.
/*
These defines are used specifically with the atom/pass_flags bitmask

View File

@@ -116,6 +116,7 @@ GLOBAL_LIST_INIT(bitfields, list(
"ABSTRACT_1" = ABSTRACT_1,
"NODECONSTRUCT_1" = NODECONSTRUCT_1,
"OVERLAY_QUEUED_1" = OVERLAY_QUEUED_1,
<<<<<<< HEAD
"NOSLIP_1" = NOSLIP_1
),
"flags_2" = list(
@@ -130,4 +131,18 @@ GLOBAL_LIST_INIT(bitfields, list(
"NO_MAT_REDEMPTION_2" = NO_MAT_REDEMPTION_2,
"LAVA_PROTECT_2" = LAVA_PROTECT_2
)
=======
"NO_EMP_WIRES_1" = NO_EMP_WIRES_1,
"HOLOGRAM_1" = HOLOGRAM_1,
"TESLA_IGNORE_1" = TESLA_IGNORE_1
),
"clothing_flags" = list(
"LAVAPROTECT" = LAVAPROTECT,
"STOPSPRESSUREDAMAGE" = STOPSPRESSUREDAMAGE,
"BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT,
"MASKINTERNALS" = MASKINTERNALS,
"NOSLIP" = NOSLIP,
"THICKMATERIAL" = THICKMATERIAL,
)
>>>>>>> fd4c753... replaces BANG_PROTECT_2 with a component, also kills OMNITONGUE_2 and flags_2 (#37597)
))

View File

@@ -0,0 +1,11 @@
/datum/component/wearertargeting/earprotection
signals = list(COMSIG_CARBON_SOUNDBANG)
mobtype = /mob/living/carbon
/datum/component/wearertargeting/earprotection/Initialize(_valid_slots)
. = ..()
valid_slots = _valid_slots
callback = CALLBACK(src, .proc/reducebang)
/datum/component/wearertargeting/earprotection/proc/reducebang(list/reflist)
reflist[1]--

View File

@@ -53,7 +53,11 @@
var/list/tc = allowed_typecache
if(user.a_intent != INTENT_HELP)
return
<<<<<<< HEAD
if((I.flags_2 & (HOLOGRAM_2 | NO_MAT_REDEMPTION_2)) || (tc && !is_type_in_typecache(I, tc)))
=======
if((I.flags_1 & HOLOGRAM_1) || (I.item_flags & NO_MAT_REDEMPTION) || (tc && !is_type_in_typecache(I, tc)))
>>>>>>> fd4c753... replaces BANG_PROTECT_2 with a component, also kills OMNITONGUE_2 and flags_2 (#37597)
to_chat(user, "<span class='warning'>[parent] won't accept [I]!</span>")
return
. = COMPONENT_NO_AFTERATTACK

View File

@@ -4,5 +4,6 @@
/datum/component/redirect/Initialize(list/signals, datum/callback/_callback)
//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
RegisterSignal(signals, _callback)

View File

@@ -4,7 +4,6 @@
var/level = 2
var/flags_1 = NONE
var/flags_2 = NONE
var/interaction_flags_atom = NONE
var/container_type = NONE
var/admin_spawned = 0 //was this spawned by an admin? used for stat tracking stuff.
@@ -223,7 +222,7 @@
/atom/proc/emp_act(severity)
SendSignal(COMSIG_ATOM_EMP_ACT, severity)
if(istype(wires) && !(flags_2 & NO_EMP_WIRES_2))
if(istype(wires) && !(flags_1 & NO_EMP_WIRES_1))
wires.emp_pulse()
/atom/proc/bullet_act(obj/item/projectile/P, def_zone)

View File

@@ -50,7 +50,10 @@
desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs. \nTo access the syndicate channel, use ; before speaking."
icon_state = "syndie_headset"
item_state = "syndie_headset"
flags_2 = BANG_PROTECT_2 | NO_EMP_WIRES_2
/obj/item/radio/headset/syndicate/alt/ComponentInitialize()
. = ..()
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
/obj/item/radio/headset/syndicate/alt/leader
name = "team leader headset"
@@ -78,7 +81,10 @@
desc = "This is used by your elite security force. Protects ears from flashbangs.\nTo access the security channel, use :s."
icon_state = "sec_headset_alt"
item_state = "sec_headset_alt"
flags_2 = BANG_PROTECT_2 | NO_EMP_WIRES_2
/obj/item/radio/headset/headset_sec/alt/ComponentInitialize()
. = ..()
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
/obj/item/radio/headset/headset_eng
name = "engineering radio headset"
@@ -130,7 +136,10 @@
desc = "The headset of the boss. Protects ears from flashbangs.\nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
flags_2 = BANG_PROTECT_2 | NO_EMP_WIRES_2
/obj/item/radio/headset/heads/captain/alt/ComponentInitialize()
. = ..()
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
/obj/item/radio/headset/heads/rd
name = "\proper the research director's headset"
@@ -149,7 +158,10 @@
desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs.\nTo access the security channel, use :s. For command, use :c."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
flags_2 = BANG_PROTECT_2 | NO_EMP_WIRES_2
/obj/item/radio/headset/heads/hos/ComponentInitialize()
. = ..()
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
/obj/item/radio/headset/heads/ce
name = "\proper the chief engineer's headset"
@@ -207,7 +219,10 @@
icon_state = "cent_headset_alt"
item_state = "cent_headset_alt"
keyslot = null
flags_2 = BANG_PROTECT_2 | NO_EMP_WIRES_2
/obj/item/radio/headset/headset_cent/alt/ComponentInitialize()
. = ..()
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
/obj/item/radio/headset/ai
name = "\proper Integrated Subspace Transceiver "

View File

@@ -6,9 +6,14 @@
desc = "A basic handheld radio that communicates with local telecommunication networks."
dog_fashion = /datum/dog_fashion/back
<<<<<<< HEAD
flags_1 = CONDUCT_1 | HEAR_1
flags_2 = NO_EMP_WIRES_2
slot_flags = SLOT_BELT
=======
flags_1 = CONDUCT_1 | HEAR_1 | NO_EMP_WIRES_1
slot_flags = ITEM_SLOT_BELT
>>>>>>> fd4c753... replaces BANG_PROTECT_2 with a component, also kills OMNITONGUE_2 and flags_2 (#37597)
throw_speed = 3
throw_range = 7
w_class = WEIGHT_CLASS_SMALL
@@ -365,7 +370,6 @@
name = "cyborg radio"
subspace_switchable = TRUE
dog_fashion = null
flags_2 = NO_EMP_WIRES_2
/obj/item/radio/borg/Initialize(mapload)
. = ..()

View File

@@ -5,8 +5,7 @@
item_state = "plastic-explosive"
lefthand_file = 'icons/mob/inhands/weapons/bombs_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/bombs_righthand.dmi'
flags_1 = NOBLUDGEON_1
flags_2 = NO_EMP_WIRES_2
flags_1 = NOBLUDGEON_1 | NO_EMP_WIRES_1
det_time = 10
display_timer = 0
w_class = WEIGHT_CLASS_SMALL

View File

@@ -620,12 +620,15 @@ Congratulations! You are now trained for invasive xenobiology research!"}
icon_state = "abductor_headset"
item_state = "abductor_headset"
keyslot2 = new /obj/item/encryptionkey/heads/captain
flags_2 = BANG_PROTECT_2
/obj/item/radio/headset/abductor/Initialize(mapload)
. = ..()
make_syndie()
/obj/item/radio/headset/abductor/ComponentInitialize()
. = ..()
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
/obj/item/radio/headset/abductor/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/screwdriver))
return // Stops humans from disassembling abductor headsets.

View File

@@ -1,3 +1,4 @@
<<<<<<< HEAD
/datum/spellbook_entry
var/name = "Entry Name"
@@ -714,3 +715,721 @@
tab = sanitize(href_list["page"])
attack_self(H)
return
=======
/datum/spellbook_entry
var/name = "Entry Name"
var/spell_type = null
var/desc = ""
var/category = "Offensive"
var/cost = 2
var/refundable = 1
var/surplus = -1 // -1 for infinite, not used by anything atm
var/obj/effect/proc_holder/spell/S = null //Since spellbooks can be used by only one person anyway we can track the actual spell
var/buy_word = "Learn"
var/limit //used to prevent a spellbook_entry from being bought more than X times with one wizard spellbook
var/list/no_coexistance_typecache //Used so you can't have specific spells together
/datum/spellbook_entry/New()
..()
no_coexistance_typecache = typecacheof(no_coexistance_typecache)
/datum/spellbook_entry/proc/IsAvailible() // For config prefs / gamemode restrictions - these are round applied
return 1
/datum/spellbook_entry/proc/CanBuy(mob/living/carbon/human/user,obj/item/spellbook/book) // Specific circumstances
if(book.uses<cost || limit == 0)
return 0
for(var/spell in user.mind.spell_list)
if(is_type_in_typecache(spell, no_coexistance_typecache))
return 0
return 1
/datum/spellbook_entry/proc/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) //return 1 on success
if(!S || QDELETED(S))
S = new spell_type()
//Check if we got the spell already
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
if(initial(S.name) == initial(aspell.name)) // Not using directly in case it was learned from one spellbook then upgraded in another
if(aspell.spell_level >= aspell.level_max)
to_chat(user, "<span class='warning'>This spell cannot be improved further.</span>")
return 0
else
aspell.name = initial(aspell.name)
aspell.spell_level++
aspell.charge_max = round(initial(aspell.charge_max) - aspell.spell_level * (initial(aspell.charge_max) - aspell.cooldown_min)/ aspell.level_max)
if(aspell.charge_max < aspell.charge_counter)
aspell.charge_counter = aspell.charge_max
switch(aspell.spell_level)
if(1)
to_chat(user, "<span class='notice'>You have improved [aspell.name] into Efficient [aspell.name].</span>")
aspell.name = "Efficient [aspell.name]"
if(2)
to_chat(user, "<span class='notice'>You have further improved [aspell.name] into Quickened [aspell.name].</span>")
aspell.name = "Quickened [aspell.name]"
if(3)
to_chat(user, "<span class='notice'>You have further improved [aspell.name] into Free [aspell.name].</span>")
aspell.name = "Free [aspell.name]"
if(4)
to_chat(user, "<span class='notice'>You have further improved [aspell.name] into Instant [aspell.name].</span>")
aspell.name = "Instant [aspell.name]"
if(aspell.spell_level >= aspell.level_max)
to_chat(user, "<span class='notice'>This spell cannot be strengthened any further.</span>")
SSblackbox.record_feedback("nested tally", "wizard_spell_improved", 1, list("[name]", "[aspell.spell_level]"))
return 1
//No same spell found - just learn it
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
user.mind.AddSpell(S)
to_chat(user, "<span class='notice'>You have learned [S.name].</span>")
return 1
/datum/spellbook_entry/proc/CanRefund(mob/living/carbon/human/user,obj/item/spellbook/book)
if(!refundable)
return 0
if(!S)
S = new spell_type()
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
if(initial(S.name) == initial(aspell.name))
return 1
return 0
/datum/spellbook_entry/proc/Refund(mob/living/carbon/human/user,obj/item/spellbook/book) //return point value or -1 for failure
var/area/wizard_station/A = locate() in GLOB.sortedAreas
if(!(user in A.contents))
to_chat(user, "<span class='warning'>You can only refund spells at the wizard lair</span>")
return -1
if(!S)
S = new spell_type()
var/spell_levels = 0
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
if(initial(S.name) == initial(aspell.name))
spell_levels = aspell.spell_level
user.mind.spell_list.Remove(aspell)
qdel(S)
return cost * (spell_levels+1)
return -1
/datum/spellbook_entry/proc/GetInfo()
if(!S)
S = new spell_type()
var/dat =""
dat += "<b>[initial(S.name)]</b>"
if(S.charge_type == "recharge")
dat += " Cooldown:[S.charge_max/10]"
dat += " Cost:[cost]<br>"
dat += "<i>[S.desc][desc]</i><br>"
dat += "[S.clothes_req?"Needs wizard garb":"Can be cast without wizard garb"]<br>"
return dat
/datum/spellbook_entry/fireball
name = "Fireball"
spell_type = /obj/effect/proc_holder/spell/aimed/fireball
/datum/spellbook_entry/spell_cards
name = "Spell Cards"
spell_type = /obj/effect/proc_holder/spell/aimed/spell_cards
/datum/spellbook_entry/rod_form
name = "Rod Form"
spell_type = /obj/effect/proc_holder/spell/targeted/rod_form
/datum/spellbook_entry/magicm
name = "Magic Missile"
spell_type = /obj/effect/proc_holder/spell/targeted/projectile/magic_missile
category = "Defensive"
/datum/spellbook_entry/disintegrate
name = "Disintegrate"
spell_type = /obj/effect/proc_holder/spell/targeted/touch/disintegrate
/datum/spellbook_entry/disabletech
name = "Disable Tech"
spell_type = /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech
category = "Defensive"
cost = 1
/datum/spellbook_entry/repulse
name = "Repulse"
spell_type = /obj/effect/proc_holder/spell/aoe_turf/repulse
category = "Defensive"
/datum/spellbook_entry/lightningPacket
name = "Lightning bolt! Lightning bolt!"
spell_type = /obj/effect/proc_holder/spell/targeted/conjure_item/spellpacket
category = "Defensive"
/datum/spellbook_entry/timestop
name = "Time Stop"
spell_type = /obj/effect/proc_holder/spell/aoe_turf/conjure/timestop
category = "Defensive"
/datum/spellbook_entry/smoke
name = "Smoke"
spell_type = /obj/effect/proc_holder/spell/targeted/smoke
category = "Defensive"
cost = 1
/datum/spellbook_entry/blind
name = "Blind"
spell_type = /obj/effect/proc_holder/spell/targeted/trigger/blind
cost = 1
/datum/spellbook_entry/mindswap
name = "Mindswap"
spell_type = /obj/effect/proc_holder/spell/targeted/mind_transfer
category = "Mobility"
/datum/spellbook_entry/forcewall
name = "Force Wall"
spell_type = /obj/effect/proc_holder/spell/targeted/forcewall
category = "Defensive"
cost = 1
/datum/spellbook_entry/blink
name = "Blink"
spell_type = /obj/effect/proc_holder/spell/targeted/turf_teleport/blink
category = "Mobility"
/datum/spellbook_entry/teleport
name = "Teleport"
spell_type = /obj/effect/proc_holder/spell/targeted/area_teleport/teleport
category = "Mobility"
/datum/spellbook_entry/mutate
name = "Mutate"
spell_type = /obj/effect/proc_holder/spell/targeted/genetic/mutate
/datum/spellbook_entry/jaunt
name = "Ethereal Jaunt"
spell_type = /obj/effect/proc_holder/spell/targeted/ethereal_jaunt
category = "Mobility"
/datum/spellbook_entry/knock
name = "Knock"
spell_type = /obj/effect/proc_holder/spell/aoe_turf/knock
category = "Mobility"
cost = 1
/datum/spellbook_entry/fleshtostone
name = "Flesh to Stone"
spell_type = /obj/effect/proc_holder/spell/targeted/touch/flesh_to_stone
/datum/spellbook_entry/summonitem
name = "Summon Item"
spell_type = /obj/effect/proc_holder/spell/targeted/summonitem
category = "Assistance"
cost = 1
/datum/spellbook_entry/lichdom
name = "Bind Soul"
spell_type = /obj/effect/proc_holder/spell/targeted/lichdom
category = "Defensive"
/datum/spellbook_entry/teslablast
name = "Tesla Blast"
spell_type = /obj/effect/proc_holder/spell/targeted/tesla
/datum/spellbook_entry/lightningbolt
name = "Lightning Bolt"
spell_type = /obj/effect/proc_holder/spell/aimed/lightningbolt
cost = 3
/datum/spellbook_entry/lightningbolt/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) //return 1 on success
. = ..()
user.flags_1 |= TESLA_IGNORE_1
/datum/spellbook_entry/infinite_guns
name = "Lesser Summon Guns"
spell_type = /obj/effect/proc_holder/spell/targeted/infinite_guns/gun
cost = 3
no_coexistance_typecache = /obj/effect/proc_holder/spell/targeted/infinite_guns/arcane_barrage
/datum/spellbook_entry/arcane_barrage
name = "Arcane Barrage"
spell_type = /obj/effect/proc_holder/spell/targeted/infinite_guns/arcane_barrage
cost = 3
no_coexistance_typecache = /obj/effect/proc_holder/spell/targeted/infinite_guns/gun
/datum/spellbook_entry/barnyard
name = "Barnyard Curse"
spell_type = /obj/effect/proc_holder/spell/targeted/barnyardcurse
/datum/spellbook_entry/charge
name = "Charge"
spell_type = /obj/effect/proc_holder/spell/targeted/charge
category = "Assistance"
cost = 1
/datum/spellbook_entry/shapeshift
name = "Wild Shapeshift"
spell_type = /obj/effect/proc_holder/spell/targeted/shapeshift
category = "Assistance"
cost = 1
/datum/spellbook_entry/spacetime_dist
name = "Spacetime Distortion"
spell_type = /obj/effect/proc_holder/spell/spacetime_dist
category = "Defensive"
cost = 1
/datum/spellbook_entry/the_traps
name = "The Traps!"
spell_type = /obj/effect/proc_holder/spell/aoe_turf/conjure/the_traps
category = "Defensive"
cost = 1
/datum/spellbook_entry/item
name = "Buy Item"
refundable = 0
buy_word = "Summon"
var/item_path= null
/datum/spellbook_entry/item/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
new item_path(get_turf(user))
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
return 1
/datum/spellbook_entry/item/GetInfo()
var/dat =""
dat += "<b>[name]</b>"
dat += " Cost:[cost]<br>"
dat += "<i>[desc]</i><br>"
if(surplus>=0)
dat += "[surplus] left.<br>"
return dat
/datum/spellbook_entry/item/staffchange
name = "Staff of Change"
desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself."
item_path = /obj/item/gun/magic/staff/change
/datum/spellbook_entry/item/staffanimation
name = "Staff of Animation"
desc = "An arcane staff capable of shooting bolts of eldritch energy which cause inanimate objects to come to life. This magic doesn't affect machines."
item_path = /obj/item/gun/magic/staff/animate
category = "Assistance"
/datum/spellbook_entry/item/staffchaos
name = "Staff of Chaos"
desc = "A caprious tool that can fire all sorts of magic without any rhyme or reason. Using it on people you care about is not recommended."
item_path = /obj/item/gun/magic/staff/chaos
/datum/spellbook_entry/item/spellblade
name = "Spellblade"
desc = "A sword capable of firing blasts of energy which rip targets limb from limb."
item_path = /obj/item/gun/magic/staff/spellblade
/datum/spellbook_entry/item/staffdoor
name = "Staff of Door Creation"
desc = "A particular staff that can mold solid metal into ornate doors. Useful for getting around in the absence of other transportation. Does not work on glass."
item_path = /obj/item/gun/magic/staff/door
cost = 1
category = "Mobility"
/datum/spellbook_entry/item/staffhealing
name = "Staff of Healing"
desc = "An altruistic staff that can heal the lame and raise the dead."
item_path = /obj/item/gun/magic/staff/healing
cost = 1
category = "Defensive"
/datum/spellbook_entry/item/scryingorb
name = "Scrying Orb"
desc = "An incandescent orb of crackling energy, using it will allow you to ghost while alive, allowing you to spy upon the station with ease. In addition, buying it will permanently grant you x-ray vision."
item_path = /obj/item/scrying
category = "Defensive"
/datum/spellbook_entry/item/soulstones
name = "Six Soul Stone Shards and the spell Artificer"
desc = "Soul Stone Shards are ancient tools capable of capturing and harnessing the spirits of the dead and dying. The spell Artificer allows you to create arcane machines for the captured souls to pilot."
item_path = /obj/item/storage/belt/soulstone/full
category = "Assistance"
/datum/spellbook_entry/item/soulstones/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
. =..()
if(.)
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/construct(null))
return .
/datum/spellbook_entry/item/necrostone
name = "A Necromantic Stone"
desc = "A Necromantic stone is able to resurrect three dead individuals as skeletal thralls for you to command."
item_path = /obj/item/necromantic_stone
category = "Assistance"
/datum/spellbook_entry/item/wands
name = "Wand Assortment"
desc = "A collection of wands that allow for a wide variety of utility. Wands have a limited number of charges, so be conservative in use. Comes in a handy belt."
item_path = /obj/item/storage/belt/wands/full
category = "Defensive"
/datum/spellbook_entry/item/armor
name = "Mastercrafted Armor Set"
desc = "An artefact suit of armor that allows you to cast spells while providing more protection against attacks and the void of space."
item_path = /obj/item/clothing/suit/space/hardsuit/wizard
category = "Defensive"
/datum/spellbook_entry/item/armor/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
. = ..()
if(.)
new /obj/item/clothing/shoes/sandal/magic(get_turf(user)) //In case they've lost them.
new /obj/item/clothing/gloves/color/purple(get_turf(user))//To complete the outfit
/datum/spellbook_entry/item/contract
name = "Contract of Apprenticeship"
desc = "A magical contract binding an apprentice wizard to your service, using it will summon them to your side."
item_path = /obj/item/antag_spawner/contract
category = "Assistance"
/datum/spellbook_entry/item/guardian
name = "Guardian Deck"
desc = "A deck of guardian tarot cards, capable of binding a personal guardian to your body. There are multiple types of guardian available, but all of them will transfer some amount of damage to you. \
It would be wise to avoid buying these with anything capable of causing you to swap bodies with others."
item_path = /obj/item/guardiancreator/choose/wizard
category = "Assistance"
/datum/spellbook_entry/item/guardian/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
. = ..()
if(.)
new /obj/item/paper/guides/antag/guardian/wizard(get_turf(user))
/datum/spellbook_entry/item/bloodbottle
name = "Bottle of Blood"
desc = "A bottle of magically infused blood, the smell of which will attract extradimensional beings when broken. Be careful though, the kinds of creatures summoned by blood magic are indiscriminate in their killing, and you yourself may become a victim."
item_path = /obj/item/antag_spawner/slaughter_demon
limit = 3
category = "Assistance"
/datum/spellbook_entry/item/hugbottle
name = "Bottle of Tickles"
desc = "A bottle of magically infused fun, the smell of which will \
attract adorable extradimensional beings when broken. These beings \
are similar to slaughter demons, but they do not permamently kill \
their victims, instead putting them in an extradimensional hugspace, \
to be released on the demon's death. Chaotic, but not ultimately \
damaging. The crew's reaction to the other hand could be very \
destructive."
item_path = /obj/item/antag_spawner/slaughter_demon/laughter
cost = 1 //non-destructive; it's just a jape, sibling!
limit = 3
category = "Assistance"
/datum/spellbook_entry/item/mjolnir
name = "Mjolnir"
desc = "A mighty hammer on loan from Thor, God of Thunder. It crackles with barely contained power."
item_path = /obj/item/twohanded/mjollnir
/datum/spellbook_entry/item/singularity_hammer
name = "Singularity Hammer"
desc = "A hammer that creates an intensely powerful field of gravity where it strikes, pulling everything nearby to the point of impact."
item_path = /obj/item/twohanded/singularityhammer
/datum/spellbook_entry/item/battlemage
name = "Battlemage Armour"
desc = "An ensorcelled suit of armour, protected by a powerful shield. The shield can completly negate sixteen attacks before being permanently depleted."
item_path = /obj/item/clothing/suit/space/hardsuit/shielded/wizard
limit = 1
category = "Defensive"
/datum/spellbook_entry/item/battlemage_charge
name = "Battlemage Armour Charges"
desc = "A powerful defensive rune, it will grant eight additional charges to a suit of battlemage armour."
item_path = /obj/item/wizard_armour_charge
category = "Defensive"
cost = 1
/datum/spellbook_entry/item/warpwhistle
name = "Warp Whistle"
desc = "A strange whistle that will transport you to a distant safe place on the station. There is a window of vulnerability at the beginning of every use."
item_path = /obj/item/warpwhistle
category = "Mobility"
cost = 1
/datum/spellbook_entry/summon
name = "Summon Stuff"
category = "Rituals"
refundable = 0
buy_word = "Cast"
var/active = 0
/datum/spellbook_entry/summon/CanBuy(mob/living/carbon/human/user,obj/item/spellbook/book)
return ..() && !active
/datum/spellbook_entry/summon/GetInfo()
var/dat =""
dat += "<b>[name]</b>"
if(cost>0)
dat += " Cost:[cost]<br>"
else
dat += " No Cost<br>"
dat += "<i>[desc]</i><br>"
if(active)
dat += "<b>Already cast!</b><br>"
return dat
/datum/spellbook_entry/summon/ghosts
name = "Summon Ghosts"
desc = "Spook the crew out by making them see dead people. Be warned, ghosts are capricious and occasionally vindicative, and some will use their incredibly minor abilties to frustrate you."
cost = 0
/datum/spellbook_entry/summon/ghosts/IsAvailible()
if(!SSticker.mode)
return FALSE
else
return TRUE
/datum/spellbook_entry/summon/ghosts/Buy(mob/living/carbon/human/user, obj/item/spellbook/book)
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
new /datum/round_event/wizard/ghost()
active = TRUE
to_chat(user, "<span class='notice'>You have cast summon ghosts!</span>")
playsound(get_turf(user), 'sound/effects/ghost2.ogg', 50, 1)
return TRUE
/datum/spellbook_entry/summon/guns
name = "Summon Guns"
desc = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill you. Just be careful not to stand still too long!"
/datum/spellbook_entry/summon/guns/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
return !CONFIG_GET(flag/no_summon_guns)
/datum/spellbook_entry/summon/guns/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
rightandwrong(SUMMON_GUNS, user, 25)
active = 1
playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1)
to_chat(user, "<span class='notice'>You have cast summon guns!</span>")
return 1
/datum/spellbook_entry/summon/magic
name = "Summon Magic"
desc = "Share the wonders of magic with the crew and show them why they aren't to be trusted with it at the same time."
/datum/spellbook_entry/summon/magic/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
return !CONFIG_GET(flag/no_summon_magic)
/datum/spellbook_entry/summon/magic/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
rightandwrong(SUMMON_MAGIC, user, 25)
active = 1
playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1)
to_chat(user, "<span class='notice'>You have cast summon magic!</span>")
return 1
/datum/spellbook_entry/summon/events
name = "Summon Events"
desc = "Give Murphy's law a little push and replace all events with special wizard ones that will confound and confuse everyone. Multiple castings increase the rate of these events."
var/times = 0
/datum/spellbook_entry/summon/events/IsAvailible()
if(!SSticker.mode) // In case spellbook is placed on map
return 0
return !CONFIG_GET(flag/no_summon_events)
/datum/spellbook_entry/summon/events/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
summonevents()
times++
playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, 1)
to_chat(user, "<span class='notice'>You have cast summon events.</span>")
return 1
/datum/spellbook_entry/summon/events/GetInfo()
. = ..()
if(times>0)
. += "You cast it [times] times.<br>"
return .
/obj/item/spellbook
name = "spell book"
desc = "An unearthly tome that glows with power."
icon = 'icons/obj/library.dmi'
icon_state ="book"
throw_speed = 2
throw_range = 5
w_class = WEIGHT_CLASS_TINY
var/uses = 10
var/temp = null
var/tab = null
var/mob/living/carbon/human/owner
var/list/datum/spellbook_entry/entries = list()
var/list/categories = list()
/obj/item/spellbook/examine(mob/user)
..()
if(owner)
to_chat(user, "There is a small signature on the front cover: \"[owner]\".")
else
to_chat(user, "It appears to have no author.")
/obj/item/spellbook/Initialize()
. = ..()
prepare_spells()
/obj/item/spellbook/proc/prepare_spells()
var/entry_types = subtypesof(/datum/spellbook_entry) - /datum/spellbook_entry/item - /datum/spellbook_entry/summon
for(var/T in entry_types)
var/datum/spellbook_entry/E = new T
if(E.IsAvailible())
entries |= E
categories |= E.category
else
qdel(E)
tab = categories[1]
/obj/item/spellbook/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/antag_spawner/contract))
var/obj/item/antag_spawner/contract/contract = O
if(contract.used)
to_chat(user, "<span class='warning'>The contract has been used, you can't get your points back now!</span>")
else
to_chat(user, "<span class='notice'>You feed the contract back into the spellbook, refunding your points.</span>")
uses++
for(var/datum/spellbook_entry/item/contract/CT in entries)
if(!isnull(CT.limit))
CT.limit++
qdel(O)
else if(istype(O, /obj/item/antag_spawner/slaughter_demon))
to_chat(user, "<span class='notice'>On second thought, maybe summoning a demon is a bad idea. You refund your points.</span>")
uses++
for(var/datum/spellbook_entry/item/bloodbottle/BB in entries)
if(!isnull(BB.limit))
BB.limit++
qdel(O)
/obj/item/spellbook/proc/GetCategoryHeader(category)
var/dat = ""
switch(category)
if("Offensive")
dat += "Spells and items geared towards debilitating and destroying.<BR><BR>"
dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.<BR>"
dat += "For spells: the number after the spell name is the cooldown time.<BR>"
dat += "You can reduce this number by spending more points on the spell.<BR>"
if("Defensive")
dat += "Spells and items geared towards improving your survivabilty or reducing foes' ability to attack.<BR><BR>"
dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.<BR>"
dat += "For spells: the number after the spell name is the cooldown time.<BR>"
dat += "You can reduce this number by spending more points on the spell.<BR>"
if("Mobility")
dat += "Spells and items geared towards improving your ability to move. It is a good idea to take at least one.<BR><BR>"
dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.<BR>"
dat += "For spells: the number after the spell name is the cooldown time.<BR>"
dat += "You can reduce this number by spending more points on the spell.<BR>"
if("Assistance")
dat += "Spells and items geared towards bringing in outside forces to aid you or improving upon your other items and abilties.<BR><BR>"
dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.<BR>"
dat += "For spells: the number after the spell name is the cooldown time.<BR>"
dat += "You can reduce this number by spending more points on the spell.<BR>"
if("Challenges")
dat += "The Wizard Federation typically has hard limits on the potency and number of spells brought to the station based on risk.<BR>"
dat += "Arming the station against you will increases the risk, but will grant you one more charge for your spellbook.<BR>"
if("Rituals")
dat += "These powerful spells change the very fabric of reality. Not always in your favour.<BR>"
return dat
/obj/item/spellbook/proc/wrap(content)
var/dat = ""
dat +="<html><head><title>Spellbook</title></head>"
dat += {"
<head>
<style type="text/css">
body { font-size: 80%; font-family: 'Lucida Grande', Verdana, Arial, Sans-Serif; }
ul#tabs { list-style-type: none; margin: 30px 0 0 0; padding: 0 0 0.3em 0; }
ul#tabs li { display: inline; }
ul#tabs li a { color: #42454a; background-color: #dedbde; border: 1px solid #c9c3ba; border-bottom: none; padding: 0.3em; text-decoration: none; }
ul#tabs li a:hover { background-color: #f1f0ee; }
ul#tabs li a.selected { color: #000; background-color: #f1f0ee; font-weight: bold; padding: 0.7em 0.3em 0.38em 0.3em; }
div.tabContent { border: 1px solid #c9c3ba; padding: 0.5em; background-color: #f1f0ee; }
div.tabContent.hide { display: none; }
</style>
</head>
"}
dat += {"[content]</body></html>"}
return dat
/obj/item/spellbook/attack_self(mob/user)
if(!owner)
to_chat(user, "<span class='notice'>You bind the spellbook to yourself.</span>")
owner = user
return
if(user != owner)
to_chat(user, "<span class='warning'>The [name] does not recognize you as its owner and refuses to open!</span>")
return
user.set_machine(src)
var/dat = ""
dat += "<ul id=\"tabs\">"
var/list/cat_dat = list()
for(var/category in categories)
cat_dat[category] = "<hr>"
dat += "<li><a [tab==category?"class=selected":""] href='byond://?src=[REF(src)];page=[category]'>[category]</a></li>"
dat += "<li><a><b>Points remaining : [uses]</b></a></li>"
dat += "</ul>"
var/datum/spellbook_entry/E
for(var/i=1,i<=entries.len,i++)
var/spell_info = ""
E = entries[i]
spell_info += E.GetInfo()
if(E.CanBuy(user,src))
spell_info+= "<a href='byond://?src=[REF(src)];buy=[i]'>[E.buy_word]</A><br>"
else
spell_info+= "<span>Can't [E.buy_word]</span><br>"
if(E.CanRefund(user,src))
spell_info+= "<a href='byond://?src=[REF(src)];refund=[i]'>Refund</A><br>"
spell_info += "<hr>"
if(cat_dat[E.category])
cat_dat[E.category] += spell_info
for(var/category in categories)
dat += "<div class=\"[tab==category?"tabContent":"tabContent hide"]\" id=\"[category]\">"
dat += GetCategoryHeader(category)
dat += cat_dat[category]
dat += "</div>"
user << browse(wrap(dat), "window=spellbook;size=700x500")
onclose(user, "spellbook")
return
/obj/item/spellbook/Topic(href, href_list)
..()
var/mob/living/carbon/human/H = usr
if(H.stat || H.restrained())
return
if(!ishuman(H))
return 1
if(H.mind.special_role == "apprentice")
temp = "If you got caught sneaking a peek from your teacher's spellbook, you'd likely be expelled from the Wizard Academy. Better not."
return
var/datum/spellbook_entry/E = null
if(loc == H || (in_range(src, H) && isturf(loc)))
H.set_machine(src)
if(href_list["buy"])
E = entries[text2num(href_list["buy"])]
if(E && E.CanBuy(H,src))
if(E.Buy(H,src))
if(E.limit)
E.limit--
uses -= E.cost
else if(href_list["refund"])
E = entries[text2num(href_list["refund"])]
if(E && E.refundable)
var/result = E.Refund(H,src)
if(result > 0)
if(!isnull(E.limit))
E.limit += result
uses += result
else if(href_list["page"])
tab = sanitize(href_list["page"])
attack_self(H)
return
>>>>>>> fd4c753... replaces BANG_PROTECT_2 with a component, also kills OMNITONGUE_2 and flags_2 (#37597)

View File

@@ -115,7 +115,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
return FALSE
if(!get_cost(O, contr, emag))
return FALSE
if(O.flags_2 & HOLOGRAM_2)
if(O.flags_1 & HOLOGRAM_1)
return FALSE
return TRUE

View File

@@ -1,3 +1,4 @@
<<<<<<< HEAD
//Ears: currently only used for headsets and earmuffs
/obj/item/clothing/ears
@@ -44,3 +45,55 @@
H.update_inv_neck()
H.update_inv_head()
to_chat(owner, "<span class='notice'>You turn the music [headphones_on? "on. Untz Untz Untz!" : "off."]</span>")
=======
//Ears: currently only used for headsets and earmuffs
/obj/item/clothing/ears
name = "ears"
w_class = WEIGHT_CLASS_TINY
throwforce = 0
slot_flags = ITEM_SLOT_EARS
resistance_flags = NONE
/obj/item/clothing/ears/earmuffs
name = "earmuffs"
desc = "Protects your hearing from loud noises, and quiet ones as well."
icon_state = "earmuffs"
item_state = "earmuffs"
strip_delay = 15
equip_delay_other = 25
resistance_flags = FLAMMABLE
/obj/item/clothing/ears/earmuffs/ComponentInitialize()
. = ..()
AddComponent(/datum/component/earhealing)
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_EARS))
/obj/item/clothing/ears/headphones
name = "headphones"
desc = "Unce unce unce unce. Boop!"
icon = 'icons/obj/clothing/accessories.dmi'
icon_state = "headphones"
item_state = "headphones"
slot_flags = ITEM_SLOT_EARS | ITEM_SLOT_HEAD | ITEM_SLOT_NECK //Fluff item, put it whereever you want!
actions_types = list(/datum/action/item_action/toggle_headphones)
var/headphones_on = FALSE
/obj/item/clothing/ears/headphones/Initialize()
. = ..()
update_icon()
/obj/item/clothing/ears/headphones/update_icon()
icon_state = "[initial(icon_state)]_[headphones_on? "on" : "off"]"
item_state = "[initial(item_state)]_[headphones_on? "on" : "off"]"
/obj/item/clothing/ears/headphones/proc/toggle(owner)
headphones_on = !headphones_on
update_icon()
var/mob/living/carbon/human/H = owner
if(istype(H))
H.update_inv_ears()
H.update_inv_neck()
H.update_inv_head()
to_chat(owner, "<span class='notice'>You turn the music [headphones_on? "on. Untz Untz Untz!" : "off."]</span>")
>>>>>>> fd4c753... replaces BANG_PROTECT_2 with a component, also kills OMNITONGUE_2 and flags_2 (#37597)

View File

@@ -13,10 +13,13 @@
resistance_flags = NONE
flags_cover = HEADCOVERSEYES
flags_inv = HIDEHAIR
flags_2 = BANG_PROTECT_2
dog_fashion = /datum/dog_fashion/head/helmet
/obj/item/clothing/head/helmet/ComponentInitialize()
. = ..()
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_HEAD))
/obj/item/clothing/head/helmet/sec
can_flashlight = 1
@@ -203,11 +206,12 @@
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
strip_delay = 80
dog_fashion = null
// old knight helmets do not offer protection against loud noises
flags_2 = NONE
/obj/item/clothing/head/helmet/knight/Initialize(mapload)
. = ..()
var/datum/component = GetComponent(/datum/component/wearertargeting/earprotection)
qdel(component)
/obj/item/clothing/head/helmet/knight/blue
icon_state = "knight_blue"

View File

@@ -84,7 +84,7 @@
if(T.Adjacent(user))
for(var/B in T)
var/atom/movable/AM = B
if(AM.flags_2 & HOLOGRAM_2)
if(AM.flags_1 & HOLOGRAM_1)
continue
. += AM
@@ -93,7 +93,7 @@
.["tool_behaviour"] = list()
.["other"] = list()
for(var/obj/item/I in get_environment(user))
if(I.flags_2 & HOLOGRAM_2)
if(I.flags_1 & HOLOGRAM_1)
continue
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I

View File

@@ -50,8 +50,7 @@
SA.key = SG.key
SA.grant_language(/datum/language/common)
SA.flags_2 |= OMNITONGUE_2
SA.grant_all_languages(TRUE)
SA.sentience_act()

View File

@@ -36,7 +36,7 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars,list("tag", "datum_components", "area"
M.power_change()
if(holoitem)
O.flags_2 |= HOLOGRAM_2
O.flags_1 |= HOLOGRAM_1
return O

View File

@@ -24,10 +24,6 @@
/mob/living/carbon/get_ear_protection()
var/number = ..()
if(ears && (ears.flags_2 & BANG_PROTECT_2))
number += 1
if(head && (head.flags_2 & BANG_PROTECT_2))
number += 1
var/obj/item/organ/ears/E = getorganslot(ORGAN_SLOT_EARS)
if(!E)
number = INFINITY
@@ -224,7 +220,7 @@
..()
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
if(tesla_shock && (flags_2 & TESLA_IGNORE_2))
if(tesla_shock && (flags_1 & TESLA_IGNORE_1))
return FALSE
if(has_trait(TRAIT_SHOCKIMMUNE))
return FALSE
@@ -350,6 +346,9 @@
/mob/living/carbon/soundbang_act(intensity = 1, stun_pwr = 20, damage_pwr = 5, deafen_pwr = 15)
var/list/reflist = list(intensity) // Need to wrap this in a list so we can pass a reference
SendSignal(COMSIG_CARBON_SOUNDBANG, reflist)
intensity = reflist[1]
var/ear_safety = get_ear_protection()
var/obj/item/organ/ears/ears = getorganslot(ORGAN_SLOT_EARS)
var/effect_amount = intensity - ear_safety

View File

@@ -448,7 +448,7 @@
else if(S.siemens_coefficient == (-1))
total_coeff -= 1
siemens_coeff = total_coeff
if(flags_2 & TESLA_IGNORE_2)
if(flags_1 & TESLA_IGNORE_1)
siemens_coeff = 0
else if(!safety)
var/gloves_siemens_coeff = 1

View File

@@ -302,7 +302,7 @@
return 1
/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
if(tesla_shock && (flags_2 & TESLA_IGNORE_2))
if(tesla_shock && (flags_1 & TESLA_IGNORE_1))
return FALSE
if(has_trait(TRAIT_SHOCKIMMUNE))
return FALSE

View File

@@ -251,8 +251,7 @@
med.remove_hud_from(src)
if("translator")
if(href_list["toggle"])
if(!(flags_2 & OMNITONGUE_2))
grant_all_languages(TRUE)
grant_all_languages(TRUE)
// this is PERMAMENT.
if("doorjack")
if(href_list["jack"])
@@ -311,8 +310,8 @@
if(s == "medical HUD")
dat += "<a href='byond://?src=[REF(src)];software=medicalhud;sub=0'>Medical Analysis Suite</a>[(medHUD) ? "<font color=#55FF55> On</font>" : "<font color=#FF5555> Off</font>"] <br>"
if(s == "universal translator")
var/translator_on = (flags_2 & OMNITONGUE_2)
dat += "<a href='byond://?src=[REF(src)];software=translator;sub=0'>Universal Translator</a>[translator_on ? "<font color=#55FF55> On</font>" : "<font color=#FF5555> Off</font>"] <br>"
var/datum/language_holder/H = get_language_holder()
dat += "<a href='byond://?src=[REF(src)];software=translator;sub=0'>Universal Translator</a>[H.omnitongue ? "<font color=#55FF55> On</font>" : "<font color=#FF5555> Off</font>"] <br>"
if(s == "projection array")
dat += "<a href='byond://?src=[REF(src)];software=projectionarray;sub=0'>Projection Array</a> <br>"
if(s == "camera jack")
@@ -463,10 +462,10 @@
// Universal Translator
/mob/living/silicon/pai/proc/softwareTranslator()
var/translator_on = (flags_2 & OMNITONGUE_2)
var/datum/language_holder/H = get_language_holder()
. = {"<h3>Universal Translator</h3><br>
When enabled, this device will permamently be able to speak and understand all known forms of communication.<br><br>
The device is currently [translator_on ? "<font color=#55FF55>en" : "<font color=#FF5555>dis" ]abled.</font><br>[translator_on ? "" : "<a href='byond://?src=[REF(src)];software=translator;sub=0;toggle=1'>Activate Translation Module</a><br>"]"}
The device is currently [H.omnitongue ? "<font color=#55FF55>en" : "<font color=#FF5555>dis" ]abled.</font><br>[H.omnitongue ? "" : "<a href='byond://?src=[REF(src)];software=translator;sub=0;toggle=1'>Activate Translation Module</a><br>"]"}
return .
// Security HUD

View File

@@ -671,7 +671,7 @@ Difficulty: Very Hard
for(var/i in T)
if(isitem(i) && !is_type_in_typecache(i, banned_items_typecache))
var/obj/item/W = i
if(!W.admin_spawned && !(W.flags_2 & HOLOGRAM_2) && !(W.flags_1 & ABSTRACT_1))
if(!W.admin_spawned && !(W.flags_1 & HOLOGRAM_1) && !(W.flags_1 & ABSTRACT_1))
L += W
if(L.len)
var/obj/item/CHOSEN = pick(L)

View File

@@ -221,7 +221,7 @@
else if(isliving(A))
var/dist = get_dist(source, A)
var/mob/living/L = A
if(dist <= zap_range && (dist < closest_dist || !closest_mob) && L.stat != DEAD && !(L.flags_2 & TESLA_IGNORE_2))
if(dist <= zap_range && (dist < closest_dist || !closest_mob) && L.stat != DEAD && !(L.flags_1 & TESLA_IGNORE_1))
closest_mob = L
closest_atom = A
closest_dist = dist

View File

@@ -231,7 +231,6 @@
if(!new_mob)
return
new_mob.grant_language(/datum/language/common)
new_mob.flags_2 |= OMNITONGUE_2
new_mob.logging = M.logging
// Some forms can still wear some items

View File

@@ -679,7 +679,7 @@
SM.sentience_act()
to_chat(SM, "<span class='warning'>All at once it makes sense: you know what you are and who you are! Self awareness is yours!</span>")
to_chat(SM, "<span class='userdanger'>You are grateful to be self aware and owe [user.real_name] a great debt. Serve [user.real_name], and assist [user.p_them()] in completing [user.p_their()] goals at any cost.</span>")
if(SM.flags_2 & HOLOGRAM_2) //Check to see if it's a holodeck creature
if(SM.flags_1 & HOLOGRAM_1) //Check to see if it's a holodeck creature
to_chat(SM, "<span class='userdanger'>You also become depressingly aware that you are not a real creature, but instead a holoform. Your existence is limited to the parameters of the holodeck.</span>")
to_chat(user, "<span class='notice'>[SM] accepts [src] and suddenly becomes attentive and aware. It worked!</span>")
SM.copy_known_languages_from(user, FALSE)

View File

@@ -323,6 +323,11 @@
#include "code\datums\components\cleaning.dm"
#include "code\datums\components\construction.dm"
#include "code\datums\components\decal.dm"
<<<<<<< HEAD
=======
#include "code\datums\components\earhealing.dm"
#include "code\datums\components\earprotection.dm"
>>>>>>> fd4c753... replaces BANG_PROTECT_2 with a component, also kills OMNITONGUE_2 and flags_2 (#37597)
#include "code\datums\components\forensics.dm"
#include "code\datums\components\infective.dm"
#include "code\datums\components\jousting.dm"