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:
LemonInTheDark
2024-12-27 01:04:50 +00:00
committed by GitHub
parent 6b252b5309
commit 91719a400a
36 changed files with 283 additions and 278 deletions
+5 -1
View File
@@ -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
+2 -2
View File
@@ -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'
+6 -6
View File
@@ -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?")
+2 -2
View File
@@ -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
+3 -3
View File
@@ -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
+4 -4
View File
@@ -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
+1 -1
View File
@@ -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
+3 -3
View File
@@ -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
+3 -3
View File
@@ -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
+1 -1
View File
@@ -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
+3 -3
View File
@@ -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]))
+7 -7
View File
@@ -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
+26 -26
View File
@@ -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 -14
View File
@@ -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
+6 -6
View File
@@ -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
+35 -35
View File
@@ -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
+23 -22
View File
@@ -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)
. = ..()