// The day has come when this warps into existence.
// Dear god, imagine the horrors that will soon lurk in here.
/proc/chs(var/str, var/i)
return ascii2text(text2ascii(str,i))
/**
* BASH explode:
* Splits a string into string pieces the same way BASH handles this.
* - Process quoted strings LTR: Apostrophized strings are unparsed. Quoted strings are parsed.
* - Insert parsed strings back into the string by using a placeholder for spaces.
* - Split the string with the usual space separation method.
* - Return list.
*/
// TODO: Variable processing.
#define NONE 0
#define APOS 1
#define QUOT 2
#define ESCAPE "\\"
/proc/bash_explode(var/str)
var/fin = 0
var/state = NONE
var/pos = 1
var/qpos = 1
var/buf = ""
while (!fin)
switch(state)
if (NONE)
var/NA = findtext(str, "'", pos)
var/NQ = findtext(str, "\"", pos)
if (!NA && !NQ)
buf += copytext(str, pos)
fin = 1
else if (NA && !NQ || (NA && NQ && NA < NQ))
if (chs(str, NA - 1) == ESCAPE)
buf += copytext(str, pos, NA - 1) + "'"
pos = NA + 1
continue
else
buf += copytext(str, pos, NA)
pos = NA + 1
state = APOS
else if (NQ && !NA || (NA && NQ && NQ < NA))
if (chs(str, NQ - 1) == ESCAPE)
buf += copytext(str, pos, NQ - 1) + "\""
pos = NQ + 1
continue
else
buf += copytext(str, pos, NQ)
pos = NQ + 1
qpos = NQ + 1
state = QUOT
else if (NA == NQ)
//??????
return null
if (APOS)
var/NA = findtext(str, "'", pos)
if (!NA)
return null
var/temp = copytext(str, pos, NA)
buf += replacetext(temp, " ", " ")
pos = NA + 1
state = NONE
if (QUOT)
var/NQ = findtext(str, "\"", pos)
if (!NQ)
return null
if (copytext(str, NQ - 1, NQ) == ESCAPE)
pos = NQ + 1
continue
var/temp = copytext(str, qpos, NQ)
buf += replacetext(replacetext(temp, " ", " "), "\\\"", "\"")
pos = NQ + 1
state = NONE
var/list/el = splittext(buf, " ")
var/list/ret = list()
for (var/s in el)
ret += replacetext(s, " ", " ")
return ret
#undef ESCAPE
#undef QUOT
#undef APOS
#undef NONE
/proc/bash_sanitize(var/data)
var/list/allowed_chars = list(" ")
var/ret = ""
var/lgp = 0
for (var/i = 1, i <= length(data), i++)
var/char = text2ascii(data, i)
var/ord = ascii2text(char)
if ((65 <= char && char <= 90) || (97 <= char && char <= 122) || (ord in allowed_chars))
if (lgp == 0)
lgp = i
continue
if (lgp == 0)
continue
ret += copytext(data, lgp, i)
lgp = 0
if (lgp)
ret += copytext(data, lgp)
return ret
/obj/nerd_trap_door
name = "Heavily locked door"
desc = "Man, whatever is in here must be pretty valuable. This door seems to be indestructible and features an unrealistic amount of keyholes."
var/list/expected = list("silver key", "skeleton key", "literal skeleton key", "hot iron key", "cold steel key", "onyx key", "key lime pie", "futuristic key", "virtual key", "golden key", "bee key", "iron key", "iridium key", "lunar key")
var/list/unlocked = list()
var/list/ol = list()
icon = 'icons/misc/aprilfools.dmi'
icon_state = "hld0"
opacity = 1
density = 1
anchored = 1
examine()
..()
boutput(usr, "Your keen skills of observation tell you that [expected.len - unlocked.len] out of the [expected.len] locks are locked.")
attackby(var/obj/item/I, var/mob/user)
if (istype(I, /obj/item/device/key))
var/kname = null
if (I.name in expected)
kname = I.name
//for (var/N in expected)
// if (dd_hasprefix(I.name, N))
// break
if (kname)
boutput(user, "You insert the [I.name] into the [kname]hole and turn it. The door emits a loud click.")
playsound(src.loc, "sound/effects/thunk.ogg", 60, 1)
if (kname in unlocked)
unlocked -= kname
overlays -= ol[kname]
ol -= kname
else
unlocked += kname
var/image/IM = image('icons/misc/aprilfools.dmi', "[kname]hole")
ol[kname] = IM
overlays += IM
else
boutput(user, "You cannot find a matching keyhole for that key!")
else if (istype(I, /obj/item/reagent_containers/food/snacks/pie/lime))
if ("key lime pie" in expected)
boutput(user, "You insert the [I.name] into the key lime piehole and turn it. The door emits a loud click.")
playsound(src.loc, "sound/effects/thunk.ogg", 60, 1)
if ("key lime pie" in unlocked)
unlocked -= "key lime pie"
overlays -= ol["key lime pie"]
ol -= "key lime pie"
else
unlocked += "key lime pie"
var/image/IM = image('icons/misc/aprilfools.dmi', "key lime piehole")
ol["key lime pie"] = IM
overlays += IM
else
boutput(user, "You cannot find a matching keyhole for that key!")
Bumped(var/mob/M)
if (!istype(M))
return
attack_hand(M)
attack_hand(var/mob/user)
if (!density)
return
if (unlocked.len == expected.len)
open()
else
boutput(user, "The door won't budge!")
proc/open()
if (unlocked.len != expected.len)
return
playsound(src.loc, "sound/machines/door_open.ogg", 50, 1)
icon_state = "hld1"
density = 0
opacity = 0
overlays.len = 0
meteorhit()
return
ex_act()
return
blob_act()
return
bullet_act()
return
/obj/steel_beams
name = "steel beams"
desc = "A bunch of unfortunately placed, tightly packed steel beams. You cannot get a meaningful glimpse of what's on the other side."
anchored = 1
density = 1
opacity = 1
icon = 'icons/obj/stationobjs.dmi'
icon_state = "beams"
meteorhit()
return
ex_act()
return
blob_act()
return
bullet_act()
return
/obj/faint_shimmer
name = "faint shimmer"
desc = "Huh."
anchored = 1
density = 0
invisibility = 2
blend_mode = 4
icon = 'icons/misc/old_or_unused.dmi'
icon_state = "noise5"
var/decloaked_type = /obj/item/storage/toilet
dense
density = 1
// Aiming bow action.
/datum/action/bar/aim
duration = -1
var/obj/item/gun/bow/bow = null
var/progress = 0
var/direction = 1
var/progression = 0.18
var/linger = 15
var/moved = 0
New(var/mob/M, var/obj/item/gun/bow/B)
owner = M
bow = B
..()
onStart()
..()
playsound(get_turf(owner), 'sound/effects/bow_aim.ogg', 75, 1)
owner.visible_message("[owner] pulls the string on [bow]!", "You pull the string on [bow]!")
onDelete()
if (bow)
bow.aim = null
..()
onEnd()
boutput(owner, "You couldn't hold the string any longer.")
if (bow)
bow.aim = null
..()
interrupt(var/flag)
var/mob/mowner = owner
if(flag == INTERRUPT_MOVE && mowner.m_intent == "walk")
bar.color = "#FF0000"
switch (direction)
if (-1)
progress = max(0, progress - 4 * progression)
progression += 0.035
if (!progress)
state = ACTIONSTATE_FINISH
if (0)
linger = max(linger - 4, 0)
if (linger)
direction = 1
progress = max(0, progress - 4 * progression)
moved = 1
else
direction = -1
moved = 0
if (1)
moved = 2
linger = max(0, linger - 2)
progress = max(0, progress - 3 * progression)
if (!linger)
direction = -1
moved = 0
return
..()
onUpdate()
if (!progress && direction == -1)
state = ACTIONSTATE_FINISH
return
if (moved)
moved--
linger = max(0, linger - 1)
if (linger <= 0)
direction = -1
moved = 0
return
switch (direction)
if (-1)
progress = max(0, progress - progression)
if (!progress)
state = ACTIONSTATE_FINISH
if (0)
linger--
if (linger <= 0)
direction = -1
if (1)
progress = min(1, progress + progression)
if (progress == 1)
direction = 0
var/complete = progress
bar.color = "#0000FF"
bar.transform = matrix(complete, 1, MATRIX_SCALE)
bar.pixel_x = -nround( ((30 - (30 * complete)) / 2) )
/obj/item/arrow
name = "steel-headed arrow"
icon = 'icons/obj/items.dmi'
icon_state = null
flags = FPRINT | TABLEPASS | SUPPRESSATTACK
// placeholder
var/datum/material/head_material
var/datum/material/shaft_material
var/image/shaft
var/image/head
amount = 1
New()
..()
shaft = image(icon, "arrow_base")
head = image(icon, "arrow_head")
reagents = new /datum/reagents(3)
reagents.my_atom = src
overlays += shaft
overlays += head
examine()
..()
if (amount > 1)
boutput(usr, "This is a stack of [amount] arrows. Picking it up will take a single arrow from the stack.")
if (reagents.total_volume)
boutput(usr, "The tip of the arrow is coated with reagents.")
clone(var/newloc = null)
var/obj/item/arrow/O = new(loc)
if (newloc)
O.set_loc(newloc)
O.setHeadMaterial(head_material)
O.setShaftMaterial(shaft_material)
attack_hand(var/mob/user)
if (amount > 1)
amount--
var/obj/item/arrow/O = clone(loc)
user.put_in_hand_or_drop(O, user.hand)
boutput(usr, "You take \a [src] from the stack of [src]s. [amount] remaining on the stack.")
else
..()
set_loc()
..()
if (isturf(loc))
overlays.len = 0
head.layer = initial(head.layer)
shaft.layer = initial(shaft.layer)
overlays += shaft
overlays += head
else
overlays.len = 0
head.layer = HUD_LAYER+3
shaft.layer = HUD_LAYER+3
overlays += shaft
overlays += head
proc/setName()
if (head_material && shaft_material)
name = "[head_material]-headed [shaft_material] arrow"
else if (head_material)
name = "[head_material]-headed arrow"
else if (shaft_material)
name = "steel-headed [shaft_material] arrow"
else
name = "steel-headed arrow"
proc/setHeadMaterial(var/datum/material/M)
head_material = copyMaterial(M)
overlays -= head
if (M)
head.color = M.color
head.alpha = M.alpha
else
head.color = null
head.alpha = 255
overlays += head
setName()
proc/setShaftMaterial(var/datum/material/M)
shaft_material = copyMaterial(M)
material = shaft_material
overlays -= shaft
if (M)
shaft.color = M.color
shaft.alpha = M.alpha
else
shaft.color = null
shaft.alpha = 255
overlays += head
setName()
afterattack(var/atom/target, var/mob/user, reach)
if (!reach)
return
if (istype(target, /mob/living))
if (prob(50))
user.visible_message("[user] tries to stab [target] with [src] but misses!")
playsound(get_turf(user), 'sound/weapons/punchmiss.ogg', 25, 1, 1)
return
user.visible_message("[user] stabs [target] with [src]!")
user.u_equip(src)
playsound(get_turf(user), 'sound/effects/bloody_stab.ogg', 75, 1)
if (ishuman(target))
var/mob/living/carbon/human/H = target
var/obj/item/implant/projectile/arrow/A = new
A.material = head_material
A.arrow = src
A.name = name
set_loc(A)
A.set_loc(target)
A.owner = target
H.implant += A
A.implanted(H, null, 100)
reagents.reaction(target, 2)
reagents.trans_to(target, reagents.total_volume)
take_bleeding_damage(target, null, 8, DAMAGE_STAB)
if (head_material)
head_material.triggerOnAttack(src, user, target)
else
var/obj/item/I = target
if (istype(I) && I.is_open_container() == 1 && I.reagents)
if (reagents.total_volume == reagents.maximum_volume)
boutput(user, "[src] is already coated in the maximum amount of reagents it can hold.")
else if (!I.reagents.total_volume)
boutput(user, "[I] is empty.")
else
var/amt = min(reagents.maximum_volume - reagents.total_volume, I.reagents.total_volume)
logTheThing("combat", user, null, "poisoned [src] [log_reagents(I)] at [log_loc(user)].") // Logs would be nice (Convair880).
I.reagents.trans_to(src, amt)
boutput(user, "You dip [src] into [I], coating it with [amt] units of reagents.")
/obj/item/arrowhead
name = "arrowhead"
icon = 'icons/obj/items.dmi'
icon_state = "arrowhead"
examine()
..()
boutput(usr, "There [amount == 1 ? "is" : "are"] [amount] arrowhead[amount != 1 ? "s" : null] in the stack.")
/obj/item/implant/projectile/arrow
name = "arrow"
icon = null
icon_state = null
desc = "An arrow."
var/obj/item/arrow/arrow = null
New()
..()
implant_overlay = image(icon='icons/mob/human.dmi', icon_state="arrow_stick_[rand(0,4)]", layer=MOB_EFFECT_LAYER)
// Hack.
set_loc()
..()
if (isturf(loc))
if (arrow)
arrow.set_loc(loc)
qdel(src)
/obj/item/quiver
name = "quiver"
icon = 'icons/obj/items.dmi'
icon_state = "quiver-0"
wear_image_icon = 'icons/mob/back.dmi'
item_state = "quiver"
flags = FPRINT | TABLEPASS | ONBACK
attackby(var/obj/item/arrow/I, var/mob/user)
if (!istype(I))
boutput(user, "That cannot be placed in [src]!")
return
user.u_equip(I)
I.loc = src
maptext = "[contents.len]"
icon_state = "quiver-[min(contents.len, 4)]"
attack_hand(var/mob/user)
if (src in user)
if (contents.len)
boutput(user, "You take [contents[1]] from [src].")
user.put_in_hand(contents[1], user.hand)
if (contents.len)
maptext = "[contents.len]"
else
maptext = null
icon_state = "quiver-[min(contents.len, 4)]"
return
..()
MouseDrop(atom/over_object, src_location, over_location)
..()
var/obj/screen/hud/S = over_object
if (istype(S))
playsound(src.loc, "rustle", 50, 1, -5)
if (!usr.restrained() && !usr.stat && src.loc == usr)
if (S.id == "rhand")
if (!usr.r_hand)
usr.u_equip(src)
usr.put_in_hand(src, 0)
else
if (S.id == "lhand")
if (!usr.l_hand)
usr.u_equip(src)
usr.put_in_hand(src, 1)
return
if (usr.is_in_hands(src))
var/turf/T = over_object
if (istype(T, /obj/table))
T = get_turf(T)
if (!(usr in range(1, T)))
return
if (istype(T))
for (var/obj/O in T)
if (O.density && !istype(O, /obj/table) && !istype(O, /obj/rack))
return
if (!T.density)
usr.visible_message("[usr] dumps the contents of [src] onto [T]!")
for (var/obj/item/I in src)
I.set_loc(T)
I.layer = initial(I.layer)
/datum/projectile/arrow
name = "arrow"
power = 25
dissipation_delay = 4
dissipation_rate = 5
shot_sound = 'sound/effects/bow_fire.ogg'
damage_type = D_KINETIC
hit_type = DAMAGE_STAB
implanted = null
ks_ratio = 1.0
icon_turf_hit = "bhole"
icon_state = "arrow"
on_hit(var/atom/A, angle, var/obj/projectile/P)
if (ismob(A))
playsound(get_turf(A), 'sound/effects/bloody_stab.ogg', 75, 1)
var/obj/item/implant/projectile/arrow/B = P.implanted
if (istype(B))
if (B.material)
B.material.triggerOnAttack(B, null, A)
B.arrow.reagents.reaction(A, 2)
B.arrow.reagents.trans_to(A, B.arrow.reagents.total_volume)
take_bleeding_damage(A, null, round(src.power / 3), src.hit_type)
/obj/item/gun/bow
name = "bow"
icon = 'icons/obj/items.dmi'
icon_state = "bow"
var/obj/item/arrow/loaded = null
var/datum/action/bar/aim/aim = null
current_projectile = new/datum/projectile/arrow
spread_angle = 30
force = 5
attack_hand(var/mob/user)
if (loaded && user.is_in_hands(src))
user.put_in_hand_or_drop(loaded)
boutput(user, "You unload the arrow from the bow.")
overlays.len = 0
loaded = null
else
..()
attack(var/mob/target, var/mob/user)
user.lastattacked = target
target.lastattacker = user
target.lastattackertime = world.time
if(isliving(target) && aim)
src.shoot_point_blank(target, user)
else
..()
#ifdef DATALOGGER
game_stats.Increment("violence")
#endif
return
attack_self(var/mob/user)
if (!aim && loaded)
aim = new(user, src)
actions.start(aim, user)
process_ammo(var/mob/user)
if (!loaded)
boutput(user, "Nothing is loaded in the bow!")
return 0
overlays.len = 0
var/obj/item/implant/projectile/arrow/A = new
A.material = loaded.head_material
A.arrow = loaded
A.name = loaded.name
current_projectile.name = loaded.name
loaded.set_loc(A)
current_projectile.implanted = A
loaded = null
return 1
canshoot()
return loaded != null
pixelaction(atom/target, params, mob/user, reach)
if (!loaded)
boutput(user, "Nothing is loaded in the bow!")
return 1
spread_angle = 30
if (aim)
spread_angle = (1 - aim.progress) * 30
aim.state = ACTIONSTATE_FINISH
..()
attackby(var/obj/item/arrow/I, var/mob/user)
if (!istype(I))
return
if (loaded)
boutput(user, "An arrow is already loaded onto the bow.")
overlays += I
user.u_equip(I)
loaded = I
I.loc = src