mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-17 10:05:27 +01:00
Personal Translocator
Adds it to science. Has a high materials and research cost, and is considered ***contraband***, as it says in the description. Also included in this PR is device_alt.dmi, a bunch of alternate device sprites which can be fun for stuff.
This commit is contained in:
@@ -37,6 +37,15 @@
|
||||
build_path = /obj/item/clothing/glasses/omnihud
|
||||
sort_string = "GAAFB"
|
||||
|
||||
/datum/design/item/translocator
|
||||
name = "personal translocator"
|
||||
id = "translocator"
|
||||
req_tech = list(TECH_MAGNET = 5, TECH_BLUESPACE = 5, TECH_ILLEGAL = 7)
|
||||
materials = list(DEFAULT_WALL_MATERIAL = 4000, "glass" = 2000, "uranium" = 4000, "diamond" = 2000)
|
||||
build_path = /obj/item/device/perfect_tele
|
||||
sort_string = "HABAF"
|
||||
|
||||
|
||||
// Resleeving Circuitboards
|
||||
|
||||
/datum/design/circuit/comm_server
|
||||
|
||||
@@ -595,3 +595,254 @@ obj/item/weapon/material/hatchet/tacknife/combatknife/fluff/katarina/handle_shie
|
||||
user.verbs |= /mob/living/carbon/human/proc/shapeshifter_select_gender
|
||||
else
|
||||
return
|
||||
|
||||
//The perfect adminboos device?
|
||||
/obj/item/device/perfect_tele
|
||||
name = "personal translocator"
|
||||
desc = "Seems absurd, doesn't it? Yet, here we are. Generally considered dangerous contraband unless the user has permission from Central Command."
|
||||
icon = 'icons/obj/device_alt.dmi'
|
||||
icon_state = "hand_tele"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
|
||||
var/list/beacons = list()
|
||||
var/ready = 1
|
||||
var/beacons_left = 3
|
||||
var/obj/item/device/perfect_tele_beacon/destination
|
||||
var/datum/effect/effect/system/spark_spread/spk
|
||||
var/list/warned_users = list()
|
||||
var/list/logged_events = list()
|
||||
|
||||
/obj/item/device/perfect_tele/New()
|
||||
..()
|
||||
flags |= NOBLUDGEON
|
||||
spk = new(src)
|
||||
spk.set_up(5, 0, src)
|
||||
spk.attach(src)
|
||||
|
||||
/obj/item/device/perfect_tele/Destroy()
|
||||
beacons.Cut()
|
||||
qdel(spk)
|
||||
..()
|
||||
|
||||
/obj/item/device/perfect_tele/update_icon()
|
||||
if(ready)
|
||||
icon_state = "[initial(icon_state)]"
|
||||
else
|
||||
icon_state = "[initial(icon_state)]_w"
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/device/perfect_tele/attack_self(mob/user)
|
||||
if(!(user.ckey in warned_users))
|
||||
warned_users |= user.ckey
|
||||
alert(user,"This device can be easily used to break ERP preferences due to the nature of teleporting \
|
||||
and tele-vore. Make sure you carefully examine someone's OOC prefs before teleporting them if you are \
|
||||
going to use this device for ERP purposes. This device records all warnings given and teleport events for \
|
||||
admin review in case of pref-breaking, so just don't do it.","OOC WARNING")
|
||||
|
||||
var/choice = alert(user,"What do you want to do?","[src]","Create Beacon","Cancel","Target Beacon")
|
||||
switch(choice)
|
||||
if("Create Beacon")
|
||||
if(beacons_left <= 0)
|
||||
user << "<span class='warning'>\The [src] can't support any more beacons!</span>"
|
||||
return
|
||||
|
||||
var/new_name = html_encode(input(user,"New beacon's name (2-20 char):","[src]") as text|null)
|
||||
|
||||
if(length(new_name) > 20 || length(new_name) < 2)
|
||||
alert("Entered name length invalid (must be longer than 2, no more than than 20).","Error")
|
||||
return
|
||||
if(new_name in beacons)
|
||||
alert("No duplicate names, please. '[new_name]' exists already.","Error")
|
||||
return
|
||||
|
||||
var/obj/item/device/perfect_tele_beacon/nb = new(get_turf(src))
|
||||
nb.tele_name = new_name
|
||||
nb.tele_hand = src
|
||||
nb.creator = user.ckey
|
||||
beacons[new_name] = nb
|
||||
beacons_left--
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
L.put_in_any_hand_if_possible(nb)
|
||||
|
||||
if("Target Beacon")
|
||||
if(!beacons.len)
|
||||
user << "<span class='warning'>\The [src] doesn't have any beacons!</span>"
|
||||
else
|
||||
var/target = input("Which beacon do you target?","[src]") in beacons|null
|
||||
if(target && (target in beacons))
|
||||
destination = beacons[target]
|
||||
user << "<span class='notice'>Destination set to '[target]'.</span>"
|
||||
else
|
||||
return
|
||||
|
||||
/obj/item/device/perfect_tele/attackby(obj/W, mob/user)
|
||||
if(istype(W,/obj/item/device/perfect_tele_beacon))
|
||||
var/obj/item/device/perfect_tele_beacon/tb = W
|
||||
if(tb.tele_name in beacons)
|
||||
user << "<span class='notice'>You re-insert \the [tb] into \the [src].</span>"
|
||||
beacons -= tb.tele_name
|
||||
user.unEquip(tb)
|
||||
qdel(tb)
|
||||
beacons_left++
|
||||
else
|
||||
user << "<span class='notice'>\The [tb] doesn't belong to \the [src].</span>"
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/device/perfect_tele/afterattack(mob/living/target, mob/living/user, proximity)
|
||||
//No, you can't teleport people from over there.
|
||||
if(!proximity)
|
||||
return
|
||||
|
||||
//Only mob/living need apply.
|
||||
if(!istype(user) || !istype(target))
|
||||
return
|
||||
|
||||
//No, you can't teleport buckled people.
|
||||
if(target.buckled)
|
||||
user << "<span class='warning'>The target appears to be attached to something...</span>"
|
||||
return
|
||||
|
||||
//No, you can't teleport if it's not ready yet.
|
||||
if(!ready)
|
||||
user << "<span class='warning'>\The [src] is still recharging!</span>"
|
||||
return
|
||||
|
||||
//No, you can't teleport if there's no destination.
|
||||
if(!destination)
|
||||
user << "<span class='warning'>\The [src] doesn't have a current valid destination set!</span>"
|
||||
return
|
||||
|
||||
//No, you can't port to or from away missions. Stupidly complicated check.
|
||||
var/turf/uT = get_turf(user)
|
||||
var/turf/dT = get_turf(destination)
|
||||
if(!uT || !dT)
|
||||
return
|
||||
|
||||
if( (uT.z != dT.z) && ( (uT.z > max_default_z_level() ) || (dT.z > max_default_z_level()) ) )
|
||||
user << "<span class='warning'>\The [src] can't teleport you that far!</span>"
|
||||
return
|
||||
|
||||
//Bzzt.
|
||||
ready = 0
|
||||
|
||||
//Destination beacon vore checking
|
||||
var/datum/belly/target_belly
|
||||
var/atom/real_dest = get_turf(destination)
|
||||
|
||||
//Destination beacon is held/eaten
|
||||
if(isliving(destination.loc) && (user != destination.loc)) //We should definitely get televored
|
||||
var/mob/living/L = destination.loc
|
||||
|
||||
//Is the beacon IN a belly?
|
||||
target_belly = check_belly(destination)
|
||||
|
||||
//No? Well do they have vore organs at all?
|
||||
if(!target_belly && L.vore_organs.len)
|
||||
|
||||
//If they do, use their picked one.
|
||||
if(L.vore_selected)
|
||||
target_belly = L.vore_organs[L.vore_selected]
|
||||
else
|
||||
//Else just use the first one.
|
||||
var/I = L.vore_organs[1] //We're just going to use 1
|
||||
target_belly = L.vore_organs[I]
|
||||
|
||||
//Televore fluff stuff
|
||||
if(target_belly)
|
||||
real_dest = destination.loc
|
||||
target_belly.internal_contents |= target
|
||||
playsound(target_belly.owner, target_belly.vore_sound, 100, 1)
|
||||
user << "<span class='warning'>\The [src] teleports you right into [target_belly.owner]'s [target_belly.name]!</span>"
|
||||
target_belly.owner << "<span class='warning'>Your [target_belly.name] suddenly has a new occupant!</span>"
|
||||
|
||||
//Phase-out effect
|
||||
phase_out(target,get_turf(target))
|
||||
|
||||
//Move them
|
||||
target.forceMove(real_dest)
|
||||
|
||||
//Phase-in effect
|
||||
phase_in(target,get_turf(target))
|
||||
|
||||
//And any friends!
|
||||
for(var/obj/item/weapon/grab/G in target.contents)
|
||||
if(G.affecting && (G.state >= GRAB_AGGRESSIVE))
|
||||
|
||||
//Phase-out effect for grabbed person
|
||||
phase_out(G.affecting,get_turf(G.affecting))
|
||||
|
||||
//Move them, and televore if necessary
|
||||
G.affecting.forceMove(real_dest)
|
||||
if(target_belly)
|
||||
target_belly.internal_contents |= G.affecting
|
||||
G.affecting << "<span class='warning'>\The [src] teleports you right into [target_belly.owner]'s [target_belly.name]!</span>"
|
||||
|
||||
//Phase-in effect for grabbed person
|
||||
phase_in(G.affecting,get_turf(G.affecting))
|
||||
|
||||
update_icon()
|
||||
spawn(30 SECONDS)
|
||||
if(src) //If we still exist, anyway.
|
||||
ready = 1
|
||||
update_icon()
|
||||
|
||||
logged_events["[world.time]"] = "[user] teleported [target] to [real_dest] [target_belly ? "(Belly: [target_belly.name])" : null]"
|
||||
|
||||
/obj/item/device/perfect_tele/proc/phase_out(var/mob/M,var/turf/T)
|
||||
|
||||
if(!M || !T)
|
||||
return
|
||||
|
||||
spk.set_up(5, 0, M)
|
||||
spk.attach(M)
|
||||
playsound(T, "sparks", 50, 1)
|
||||
anim(T,M,'icons/mob/mob.dmi',,"phaseout",,M.dir)
|
||||
|
||||
/obj/item/device/perfect_tele/proc/phase_in(var/mob/M,var/turf/T)
|
||||
|
||||
if(!M || !T)
|
||||
return
|
||||
|
||||
spk.start()
|
||||
playsound(T, 'sound/effects/phasein.ogg', 25, 1)
|
||||
playsound(T, 'sound/effects/sparks2.ogg', 50, 1)
|
||||
anim(T,M,'icons/mob/mob.dmi',,"phasein",,M.dir)
|
||||
spk.set_up(5, 0, src)
|
||||
spk.attach(src)
|
||||
|
||||
/obj/item/device/perfect_tele_beacon
|
||||
name = "translocator beacon"
|
||||
desc = "That's unusual."
|
||||
icon = 'icons/obj/device_alt.dmi'
|
||||
icon_state = "motion2"
|
||||
w_class = ITEMSIZE_TINY
|
||||
|
||||
var/tele_name
|
||||
var/obj/item/device/perfect_tele/tele_hand
|
||||
var/creator
|
||||
var/warned_users = list()
|
||||
|
||||
/obj/item/device/perfect_tele_beacon/New()
|
||||
..()
|
||||
flags |= NOBLUDGEON
|
||||
|
||||
/obj/item/device/perfect_tele_beacon/Destroy()
|
||||
tele_name = null
|
||||
tele_hand = null
|
||||
..()
|
||||
|
||||
/obj/item/device/perfect_tele_beacon/attack_hand(mob/user)
|
||||
if((user.ckey != creator) && !(user.ckey in warned_users))
|
||||
warned_users |= user.ckey
|
||||
var/choice = alert(user,"This device is a translocator beacon. Having it on your person may mean that anyone \
|
||||
who teleports to this beacon gets teleported into your selected vore-belly. If you are prey-only \
|
||||
or don't wish to potentially have a random person teleported into you, it's suggested that you \
|
||||
not carry this around.","OOC WARNING","Take It","Leave It")
|
||||
if(choice == "Leave It")
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
Reference in New Issue
Block a user