mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-25 22:19:30 +01:00
516 Compile Compatibility (#88611)
Renames all uses of caller, as they (currently) shadow the new byond var and will in future error Ups our "wan if compiled after" experiement compile version to 516 Adds an alternate 516 unit test
This commit is contained in:
@@ -2,7 +2,11 @@
|
||||
# This is useful for making sure we maintain compatibility with both older and newer versions,
|
||||
# while still having our main tests run on a guaranteed pinned version.
|
||||
|
||||
# Format is version: map
|
||||
# Format is "version: map" or "version: map;max_required_client_version"
|
||||
# Example:
|
||||
# 500.1337: runtimestation
|
||||
# 516.1638: runtimestation;516
|
||||
# Lowest supported version
|
||||
515.1627: runtimestation
|
||||
# Beta version
|
||||
516.1648: runtimestation;516
|
||||
|
||||
@@ -183,7 +183,7 @@ jobs:
|
||||
- name: Find Alternate Tests
|
||||
id: alternate_test_finder
|
||||
run: |
|
||||
ALTERNATE_TESTS_JSON=$(jq -nRc '[inputs | capture("^(?<major>[0-9]+)\\.(?<minor>[0-9]+): (?<map>.+)$")]' .github/alternate_byond_versions.txt)
|
||||
ALTERNATE_TESTS_JSON=$(jq -nRc '[inputs | capture("^(?<major>[0-9]+)\\.(?<minor>[0-9]+): (?<map>[^;]+);?(?<max_client_version>[0-9]+)?$")]' .github/alternate_byond_versions.txt)
|
||||
echo "alternate_tests=$ALTERNATE_TESTS_JSON" >> $GITHUB_OUTPUT
|
||||
- name: Collect byond client version configuration
|
||||
id: max_required_byond_client
|
||||
@@ -219,7 +219,7 @@ jobs:
|
||||
map: ${{ matrix.setup.map }}
|
||||
major: ${{ matrix.setup.major }}
|
||||
minor: ${{ matrix.setup.minor }}
|
||||
max_required_byond_client: ${{needs.collect_data.outputs.max_required_byond_client}}
|
||||
max_required_byond_client: ${{ matrix.setup.max_client_version || needs.collect_data.outputs.max_required_byond_client }}
|
||||
|
||||
compare_screenshots:
|
||||
if: needs.collect_data.outputs.alternate_tests == '[]' || needs.run_alternate_tests.result == 'success'
|
||||
|
||||
@@ -264,8 +264,8 @@
|
||||
* Passed into CanAStarPass to provide context for a pathing attempt
|
||||
*
|
||||
* Also used to check if using a cached path_map is safe
|
||||
* There are some vars here that are unused. They exist to cover cases where caller_ref is used
|
||||
* They're the properties of caller_ref used in those cases.
|
||||
* There are some vars here that are unused. They exist to cover cases where requester_ref is used
|
||||
* They're the properties of requester_ref used in those cases.
|
||||
* It's kinda annoying, but there's some proc chains we can't convert to this datum
|
||||
*/
|
||||
/datum/can_pass_info
|
||||
@@ -314,7 +314,7 @@
|
||||
/// Weakref to the requester used to generate this info
|
||||
/// Should not use this almost ever, it's for context and to allow for proc chains that
|
||||
/// Require a movable
|
||||
var/datum/weakref/caller_ref = null
|
||||
var/datum/weakref/requester_ref = null
|
||||
|
||||
/datum/can_pass_info/New(atom/movable/construct_from, list/access, no_id = FALSE, call_depth = 0)
|
||||
// No infiniloops
|
||||
@@ -327,7 +327,7 @@
|
||||
if(isnull(construct_from))
|
||||
return
|
||||
|
||||
src.caller_ref = WEAKREF(construct_from)
|
||||
src.requester_ref = WEAKREF(construct_from)
|
||||
src.pass_flags = construct_from.pass_flags
|
||||
src.movement_type = construct_from.movement_type
|
||||
src.thrown = !!construct_from.throwing
|
||||
@@ -361,8 +361,8 @@ GLOBAL_LIST_INIT(can_pass_info_vars, GLOBAL_PROC_REF(can_pass_check_vars))
|
||||
var/datum/isaac = new()
|
||||
var/list/altar = assoc_to_keys(lamb.vars - isaac.vars)
|
||||
// Don't compare against calling atom, it's not relevant here
|
||||
altar -= "caller_ref"
|
||||
ASSERT("caller_ref" in lamb.vars, "caller_ref var was not found in /datum/can_pass_info, why are we filtering for it?")
|
||||
altar -= "requester_ref"
|
||||
ASSERT("requester_ref" in lamb.vars, "requester_ref var was not found in /datum/can_pass_info, why are we filtering for it?")
|
||||
// We will bespoke handle pulling_info
|
||||
altar -= "pulling_info"
|
||||
ASSERT("pulling_info" in lamb.vars, "pulling_info var was not found in /datum/can_pass_info, why are we filtering for it?")
|
||||
|
||||
@@ -17,6 +17,6 @@
|
||||
#define EXPERIMENT_MY_COOL_FEATURE
|
||||
#endif
|
||||
|
||||
#if DM_VERSION >= 516
|
||||
#error "Remove all 515 experiments"
|
||||
#if DM_VERSION >= 517
|
||||
#error "Remove all 516 experiments"
|
||||
#endif
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
return PreActivate(user)
|
||||
|
||||
/// Intercepts client owner clicks to activate the ability
|
||||
/datum/action/cooldown/proc/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
/datum/action/cooldown/proc/InterceptClickOn(mob/living/clicker, params, atom/target)
|
||||
if(!IsAvailable(feedback = TRUE))
|
||||
return FALSE
|
||||
if(!target)
|
||||
@@ -261,8 +261,8 @@
|
||||
|
||||
// And if we reach here, the action was complete successfully
|
||||
if(unset_after_click)
|
||||
unset_click_ability(caller, refund_cooldown = FALSE)
|
||||
caller.next_click = world.time + click_cd_override
|
||||
unset_click_ability(clicker, refund_cooldown = FALSE)
|
||||
clicker.next_click = world.time + click_cd_override
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -76,17 +76,17 @@
|
||||
on_who.click_intercept = null
|
||||
|
||||
/// Handles whenever a mob clicks on something
|
||||
/datum/action/innate/proc/InterceptClickOn(mob/living/caller, params, atom/clicked_on)
|
||||
/datum/action/innate/proc/InterceptClickOn(mob/living/clicker, params, atom/clicked_on)
|
||||
if(!IsAvailable(feedback = TRUE))
|
||||
unset_ranged_ability(caller)
|
||||
unset_ranged_ability(clicker)
|
||||
return FALSE
|
||||
if(!clicked_on)
|
||||
return FALSE
|
||||
|
||||
return do_ability(caller, clicked_on)
|
||||
return do_ability(clicker, clicked_on)
|
||||
|
||||
/// Actually goes through and does the click ability
|
||||
/datum/action/innate/proc/do_ability(mob/living/caller, atom/clicked_on)
|
||||
/datum/action/innate/proc/do_ability(mob/living/clicker, atom/clicked_on)
|
||||
return FALSE
|
||||
|
||||
/datum/action/innate/Remove(mob/removed_from)
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
try_activate_command(commander = speaker, radial_command = FALSE)
|
||||
|
||||
/// Respond to a callout
|
||||
/datum/pet_command/proc/respond_to_callout(mob/living/caller, datum/callout_option/callout, atom/target)
|
||||
/datum/pet_command/proc/respond_to_callout(mob/living/speaker, datum/callout_option/callout, atom/target)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if (isnull(callout_type) || !ispath(callout, callout_type))
|
||||
@@ -85,21 +85,21 @@
|
||||
if (!parent)
|
||||
return
|
||||
|
||||
if (!valid_callout_target(caller, callout, target))
|
||||
if (!valid_callout_target(speaker, callout, target))
|
||||
var/found_new_target = FALSE
|
||||
for (var/atom/new_target in range(2, target))
|
||||
if (valid_callout_target(caller, callout, new_target))
|
||||
if (valid_callout_target(speaker, callout, new_target))
|
||||
target = new_target
|
||||
found_new_target = TRUE
|
||||
|
||||
if (!found_new_target)
|
||||
return
|
||||
|
||||
if (try_activate_command(commander = caller, radial_command = FALSE))
|
||||
if (try_activate_command(commander = speaker, radial_command = FALSE))
|
||||
look_for_target(parent, target)
|
||||
|
||||
/// Does this callout with this target trigger this command?
|
||||
/datum/pet_command/proc/valid_callout_target(mob/living/caller, datum/callout_option/callout, atom/target)
|
||||
/datum/pet_command/proc/valid_callout_target(mob/living/speaker, datum/callout_option/callout, atom/target)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
|
||||
@@ -274,8 +274,8 @@
|
||||
. = ..()
|
||||
set_command_target(parent, victim)
|
||||
|
||||
/datum/pet_command/protect_owner/valid_callout_target(mob/living/caller, datum/callout_option/callout, atom/target)
|
||||
return target == caller || get_dist(caller, target) <= 1
|
||||
/datum/pet_command/protect_owner/valid_callout_target(mob/living/speaker, datum/callout_option/callout, atom/target)
|
||||
return target == speaker || get_dist(speaker, target) <= 1
|
||||
|
||||
/datum/pet_command/protect_owner/proc/set_attacking_target(atom/source, mob/living/attacker)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
@@ -337,7 +337,7 @@
|
||||
tile_covered = should_hide
|
||||
parent_obj.update_appearance()
|
||||
|
||||
/datum/component/plumbing/proc/change_ducting_layer(obj/caller, obj/changer, new_layer = DUCT_LAYER_DEFAULT)
|
||||
/datum/component/plumbing/proc/change_ducting_layer(obj/source, obj/changer, new_layer = DUCT_LAYER_DEFAULT)
|
||||
SIGNAL_HANDLER
|
||||
ducting_layer = new_layer
|
||||
|
||||
|
||||
@@ -22,5 +22,5 @@
|
||||
demand_connects = NORTH
|
||||
supply_connects = SOUTH
|
||||
|
||||
/datum/component/plumbing/manifold/change_ducting_layer(obj/caller, obj/changer, new_layer)
|
||||
/datum/component/plumbing/manifold/change_ducting_layer(obj/source, obj/changer, new_layer)
|
||||
return
|
||||
|
||||
@@ -35,10 +35,10 @@
|
||||
///calls from a head of staff autoconnect, if the receiving pad is not secure.
|
||||
var/head_call = FALSE
|
||||
|
||||
//creates a holocall made by `caller` from `calling_pad` to `callees`
|
||||
/datum/holocall/New(mob/living/caller, obj/machinery/holopad/calling_pad, list/callees, elevated_access = FALSE)
|
||||
//creates a holocall made by `call_source` from `calling_pad` to `callees`
|
||||
/datum/holocall/New(mob/living/call_source, obj/machinery/holopad/calling_pad, list/callees, elevated_access = FALSE)
|
||||
call_start_time = world.time
|
||||
user = caller
|
||||
user = call_source
|
||||
calling_pad.outgoing_call = src
|
||||
calling_holopad = calling_pad
|
||||
head_call = elevated_access
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
// We do this in InterceptClickOn() instead of Activate()
|
||||
// because we use the click parameters for aiming the projectile
|
||||
// (or something like that)
|
||||
/datum/action/cooldown/ink_spit/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
/datum/action/cooldown/ink_spit/InterceptClickOn(mob/living/clicker, params, atom/target)
|
||||
if(!LAZYACCESS(params2list(params), RIGHT_CLICK))
|
||||
return
|
||||
. = ..()
|
||||
@@ -45,16 +45,16 @@
|
||||
return
|
||||
|
||||
var/modifiers = params2list(params)
|
||||
caller.visible_message(
|
||||
span_danger("[caller] spits ink!"),
|
||||
clicker.visible_message(
|
||||
span_danger("[clicker] spits ink!"),
|
||||
span_bold("You spit ink."),
|
||||
)
|
||||
var/obj/projectile/ink_spit/ink = new /obj/projectile/ink_spit(caller.loc)
|
||||
ink.aim_projectile(target, caller, modifiers)
|
||||
ink.firer = caller
|
||||
var/obj/projectile/ink_spit/ink = new /obj/projectile/ink_spit(clicker.loc)
|
||||
ink.aim_projectile(target, clicker, modifiers)
|
||||
ink.firer = clicker
|
||||
ink.fire()
|
||||
playsound(caller, 'sound/items/weapons/pierce.ogg', 20, TRUE, -1)
|
||||
caller.newtonian_move(get_angle(target, caller))
|
||||
playsound(clicker, 'sound/items/weapons/pierce.ogg', 20, TRUE, -1)
|
||||
clicker.newtonian_move(get_angle(target, clicker))
|
||||
StartCooldown()
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -301,9 +301,9 @@ Possible to do for anyone motivated enough:
|
||||
for(var/I in holo_calls)
|
||||
var/datum/holocall/HC = I
|
||||
var/list/call_data = list(
|
||||
caller = HC.user,
|
||||
connected = HC.connected_holopad == src ? TRUE : FALSE,
|
||||
ref = REF(HC)
|
||||
"caller" = HC.user,
|
||||
"connected" = HC.connected_holopad == src ? TRUE : FALSE,
|
||||
"ref" = REF(HC)
|
||||
)
|
||||
data["holo_calls"] += list(call_data)
|
||||
return data
|
||||
|
||||
@@ -730,13 +730,13 @@ DEFINE_BITFIELD(turret_flags, list(
|
||||
remote_controller = null
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/porta_turret/proc/InterceptClickOn(mob/living/caller, params, atom/A)
|
||||
/obj/machinery/porta_turret/proc/InterceptClickOn(mob/living/clicker, params, atom/A)
|
||||
if(!manual_control)
|
||||
return FALSE
|
||||
if(!can_interact(caller))
|
||||
if(!can_interact(clicker))
|
||||
remove_control()
|
||||
return FALSE
|
||||
log_combat(caller,A,"fired with manual turret control at")
|
||||
log_combat(clicker, A, "fired with manual turret control at")
|
||||
target(A)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
return FALSE
|
||||
|
||||
/turf/open/openspace/CanAStarPass(to_dir, datum/can_pass_info/pass_info)
|
||||
var/atom/movable/our_movable = pass_info.caller_ref.resolve()
|
||||
var/atom/movable/our_movable = pass_info.requester_ref.resolve()
|
||||
if(our_movable && !our_movable.can_z_move(DOWN, src, null, ZMOVE_FALL_FLAGS)) //If we can't fall here (flying/lattice), it's fine to path through
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -735,16 +735,16 @@ GLOBAL_LIST_EMPTY(station_turfs)
|
||||
* Returns adjacent turfs to this turf that are reachable, in all cardinal directions
|
||||
*
|
||||
* Arguments:
|
||||
* * caller: The movable, if one exists, being used for mobility checks to see what tiles it can reach
|
||||
* * requester: The movable, if one exists, being used for mobility checks to see what tiles it can reach
|
||||
* * access: A list that decides if we can gain access to doors that would otherwise block a turf
|
||||
* * simulated_only: Do we only worry about turfs with simulated atmos, most notably things that aren't space?
|
||||
* * no_id: When true, doors with public access will count as impassible
|
||||
*/
|
||||
/turf/proc/reachableAdjacentTurfs(atom/movable/caller, list/access, simulated_only, no_id = FALSE)
|
||||
/turf/proc/reachableAdjacentTurfs(atom/movable/requester, list/access, simulated_only, no_id = FALSE)
|
||||
var/static/space_type_cache = typecacheof(/turf/open/space)
|
||||
. = list()
|
||||
|
||||
var/datum/can_pass_info/pass_info = new(caller, access, no_id)
|
||||
var/datum/can_pass_info/pass_info = new(requester, access, no_id)
|
||||
for(var/iter_dir in GLOB.cardinals)
|
||||
var/turf/turf_to_check = get_step(src,iter_dir)
|
||||
if(!turf_to_check || (simulated_only && space_type_cache[turf_to_check.type]))
|
||||
|
||||
@@ -243,12 +243,12 @@
|
||||
enable_text = span_cult("You prepare to horrify a target...")
|
||||
disable_text = span_cult("You dispel the magic...")
|
||||
|
||||
/datum/action/innate/cult/blood_spell/horror/InterceptClickOn(mob/living/caller, params, atom/clicked_on)
|
||||
var/turf/caller_turf = get_turf(caller)
|
||||
/datum/action/innate/cult/blood_spell/horror/InterceptClickOn(mob/living/clicker, params, atom/clicked_on)
|
||||
var/turf/caller_turf = get_turf(clicker)
|
||||
if(!isturf(caller_turf))
|
||||
return FALSE
|
||||
|
||||
if(!ishuman(clicked_on) || get_dist(caller, clicked_on) > 7)
|
||||
if(!ishuman(clicked_on) || get_dist(clicker, clicked_on) > 7)
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/human/human_clicked = clicked_on
|
||||
@@ -257,16 +257,16 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/cult/blood_spell/horror/do_ability(mob/living/caller, mob/living/carbon/human/clicked_on)
|
||||
/datum/action/innate/cult/blood_spell/horror/do_ability(mob/living/clicker, mob/living/carbon/human/clicked_on)
|
||||
|
||||
clicked_on.set_hallucinations_if_lower(240 SECONDS)
|
||||
SEND_SOUND(caller, sound('sound/effects/ghost.ogg', FALSE, TRUE, 50))
|
||||
SEND_SOUND(clicker, sound('sound/effects/ghost.ogg', FALSE, TRUE, 50))
|
||||
|
||||
var/image/sparkle_image = image('icons/effects/cult.dmi', clicked_on, "bloodsparkles", ABOVE_MOB_LAYER)
|
||||
clicked_on.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/has_antagonist/cult, "cult_apoc", sparkle_image, NONE)
|
||||
|
||||
addtimer(CALLBACK(clicked_on, TYPE_PROC_REF(/atom/, remove_alt_appearance), "cult_apoc", TRUE), 4 MINUTES, TIMER_OVERRIDE|TIMER_UNIQUE)
|
||||
to_chat(caller, span_cult_bold("[clicked_on] has been cursed with living nightmares!"))
|
||||
to_chat(clicker, span_cult_bold("[clicked_on] has been cursed with living nightmares!"))
|
||||
|
||||
charges--
|
||||
desc = base_desc
|
||||
@@ -274,7 +274,7 @@
|
||||
build_all_button_icons()
|
||||
SSblackbox.record_feedback("tally", "cult_spell_invoke", 1, "[name]")
|
||||
if(charges <= 0)
|
||||
to_chat(caller, span_cult("You have exhausted the spell's power!"))
|
||||
to_chat(clicker, span_cult("You have exhausted the spell's power!"))
|
||||
qdel(src)
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -293,18 +293,18 @@
|
||||
/datum/action/innate/cult/master/cultmark/IsAvailable(feedback = FALSE)
|
||||
return ..() && COOLDOWN_FINISHED(src, cult_mark_cooldown)
|
||||
|
||||
/datum/action/innate/cult/master/cultmark/InterceptClickOn(mob/caller, params, atom/clicked_on)
|
||||
var/turf/caller_turf = get_turf(caller)
|
||||
if(!isturf(caller_turf))
|
||||
/datum/action/innate/cult/master/cultmark/InterceptClickOn(mob/clicker, params, atom/clicked_on)
|
||||
var/turf/clicker_turf = get_turf(clicker)
|
||||
if(!isturf(clicker_turf))
|
||||
return FALSE
|
||||
|
||||
if(!(clicked_on in view(7, caller_turf)))
|
||||
if(!(clicked_on in view(7, clicker_turf)))
|
||||
return FALSE
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/cult/master/cultmark/do_ability(mob/living/caller, atom/clicked_on)
|
||||
var/datum/antagonist/cult/cultist = caller.mind.has_antag_datum(/datum/antagonist/cult, TRUE)
|
||||
/datum/action/innate/cult/master/cultmark/do_ability(mob/living/clicker, atom/clicked_on)
|
||||
var/datum/antagonist/cult/cultist = clicker.mind.has_antag_datum(/datum/antagonist/cult, TRUE)
|
||||
if(!cultist)
|
||||
CRASH("[type] was casted by someone without a cult antag datum.")
|
||||
|
||||
@@ -313,17 +313,17 @@
|
||||
CRASH("[type] was casted by a cultist without a cult team datum.")
|
||||
|
||||
if(cult_team.blood_target)
|
||||
to_chat(caller, span_cult("The cult has already designated a target!"))
|
||||
to_chat(clicker, span_cult("The cult has already designated a target!"))
|
||||
return FALSE
|
||||
|
||||
if(cult_team.set_blood_target(clicked_on, caller, cult_mark_duration))
|
||||
unset_ranged_ability(caller, span_cult("The marking rite is complete! It will last for [DisplayTimeText(cult_mark_duration)] seconds."))
|
||||
if(cult_team.set_blood_target(clicked_on, clicker, cult_mark_duration))
|
||||
unset_ranged_ability(clicker, span_cult("The marking rite is complete! It will last for [DisplayTimeText(cult_mark_duration)] seconds."))
|
||||
COOLDOWN_START(src, cult_mark_cooldown, cult_mark_cooldown_duration)
|
||||
build_all_button_icons()
|
||||
addtimer(CALLBACK(src, PROC_REF(build_all_button_icons)), cult_mark_cooldown_duration + 1)
|
||||
return TRUE
|
||||
|
||||
unset_ranged_ability(caller, span_cult("The marking rite failed!"))
|
||||
unset_ranged_ability(clicker, span_cult("The marking rite failed!"))
|
||||
return TRUE
|
||||
|
||||
/datum/action/innate/cult/ghostmark //Ghost version
|
||||
@@ -423,44 +423,44 @@
|
||||
/datum/action/innate/cult/master/pulse/IsAvailable(feedback = FALSE)
|
||||
return ..() && COOLDOWN_FINISHED(src, pulse_cooldown)
|
||||
|
||||
/datum/action/innate/cult/master/pulse/InterceptClickOn(mob/living/caller, params, atom/clicked_on)
|
||||
var/turf/caller_turf = get_turf(caller)
|
||||
if(!isturf(caller_turf))
|
||||
/datum/action/innate/cult/master/pulse/InterceptClickOn(mob/living/clicker, params, atom/clicked_on)
|
||||
var/turf/clicker_turf = get_turf(clicker)
|
||||
if(!isturf(clicker_turf))
|
||||
return FALSE
|
||||
|
||||
if(!(clicked_on in view(7, caller_turf)))
|
||||
if(!(clicked_on in view(7, clicker_turf)))
|
||||
return FALSE
|
||||
|
||||
if(clicked_on == caller)
|
||||
if(clicked_on == clicker)
|
||||
return FALSE
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/cult/master/pulse/do_ability(mob/living/caller, atom/clicked_on)
|
||||
/datum/action/innate/cult/master/pulse/do_ability(mob/living/clicker, atom/clicked_on)
|
||||
var/atom/throwee = throwee_ref?.resolve()
|
||||
|
||||
if(QDELETED(throwee))
|
||||
to_chat(caller, span_cult("You lost your target!"))
|
||||
to_chat(clicker, span_cult("You lost your target!"))
|
||||
throwee = null
|
||||
throwee_ref = null
|
||||
return FALSE
|
||||
|
||||
if(throwee)
|
||||
if(get_dist(throwee, clicked_on) >= 16)
|
||||
to_chat(caller, span_cult("You can't teleport [clicked_on.p_them()] that far!"))
|
||||
to_chat(clicker, span_cult("You can't teleport [clicked_on.p_them()] that far!"))
|
||||
return FALSE
|
||||
|
||||
var/turf/throwee_turf = get_turf(throwee)
|
||||
|
||||
playsound(throwee_turf, 'sound/effects/magic/exit_blood.ogg')
|
||||
new /obj/effect/temp_visual/cult/sparks(throwee_turf, caller.dir)
|
||||
new /obj/effect/temp_visual/cult/sparks(throwee_turf, clicker.dir)
|
||||
throwee.visible_message(
|
||||
span_warning("A pulse of magic whisks [throwee] away!"),
|
||||
span_cult("A pulse of blood magic whisks you away..."),
|
||||
)
|
||||
|
||||
if(!do_teleport(throwee, clicked_on, channel = TELEPORT_CHANNEL_CULT))
|
||||
to_chat(caller, span_cult("The teleport fails!"))
|
||||
to_chat(clicker, span_cult("The teleport fails!"))
|
||||
throwee.visible_message(
|
||||
span_warning("...Except they don't go very far"),
|
||||
span_cult("...Except you don't appear to have moved very far."),
|
||||
@@ -468,15 +468,15 @@
|
||||
return FALSE
|
||||
|
||||
throwee_turf.Beam(clicked_on, icon_state = "sendbeam", time = 0.4 SECONDS)
|
||||
new /obj/effect/temp_visual/cult/sparks(get_turf(clicked_on), caller.dir)
|
||||
new /obj/effect/temp_visual/cult/sparks(get_turf(clicked_on), clicker.dir)
|
||||
throwee.visible_message(
|
||||
span_warning("[throwee] appears suddenly in a pulse of magic!"),
|
||||
span_cult("...And you appear elsewhere."),
|
||||
)
|
||||
|
||||
COOLDOWN_START(src, pulse_cooldown, pulse_cooldown_duration)
|
||||
to_chat(caller, span_cult("A pulse of blood magic surges through you as you shift [throwee] through time and space."))
|
||||
caller.click_intercept = null
|
||||
to_chat(clicker, span_cult("A pulse of blood magic surges through you as you shift [throwee] through time and space."))
|
||||
clicker.click_intercept = null
|
||||
throwee_ref = null
|
||||
build_all_button_icons()
|
||||
addtimer(CALLBACK(src, PROC_REF(build_all_button_icons)), pulse_cooldown_duration + 1)
|
||||
@@ -488,13 +488,13 @@
|
||||
var/mob/living/living_clicked = clicked_on
|
||||
if(!IS_CULTIST(living_clicked))
|
||||
return FALSE
|
||||
SEND_SOUND(caller, sound('sound/items/weapons/thudswoosh.ogg'))
|
||||
to_chat(caller, span_cult_bold("You reach through the veil with your mind's eye and seize [clicked_on]! <b>Click anywhere nearby to teleport [clicked_on.p_them()]!</b>"))
|
||||
SEND_SOUND(clicker, sound('sound/items/weapons/thudswoosh.ogg'))
|
||||
to_chat(clicker, span_cult_bold("You reach through the veil with your mind's eye and seize [clicked_on]! <b>Click anywhere nearby to teleport [clicked_on.p_them()]!</b>"))
|
||||
throwee_ref = WEAKREF(clicked_on)
|
||||
return TRUE
|
||||
|
||||
if(istype(clicked_on, /obj/structure/destructible/cult))
|
||||
to_chat(caller, span_cult_bold("You reach through the veil with your mind's eye and lift [clicked_on]! <b>Click anywhere nearby to teleport it!</b>"))
|
||||
to_chat(clicker, span_cult_bold("You reach through the veil with your mind's eye and lift [clicked_on]! <b>Click anywhere nearby to teleport it!</b>"))
|
||||
throwee_ref = WEAKREF(clicked_on)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -45,12 +45,12 @@
|
||||
|
||||
unset_click_ability(source, refund_cooldown = TRUE)
|
||||
|
||||
/datum/action/cooldown/spell/pointed/projectile/furious_steel/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
/datum/action/cooldown/spell/pointed/projectile/furious_steel/InterceptClickOn(mob/living/clicker, params, atom/target)
|
||||
// Let the caster prioritize using items like guns over blade casts
|
||||
if(caller.get_active_held_item())
|
||||
if(clicker.get_active_held_item())
|
||||
return FALSE
|
||||
// Let the caster prioritize melee attacks like punches and shoves over blade casts
|
||||
if(get_dist(caller, target) <= 1)
|
||||
if(get_dist(clicker, target) <= 1)
|
||||
return FALSE
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
/**
|
||||
* Overrides 'aim assist' because we always want to hit just the turf we clicked on.
|
||||
*/
|
||||
/datum/action/cooldown/spell/pointed/rust_construction/aim_assist(mob/living/caller, atom/target)
|
||||
/datum/action/cooldown/spell/pointed/rust_construction/aim_assist(mob/living/clicker, atom/target)
|
||||
return get_turf(target)
|
||||
|
||||
/datum/action/cooldown/spell/pointed/rust_construction/is_valid_target(atom/cast_on)
|
||||
|
||||
@@ -445,12 +445,12 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf))
|
||||
. = ..()
|
||||
desc = "[desc] It has [uses] use\s remaining."
|
||||
|
||||
/datum/action/innate/ai/ranged/override_machine/do_ability(mob/living/caller, atom/clicked_on)
|
||||
if(caller.incapacitated)
|
||||
unset_ranged_ability(caller)
|
||||
/datum/action/innate/ai/ranged/override_machine/do_ability(mob/living/clicker, atom/clicked_on)
|
||||
if(clicker.incapacitated)
|
||||
unset_ranged_ability(clicker)
|
||||
return FALSE
|
||||
if(!ismachinery(clicked_on))
|
||||
to_chat(caller, span_warning("You can only animate machines!"))
|
||||
to_chat(clicker, span_warning("You can only animate machines!"))
|
||||
return FALSE
|
||||
var/obj/machinery/clicked_machine = clicked_on
|
||||
|
||||
@@ -459,14 +459,14 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf))
|
||||
clicked_machine = clicked_turret.parent_turret
|
||||
|
||||
if((clicked_machine.resistance_flags & INDESTRUCTIBLE) || is_type_in_typecache(clicked_machine, GLOB.blacklisted_malf_machines))
|
||||
to_chat(caller, span_warning("That machine can't be overridden!"))
|
||||
to_chat(clicker, span_warning("That machine can't be overridden!"))
|
||||
return FALSE
|
||||
|
||||
caller.playsound_local(caller, 'sound/misc/interference.ogg', 50, FALSE, use_reverb = FALSE)
|
||||
clicker.playsound_local(clicker, 'sound/misc/interference.ogg', 50, FALSE, use_reverb = FALSE)
|
||||
|
||||
clicked_machine.audible_message(span_userdanger("You hear a loud electrical buzzing sound coming from [clicked_machine]!"))
|
||||
addtimer(CALLBACK(src, PROC_REF(animate_machine), caller, clicked_machine), 5 SECONDS) //kabeep!
|
||||
unset_ranged_ability(caller, span_danger("Sending override signal..."))
|
||||
addtimer(CALLBACK(src, PROC_REF(animate_machine), clicker, clicked_machine), 5 SECONDS) //kabeep!
|
||||
unset_ranged_ability(clicker, span_danger("Sending override signal..."))
|
||||
adjust_uses(-1) //adjust after we unset the active ability since we may run out of charges, thus deleting the ability
|
||||
|
||||
if(uses)
|
||||
@@ -474,11 +474,11 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf))
|
||||
build_all_button_icons()
|
||||
return TRUE
|
||||
|
||||
/datum/action/innate/ai/ranged/override_machine/proc/animate_machine(mob/living/caller, obj/machinery/to_animate)
|
||||
/datum/action/innate/ai/ranged/override_machine/proc/animate_machine(mob/living/clicker, obj/machinery/to_animate)
|
||||
if(QDELETED(to_animate))
|
||||
return
|
||||
|
||||
new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(to_animate), to_animate, caller, TRUE)
|
||||
new /mob/living/simple_animal/hostile/mimic/copy/machine(get_turf(to_animate), to_animate, clicker, TRUE)
|
||||
|
||||
/// Destroy RCDs: Detonates all non-cyborg RCDs on the station.
|
||||
/datum/ai_module/malf/destructive/destroy_rcd
|
||||
@@ -527,23 +527,23 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf))
|
||||
..()
|
||||
desc = "[desc] It has [uses] use\s remaining."
|
||||
|
||||
/datum/action/innate/ai/ranged/overload_machine/proc/detonate_machine(mob/living/caller, obj/machinery/to_explode)
|
||||
/datum/action/innate/ai/ranged/overload_machine/proc/detonate_machine(mob/living/clicker, obj/machinery/to_explode)
|
||||
if(QDELETED(to_explode))
|
||||
return
|
||||
|
||||
var/turf/machine_turf = get_turf(to_explode)
|
||||
message_admins("[ADMIN_LOOKUPFLW(caller)] overloaded [to_explode.name] ([to_explode.type]) at [ADMIN_VERBOSEJMP(machine_turf)].")
|
||||
caller.log_message("overloaded [to_explode.name] ([to_explode.type])", LOG_ATTACK)
|
||||
message_admins("[ADMIN_LOOKUPFLW(clicker)] overloaded [to_explode.name] ([to_explode.type]) at [ADMIN_VERBOSEJMP(machine_turf)].")
|
||||
clicker.log_message("overloaded [to_explode.name] ([to_explode.type])", LOG_ATTACK)
|
||||
explosion(to_explode, heavy_impact_range = 2, light_impact_range = 3)
|
||||
if(!QDELETED(to_explode)) //to check if the explosion killed it before we try to delete it
|
||||
qdel(to_explode)
|
||||
|
||||
/datum/action/innate/ai/ranged/overload_machine/do_ability(mob/living/caller, atom/clicked_on)
|
||||
if(caller.incapacitated)
|
||||
unset_ranged_ability(caller)
|
||||
/datum/action/innate/ai/ranged/overload_machine/do_ability(mob/living/clicker, atom/clicked_on)
|
||||
if(clicker.incapacitated)
|
||||
unset_ranged_ability(clicker)
|
||||
return FALSE
|
||||
if(!ismachinery(clicked_on))
|
||||
to_chat(caller, span_warning("You can only overload machines!"))
|
||||
to_chat(clicker, span_warning("You can only overload machines!"))
|
||||
return FALSE
|
||||
var/obj/machinery/clicked_machine = clicked_on
|
||||
|
||||
@@ -552,18 +552,18 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf))
|
||||
clicked_machine = clicked_turret.parent_turret
|
||||
|
||||
if((clicked_machine.resistance_flags & INDESTRUCTIBLE) || is_type_in_typecache(clicked_machine, GLOB.blacklisted_malf_machines))
|
||||
to_chat(caller, span_warning("You cannot overload that device!"))
|
||||
to_chat(clicker, span_warning("You cannot overload that device!"))
|
||||
return FALSE
|
||||
|
||||
caller.playsound_local(caller, SFX_SPARKS, 50, 0)
|
||||
clicker.playsound_local(clicker, SFX_SPARKS, 50, 0)
|
||||
adjust_uses(-1)
|
||||
if(uses)
|
||||
desc = "[initial(desc)] It has [uses] use\s remaining."
|
||||
build_all_button_icons()
|
||||
|
||||
clicked_machine.audible_message(span_userdanger("You hear a loud electrical buzzing sound coming from [clicked_machine]!"))
|
||||
addtimer(CALLBACK(src, PROC_REF(detonate_machine), caller, clicked_machine), 5 SECONDS) //kaboom!
|
||||
unset_ranged_ability(caller, span_danger("Overcharging machine..."))
|
||||
addtimer(CALLBACK(src, PROC_REF(detonate_machine), clicker, clicked_machine), 5 SECONDS) //kaboom!
|
||||
unset_ranged_ability(clicker, span_danger("Overcharging machine..."))
|
||||
return TRUE
|
||||
|
||||
/// Blackout: Overloads a random number of lights across the station. Three uses.
|
||||
@@ -1079,7 +1079,7 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf))
|
||||
. = ..()
|
||||
desc = "[desc] It has [uses] use\s remaining."
|
||||
|
||||
/datum/action/innate/ai/ranged/emag/do_ability(mob/living/caller, atom/clicked_on)
|
||||
/datum/action/innate/ai/ranged/emag/do_ability(mob/living/clicker, atom/clicked_on)
|
||||
|
||||
// Only things with of or subtyped of any of these types may be remotely emagged
|
||||
var/static/list/compatable_typepaths = list(
|
||||
@@ -1091,59 +1091,59 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf))
|
||||
/mob/living/silicon,
|
||||
)
|
||||
|
||||
if (!isAI(caller))
|
||||
if (!isAI(clicker))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/silicon/ai/ai_caller = caller
|
||||
var/mob/living/silicon/ai/ai_clicker = clicker
|
||||
|
||||
if(ai_caller.incapacitated)
|
||||
unset_ranged_ability(caller)
|
||||
if(ai_clicker.incapacitated)
|
||||
unset_ranged_ability(clicker)
|
||||
return FALSE
|
||||
|
||||
if (!ai_caller.can_see(clicked_on))
|
||||
clicked_on.balloon_alert(ai_caller, "can't see!")
|
||||
if (!ai_clicker.can_see(clicked_on))
|
||||
clicked_on.balloon_alert(ai_clicker, "can't see!")
|
||||
return FALSE
|
||||
|
||||
if (ismachinery(clicked_on))
|
||||
var/obj/machinery/clicked_machine = clicked_on
|
||||
if (!clicked_machine.is_operational)
|
||||
clicked_machine.balloon_alert(ai_caller, "not operational!")
|
||||
clicked_machine.balloon_alert(ai_clicker, "not operational!")
|
||||
return FALSE
|
||||
|
||||
if (!(is_type_in_list(clicked_on, compatable_typepaths)))
|
||||
clicked_on.balloon_alert(ai_caller, "incompatable!")
|
||||
clicked_on.balloon_alert(ai_clicker, "incompatable!")
|
||||
return FALSE
|
||||
|
||||
if (istype(clicked_on, /obj/machinery/door/airlock)) // I HATE THIS CODE SO MUCHHH
|
||||
var/obj/machinery/door/airlock/clicked_airlock = clicked_on
|
||||
if (!clicked_airlock.canAIControl(ai_caller))
|
||||
clicked_airlock.balloon_alert(ai_caller, "unable to interface!")
|
||||
if (!clicked_airlock.canAIControl(ai_clicker))
|
||||
clicked_airlock.balloon_alert(ai_clicker, "unable to interface!")
|
||||
return FALSE
|
||||
|
||||
if (istype(clicked_on, /obj/machinery/airalarm))
|
||||
var/obj/machinery/airalarm/alarm = clicked_on
|
||||
if (alarm.aidisabled)
|
||||
alarm.balloon_alert(ai_caller, "unable to interface!")
|
||||
alarm.balloon_alert(ai_clicker, "unable to interface!")
|
||||
return FALSE
|
||||
|
||||
if (istype(clicked_on, /obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/clicked_apc = clicked_on
|
||||
if (clicked_apc.aidisabled)
|
||||
clicked_apc.balloon_alert(ai_caller, "unable to interface!")
|
||||
clicked_apc.balloon_alert(ai_clicker, "unable to interface!")
|
||||
return FALSE
|
||||
|
||||
if (!clicked_on.emag_act(ai_caller))
|
||||
to_chat(ai_caller, span_warning("Hostile software insertion failed!")) // lets not overlap balloon alerts
|
||||
if (!clicked_on.emag_act(ai_clicker))
|
||||
to_chat(ai_clicker, span_warning("Hostile software insertion failed!")) // lets not overlap balloon alerts
|
||||
return FALSE
|
||||
|
||||
to_chat(ai_caller, span_notice("Software package successfully injected."))
|
||||
to_chat(ai_clicker, span_notice("Software package successfully injected."))
|
||||
|
||||
adjust_uses(-1)
|
||||
if(uses)
|
||||
desc = "[initial(desc)] It has [uses] use\s remaining."
|
||||
build_all_button_icons()
|
||||
else
|
||||
unset_ranged_ability(ai_caller, span_warning("Out of uses!"))
|
||||
unset_ranged_ability(ai_clicker, span_warning("Out of uses!"))
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -1176,35 +1176,35 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf))
|
||||
. = ..()
|
||||
desc = "[desc] It has [uses] use\s remaining."
|
||||
|
||||
/datum/action/innate/ai/ranged/core_tilt/do_ability(mob/living/caller, atom/clicked_on)
|
||||
/datum/action/innate/ai/ranged/core_tilt/do_ability(mob/living/clicker, atom/clicked_on)
|
||||
|
||||
if (!COOLDOWN_FINISHED(src, time_til_next_tilt))
|
||||
caller.balloon_alert(caller, "on cooldown!")
|
||||
clicker.balloon_alert(clicker, "on cooldown!")
|
||||
return FALSE
|
||||
|
||||
if (!isAI(caller))
|
||||
if (!isAI(clicker))
|
||||
return FALSE
|
||||
var/mob/living/silicon/ai/ai_caller = caller
|
||||
var/mob/living/silicon/ai/ai_clicker = clicker
|
||||
|
||||
if (ai_caller.incapacitated || !isturf(ai_caller.loc))
|
||||
if (ai_clicker.incapacitated || !isturf(ai_clicker.loc))
|
||||
return FALSE
|
||||
|
||||
var/turf/target = get_turf(clicked_on)
|
||||
if (isnull(target))
|
||||
return FALSE
|
||||
|
||||
if (target == ai_caller.loc)
|
||||
target.balloon_alert(ai_caller, "can't roll on yourself!")
|
||||
if (target == ai_clicker.loc)
|
||||
target.balloon_alert(ai_clicker, "can't roll on yourself!")
|
||||
return FALSE
|
||||
|
||||
var/picked_dir = get_dir(ai_caller, target)
|
||||
var/picked_dir = get_dir(ai_clicker, target)
|
||||
if (!picked_dir)
|
||||
return FALSE
|
||||
var/turf/temp_target = get_step(ai_caller, picked_dir) // we can move during the timer so we cant just pass the ref
|
||||
var/turf/temp_target = get_step(ai_clicker, picked_dir) // we can move during the timer so we cant just pass the ref
|
||||
|
||||
new /obj/effect/temp_visual/telegraphing/vending_machine_tilt(temp_target, roll_over_time)
|
||||
ai_caller.balloon_alert_to_viewers("rolling...")
|
||||
addtimer(CALLBACK(src, PROC_REF(do_roll_over), ai_caller, picked_dir), roll_over_time)
|
||||
ai_clicker.balloon_alert_to_viewers("rolling...")
|
||||
addtimer(CALLBACK(src, PROC_REF(do_roll_over), ai_clicker, picked_dir), roll_over_time)
|
||||
|
||||
adjust_uses(-1)
|
||||
if(uses)
|
||||
@@ -1213,22 +1213,22 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf))
|
||||
|
||||
COOLDOWN_START(src, time_til_next_tilt, roll_over_cooldown)
|
||||
|
||||
/datum/action/innate/ai/ranged/core_tilt/proc/do_roll_over(mob/living/silicon/ai/ai_caller, picked_dir)
|
||||
if (ai_caller.incapacitated || !isturf(ai_caller.loc)) // prevents bugs where the ai is carded and rolls
|
||||
/datum/action/innate/ai/ranged/core_tilt/proc/do_roll_over(mob/living/silicon/ai/ai_clicker, picked_dir)
|
||||
if (ai_clicker.incapacitated || !isturf(ai_clicker.loc)) // prevents bugs where the ai is carded and rolls
|
||||
return
|
||||
|
||||
var/turf/target = get_step(ai_caller, picked_dir) // in case we moved we pass the dir not the target turf
|
||||
var/turf/target = get_step(ai_clicker, picked_dir) // in case we moved we pass the dir not the target turf
|
||||
|
||||
if (isnull(target))
|
||||
return
|
||||
|
||||
var/paralyze_time = clamp(6 SECONDS, 0 SECONDS, (roll_over_cooldown * 0.9)) //the clamp prevents stunlocking as the max is always a little less than the cooldown between rolls
|
||||
|
||||
return ai_caller.fall_and_crush(target, MALF_AI_ROLL_DAMAGE, MALF_AI_ROLL_CRIT_CHANCE, null, paralyze_time, picked_dir, rotation = get_rotation_from_dir(picked_dir))
|
||||
return ai_clicker.fall_and_crush(target, MALF_AI_ROLL_DAMAGE, MALF_AI_ROLL_CRIT_CHANCE, null, paralyze_time, picked_dir, rotation = get_rotation_from_dir(picked_dir))
|
||||
|
||||
/// Used in our radial menu, state-checking proc after the radial menu sleeps
|
||||
/datum/action/innate/ai/ranged/core_tilt/proc/radial_check(mob/living/silicon/ai/caller)
|
||||
if (QDELETED(caller) || caller.incapacitated || caller.stat == DEAD)
|
||||
/datum/action/innate/ai/ranged/core_tilt/proc/radial_check(mob/living/silicon/ai/clicker)
|
||||
if (QDELETED(clicker) || clicker.incapacitated || clicker.stat == DEAD)
|
||||
return FALSE
|
||||
|
||||
if (uses <= 0)
|
||||
@@ -1269,42 +1269,42 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf))
|
||||
. = ..()
|
||||
desc = "[desc] It has [uses] use\s remaining."
|
||||
|
||||
/datum/action/innate/ai/ranged/remote_vendor_tilt/do_ability(mob/living/caller, atom/clicked_on)
|
||||
/datum/action/innate/ai/ranged/remote_vendor_tilt/do_ability(mob/living/clicker, atom/clicked_on)
|
||||
|
||||
if (!isAI(caller))
|
||||
if (!isAI(clicker))
|
||||
return FALSE
|
||||
var/mob/living/silicon/ai/ai_caller = caller
|
||||
var/mob/living/silicon/ai/ai_clicker = clicker
|
||||
|
||||
if(ai_caller.incapacitated)
|
||||
unset_ranged_ability(caller)
|
||||
if(ai_clicker.incapacitated)
|
||||
unset_ranged_ability(clicker)
|
||||
return FALSE
|
||||
|
||||
if(!isvendor(clicked_on))
|
||||
clicked_on.balloon_alert(ai_caller, "not a vendor!")
|
||||
clicked_on.balloon_alert(ai_clicker, "not a vendor!")
|
||||
return FALSE
|
||||
|
||||
var/obj/machinery/vending/clicked_vendor = clicked_on
|
||||
|
||||
if (clicked_vendor.tilted)
|
||||
clicked_vendor.balloon_alert(ai_caller, "already tilted!")
|
||||
clicked_vendor.balloon_alert(ai_clicker, "already tilted!")
|
||||
return FALSE
|
||||
|
||||
if (!clicked_vendor.tiltable)
|
||||
clicked_vendor.balloon_alert(ai_caller, "cannot be tilted!")
|
||||
clicked_vendor.balloon_alert(ai_clicker, "cannot be tilted!")
|
||||
return FALSE
|
||||
|
||||
if (!clicked_vendor.is_operational)
|
||||
clicked_vendor.balloon_alert(ai_caller, "inoperable!")
|
||||
clicked_vendor.balloon_alert(ai_clicker, "inoperable!")
|
||||
return FALSE
|
||||
|
||||
var/picked_dir_string = show_radial_menu(ai_caller, clicked_vendor, GLOB.all_radial_directions, custom_check = CALLBACK(src, PROC_REF(radial_check), caller, clicked_vendor))
|
||||
var/picked_dir_string = show_radial_menu(ai_clicker, clicked_vendor, GLOB.all_radial_directions, custom_check = CALLBACK(src, PROC_REF(radial_check), clicker, clicked_vendor))
|
||||
if (isnull(picked_dir_string))
|
||||
return FALSE
|
||||
var/picked_dir = text2dir(picked_dir_string)
|
||||
|
||||
var/turf/target = get_step(clicked_vendor, picked_dir)
|
||||
if (!ai_caller.can_see(target))
|
||||
to_chat(ai_caller, span_warning("You can't see the target tile!"))
|
||||
if (!ai_clicker.can_see(target))
|
||||
to_chat(ai_clicker, span_warning("You can't see the target tile!"))
|
||||
return FALSE
|
||||
|
||||
new /obj/effect/temp_visual/telegraphing/vending_machine_tilt(target, time_to_tilt)
|
||||
@@ -1317,7 +1317,7 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf))
|
||||
desc = "[initial(desc)] It has [uses] use\s remaining."
|
||||
build_all_button_icons()
|
||||
|
||||
unset_ranged_ability(caller, span_danger("Tilting..."))
|
||||
unset_ranged_ability(clicker, span_danger("Tilting..."))
|
||||
return TRUE
|
||||
|
||||
/datum/action/innate/ai/ranged/remote_vendor_tilt/proc/do_vendor_tilt(obj/machinery/vending/vendor, turf/target)
|
||||
@@ -1330,8 +1330,8 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf))
|
||||
vendor.tilt(target, MALF_VENDOR_TIPPING_CRIT_CHANCE)
|
||||
|
||||
/// Used in our radial menu, state-checking proc after the radial menu sleeps
|
||||
/datum/action/innate/ai/ranged/remote_vendor_tilt/proc/radial_check(mob/living/silicon/ai/caller, obj/machinery/vending/clicked_vendor)
|
||||
if (QDELETED(caller) || caller.incapacitated || caller.stat == DEAD)
|
||||
/datum/action/innate/ai/ranged/remote_vendor_tilt/proc/radial_check(mob/living/silicon/ai/clicker, obj/machinery/vending/clicked_vendor)
|
||||
if (QDELETED(clicker) || clicker.incapacitated || clicker.stat == DEAD)
|
||||
return FALSE
|
||||
|
||||
if (QDELETED(clicked_vendor))
|
||||
@@ -1340,8 +1340,8 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module/malf))
|
||||
if (uses <= 0)
|
||||
return FALSE
|
||||
|
||||
if (!caller.can_see(clicked_vendor))
|
||||
to_chat(caller, span_warning("Lost sight of [clicked_vendor]!"))
|
||||
if (!clicker.can_see(clicked_vendor))
|
||||
to_chat(clicker, span_warning("Lost sight of [clicked_vendor]!"))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -14,33 +14,33 @@
|
||||
disable_text = span_cult("You decide it was a bad call...")
|
||||
COOLDOWN_DECLARE(whistle_cooldown_minigame)
|
||||
|
||||
/datum/action/innate/timeout/InterceptClickOn(mob/living/caller, params, atom/clicked_on)
|
||||
var/turf/caller_turf = get_turf(caller)
|
||||
if(!isturf(caller_turf))
|
||||
/datum/action/innate/timeout/InterceptClickOn(mob/living/clicker, params, atom/clicked_on)
|
||||
var/turf/clicker_turf = get_turf(clicker)
|
||||
if(!isturf(clicker_turf))
|
||||
return FALSE
|
||||
|
||||
if(!ishuman(clicked_on) || get_dist(caller, clicked_on) > 7)
|
||||
if(!ishuman(clicked_on) || get_dist(clicker, clicked_on) > 7)
|
||||
return FALSE
|
||||
|
||||
if(clicked_on == caller) // can't call a foul on yourself
|
||||
if(clicked_on == clicker) // can't call a foul on yourself
|
||||
return FALSE
|
||||
|
||||
if(!COOLDOWN_FINISHED(src, whistle_cooldown_minigame))
|
||||
caller.balloon_alert(caller, "cant cast for [COOLDOWN_TIMELEFT(src, whistle_cooldown_minigame) *0.1] seconds!")
|
||||
unset_ranged_ability(caller)
|
||||
clicker.balloon_alert(clicker, "cant cast for [COOLDOWN_TIMELEFT(src, whistle_cooldown_minigame) *0.1] seconds!")
|
||||
unset_ranged_ability(clicker)
|
||||
return FALSE
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/timeout/do_ability(mob/living/caller, mob/living/carbon/human/target)
|
||||
caller.say("FOUL BY [target]!", forced = "whistle")
|
||||
playsound(caller, 'sound/items/whistle/whistle.ogg', 30, FALSE, 4)
|
||||
/datum/action/innate/timeout/do_ability(mob/living/clicker, mob/living/carbon/human/target)
|
||||
clicker.say("FOUL BY [target]!", forced = "whistle")
|
||||
playsound(clicker, 'sound/items/whistle/whistle.ogg', 30, FALSE, 4)
|
||||
|
||||
new /obj/effect/timestop(get_turf(target), 0, 5 SECONDS, list(caller), TRUE, TRUE)
|
||||
new /obj/effect/timestop(get_turf(target), 0, 5 SECONDS, list(clicker), TRUE, TRUE)
|
||||
|
||||
COOLDOWN_START(src, whistle_cooldown_minigame, 1 MINUTES)
|
||||
unset_ranged_ability(caller)
|
||||
unset_ranged_ability(clicker)
|
||||
|
||||
to_chat(target, span_bold("[caller] has given you a timeout for a foul!"))
|
||||
to_chat(caller, span_bold("You put [target] in a timeout!"))
|
||||
to_chat(target, span_bold("[clicker] has given you a timeout for a foul!"))
|
||||
to_chat(clicker, span_bold("You put [target] in a timeout!"))
|
||||
return TRUE
|
||||
|
||||
@@ -783,11 +783,11 @@ GLOBAL_LIST_INIT(command_strings, list(
|
||||
initial_access = access_card.access.Copy()
|
||||
|
||||
|
||||
/mob/living/basic/bot/proc/summon_bot(atom/caller, turf/turf_destination, user_access = list(), grant_all_access = FALSE)
|
||||
if(isAI(caller) && !set_ai_caller(caller))
|
||||
/mob/living/basic/bot/proc/summon_bot(atom/summoner, turf/turf_destination, user_access = list(), grant_all_access = FALSE)
|
||||
if(isAI(summoner) && !set_ai_caller(summoner))
|
||||
return FALSE
|
||||
bot_reset(bypass_ai_reset = isAI(caller))
|
||||
var/turf/destination = turf_destination ? turf_destination : get_turf(caller)
|
||||
bot_reset(bypass_ai_reset = isAI(summoner))
|
||||
var/turf/destination = turf_destination ? turf_destination : get_turf(summoner)
|
||||
ai_controller?.set_blackboard_key(BB_BOT_SUMMON_TARGET, destination)
|
||||
var/list/access_to_grant = grant_all_access ? REGION_ACCESS_ALL_STATION : user_access + initial_access
|
||||
access_card.set_access(access_to_grant)
|
||||
@@ -797,11 +797,11 @@ GLOBAL_LIST_INIT(command_strings, list(
|
||||
addtimer(CALLBACK(src, PROC_REF(bot_reset)), SENTIENT_BOT_RESET_TIMER)
|
||||
return TRUE
|
||||
|
||||
/mob/living/basic/bot/proc/set_ai_caller(mob/living/caller)
|
||||
/mob/living/basic/bot/proc/set_ai_caller(mob/living/ai_caller)
|
||||
var/atom/calling_ai = calling_ai_ref?.resolve()
|
||||
if(!isnull(calling_ai) && calling_ai != src)
|
||||
return FALSE
|
||||
calling_ai_ref = WEAKREF(caller)
|
||||
calling_ai_ref = WEAKREF(ai_caller)
|
||||
return TRUE
|
||||
|
||||
/mob/living/basic/bot/proc/update_bot_mode(new_mode, update_hud = TRUE)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
var/datum/action/cooldown/ability = controller.blackboard[BB_TARGETED_ACTION]
|
||||
if(QDELETED(target) || QDELETED(controller.pawn) || !ability?.IsAvailable())
|
||||
return
|
||||
ability.InterceptClickOn(caller = controller.pawn, target = target)
|
||||
ability.InterceptClickOn(clicker = controller.pawn, target = target)
|
||||
|
||||
/datum/ai_planning_subtree/targeted_mob_ability/brimbeam
|
||||
use_ability_behaviour = /datum/ai_behavior/targeted_mob_ability/brimbeam
|
||||
|
||||
@@ -285,7 +285,7 @@
|
||||
speech_commands = list("mine")
|
||||
callout_type = /datum/callout_option/mine
|
||||
|
||||
/datum/pet_command/automate_mining/valid_callout_target(mob/living/caller, datum/callout_option/callout, atom/target)
|
||||
/datum/pet_command/automate_mining/valid_callout_target(mob/living/speaker, datum/callout_option/callout, atom/target)
|
||||
return ismineralturf(target)
|
||||
|
||||
/datum/pet_command/automate_mining/retrieve_command_text(atom/living_pet, atom/target)
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
projectile_type = pick(permitted_projectiles)
|
||||
return ..()
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/projectile_attack/magicarp_bolt/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
if (!caller.combat_mode)
|
||||
/datum/action/cooldown/mob_cooldown/projectile_attack/magicarp_bolt/InterceptClickOn(mob/living/clicker, params, atom/target)
|
||||
if (!clicker.combat_mode)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
SIGNAL_HANDLER
|
||||
|
||||
// linters hate this if it's not async for some reason even though nothing blocks
|
||||
INVOKE_ASYNC(disguise_ability, TYPE_PROC_REF(/datum/action/cooldown, InterceptClickOn), caller = source, target = target)
|
||||
INVOKE_ASYNC(disguise_ability, TYPE_PROC_REF(/datum/action/cooldown, InterceptClickOn), clicker = source, target = target)
|
||||
return COMSIG_MOB_CANCEL_CLICKON
|
||||
|
||||
/// Handles the logic for attacking anything.
|
||||
|
||||
@@ -283,22 +283,22 @@ Doesn't work on other aliens/AI.*/
|
||||
// We do this in InterceptClickOn() instead of Activate()
|
||||
// because we use the click parameters for aiming the projectile
|
||||
// (or something like that)
|
||||
/datum/action/cooldown/alien/acid/neurotoxin/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
/datum/action/cooldown/alien/acid/neurotoxin/InterceptClickOn(mob/living/clicker, params, atom/target)
|
||||
. = ..()
|
||||
if(!.)
|
||||
unset_click_ability(caller, refund_cooldown = FALSE)
|
||||
unset_click_ability(clicker, refund_cooldown = FALSE)
|
||||
return FALSE
|
||||
|
||||
var/modifiers = params2list(params)
|
||||
caller.visible_message(
|
||||
span_danger("[caller] spits neurotoxin!"),
|
||||
clicker.visible_message(
|
||||
span_danger("[clicker] spits neurotoxin!"),
|
||||
span_alertalien("You spit neurotoxin."),
|
||||
)
|
||||
var/obj/projectile/neurotoxin/neurotoxin = new /obj/projectile/neurotoxin(caller.loc)
|
||||
neurotoxin.aim_projectile(target, caller, modifiers)
|
||||
neurotoxin.firer = caller
|
||||
var/obj/projectile/neurotoxin/neurotoxin = new /obj/projectile/neurotoxin(clicker.loc)
|
||||
neurotoxin.aim_projectile(target, clicker, modifiers)
|
||||
neurotoxin.firer = clicker
|
||||
neurotoxin.fire()
|
||||
caller.newtonian_move(get_angle(target, caller))
|
||||
clicker.newtonian_move(get_angle(target, clicker))
|
||||
return TRUE
|
||||
|
||||
// Has to return TRUE, otherwise is skipped.
|
||||
|
||||
@@ -14,28 +14,28 @@
|
||||
enable_text = span_notice("You prepare to power any APC you see.")
|
||||
disable_text = span_notice("You stop focusing on powering APCs.")
|
||||
|
||||
/datum/action/innate/ai/ranged/power_apc/do_ability(mob/living/caller, atom/clicked_on)
|
||||
/datum/action/innate/ai/ranged/power_apc/do_ability(mob/living/clicker, atom/clicked_on)
|
||||
|
||||
if (!isAI(caller))
|
||||
if (!isAI(clicker))
|
||||
return FALSE
|
||||
var/mob/living/silicon/ai/ai_caller = caller
|
||||
var/mob/living/silicon/ai/ai_clicker = clicker
|
||||
|
||||
if(caller.incapacitated)
|
||||
unset_ranged_ability(caller)
|
||||
if(clicker.incapacitated)
|
||||
unset_ranged_ability(clicker)
|
||||
return FALSE
|
||||
|
||||
if(!isapc(clicked_on))
|
||||
clicked_on.balloon_alert(ai_caller, "not an APC!")
|
||||
clicked_on.balloon_alert(ai_clicker, "not an APC!")
|
||||
return FALSE
|
||||
|
||||
if(ai_caller.battery - 50 <= 0)
|
||||
to_chat(ai_caller, span_warning("You do not have the battery to charge an APC!"))
|
||||
if(ai_clicker.battery - 50 <= 0)
|
||||
to_chat(ai_clicker, span_warning("You do not have the battery to charge an APC!"))
|
||||
return FALSE
|
||||
|
||||
var/obj/machinery/power/apc/apc = clicked_on
|
||||
var/obj/item/stock_parts/power_store/cell = apc.get_cell()
|
||||
cell.give(STANDARD_BATTERY_CHARGE)
|
||||
ai_caller.battery -= 50
|
||||
ai_clicker.battery -= 50
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -686,8 +686,8 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
if(mode != BOT_SUMMON && mode != BOT_RESPONDING)
|
||||
access_card.set_access(prev_access)
|
||||
|
||||
/mob/living/simple_animal/bot/proc/call_bot(caller, turf/waypoint, message = TRUE)
|
||||
if(isAI(caller) && calling_ai && calling_ai != src) //Prevents an override if another AI is controlling this bot.
|
||||
/mob/living/simple_animal/bot/proc/call_bot(summoner, turf/waypoint, message = TRUE)
|
||||
if(isAI(summoner) && calling_ai && calling_ai != src) //Prevents an override if another AI is controlling this bot.
|
||||
return FALSE
|
||||
|
||||
bot_reset() //Reset a bot before setting it to call mode.
|
||||
@@ -696,7 +696,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
//Easier then building the list ourselves. I'm sorry.
|
||||
var/static/obj/item/card/id/all_access = new /obj/item/card/id/advanced/gold/captains_spare()
|
||||
set_path(get_path_to(src, waypoint, max_distance=200, access = all_access.GetAccess()))
|
||||
calling_ai = caller //Link the AI to the bot!
|
||||
calling_ai = summoner //Link the AI to the bot!
|
||||
ai_waypoint = waypoint
|
||||
|
||||
if(path?.len) //Ensures that a valid path is calculated!
|
||||
@@ -706,7 +706,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
access_card.set_access(REGION_ACCESS_ALL_STATION) //Give the bot all-access while under the AI's command.
|
||||
if(client)
|
||||
reset_access_timer_id = addtimer(CALLBACK (src, PROC_REF(bot_reset)), 60 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE) //if the bot is player controlled, they get the extra access for a limited time
|
||||
to_chat(src, span_notice("[span_big("Priority waypoint set by [icon2html(calling_ai, src)] <b>[caller]</b>. Proceed to <b>[end_area]</b>.")]<br>[path.len-1] meters to destination. You have been granted additional door access for 60 seconds."))
|
||||
to_chat(src, span_notice("[span_big("Priority waypoint set by [icon2html(calling_ai, src)] <b>[summoner]</b>. Proceed to <b>[end_area]</b>.")]<br>[path.len-1] meters to destination. You have been granted additional door access for 60 seconds."))
|
||||
if(message)
|
||||
to_chat(calling_ai, span_notice("[icon2html(src, calling_ai)] [name] called to [end_area]. [path.len-1] meters to destination."))
|
||||
pathset = TRUE
|
||||
|
||||
@@ -352,7 +352,7 @@
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/action/cooldown/globules/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
/datum/action/cooldown/globules/InterceptClickOn(mob/living/clicker, params, atom/target)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return FALSE
|
||||
@@ -361,19 +361,19 @@
|
||||
// Well, we need to use the params of the click intercept
|
||||
// for passing into aim_projectile, so we'll handle it here instead.
|
||||
// We just need to make sure Pre-activate and Activate return TRUE so we make it this far
|
||||
caller.visible_message(
|
||||
span_nicegreen("[caller] launches a mending globule!"),
|
||||
clicker.visible_message(
|
||||
span_nicegreen("[clicker] launches a mending globule!"),
|
||||
span_notice("You launch a mending globule."),
|
||||
)
|
||||
|
||||
var/mob/living/simple_animal/hostile/ooze/oozy = caller
|
||||
var/mob/living/simple_animal/hostile/ooze/oozy = clicker
|
||||
if(istype(oozy))
|
||||
oozy.adjust_ooze_nutrition(-5)
|
||||
|
||||
var/modifiers = params2list(params)
|
||||
var/obj/projectile/globule/globule = new(caller.loc)
|
||||
globule.aim_projectile(target, caller, modifiers)
|
||||
globule.def_zone = caller.zone_selected
|
||||
var/obj/projectile/globule/globule = new(clicker.loc)
|
||||
globule.aim_projectile(target, clicker, modifiers)
|
||||
globule.def_zone = clicker.zone_selected
|
||||
globule.fire()
|
||||
|
||||
StartCooldown()
|
||||
|
||||
@@ -85,13 +85,13 @@
|
||||
if(refund_cooldown)
|
||||
to_chat(on_who, span_notice("You stop preparing your [on_who == owner ? "":"steed's "]pimp-tentacle."))
|
||||
|
||||
/datum/action/cooldown/tentacle_slap/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
/datum/action/cooldown/tentacle_slap/InterceptClickOn(mob/living/clicker, params, atom/target)
|
||||
// Check if we can slap
|
||||
if(!isliving(target) || target == owner)
|
||||
return FALSE
|
||||
|
||||
if(!owner.Adjacent(target))
|
||||
owner.balloon_alert(caller, "too far!")
|
||||
owner.balloon_alert(clicker, "too far!")
|
||||
return FALSE
|
||||
|
||||
// Do the slap
|
||||
@@ -101,8 +101,8 @@
|
||||
|
||||
// Give feedback from the slap.
|
||||
// Additional feedback for if a rider did it
|
||||
if(caller != owner)
|
||||
to_chat(caller, span_notice("You command [owner] to slap [target] with its tentacles."))
|
||||
if(clicker != owner)
|
||||
to_chat(clicker, span_notice("You command [owner] to slap [target] with its tentacles."))
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -397,7 +397,7 @@
|
||||
RETURN_TYPE(/datum/mod_link)
|
||||
if(!link_call)
|
||||
return
|
||||
return link_call.caller == src ? link_call.receiver : link_call.caller
|
||||
return link_call.link_caller == src ? link_call.link_receiver : link_call.link_caller
|
||||
|
||||
/datum/mod_link/proc/call_link(datum/mod_link/called, mob/user)
|
||||
if(!frequency)
|
||||
@@ -424,8 +424,8 @@
|
||||
link_target.playsound_local(get_turf(called.holder), 'sound/items/weapons/ring.ogg', 15, vary = TRUE)
|
||||
var/atom/movable/screen/alert/modlink_call/alert = link_target.throw_alert("[REF(src)]_modlink", /atom/movable/screen/alert/modlink_call)
|
||||
alert.desc = "[holder] ([id]) is calling you! Left-click this to accept the call. Right-click to deny it."
|
||||
alert.caller_ref = WEAKREF(src)
|
||||
alert.receiver_ref = WEAKREF(called)
|
||||
alert.link_caller_ref = WEAKREF(src)
|
||||
alert.link_receiver_ref = WEAKREF(called)
|
||||
alert.user_ref = WEAKREF(user)
|
||||
|
||||
/datum/mod_link/proc/end_call()
|
||||
@@ -438,33 +438,33 @@
|
||||
/// A MODlink call datum, used to handle the call between two MODlinks.
|
||||
/datum/mod_link_call
|
||||
/// The MODlink that is calling.
|
||||
var/datum/mod_link/caller
|
||||
var/datum/mod_link/link_caller
|
||||
/// The MODlink that is being called.
|
||||
var/datum/mod_link/receiver
|
||||
var/datum/mod_link/link_receiver
|
||||
|
||||
/datum/mod_link_call/New(datum/mod_link/caller, datum/mod_link/receiver)
|
||||
caller.link_call = src
|
||||
receiver.link_call = src
|
||||
src.caller = caller
|
||||
src.receiver = receiver
|
||||
var/mob/living/caller_mob = caller.get_user_callback.Invoke()
|
||||
/datum/mod_link_call/New(datum/mod_link/link_caller, datum/mod_link/link_receiver)
|
||||
link_caller.link_call = src
|
||||
link_receiver.link_call = src
|
||||
src.link_caller = link_caller
|
||||
src.link_receiver = link_receiver
|
||||
var/mob/living/caller_mob = link_caller.get_user_callback.Invoke()
|
||||
ADD_TRAIT(caller_mob, TRAIT_IN_CALL, REF(src))
|
||||
var/mob/living/receiver_mob = receiver.get_user_callback.Invoke()
|
||||
var/mob/living/receiver_mob = link_receiver.get_user_callback.Invoke()
|
||||
ADD_TRAIT(receiver_mob, TRAIT_IN_CALL, REF(src))
|
||||
make_visuals()
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
/datum/mod_link_call/Destroy()
|
||||
var/mob/living/caller_mob = caller.get_user_callback.Invoke()
|
||||
var/mob/living/caller_mob = link_caller.get_user_callback.Invoke()
|
||||
if(!QDELETED(caller_mob))
|
||||
REMOVE_TRAIT(caller_mob, TRAIT_IN_CALL, REF(src))
|
||||
var/mob/living/receiver_mob = receiver.get_user_callback.Invoke()
|
||||
var/mob/living/receiver_mob = link_receiver.get_user_callback.Invoke()
|
||||
if(!QDELETED(receiver_mob))
|
||||
REMOVE_TRAIT(receiver_mob, TRAIT_IN_CALL, REF(src))
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
clear_visuals()
|
||||
caller.link_call = null
|
||||
receiver.link_call = null
|
||||
link_caller.link_call = null
|
||||
link_receiver.link_call = null
|
||||
return ..()
|
||||
|
||||
/datum/mod_link_call/process(seconds_per_tick)
|
||||
@@ -473,17 +473,17 @@
|
||||
qdel(src)
|
||||
|
||||
/datum/mod_link_call/proc/can_continue_call()
|
||||
return caller.frequency == receiver.frequency && caller.can_call_callback.Invoke() && receiver.can_call_callback.Invoke()
|
||||
return link_caller.frequency == link_receiver.frequency && link_caller.can_call_callback.Invoke() && link_receiver.can_call_callback.Invoke()
|
||||
|
||||
/datum/mod_link_call/proc/make_visuals()
|
||||
var/caller_visual = caller.make_visual_callback.Invoke()
|
||||
var/receiver_visual = receiver.make_visual_callback.Invoke()
|
||||
caller.get_visual_callback.Invoke(receiver_visual)
|
||||
receiver.get_visual_callback.Invoke(caller_visual)
|
||||
var/caller_visual = link_caller.make_visual_callback.Invoke()
|
||||
var/receiver_visual = link_receiver.make_visual_callback.Invoke()
|
||||
link_caller.get_visual_callback.Invoke(receiver_visual)
|
||||
link_receiver.get_visual_callback.Invoke(caller_visual)
|
||||
|
||||
/datum/mod_link_call/proc/clear_visuals()
|
||||
caller.delete_visual_callback.Invoke()
|
||||
receiver.delete_visual_callback.Invoke()
|
||||
link_caller.delete_visual_callback.Invoke()
|
||||
link_receiver.delete_visual_callback.Invoke()
|
||||
|
||||
/proc/call_link(mob/user, datum/mod_link/calling_link)
|
||||
if(!calling_link.frequency)
|
||||
@@ -514,9 +514,9 @@
|
||||
clickable_glow = TRUE
|
||||
var/end_message = "call timed out!"
|
||||
/// A weak reference to the MODlink that is calling.
|
||||
var/datum/weakref/caller_ref
|
||||
var/datum/weakref/link_caller_ref
|
||||
/// A weak reference to the MODlink that is being called.
|
||||
var/datum/weakref/receiver_ref
|
||||
var/datum/weakref/link_receiver_ref
|
||||
/// A weak reference to the mob that is calling.
|
||||
var/datum/weakref/user_ref
|
||||
|
||||
@@ -524,25 +524,25 @@
|
||||
. = ..()
|
||||
if(usr != owner)
|
||||
return
|
||||
var/datum/mod_link/caller = caller_ref.resolve()
|
||||
var/datum/mod_link/receiver = receiver_ref.resolve()
|
||||
if(!caller || !receiver)
|
||||
var/datum/mod_link/link_caller = link_caller_ref.resolve()
|
||||
var/datum/mod_link/link_receiver = link_receiver_ref.resolve()
|
||||
if(!link_caller || !link_receiver)
|
||||
return
|
||||
if(caller.link_call || receiver.link_call)
|
||||
if(link_caller.link_call || link_receiver.link_call)
|
||||
return
|
||||
var/list/modifiers = params2list(params)
|
||||
if(LAZYACCESS(modifiers, RIGHT_CLICK))
|
||||
end_message = "call denied!"
|
||||
owner.clear_alert("[REF(caller)]_modlink")
|
||||
owner.clear_alert("[REF(link_caller)]_modlink")
|
||||
return
|
||||
end_message = "call accepted"
|
||||
new /datum/mod_link_call(caller, receiver)
|
||||
owner.clear_alert("[REF(caller)]_modlink")
|
||||
new /datum/mod_link_call(link_caller, link_receiver)
|
||||
owner.clear_alert("[REF(link_caller)]_modlink")
|
||||
|
||||
/atom/movable/screen/alert/modlink_call/Destroy()
|
||||
var/mob/living/user = user_ref?.resolve()
|
||||
var/datum/mod_link/caller = caller_ref?.resolve()
|
||||
if(!user || !caller)
|
||||
var/datum/mod_link/link_caller = link_caller_ref?.resolve()
|
||||
if(!user || !link_caller)
|
||||
return ..()
|
||||
caller.holder.balloon_alert(user, end_message)
|
||||
link_caller.holder.balloon_alert(user, end_message)
|
||||
return ..()
|
||||
|
||||
@@ -549,11 +549,11 @@
|
||||
* The program calling this proc.
|
||||
* The message that the program wishes to display.
|
||||
*/
|
||||
/obj/item/modular_computer/proc/alert_call(datum/computer_file/program/caller, alerttext, sound = 'sound/machines/beep/twobeep_high.ogg')
|
||||
if(!caller || !caller.alert_able || caller.alert_silenced || !alerttext) //Yeah, we're checking alert_able. No, you don't get to make alerts that the user can't silence.
|
||||
/obj/item/modular_computer/proc/alert_call(datum/computer_file/program/call_source, alerttext, sound = 'sound/machines/beep/twobeep_high.ogg')
|
||||
if(!call_source || !call_source.alert_able || call_source.alert_silenced || !alerttext) //Yeah, we're checking alert_able. No, you don't get to make alerts that the user can't silence.
|
||||
return FALSE
|
||||
playsound(src, sound, 50, TRUE)
|
||||
physical.loc.visible_message(span_notice("[icon2html(physical, viewers(physical.loc))] \The [src] displays a [caller.filedesc] notification: [alerttext]"))
|
||||
physical.loc.visible_message(span_notice("[icon2html(physical, viewers(physical.loc))] \The [src] displays a [call_source.filedesc] notification: [alerttext]"))
|
||||
|
||||
/obj/item/modular_computer/proc/ring(ringtone, list/balloon_alertees) // bring bring
|
||||
if(!use_energy())
|
||||
|
||||
@@ -64,13 +64,13 @@
|
||||
build_all_button_icons()
|
||||
return TRUE
|
||||
|
||||
/datum/action/cooldown/spell/pointed/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
/datum/action/cooldown/spell/pointed/InterceptClickOn(mob/living/clicker, params, atom/target)
|
||||
var/atom/aim_assist_target
|
||||
if(aim_assist)
|
||||
aim_assist_target = aim_assist(caller, target)
|
||||
return ..(caller, params, aim_assist_target || target)
|
||||
aim_assist_target = aim_assist(clicker, target)
|
||||
return ..(clicker, params, aim_assist_target || target)
|
||||
|
||||
/datum/action/cooldown/spell/pointed/proc/aim_assist(mob/living/caller, atom/target)
|
||||
/datum/action/cooldown/spell/pointed/proc/aim_assist(mob/living/clicker, atom/target)
|
||||
if(!isturf(target))
|
||||
return
|
||||
|
||||
|
||||
@@ -35,29 +35,30 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/action/cooldown/spell/pointed/swap/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
if(LAZYACCESS(params2list(params), RIGHT_CLICK))
|
||||
if(!IsAvailable(feedback = TRUE))
|
||||
return FALSE
|
||||
if(!target)
|
||||
return FALSE
|
||||
if(!isliving(target) || isturf(target))
|
||||
// Find any living being in the list. We aren't picky, it's aim assist after all
|
||||
target = locate(/mob/living) in target
|
||||
if(!target)
|
||||
to_chat(owner, span_warning("You can only select living beings as secondary target!"))
|
||||
return FALSE
|
||||
if(target == owner)
|
||||
if(!isnull(second_target))
|
||||
to_chat(owner, span_notice("You cancel your secondary swap target!"))
|
||||
second_target = null
|
||||
else
|
||||
to_chat(owner, span_warning("You have no secondary swap target!"))
|
||||
return FALSE
|
||||
second_target = target
|
||||
to_chat(owner, span_notice("You select [target.name] as a secondary swap target!"))
|
||||
/datum/action/cooldown/spell/pointed/swap/InterceptClickOn(mob/living/clicker, params, atom/target)
|
||||
if(!LAZYACCESS(params2list(params), RIGHT_CLICK))
|
||||
return ..()
|
||||
|
||||
if(!IsAvailable(feedback = TRUE))
|
||||
return FALSE
|
||||
return ..()
|
||||
if(!target)
|
||||
return FALSE
|
||||
if(!isliving(target) || isturf(target))
|
||||
// Find any living being in the list. We aren't picky, it's aim assist after all
|
||||
target = locate(/mob/living) in target
|
||||
if(!target)
|
||||
to_chat(owner, span_warning("You can only select living beings as secondary target!"))
|
||||
return FALSE
|
||||
if(target == owner)
|
||||
if(!isnull(second_target))
|
||||
to_chat(owner, span_notice("You cancel your secondary swap target!"))
|
||||
second_target = null
|
||||
else
|
||||
to_chat(owner, span_warning("You have no secondary swap target!"))
|
||||
return FALSE
|
||||
second_target = target
|
||||
to_chat(owner, span_notice("You select [target.name] as a secondary swap target!"))
|
||||
return FALSE
|
||||
|
||||
/datum/action/cooldown/spell/pointed/swap/cast(mob/living/carbon/cast_on)
|
||||
. = ..()
|
||||
|
||||
Reference in New Issue
Block a user