Files
Bubberstation/code/game/objects/objs.dm
Kyle Spier-Swenson 280dbe20c3 [Ready] SSthrowing + callbacks! (#22476)
* SSthrowing + callbacks!
Throwing is now a subsystem.
It's low priority, but is a ticker subsystem so is ran before most other subsystems.
To allow for shit to run after the throw finishes, throwing now supports a callback.
A callback datum system was created, conversion of addtimer is planned for another PR.
Throwing now has a limit of 2048 turfs (was 600)
Throwing now ticks every world.tick, and properly converts the speed arg from 1ds to what ever tick_lag is.
Throwing now properly accounts for missed ticks.
Throwing no longer uses sleep.
Throwing should no longer lag since it's not filling the sleep queue up

* Smoother tentacles

* Some improvements

* Missed a spot.

* Makes shit quicker.
Inlines the thrownthing.tick() proc.
Raises missed ticks value
Lowers max dist value
Inlines the two sister overrides for /atom/movable/Moved() because that just seemed like a waste

* >PRs open that use procs i'm removing.

* STOP THE PRESSES!

* throw_at now runs the first throw tick() immediately
This will help some with throwing while running.

* Item throwing now imparts the momentum of the user throwing.

(ie, running in the direction you are throwing makes you throw faster, running away from the direction you are throwing makes you throw the item slower)

* Moves throwing momentum from carbon/throw_item to movable/throw_at.
There are other things that cause a mob to "throw" an item, I figured we keep this universal since thrower is already an arg.

* Explosions throw shit faster.
This was stupid, "Hey, lets set the item's throw_speed to 4 so embedding works, but lets make it throw at the base 2 throw speed for no reason."

* Fixes explosion embedding.
This also acts as a nice example of how to override a callback in an override of throw_at properly.
2017-01-02 20:08:03 +11:00

228 lines
6.3 KiB
Plaintext

/obj
languages_spoken = HUMAN
languages_understood = HUMAN
var/crit_fail = 0
animate_movement = 2
var/throwforce = 0
var/in_use = 0 // If we have a user using us, this will be set on. We will check if the user has stopped using us, and thus stop updating and LAGGING EVERYTHING!
var/damtype = "brute"
var/force = 0
var/list/armor
var/obj_integrity = 500
var/max_integrity = 500
var/integrity_failure = 0 //0 if we have no special broken behavior
var/resistance_flags = 0 // INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ON_FIRE | UNACIDABLE | ACID_PROOF
var/acid_level = 0 //how much acid is on that obj
var/being_shocked = 0
var/on_blueprints = FALSE //Are we visible on the station blueprints at roundstart?
var/force_blueprints = FALSE //forces the obj to be on the blueprints, regardless of when it was created.
var/persistence_replacement = null //have something WAY too amazing to live to the next round? Set a new path here. Overuse of this var will make me upset.
var/is_frozen = FALSE
var/unique_rename = 0 // can you customize the description/name of the thing?
/obj/New()
..()
if (!armor)
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0)
if(on_blueprints && isturf(loc))
var/turf/T = loc
if(force_blueprints)
T.add_blueprints(src)
else
T.add_blueprints_preround(src)
/obj/Destroy()
if(!istype(src, /obj/machinery))
STOP_PROCESSING(SSobj, src) // TODO: Have a processing bitflag to reduce on unnecessary loops through the processing lists
SStgui.close_uis(src)
return ..()
/obj/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
..()
if(is_frozen)
visible_message("<span class = 'danger'><b>[src] shatters into a million pieces!</b></span>")
qdel(src)
/obj/assume_air(datum/gas_mixture/giver)
if(loc)
return loc.assume_air(giver)
else
return null
/obj/remove_air(amount)
if(loc)
return loc.remove_air(amount)
else
return null
/obj/return_air()
if(loc)
return loc.return_air()
else
return null
/obj/proc/rewrite(mob/user)
var/penchoice = alert("What would you like to edit?", "Rename or change description?", "Rename", "Change description", "Cancel")
if(!qdeleted(src) && user.canUseTopic(src, BE_CLOSE))
if(penchoice == "Rename")
rename_obj(user)
if(penchoice == "Change description")
redesc_obj(user)
/obj/proc/handle_internal_lifeform(mob/lifeform_inside_me, breath_request)
//Return: (NONSTANDARD)
// null if object handles breathing logic for lifeform
// datum/air_group to tell lifeform to process using that breath return
//DEFAULT: Take air from turf to give to have mob process
if(breath_request>0)
var/datum/gas_mixture/environment = return_air()
var/breath_percentage = BREATH_VOLUME / environment.return_volume()
return remove_air(environment.total_moles() * breath_percentage)
else
return null
/obj/proc/updateUsrDialog()
if(in_use)
var/is_in_use = 0
var/list/nearby = viewers(1, src)
for(var/mob/M in nearby)
if ((M.client && M.machine == src))
is_in_use = 1
src.attack_hand(M)
if(isAI(usr) || iscyborg(usr) || IsAdminGhost(usr))
if (!(usr in nearby))
if (usr.client && usr.machine==src) // && M.machine == src is omitted because if we triggered this by using the dialog, it doesn't matter if our machine changed in between triggering it and this - the dialog is probably still supposed to refresh.
is_in_use = 1
src.attack_ai(usr)
// check for TK users
if(ishuman(usr))
var/mob/living/carbon/human/H = usr
if(!(usr in nearby))
if(usr.client && usr.machine==src)
if(H.dna.check_mutation(TK))
is_in_use = 1
src.attack_hand(usr)
in_use = is_in_use
/obj/proc/updateDialog()
// Check that people are actually using the machine. If not, don't update anymore.
if(in_use)
var/list/nearby = viewers(1, src)
var/is_in_use = 0
for(var/mob/M in nearby)
if ((M.client && M.machine == src))
is_in_use = 1
src.interact(M)
var/ai_in_use = AutoUpdateAI(src)
if(!ai_in_use && !is_in_use)
in_use = 0
/obj/attack_ghost(mob/user)
if(ui_interact(user) != -1)
return
..()
/obj/proc/container_resist(mob/living/user)
return
/obj/proc/update_icon()
return
/mob/proc/unset_machine()
if(machine)
machine.on_unset_machine(src)
machine = null
//called when the user unsets the machine.
/atom/movable/proc/on_unset_machine(mob/user)
return
/mob/proc/set_machine(obj/O)
if(src.machine)
unset_machine()
src.machine = O
if(istype(O))
O.in_use = 1
/obj/item/proc/updateSelfDialog()
var/mob/M = src.loc
if(istype(M) && M.client && M.machine == src)
src.attack_self(M)
/obj/proc/hide(h)
return
//If a mob logouts/logins in side of an object you can use this proc
/obj/proc/on_log()
..()
if(isobj(loc))
var/obj/Loc=loc
Loc.on_log()
/obj/singularity_pull(S, current_size)
if(!anchored || current_size >= STAGE_FIVE)
step_towards(src,S)
/obj/get_spans()
return ..() | SPAN_ROBOT
/obj/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
var/turf/T = get_turf(src)
return T.storage_contents_dump_act(src_object, user)
/obj/proc/CanAStarPass()
. = !density
/obj/proc/check_uplink_validity()
return 1
/obj/proc/on_mob_move(dir, mob)
return
/obj/vv_get_dropdown()
. = ..()
.["Delete all of type"] = "?_src_=vars;delall=\ref[src]"
/obj/examine(mob/user)
..()
if(unique_rename)
user << "<span class='notice'>Use a pen on it to rename it or change its description.</span>"
/obj/proc/rename_obj(mob/M)
var/input = stripped_input(M,"What do you want to name \the [name]?", ,"", MAX_NAME_LEN)
var/oldname = name
if(!qdeleted(src) && M.canUseTopic(src, BE_CLOSE) && input != "")
if(oldname == input)
M << "You changed \the [name] to... well... \the [name]."
return
else
name = input
M << "\The [oldname] has been successfully been renamed to \the [input]."
return
else
return
/obj/proc/redesc_obj(mob/M)
var/input = stripped_input(M,"Describe \the [name] here", ,"", 100)
if(!qdeleted(src) && M.canUseTopic(src, BE_CLOSE) && input != "")
desc = input
M << "You have successfully changed \the [name]'s description."
return
else
return