9eee3e5067
Works pretty well. If it can't GC something, it'll just del() it and be done. Speed is amazing, holy shit. New procs you should be aware of: qdel(atom/movable) - sets up an object for garbage collection. Call this rather than del(atom/movable). atom/movable/Destroy() - called right before the object is GC'd, so it still has a loc. Also called if the object is del()'d. new controller - garbage.dm has all the details on this. Basically it nulls all references on GC'd objects and force del() them if necessary. Generally speaking, objects should use Destroy() for behavior prior to deletion rather than Del(). You should also always call the parent so the object gets the right gc_destroyed var set. ISSUES: Tries to GC mobs atm. This actually works for new players, not so much for humans/monkies/simple_animals/anything. I'm guessing it needs to clear out their mind and HUD and maybe other things. Gibbing is really bugged. It works, but the overlays just sit there for awhile and ugh. I'm very tempted just to del() mob/living and mob/camera and call it a day. qdel() equipment doesn't unequip the item. Pipes don't generally GC correctly. Debugging suggests they get referenced in many pipenets and that isn't cleared properly. However some do work fine. Need assistance here. Bots don't GC, probably in the radio controller. Lots of other shit doesn't GC but it's hard to find them because of the pipe spam. I think I'm calling Destroy() twice by accident.
325 lines
10 KiB
Plaintext
325 lines
10 KiB
Plaintext
/obj/structure/bigDelivery
|
|
name = "large parcel"
|
|
desc = "A big wrapped package."
|
|
icon = 'icons/obj/storage.dmi'
|
|
icon_state = "deliverycloset"
|
|
density = 1
|
|
mouse_drag_pointer = MOUSE_ACTIVE_POINTER
|
|
var/obj/wrapped = null
|
|
var/sortTag = 0
|
|
|
|
|
|
/obj/structure/bigDelivery/attack_hand(mob/user as mob)
|
|
qdel(src)
|
|
|
|
/obj/structure/bigDelivery/Destroy()
|
|
if(wrapped) //sometimes items can disappear. For example, bombs. --rastaf0
|
|
wrapped.loc = (get_turf(loc))
|
|
if(istype(wrapped, /obj/structure/closet))
|
|
var/obj/structure/closet/O = wrapped
|
|
O.welded = 0
|
|
var/turf/T = get_turf(src)
|
|
for(var/atom/movable/AM in contents)
|
|
AM.loc = T
|
|
..()
|
|
|
|
/obj/structure/bigDelivery/attackby(obj/item/W as obj, mob/user as mob)
|
|
if(istype(W, /obj/item/device/destTagger))
|
|
var/obj/item/device/destTagger/O = W
|
|
|
|
if(sortTag != O.currTag)
|
|
var/tag = uppertext(TAGGERLOCATIONS[O.currTag])
|
|
user << "\blue *[tag]*"
|
|
sortTag = O.currTag
|
|
playsound(loc, 'sound/machines/twobeep.ogg', 100, 1)
|
|
|
|
else if(istype(W, /obj/item/weapon/pen))
|
|
var/str = copytext(sanitize(input(user,"Label text?","Set label","")),1,MAX_NAME_LEN)
|
|
if(!str || !length(str))
|
|
user << "<span class='notice'>Invalid text.</span>"
|
|
return
|
|
user.visible_message("<span class='notice'>[user] labels [src] as [str].</span>")
|
|
name = "[name] ([str])"
|
|
|
|
else if(istype(W, /obj/item/weapon/wrapping_paper))
|
|
user.visible_message("<span class='notice'>[user] wraps the package in festive paper!</span>")
|
|
if(istype(wrapped, /obj/structure/closet/crate))
|
|
icon_state = "giftcrate"
|
|
else
|
|
icon_state = "giftcloset"
|
|
|
|
|
|
/obj/item/smallDelivery
|
|
name = "small parcel"
|
|
desc = "A small wrapped package."
|
|
icon = 'icons/obj/storage.dmi'
|
|
icon_state = "deliverycrateSmall"
|
|
var/obj/item/wrapped = null
|
|
var/sortTag = 0
|
|
|
|
|
|
attack_self(mob/user as mob)
|
|
if(wrapped) //sometimes items can disappear. For example, bombs. --rastaf0
|
|
wrapped.loc = user.loc
|
|
if(ishuman(user))
|
|
user.put_in_hands(wrapped)
|
|
else
|
|
wrapped.loc = get_turf(src)
|
|
|
|
qdel(src)
|
|
|
|
|
|
attackby(obj/item/W as obj, mob/user as mob)
|
|
if(istype(W, /obj/item/device/destTagger))
|
|
var/obj/item/device/destTagger/O = W
|
|
|
|
if(sortTag != O.currTag)
|
|
var/tag = uppertext(TAGGERLOCATIONS[O.currTag])
|
|
user << "\blue *[tag]*"
|
|
sortTag = O.currTag
|
|
playsound(loc, 'sound/machines/twobeep.ogg', 100, 1)
|
|
|
|
else if(istype(W, /obj/item/weapon/pen))
|
|
var/str = copytext(sanitize(input(user,"Label text?","Set label","")),1,MAX_NAME_LEN)
|
|
if(!str || !length(str))
|
|
user << "<span class='notice'>Invalid text.</span>"
|
|
return
|
|
user.visible_message("<span class='notice'>[user] labels [src] as [str].</span>")
|
|
name = "[name] ([str])"
|
|
|
|
else if(istype(W, /obj/item/weapon/wrapping_paper))
|
|
icon_state = "giftcrate[wrapped.w_class]"
|
|
user.visible_message("<span class='notice'>[user] wraps the package in festive paper!</span>")
|
|
|
|
|
|
/obj/item/weapon/packageWrap
|
|
name = "package wrapper"
|
|
icon = 'icons/obj/items.dmi'
|
|
icon_state = "deliveryPaper"
|
|
flags = NOBLUDGEON
|
|
w_class = 3.0
|
|
var/amount = 25.0
|
|
|
|
|
|
afterattack(var/obj/target as obj, mob/user as mob, proximity)
|
|
if(!proximity) return
|
|
if(!istype(target)) //this really shouldn't be necessary (but it is). -Pete
|
|
return
|
|
if(istype(target, /obj/item/smallDelivery) || istype(target,/obj/structure/bigDelivery) \
|
|
|| istype(target, /obj/item/weapon/evidencebag) || istype(target, /obj/structure/closet/body_bag))
|
|
return
|
|
if(target.anchored)
|
|
return
|
|
if(target in user)
|
|
return
|
|
|
|
user.attack_log += text("\[[time_stamp()]\] <font color='blue'>Has used [name] on \ref[target]</font>")
|
|
|
|
if(istype(target, /obj/item) && !(istype(target, /obj/item/weapon/storage) && !istype(target,/obj/item/weapon/storage/box)))
|
|
var/obj/item/O = target
|
|
if(amount > 1)
|
|
var/obj/item/smallDelivery/P = new /obj/item/smallDelivery(get_turf(O.loc)) //Aaannd wrap it up!
|
|
if(!istype(O.loc, /turf))
|
|
if(user.client)
|
|
user.client.screen -= O
|
|
P.wrapped = O
|
|
O.loc = P
|
|
var/i = round(O.w_class)
|
|
if(i in list(1,2,3,4,5))
|
|
P.icon_state = "deliverycrate[i]"
|
|
P.w_class = i
|
|
P.add_fingerprint(usr)
|
|
O.add_fingerprint(usr)
|
|
add_fingerprint(usr)
|
|
amount -= 1
|
|
else if(istype(target, /obj/structure/closet/crate))
|
|
var/obj/structure/closet/crate/O = target
|
|
if(amount > 3 && !O.opened)
|
|
var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc))
|
|
P.icon_state = "deliverycrate"
|
|
P.wrapped = O
|
|
O.loc = P
|
|
amount -= 3
|
|
else if(amount < 3)
|
|
user << "<span class='notice'>You need more paper.</span>"
|
|
else if(istype (target, /obj/structure/closet))
|
|
var/obj/structure/closet/O = target
|
|
if(amount > 3 && !O.opened)
|
|
var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc))
|
|
P.wrapped = O
|
|
O.welded = 1
|
|
O.loc = P
|
|
amount -= 3
|
|
else if(amount < 3)
|
|
user << "<span class='notice'>You need more paper.</span>"
|
|
else
|
|
user << "<span class='notice'>The object you are trying to wrap is unsuitable for the sorting machinery.</span>"
|
|
if(amount <= 0)
|
|
new /obj/item/weapon/c_tube( loc )
|
|
qdel(src)
|
|
return
|
|
return
|
|
|
|
|
|
examine()
|
|
if(src in usr)
|
|
usr << "<span class='notice'>There are [amount] units of package wrap left.</span>"
|
|
..()
|
|
return
|
|
|
|
|
|
/obj/item/device/destTagger
|
|
name = "destination tagger"
|
|
desc = "Used to set the destination of properly wrapped packages."
|
|
icon_state = "forensic0"
|
|
var/currTag = 0
|
|
//The whole system for the sorttype var is determined based on the order of this list,
|
|
//disposals must always be 1, since anything that's untagged will automatically go to disposals, or sorttype = 1 --Superxpdude
|
|
|
|
//If you don't want to fuck up disposals, add to this list, and don't change the order.
|
|
//If you insist on changing the order, you'll have to change every sort junction to reflect the new order. --Pete
|
|
|
|
w_class = 1
|
|
item_state = "electronic"
|
|
flags = CONDUCT
|
|
slot_flags = SLOT_BELT
|
|
|
|
proc/openwindow(mob/user as mob)
|
|
var/dat = "<tt><center><h1><b>TagMaster 2.2</b></h1></center>"
|
|
|
|
dat += "<table style='width:100%; padding:4px;'><tr>"
|
|
for (var/i = 1, i <= TAGGERLOCATIONS.len, i++)
|
|
dat += "<td><a href='?src=\ref[src];nextTag=[i]'>[TAGGERLOCATIONS[i]]</a></td>"
|
|
|
|
if(i%4==0)
|
|
dat += "</tr><tr>"
|
|
|
|
dat += "</tr></table><br>Current Selection: [currTag ? TAGGERLOCATIONS[currTag] : "None"]</tt>"
|
|
|
|
user << browse(dat, "window=destTagScreen;size=450x350")
|
|
onclose(user, "destTagScreen")
|
|
|
|
attack_self(mob/user as mob)
|
|
openwindow(user)
|
|
return
|
|
|
|
Topic(href, href_list)
|
|
add_fingerprint(usr)
|
|
if(href_list["nextTag"])
|
|
var/n = text2num(href_list["nextTag"])
|
|
currTag = n
|
|
openwindow(usr)
|
|
|
|
/obj/machinery/disposal/deliveryChute
|
|
name = "delivery chute"
|
|
desc = "A chute for big and small packages alike!"
|
|
density = 1
|
|
icon_state = "intake"
|
|
|
|
var/start_flush = 0
|
|
var/c_mode = 0
|
|
|
|
/obj/machinery/disposal/deliveryChute/New()
|
|
..()
|
|
spawn(5)
|
|
trunk = locate() in loc
|
|
if(trunk)
|
|
trunk.linked = src // link the pipe trunk to self
|
|
|
|
/obj/machinery/disposal/deliveryChute/interact()
|
|
return
|
|
|
|
/obj/machinery/disposal/deliveryChute/update()
|
|
return
|
|
|
|
/obj/machinery/disposal/deliveryChute/Bumped(var/atom/movable/AM) //Go straight into the chute
|
|
if(istype(AM, /obj/item/projectile)) return
|
|
switch(dir)
|
|
if(NORTH)
|
|
if(AM.loc.y != loc.y+1) return
|
|
if(EAST)
|
|
if(AM.loc.x != loc.x+1) return
|
|
if(SOUTH)
|
|
if(AM.loc.y != loc.y-1) return
|
|
if(WEST)
|
|
if(AM.loc.x != loc.x-1) return
|
|
|
|
if(istype(AM, /obj))
|
|
var/obj/O = AM
|
|
O.loc = src
|
|
else if(istype(AM, /mob))
|
|
var/mob/M = AM
|
|
M.loc = src
|
|
flush()
|
|
|
|
/obj/machinery/disposal/deliveryChute/flush()
|
|
flushing = 1
|
|
flick("intake-closing", src)
|
|
var/deliveryCheck = 0
|
|
var/obj/structure/disposalholder/H = new() // virtual holder object which actually
|
|
// travels through the pipes.
|
|
/* for(var/obj/structure/bigDelivery/O in src)
|
|
deliveryCheck = 1
|
|
if(O.sortTag == 0) //This auto-sorts package wrapped objects to disposals
|
|
O.sortTag = 1 //Cargo techs can do this themselves with their taggers
|
|
for(var/obj/item/smallDelivery/O in src) //With this disabled packages will loop back round and come out the mail chute
|
|
deliveryCheck = 1
|
|
if(O.sortTag == 0)
|
|
O.sortTag = 1 */
|
|
if(deliveryCheck == 0)
|
|
H.destinationTag = 1
|
|
|
|
sleep(10)
|
|
if((start_flush + 15) < world.time)
|
|
start_flush = world.time
|
|
playsound(src, 'sound/machines/disposalflush.ogg', 50, 0, 0)
|
|
sleep(5) // wait for animation to finish
|
|
|
|
H.init(src) // copy the contents of disposer to holder
|
|
air_contents = new() // new empty gas resv.
|
|
|
|
H.start(src) // start the holder processing movement
|
|
flushing = 0
|
|
// now reset disposal state
|
|
flush = 0
|
|
if(mode == 2) // if was ready,
|
|
mode = 1 // switch to charging
|
|
update()
|
|
return
|
|
|
|
/obj/machinery/disposal/deliveryChute/attackby(var/obj/item/I, var/mob/user)
|
|
if(!I || !user)
|
|
return
|
|
|
|
if(istype(I, /obj/item/weapon/screwdriver))
|
|
if(c_mode==0)
|
|
c_mode=1
|
|
playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
|
user << "<span class='notice'>You remove the screws around the power connection.</span>"
|
|
return
|
|
else if(c_mode==1)
|
|
c_mode=0
|
|
playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
|
|
user << "<span class='notice'>You attach the screws around the power connection.</span>"
|
|
return
|
|
else if(istype(I,/obj/item/weapon/weldingtool) && c_mode==1)
|
|
var/obj/item/weapon/weldingtool/W = I
|
|
if(W.remove_fuel(0,user))
|
|
playsound(loc, 'sound/items/Welder2.ogg', 100, 1)
|
|
user << "<span class='notice'>You start slicing the floorweld off the delivery chute.</span>"
|
|
if(do_after(user,20))
|
|
if(!src || !W.isOn()) return
|
|
user << "<span class='notice'>You sliced the floorweld off the delivery chute.</span>"
|
|
var/obj/structure/disposalconstruct/C = new (loc)
|
|
C.ptype = 8 // 8 = Delivery chute
|
|
C.update()
|
|
C.anchored = 1
|
|
C.density = 1
|
|
qdel(src)
|
|
return
|
|
else
|
|
user << "<span class='notice'>You need more welding fuel to complete this task.</span>"
|
|
return
|
|
|
|
/obj/machinery/disposal/deliveryChute/process()
|
|
return PROCESS_KILL |