Merge remote-tracking branch 'origin/master' into bloodsucker_death_lessspam

This commit is contained in:
Artur
2020-08-02 11:12:18 +03:00
463 changed files with 6911 additions and 5470 deletions
-8
View File
@@ -138,14 +138,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define MOBILITY_FLAGS_DEFAULT (MOBILITY_MOVE | MOBILITY_STAND | MOBILITY_PICKUP | MOBILITY_USE | MOBILITY_UI | MOBILITY_STORAGE | MOBILITY_PULL | MOBILITY_RESIST)
#define MOBILITY_FLAGS_ANY_INTERACTION (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_UI | MOBILITY_STORAGE)
// melee_attack_chain() attackchain_flags
/// The attack is from a parry counterattack.
#define ATTACKCHAIN_PARRY_COUNTERATTACK (1<<0)
// UnarmedAttack() flags
/// Attack is from a parry counterattack
#define UNARMED_ATTACK_PARRY (1<<0)
/// If the thing can reflect light (lasers/energy)
#define RICOCHET_SHINY (1<<0)
/// If the thing can reflect matter (bullets/bomb shrapnel)
+22
View File
@@ -0,0 +1,22 @@
/////////// ATTACKCHAIN_FLAGS ////////////
// melee_attack_chain(), attackby(), pre_attack(), afterattack(), and tool_act(), attack() and **anything that is called by ClickOn()** return values.
// These are all passed down through the attack chain and are binary OR'd into each other!
/// Stop the attack chain if still in melee_attack_chain()
#define STOP_ATTACK_PROC_CHAIN (1<<0)
/// This attack should discard last_action instead of flushing (storing) it). You should probably know what you're doing if you use this considering this is how clickdelay is enforced.
#define DISCARD_LAST_ACTION (1<<1)
/// There are a number of "safety nets" intended to default-handle clickdelay. Return this flag to bypass ALL of them. Be sure
/// you know EXACTLY what you are doing!
#define NO_AUTO_CLICKDELAY_HANDLING (1<<2)
/// Only used with UnarmedAttack(). Interrupts unarmed attack from progressing.
#define INTERRUPT_UNARMED_ATTACK (1<<3)
/// Attack should not set next action even if the atom wants it to be an action
#define ATTACK_IGNORE_ACTION (1<<4)
/// Attack should not at all check last_action/attack_hand_speed even if the atom wants to
#define ATTACK_IGNORE_CLICKDELAY (1<<5)
/// This attack is from a parry counterattack
#define ATTACK_IS_PARRY_COUNTERATTACK (1<<6)
// obj/item/dropped()
/// dropped() relocated this item, return FALSE for doUnEquip.
#define ITEM_RELOCATED_BY_DROPPED "relocated_by_dropped"
+1
View File
@@ -74,6 +74,7 @@
#define ADMIN_PUNISHMENT_MAZING "Puzzle"
#define ADMIN_PUNISHMENT_PIE "Cream Pie"
#define ADMIN_PUNISHMENT_CUSTOM_PIE "Custom Cream Pie"
#define ADMIN_PUNISHMENT_SHOES "Knot Shoes"
#define ADMIN_PUNISHMENT_CRACK ":B:oneless"
#define ADMIN_PUNISHMENT_BLEED ":B:loodless"
#define ADMIN_PUNISHMENT_SCARIFY "Scarify"
+15 -9
View File
@@ -8,6 +8,7 @@
GLOBAL_VAR_INIT(clockwork_construction_value, 0) //The total value of all structures built by the clockwork cult
GLOBAL_VAR_INIT(clockwork_vitality, 0) //How much Vitality is stored, total
GLOBAL_VAR_INIT(clockwork_power, 0) //How many watts of power are globally available to the clockwork cult
GLOBAL_LIST_EMPTY(active_daemons) //A list of all active tinkerer's daemons
GLOBAL_VAR_INIT(neovgre_exists, 0) //Does neovgre exist?
GLOBAL_LIST_EMPTY(all_clockwork_objects) //All clockwork items, structures, and effects in existence
@@ -19,7 +20,8 @@ GLOBAL_VAR_INIT(ark_of_the_clockwork_justiciar, FALSE) //The Ark on the Reebe z-
GLOBAL_VAR_INIT(clockwork_gateway_activated, FALSE) //if a gateway to the celestial derelict has ever been successfully activated
GLOBAL_VAR_INIT(script_scripture_unlocked, FALSE) //If script scripture is available, through converting at least one crewmember
GLOBAL_VAR_INIT(application_scripture_unlocked, FALSE) //If script scripture is available
GLOBAL_VAR_INIT(application_scripture_unlocked, FALSE) //If application scripture is available
GLOBAL_VAR_INIT(judgement_scripture_unlocked, FALSE) //If judgement scripture is available
GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not used to track existing scripture
//Scripture tiers and requirements; peripherals should never be used
@@ -27,13 +29,13 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
#define SCRIPTURE_DRIVER "Driver"
#define SCRIPTURE_SCRIPT "Script"
#define SCRIPTURE_APPLICATION "Application"
#define SCRIPTURE_JUDGEMENT "Judgement"
//Various costs related to power.
#define MAX_CLOCKWORK_POWER 80000 //The max power in W that the cult can stockpile
#define SCRIPT_UNLOCK_THRESHOLD 35000 //Scripts will unlock if the total power reaches this amount
#define APPLICATION_UNLOCK_THRESHOLD 50000 //Applications will unlock if the total powre reaches this amount
#define ABSCOND_ABDUCTION_COST 95
#define APPLICATION_UNLOCK_THRESHOLD 50000 //Applications will unlock if the total power reaches this amount
#define JUDGEMENT_UNLOCK_THRESHOLD 80000 //might as well have this unlock at a power amount like the other scriptures, Judgement unlocks at this amount.
//clockcult power defines
#define MIN_CLOCKCULT_POWER 25 //the minimum amount of power clockcult machines will handle gracefully
@@ -59,11 +61,11 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
//Ark defines
#define GATEWAY_SUMMON_RATE 1 //the time amount the Gateway to the Celestial Derelict gets each process tick; defaults to 1 per tick
#define GATEWAY_REEBE_FOUND 240 //when progress is at or above this, the gateway finds reebe and begins drawing power
#define GATEWAY_REEBE_FOUND 120 //when progress is at or above this, the gateway finds reebe and begins drawing power
#define GATEWAY_RATVAR_COMING 480 //when progress is at or above this, ratvar has entered and is coming through the gateway
#define GATEWAY_RATVAR_COMING 240 //when progress is at or above this, ratvar has entered and is coming through the gateway
#define GATEWAY_RATVAR_ARRIVAL 600 //when progress is at or above this, game over ratvar's here everybody go home
#define GATEWAY_RATVAR_ARRIVAL 300 //when progress is at or above this, game over ratvar's here everybody go home
//Objective text define
#define CLOCKCULT_OBJECTIVE "Construct the Ark of the Clockwork Justicar and free Ratvar."
@@ -81,7 +83,7 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
#define CLOCKWORK_ARMOR_COOLDOWN 1800 //The cooldown period between summoning suits of clockwork armor
#define RATVARIAN_SPEAR_COOLDOWN 300 //The cooldown period between summoning another Ratvarian spear
#define RATVARIAN_WEAPON_COOLDOWN 300 //The cooldown period between summoning another Ratvarian spear
#define MARAUDER_SCRIPTURE_SCALING_THRESHOLD 600 //The amount of deciseconds that must pass before marauder scripture will not gain a recital penalty
@@ -89,4 +91,8 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
#define MARAUDER_SCRIPTURE_SCALING_MAX 300 //The maximum extra time applied to the marauder scripture
#define ARK_SCREAM_COOLDOWN 600 //This much time has to pass between instances of the Ark taking damage before it will "scream" again
#define GUARDIAN_EMERGE_THRESHOLD 65 //guardian cannot emerge unless host is at this% or less health
#define ARK_SCREAM_COOLDOWN 300 //This much time has to pass between instances of the Ark taking damage before it will "scream" again
#define PRISM_DELAY_DURATION 1200 //how long prolonging prisms delay the shuttle for; defaults to 2 minutes
+1 -2
View File
@@ -108,7 +108,6 @@
#define CLICK_CD_RANGE 4
#define CLICK_CD_RAPID 2
#define CLICK_CD_CLICK_ABILITY 6
#define CLICK_CD_BREAKOUT 100
#define CLICK_CD_HANDCUFFED 10
#define CLICK_CD_RESIST 20
#define CLICK_CD_GRABBING 10
@@ -281,7 +280,7 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
/// changeNext_move penalty multiplier of the above.
#define STAM_CRIT_ITEM_ATTACK_DELAY 1.75
/// Damage penalty when fighting prone.
#define LYING_DAMAGE_PENALTY 0.5
#define LYING_DAMAGE_PENALTY 0.7
/// Added delay when firing guns stam-softcritted. Summed with a hardset CLICK_CD_RANGE delay, similar to STAM_CRIT_DAMAGE_DELAY otherwise.
#define STAM_CRIT_GUN_DELAY 2.75
+5
View File
@@ -535,4 +535,9 @@ GLOBAL_LIST_INIT(pda_reskins, list(PDA_SKIN_CLASSIC = 'icons/obj/pda.dmi', PDA_S
#define LOOT_RESTRICTION_MIND_PILE 3 //limited to the current pile.
#define LOOT_RESTRICTION_CKEY_PILE 4 //Idem
//stages of shoe tying-ness
#define SHOES_UNTIED 0
#define SHOES_TIED 1
#define SHOES_KNOTTED 2
#define WANTED_FILE "wanted_message.json"
-3
View File
@@ -1,3 +0,0 @@
// obj/item/dropped
/// dropped() relocated this item, return FALSE for doUnEquip.
#define ITEM_RELOCATED_BY_DROPPED "relocated_by_dropped"
+1
View File
@@ -107,6 +107,7 @@
#define FIRE_PRIORITY_INSTRUMENTS 30
#define FIRE_PRIORITY_FIELDS 30
#define FIRE_PRIOTITY_SMOOTHING 35
#define FIRE_PRIORITY_HUDS 40
#define FIRE_PRIORITY_NETWORKS 40
#define FIRE_PRIORITY_OBJ 40
#define FIRE_PRIORITY_ACID 40
+15 -1
View File
@@ -167,6 +167,7 @@
var/target_loc = target.loc
LAZYADD(user.do_afters, target)
LAZYADD(target.targeted_by, user)
var/holding = user.get_active_held_item()
var/datum/progressbar/progbar
@@ -189,6 +190,10 @@
. = FALSE
break
if(!(target in user.do_afters))
. = FALSE
break
if(drifting && !user.inertia_dir)
drifting = 0
user_loc = user.loc
@@ -198,12 +203,14 @@
break
if(progress)
qdel(progbar)
if(!QDELETED(target))
LAZYREMOVE(user.do_afters, target)
LAZYREMOVE(target.targeted_by, user)
//some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action
/mob/proc/break_do_after_checks(list/checked_health, check_clicks)
if(check_clicks && next_move > world.time)
if(check_clicks && !CheckActionCooldown())
return FALSE
return TRUE
@@ -224,6 +231,7 @@
if(target)
LAZYADD(user.do_afters, target)
LAZYADD(target.targeted_by, user)
var/atom/Uloc = user.loc
@@ -288,6 +296,10 @@
if(!QDELETED(target))
LAZYREMOVE(user.do_afters, target)
if(!QDELETED(target))
LAZYREMOVE(user.do_afters, target)
LAZYREMOVE(target.targeted_by, user)
/mob/proc/do_after_coefficent() // This gets added to the delay on a do_after, default 1
. = 1
return
@@ -307,6 +319,7 @@
for(var/atom/target in targets)
originalloc[target] = target.loc
LAZYADD(user.do_afters, target)
LAZYADD(target.targeted_by, user)
var/holding = user.get_active_held_item()
var/datum/progressbar/progbar
@@ -341,3 +354,4 @@
var/atom/target = thing
if(!QDELETED(target))
LAZYREMOVE(user.do_afters, target)
LAZYREMOVE(target.targeted_by, user)
+4 -8
View File
@@ -19,10 +19,6 @@
A.move_camera_by_click()
/mob/living/silicon/ai/ClickOn(var/atom/A, params)
if(world.time <= next_click)
return
next_click = world.time + 1
if(!can_interact_with(A))
return
@@ -74,16 +70,16 @@
CtrlClickOn(A)
return
if(world.time <= next_move)
if(!CheckActionCooldown(immediate = TRUE))
return
if(aicamera.in_camera_mode)
aicamera.camera_mode_off()
aicamera.captureimage(pixel_turf, usr)
INVOKE_ASYNC(aicamera, /obj/item/camera.proc/captureimage, pixel_turf, usr)
return
if(waypoint_mode)
waypoint_mode = 0
set_waypoint(A)
waypoint_mode = FALSE
INVOKE_ASYNC(src, .proc/set_waypoint, A)
return
A.attack_ai(src)
+55 -90
View File
@@ -1,38 +1,3 @@
/*
Click code cleanup
~Sayu
*/
// 1 decisecond click delay (above and beyond mob/next_move)
//This is mainly modified by click code, to modify click delays elsewhere, use next_move and changeNext_move()
/mob/var/next_click = 0
// THESE DO NOT EFFECT THE BASE 1 DECISECOND DELAY OF NEXT_CLICK
/mob/var/next_move_adjust = 0 //Amount to adjust action/click delays by, + or -
/mob/var/next_move_modifier = 1 //Value to multiply action/click delays by
//Delays the mob's next click/action by num deciseconds
// eg: 10-3 = 7 deciseconds of delay
// eg: 10*0.5 = 5 deciseconds of delay
// DOES NOT EFFECT THE BASE 1 DECISECOND DELAY OF NEXT_CLICK
/mob/proc/timeToNextMove()
return max(0, next_move - world.time)
/mob/proc/changeNext_move(num)
next_move = world.time + ((num+next_move_adjust)*next_move_modifier)
/mob/living/changeNext_move(num)
last_click_move = next_move
var/mod = next_move_modifier
var/adj = next_move_adjust
for(var/i in status_effects)
var/datum/status_effect/S = i
mod *= S.nextmove_modifier()
adj += S.nextmove_adjust()
next_move = world.time + ((num + adj)*mod)
/*
Before anything else, defer these calls to a per-mobtype handler. This allows us to
remove istype() spaghetti code, but requires the addition of other handler procs to simplify it.
@@ -45,7 +10,7 @@
/atom/Click(location,control,params)
if(flags_1 & INITIALIZED_1)
SEND_SIGNAL(src, COMSIG_CLICK, location, control, params, usr)
usr.ClickOn(src, params)
usr.CommonClickOn(src, params)
/atom/DblClick(location,control,params)
if(flags_1 & INITIALIZED_1)
@@ -55,6 +20,21 @@
if(flags_1 & INITIALIZED_1)
usr.MouseWheelOn(src, delta_x, delta_y, params)
/**
* Common mob click code
*/
/mob/proc/CommonClickOn(atom/A, params)
SHOULD_NOT_SLEEP(TRUE)
if(mob_transforming)
return
if(SEND_SIGNAL(src, COMSIG_MOB_CLICKON, A, params) & COMSIG_MOB_CANCEL_CLICKON)
return
. = ClickOn(A, params)
if(!(. & DISCARD_LAST_ACTION))
FlushCurrentAction()
else
DiscardCurrentAction()
/*
Standard mob ClickOn()
Handles exceptions: Buildmode, middle click, modified clicks, mech actions
@@ -68,50 +48,34 @@
* item/afterattack(atom,user,adjacent,params) - used both ranged and adjacent
* mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed
*/
/mob/proc/ClickOn( atom/A, params )
if(world.time <= next_click)
return
next_click = world.time + world.tick_lag
/mob/proc/ClickOn(atom/A, params)
SHOULD_NOT_SLEEP(TRUE)
if(check_click_intercept(params,A))
return
if(mob_transforming)
return
if(SEND_SIGNAL(src, COMSIG_MOB_CLICKON, A, params) & COMSIG_MOB_CANCEL_CLICKON)
return
var/list/modifiers = params2list(params)
if(modifiers["shift"] && modifiers["middle"])
ShiftMiddleClickOn(A)
return
return ShiftMiddleClickOn(A)
if(modifiers["shift"] && modifiers["ctrl"])
CtrlShiftClickOn(A)
return
return CtrlShiftClickOn(A)
if(modifiers["middle"])
MiddleClickOn(A)
return
return MiddleClickOn(A)
if(modifiers["shift"] && (client && client.show_popup_menus || modifiers["right"])) //CIT CHANGE - makes shift-click examine use right click instead of left click in combat mode
ShiftClickOn(A)
return
return ShiftClickOn(A)
if(modifiers["alt"]) // alt and alt-gr (rightalt)
AltClickOn(A)
return
return AltClickOn(A)
if(modifiers["ctrl"])
CtrlClickOn(A)
return
return CtrlClickOn(A)
if(modifiers["right"]) //CIT CHANGE - allows right clicking to perform actions
RightClickOn(A,params) //CIT CHANGE - ditto
return //CIT CHANGE - ditto
return RightClickOn(A, params) //CIT CHANGE - ditto
if(incapacitated(ignore_restraints = 1))
return
face_atom(A)
if(next_move > world.time) // in the year 2000...
if(!CheckActionCooldown(immediate = TRUE))
return
if(!modifiers["catcher"] && A.IsObscured())
@@ -119,12 +83,12 @@
if(ismecha(loc))
var/obj/mecha/M = loc
return M.click_action(A,src,params)
M.click_action(A,src,params)
return TRUE
if(restrained())
changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow
RestrainedClickOn(A)
return
DelayNextAction(CLICK_CD_HANDCUFFED)
return RestrainedClickOn(A)
if(in_throw_mode)
throw_item(A)
@@ -141,12 +105,12 @@
//User itself, current loc, and user inventory
if(A in DirectAccess())
if(W)
W.melee_attack_chain(src, A, params)
return W.melee_attack_chain(src, A, params)
else
if(ismob(A))
changeNext_move(CLICK_CD_MELEE)
UnarmedAttack(A)
return
. = UnarmedAttack(A, TRUE, a_intent)
if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A))
DelayNextAction(CLICK_CD_MELEE)
return
//Can't reach anything else in lockers or other weirdness
if(!loc.AllowClick())
@@ -155,16 +119,17 @@
//Standard reach turf to turf or reaching inside storage
if(CanReach(A,W))
if(W)
W.melee_attack_chain(src, A, params)
return W.melee_attack_chain(src, A, params)
else
if(ismob(A))
changeNext_move(CLICK_CD_MELEE)
UnarmedAttack(A, 1)
. = UnarmedAttack(A, TRUE, a_intent)
if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A))
DelayNextAction(CLICK_CD_MELEE)
return
else
if(W)
W.ranged_attack_chain(src, A, params)
return W.ranged_attack_chain(src, A, params)
else
RangedAttack(A,params)
return RangedAttack(A,params)
//Is the atom obscured by a PREVENT_CLICK_UNDER_1 object above it
/atom/proc/IsObscured()
@@ -270,8 +235,6 @@
in human click code to allow glove touches only at melee range.
*/
/mob/proc/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE)
if(ismob(A))
changeNext_move(CLICK_CD_MELEE)
/*
Ranged unarmed attack:
@@ -304,7 +267,6 @@
var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling)
if(C && C.chosen_sting)
C.chosen_sting.try_to_sting(src,A)
next_click = world.time + 5
return
swap_hand()
@@ -337,24 +299,24 @@
*/
/mob/proc/CtrlClickOn(atom/A)
A.CtrlClick(src)
return
return A.CtrlClick(src)
/atom/proc/CtrlClick(mob/user)
SEND_SIGNAL(src, COMSIG_CLICK_CTRL, user)
var/mob/living/ML = user
if(istype(ML))
ML.pulled(src)
INVOKE_ASYNC(ML, /mob/living.verb/pulled, src)
/mob/living/carbon/human/CtrlClick(mob/user)
if(ishuman(user) && Adjacent(user) && !user.incapacitated())
if(world.time < user.next_move)
if(!user.CheckActionCooldown())
return FALSE
var/mob/living/carbon/human/H = user
H.dna.species.grab(H, src, H.mind.martial_art)
H.changeNext_move(CLICK_CD_MELEE)
H.DelayNextAction(CLICK_CD_MELEE)
return TRUE
else
..()
return ..()
/*
Alt click
Unused except for AI
@@ -377,8 +339,8 @@
var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling)
if(C && C.chosen_sting)
C.chosen_sting.try_to_sting(src,A)
next_click = world.time + 5
return
DelayNextAction(CLICK_CD_RANGE)
return TRUE
..()
/atom/proc/AltClick(mob/user)
@@ -413,9 +375,11 @@
return
/mob/living/LaserEyes(atom/A, params)
changeNext_move(CLICK_CD_RANGE)
if(!CheckActionCooldown(CLICK_CD_RANGE))
return
DelayNextAction()
var/obj/item/projectile/beam/LE = new /obj/item/projectile/beam( loc )
var/obj/item/projectile/beam/LE = new /obj/item/projectile/beam(loc)
LE.icon = 'icons/effects/genetics.dmi'
LE.icon_state = "eyelasers"
playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1)
@@ -424,6 +388,7 @@
LE.def_zone = get_organ_target()
LE.preparePixelProjectile(A, src, params)
LE.fire()
return TRUE
// Simple helper to face what you clicked on, in case it should be needed in more than one place
/mob/proc/face_atom(atom/A, ismousemovement = FALSE)
+17 -29
View File
@@ -7,10 +7,6 @@
*/
/mob/living/silicon/robot/ClickOn(var/atom/A, var/params)
if(world.time <= next_click)
return
next_click = world.time + 1
if(check_click_intercept(params,A))
return
@@ -19,25 +15,19 @@
var/list/modifiers = params2list(params)
if(modifiers["shift"] && modifiers["ctrl"])
CtrlShiftClickOn(A)
return
return CtrlShiftClickOn(A)
if(modifiers["shift"] && modifiers["middle"])
ShiftMiddleClickOn(A)
return
return ShiftMiddleClickOn(A)
if(modifiers["middle"])
MiddleClickOn(A)
return
return MiddleClickOn(A)
if(modifiers["shift"])
ShiftClickOn(A)
return
return ShiftClickOn(A)
if(modifiers["alt"]) // alt and alt-gr (rightalt)
AltClickOn(A)
return
return AltClickOn(A)
if(modifiers["ctrl"])
CtrlClickOn(A)
return
return CtrlClickOn(A)
if(next_move >= world.time)
if(!CheckActionCooldown(immediate = TRUE))
return
face_atom(A) // change direction to face what you clicked on
@@ -50,7 +40,7 @@
*/
if(aicamera.in_camera_mode) //Cyborg picture taking
aicamera.camera_mode_off()
aicamera.captureimage(A, usr)
INVOKE_ASYNC(aicamera, /obj/item/camera.proc/captureimage, A, usr)
return
var/obj/item/W = get_active_held_item()
@@ -58,13 +48,8 @@
if(!W && A.Adjacent(src) && (isobj(A) || ismob(A)))
var/atom/movable/C = A
if(C.can_buckle && C.has_buckled_mobs())
if(C.buckled_mobs.len > 1)
var/unbuckled = input(src, "Who do you wish to unbuckle?","Unbuckle Who?") as null|mob in C.buckled_mobs
if(C.user_unbuckle_mob(unbuckled,src))
return
else
if(C.user_unbuckle_mob(C.buckled_mobs[1],src))
return
INVOKE_ASYNC(C, /atom/movable.proc/precise_user_unbuckle_mob, src)
return
if(!W && (get_dist(src,A) <= interaction_range))
A.attack_robot(src)
@@ -81,7 +66,9 @@
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents)
if(A == loc || (A in loc) || (A in contents))
W.melee_attack_chain(src, A, params)
. = W.melee_attack_chain(src, A, params)
if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A))
DelayNextAction(CLICK_CD_MELEE)
return
if(!isturf(loc))
@@ -90,11 +77,12 @@
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc))
if(isturf(A) || isturf(A.loc))
if(A.Adjacent(src)) // see adjacent.dm
W.melee_attack_chain(src, A, params)
. = W.melee_attack_chain(src, A, params)
if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A))
DelayNextAction(CLICK_CD_MELEE)
return
else
W.afterattack(A, src, 0, params)
return
return W.afterattack(A, src, 0, params)
//Middle click cycles through selected modules.
/mob/living/silicon/robot/MiddleClickOn(atom/A)
+2
View File
@@ -168,6 +168,8 @@
//UI position overrides for 1:1 screen layout. (default is 7:5)
#define ui_stamina "EAST-1:28,CENTER:17" // replacing internals button
#define ui_overridden_resist "EAST-3:24,SOUTH+1:7"
#define ui_clickdelay "CENTER,SOUTH+1:-31"
#define ui_resistdelay "EAST-3:24,SOUTH+1:4"
#define ui_combat_toggle "EAST-4:22,SOUTH:5"
#define ui_boxcraft "EAST-4:22,SOUTH+1:6"
-3
View File
@@ -56,9 +56,6 @@
if(id && usr.client) //try to (un)remember position
usr.client.prefs.action_buttons_screen_locs["[name]_[id]"] = locked ? moved : null
return TRUE
if(usr.next_click > world.time)
return
usr.next_click = world.time + 1
linked_action.Trigger()
return TRUE
+24 -11
View File
@@ -22,7 +22,7 @@
if(alerts[category])
thealert = alerts[category]
if(thealert.override_alerts)
return 0
return thealert
if(new_master && new_master != thealert.master)
WARNING("[src] threw alert [category] with new_master [new_master] while already having that alert with master [thealert.master]")
@@ -36,7 +36,7 @@
clear_alert(category)
return .()
else //no need to update
return 0
return thealert
else
thealert = new type()
thealert.override_alerts = override
@@ -272,7 +272,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
var/mob/living/L = usr
if(!istype(L) || !L.can_resist())
return
L.changeNext_move(CLICK_CD_RESIST)
L.MarkResistTime()
if(CHECK_MOBILITY(L, MOBILITY_MOVE))
return L.resist_fire() //I just want to start a flame in your hearrrrrrtttttt.
@@ -447,8 +447,6 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
var/time_name
if(G.seconds_until_activation)
time_name = "until the Ark activates"
else if(G.grace_period)
time_name = "of grace period remaining"
else if(G.progress_in_seconds)
time_name = "until the Ark finishes summoning"
if(time_info)
@@ -600,17 +598,32 @@ so as to remain in compliance with the most up-to-date laws."
var/mob/living/L = usr
if(!istype(L) || !L.can_resist())
return
L.changeNext_move(CLICK_CD_RESIST)
if(CHECK_MOBILITY(L, MOBILITY_MOVE) && (L.last_special <= world.time))
return L.resist_restraints()
L.MarkResistTime()
return L.resist_restraints()
/obj/screen/alert/restrained/buckled/Click()
var/mob/living/L = usr
if(!istype(L) || !L.can_resist())
return
L.changeNext_move(CLICK_CD_RESIST)
if(L.last_special <= world.time)
return L.resist_buckle()
L.MarkResistTime()
return L.resist_buckle()
/obj/screen/alert/shoes/untied
name = "Untied Shoes"
desc = "Your shoes are untied! Click the alert or your shoes to tie them."
icon_state = "shoealert"
/obj/screen/alert/shoes/knotted
name = "Knotted Shoes"
desc = "Someone tied your shoelaces together! Click the alert or your shoes to undo the knot."
icon_state = "shoealert"
/obj/screen/alert/shoes/Click()
var/mob/living/carbon/C = usr
if(!istype(C) || !C.can_resist() || C != mob_viewer || !C.shoes)
return
C.MarkResistTime()
C.shoes.handle_tying(C)
// PRIVATE = only edit, use, or override these if you're editing the system as a whole
+45
View File
@@ -0,0 +1,45 @@
/datum/hud/marauder
var/obj/screen/hosthealth
var/obj/screen/blockchance
var/obj/screen/counterchance
/datum/hud/marauder/New(mob/living/simple_animal/hostile/clockwork/marauder/guardian/owner)
..()
var/obj/screen/using
healths = new /obj/screen/healths/clock()
infodisplay += healths
hosthealth = new /obj/screen/healths/clock()
hosthealth.screen_loc = ui_internal
infodisplay += hosthealth
using = new /obj/screen/marauder/emerge()
using.screen_loc = ui_zonesel
static_inventory += using
/datum/hud/marauder/Destroy()
blockchance = null
counterchance = null
hosthealth = null
return ..()
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/create_mob_hud()
if(client && !hud_used)
hud_used = new /datum/hud/marauder(src, ui_style2icon(client.prefs.UI_style))
/obj/screen/marauder
icon = 'icons/mob/clockwork_mobs.dmi'
/obj/screen/marauder/emerge
icon_state = "clockguard_emerge"
name = "Emerge/Return"
desc = "Emerge or Return."
/obj/screen/marauder/emerge/Click()
if(istype(usr, /mob/living/simple_animal/hostile/clockwork/marauder/guardian))
var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/G = usr
if(G.is_in_host())
G.try_emerge()
else
G.return_to_host()
+11
View File
@@ -140,6 +140,17 @@
sprint_buffer.hud = src
static_inventory += sprint_buffer
// clickdelay
clickdelay = new
clickdelay.hud = src
clickdelay.screen_loc = ui_clickdelay
static_inventory += clickdelay
// resistdelay
resistdelay = new
resistdelay.hud = src
resistdelay.screen_loc = ui_resistdelay
static_inventory += resistdelay
using = new /obj/screen/drop()
using.icon = ui_style
+1
View File
@@ -219,6 +219,7 @@
L.screen_loc = "CENTER-7:[round(L.offset_x,1)],CENTER-7:[round(L.offset_y,1)]"
/atom/movable/proc/update_parallax_contents()
set waitfor = FALSE
if(length(client_mobs_in_contents))
for(var/thing in client_mobs_in_contents)
var/mob/M = thing
+8 -31
View File
@@ -47,17 +47,7 @@
name = "swap hand"
/obj/screen/swap_hand/Click()
// At this point in client Click() code we have passed the 1/10 sec check and little else
// We don't even know if it's a middle click
if(world.time <= usr.next_move)
return 1
if(usr.incapacitated())
return 1
if(ismob(usr))
var/mob/M = usr
M.swap_hand()
usr.swap_hand()
return 1
/obj/screen/craft
@@ -101,15 +91,9 @@
plane = HUD_PLANE
/obj/screen/inventory/Click(location, control, params)
// At this point in client Click() code we have passed the 1/10 sec check and little else
// We don't even know if it's a middle click
if(world.time <= usr.next_move)
return TRUE
if(usr.incapacitated())
return TRUE
if(ismecha(usr.loc)) // stops inventory actions in a mech
return TRUE
if(hud?.mymob && (hud.mymob != usr))
return
// just redirect clicks
if(hud?.mymob && slot_id)
var/obj/item/inv_item = hud.mymob.get_item_by_slot(slot_id)
@@ -190,17 +174,10 @@
/obj/screen/inventory/hand/Click(location, control, params)
// At this point in client Click() code we have passed the 1/10 sec check and little else
// We don't even know if it's a middle click
var/mob/user = hud?.mymob
if(usr != user)
return TRUE
if(world.time <= user.next_move)
return TRUE
if(user.incapacitated())
return TRUE
if (ismecha(user.loc)) // stops inventory actions in a mech
return TRUE
if(hud?.mymob && (hud.mymob != usr))
return
var/mob/user = hud.mymob
// just redirect clicks
if(user.active_hand_index == held_index)
var/obj/item/I = user.get_active_held_item()
@@ -0,0 +1,58 @@
/obj/screen/action_bar
/obj/screen/action_bar/Destroy()
STOP_PROCESSING(SShuds, src)
return ..()
/obj/screen/action_bar/proc/mark_dirty()
var/mob/living/L = hud?.mymob
if(L?.client && update_to_mob(L))
START_PROCESSING(SShuds, src)
/obj/screen/action_bar/process()
var/mob/living/L = hud?.mymob
if(!L?.client || !update_to_mob(L))
return PROCESS_KILL
/obj/screen/action_bar/proc/update_to_mob(mob/living/L)
return FALSE
/datum/hud/var/obj/screen/action_bar/clickdelay/clickdelay
/obj/screen/action_bar/clickdelay
name = "click delay"
icon = 'icons/effects/progessbar.dmi'
icon_state = "prog_bar_100"
layer = 20 // under hand buttons
/obj/screen/action_bar/clickdelay/Initialize()
. = ..()
var/matrix/M = new
M.Scale(2, 1)
transform = M
/obj/screen/action_bar/clickdelay/update_to_mob(mob/living/L)
var/estimated = L.EstimatedNextActionTime()
var/diff = estimated - L.last_action
var/left = estimated - world.time
if(left < 0 || diff < 0)
icon_state = "prog_bar_100"
return FALSE
icon_state = "prog_bar_[round(clamp(((diff - left)/diff) * 100, 0, 100), 5)]"
return TRUE
/datum/hud/var/obj/screen/action_bar/resistdelay/resistdelay
/obj/screen/action_bar/resistdelay
name = "resist delay"
icon = 'icons/effects/progessbar.dmi'
icon_state = "prog_bar_100"
/obj/screen/action_bar/resistdelay/update_to_mob(mob/living/L)
var/diff = L.next_resist - L.last_resist
var/left = L.next_resist - world.time
if(left < 0 || diff < 0)
icon_state = "prog_bar_100"
return FALSE
icon_state = "prog_bar_[round(clamp(((diff - left)/diff) * 100, 0, 100), 5)]"
return TRUE
@@ -0,0 +1,58 @@
/obj/screen/mov_intent
icon = 'modular_citadel/icons/ui/screen_midnight.dmi'
/obj/screen/sprintbutton
name = "toggle sprint"
icon = 'modular_citadel/icons/ui/screen_midnight.dmi'
icon_state = "act_sprint"
layer = ABOVE_HUD_LAYER - 0.1
var/mutable_appearance/flashy
/obj/screen/sprintbutton/Click()
if(ishuman(usr))
var/mob/living/carbon/human/H = usr
H.default_toggle_sprint()
/obj/screen/sprintbutton/update_icon_state()
var/mob/living/user = hud?.mymob
if(!istype(user))
return
if(user.combat_flags & COMBAT_FLAG_SPRINT_ACTIVE)
icon_state = "act_sprint_on"
else if(HAS_TRAIT(user, TRAIT_SPRINT_LOCKED))
icon_state = "act_sprint_locked"
else
icon_state = "act_sprint"
/obj/screen/sprintbutton/update_overlays()
. = ..()
var/mob/living/carbon/user = hud?.mymob
if(!istype(user) || !user.client)
return
if((user.combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) && user.client.prefs.hud_toggle_flash)
if(!flashy)
flashy = mutable_appearance('icons/mob/screen_gen.dmi', "togglehalf_flash")
if(flashy.color != user.client.prefs.hud_toggle_color)
flashy.color = user.client.prefs.hud_toggle_color
. += flashy
//Sprint buffer onscreen code.
/datum/hud/var/obj/screen/sprint_buffer/sprint_buffer
/obj/screen/sprint_buffer
name = "sprint buffer"
icon = 'icons/effects/progessbar.dmi'
icon_state = "prog_bar_100"
/obj/screen/sprint_buffer/Click()
if(isliving(usr))
var/mob/living/L = usr
to_chat(L, "<span class='boldnotice'>Your sprint buffer's maximum capacity is [L.sprint_buffer_max]. It is currently at [L.sprint_buffer], regenerating at [L.sprint_buffer_regen_ds * 10] per second. \
Sprinting while this is empty will incur a [L.sprint_stamina_cost] stamina cost per tile.</span>")
/obj/screen/sprint_buffer/proc/update_to_mob(mob/living/L)
var/amount = 0
if(L.sprint_buffer_max > 0)
amount = round(clamp((L.sprint_buffer / L.sprint_buffer_max) * 100, 0, 100), 5)
icon_state = "prog_bar_[amount]"
@@ -0,0 +1,61 @@
/datum/hud/var/obj/screen/staminas/staminas
/datum/hud/var/obj/screen/staminabuffer/staminabuffer
/obj/screen/staminas
icon = 'modular_citadel/icons/ui/screen_gen.dmi'
name = "stamina"
icon_state = "stamina0"
screen_loc = ui_stamina
mouse_opacity = 1
/obj/screen/staminas/Click(location,control,params)
if(isliving(usr))
var/mob/living/L = usr
to_chat(L, "<span class='notice'>You have <b>[L.getStaminaLoss()]</b> stamina loss.<br>Your stamina buffer can take <b>[L.stambuffer]</b> stamina loss, and recharges at no cost.<br>Your stamina buffer is <b>[(L.stambuffer*(100/L.stambuffer))-(L.bufferedstam*(100/L.stambuffer))]%</b> full.</span>")
/obj/screen/staminas/update_icon_state()
var/mob/living/carbon/user = hud?.mymob
if(!user)
return
if(user.stat == DEAD || (user.combat_flags & COMBAT_FLAG_HARD_STAMCRIT) || (user.hal_screwyhud in 1 to 2))
icon_state = "staminacrit"
else if(user.hal_screwyhud == 5)
icon_state = "stamina0"
else
icon_state = "stamina[clamp(FLOOR(user.getStaminaLoss() /20, 1), 0, 6)]"
//stam buffer
/obj/screen/staminabuffer
icon = 'modular_citadel/icons/ui/screen_gen.dmi'
name = "stamina buffer"
icon_state = "stambuffer0"
screen_loc = ui_stamina
layer = ABOVE_HUD_LAYER + 0.1
mouse_opacity = 0
/obj/screen/staminabuffer/update_icon_state()
var/mob/living/carbon/user = hud?.mymob
if(!user)
return
if(user.stat == DEAD || (user.combat_flags & COMBAT_FLAG_HARD_STAMCRIT) || (user.hal_screwyhud in 1 to 2))
icon_state = "stambuffer7"
else if(user.hal_screwyhud == 5)
icon_state = "stambuffer0"
else
switch(user.bufferedstam / user.stambuffer)
if(0.95 to INFINITY)
icon_state = "stambuffer7"
if(0.9 to 0.95)
icon_state = "stambuffer6"
if(0.8 to 0.9)
icon_state = "stambuffer5"
if(0.6 to 0.8)
icon_state = "stambuffer4"
if(0.4 to 0.6)
icon_state = "stambuffer3"
if(0.2 to 0.4)
icon_state = "stambuffer2"
if(0.05 to 0.2)
icon_state = "stambuffer1"
else
icon_state = "stambuffer0"
+3 -6
View File
@@ -9,12 +9,9 @@
/obj/screen/storage/Click(location, control, params)
if(!insertion_click)
return ..()
if(world.time <= usr.next_move)
return TRUE
if(usr.incapacitated())
return TRUE
if (ismecha(usr.loc)) // stops inventory actions in a mech
return TRUE
if(hud?.mymob && (hud.mymob != usr))
return
// just redirect clicks
if(master)
var/obj/item/I = usr.get_active_held_item()
if(I)
+22
View File
@@ -0,0 +1,22 @@
/obj/screen/voretoggle
name = "toggle vore mode"
icon = 'modular_citadel/icons/ui/screen_midnight.dmi'
icon_state = "nom_off"
/obj/screen/voretoggle/Click()
if(usr != hud.mymob)
return
var/mob/living/carbon/C = usr
if(SEND_SIGNAL(usr, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE))
to_chat(usr, "<span class='warning'>Disable combat mode first.</span>")
return
C.toggle_vore_mode()
/obj/screen/voretoggle/update_icon_state()
var/mob/living/carbon/user = hud?.mymob
if(!istype(user))
return
if(user.voremode)
icon_state = "nom"
else
icon_state = "nom_off"
+65 -37
View File
@@ -7,21 +7,22 @@
*and lastly
*afterattack. The return value does not matter.
*/
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params, flags, damage_multiplier = 1)
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params, attackchain_flags, damage_multiplier = 1)
if(isliving(user))
var/mob/living/L = user
if(!CHECK_MOBILITY(L, MOBILITY_USE) && !(flags & ATTACKCHAIN_PARRY_COUNTERATTACK))
if(!CHECK_MOBILITY(L, MOBILITY_USE) && !(attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK))
to_chat(L, "<span class='warning'>You are unable to swing [src] right now!</span>")
return
if(tool_behaviour && target.tool_act(user, src, tool_behaviour))
. = attackchain_flags
if(tool_behaviour && ((. = target.tool_act(user, src, tool_behaviour)) & STOP_ATTACK_PROC_CHAIN))
return
if(pre_attack(target, user, params))
if((. |= pre_attack(target, user, params, ., damage_multiplier)) & STOP_ATTACK_PROC_CHAIN)
return
if(target.attackby(src, user, params, flags, damage_multiplier))
if((. |= target.attackby(src, user, params, ., damage_multiplier)) & STOP_ATTACK_PROC_CHAIN)
return
if(QDELETED(src) || QDELETED(target))
return
afterattack(target, user, TRUE, params)
. |= afterattack(target, user, TRUE, params)
/// Like melee_attack_chain but for ranged.
/obj/item/proc/ranged_attack_chain(mob/user, atom/target, params)
@@ -30,7 +31,7 @@
if(!CHECK_MOBILITY(L, MOBILITY_USE))
to_chat(L, "<span class='warning'>You are unable to raise [src] right now!</span>")
return
afterattack(target, user, FALSE, params)
return afterattack(target, user, FALSE, params)
// Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown.
/obj/item/proc/attack_self(mob/user)
@@ -38,28 +39,43 @@
return
interact(user)
/obj/item/proc/pre_attack(atom/A, mob/living/user, params) //do stuff before attackby!
/obj/item/proc/pre_attack(atom/A, mob/living/user, params, attackchain_flags, damage_multiplier) //do stuff before attackby!
if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_NO_ATTACK)
return TRUE
return FALSE //return TRUE to avoid calling attackby after this proc does stuff
return STOP_ATTACK_PROC_CHAIN
if(!(attackchain_flags & ATTACK_IGNORE_CLICKDELAY) && !CheckAttackCooldown(user, A))
return STOP_ATTACK_PROC_CHAIN
// No comment
/atom/proc/attackby(obj/item/W, mob/user, params)
if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, params) & COMPONENT_NO_AFTERATTACK)
return TRUE
return FALSE
return STOP_ATTACK_PROC_CHAIN
/obj/attackby(obj/item/I, mob/living/user, params)
return ..() || ((obj_flags & CAN_BE_HIT) && I.attack_obj(src, user))
. = ..()
if(. & STOP_ATTACK_PROC_CHAIN)
return
if(obj_flags & CAN_BE_HIT)
. |= I.attack_obj(src, user)
/mob/living/attackby(obj/item/I, mob/living/user, params, attackchain_flags, damage_multiplier)
if(..())
return TRUE
I.attack_delay_done = FALSE //Should be set TRUE in pre_attacked_by()
. = I.attack(src, user, attackchain_flags, damage_multiplier)
if(!I.attack_delay_done) //Otherwise, pre_attacked_by() should handle it.
user.changeNext_move(I.click_delay)
. = ..()
if(. & STOP_ATTACK_PROC_CHAIN)
return
. |= I.attack(src, user, attackchain_flags, damage_multiplier)
if(!(. & NO_AUTO_CLICKDELAY_HANDLING)) // SAFETY NET - unless the proc tells us we should not handle this, give them the basic melee cooldown!
I.ApplyAttackCooldown(user, src, attackchain_flags)
/**
* Called when someone uses us to attack a mob in melee combat.
*
* This proc respects CheckAttackCooldown() default clickdelay handling.
*
* @params
* * mob/living/M - target
* * mob/living/user - attacker
* * attackchain_Flags - see [code/__DEFINES/_flags/return_values.dm]
* * damage_multiplier - what to multiply the damage by
*/
/obj/item/proc/attack(mob/living/M, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user) & COMPONENT_ITEM_NO_ATTACK)
return
@@ -88,6 +104,17 @@
if(weight)
user.adjustStaminaLossBuffered(weight)
// CIT SCREENSHAKE
if(force >= 15)
shake_camera(user, ((force - 10) * 0.01 + 1), ((force - 10) * 0.01))
if(M.client)
switch (M.client.prefs.damagescreenshake)
if (1)
shake_camera(M, ((force - 10) * 0.015 + 1), ((force - 10) * 0.015))
if (2)
if(!CHECK_MOBILITY(M, MOBILITY_MOVE))
shake_camera(M, ((force - 10) * 0.015 + 1), ((force - 10) * 0.015))
//the equivalent of the standard version of attack() but for object targets.
/obj/item/proc/attack_obj(obj/O, mob/living/user)
if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_OBJ, O, user) & COMPONENT_NO_ATTACK_OBJ)
@@ -95,8 +122,7 @@
if(item_flags & NOBLUDGEON)
return
user.do_attack_animation(O)
if(!O.attacked_by(src, user))
user.changeNext_move(click_delay)
O.attacked_by(src, user)
var/weight = getweight(user, STAM_COST_ATTACK_OBJ_MULT)
if(weight)
user.adjustStaminaLossBuffered(weight)//CIT CHANGE - makes attacking things cause stamina loss
@@ -109,12 +135,9 @@
var/bad_trait
var/stamloss = user.getStaminaLoss()
var/next_move_mult = 1
if(stamloss > STAMINA_NEAR_SOFTCRIT) //The more tired you are, the less damage you do.
var/penalty = (stamloss - STAMINA_NEAR_SOFTCRIT)/(STAMINA_NEAR_CRIT - STAMINA_NEAR_SOFTCRIT)*STAM_CRIT_ITEM_ATTACK_PENALTY
totitemdamage *= 1 - penalty
next_move_mult += penalty*STAM_CRIT_ITEM_ATTACK_DELAY
user.changeNext_move(I.click_delay*next_move_mult)
if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
bad_trait = SKILL_COMBAT_MODE //blacklist combat skills.
@@ -126,18 +149,18 @@
if(!(SKILL_TRAIN_ATTACK_OBJ in I.used_skills[skill]))
continue
user.mind.auto_gain_experience(skill, I.skill_gain)
if(!(attackchain_flags & NO_AUTO_CLICKDELAY_HANDLING))
I.ApplyAttackCooldown(user, src, attackchain_flags)
if(totitemdamage)
visible_message("<span class='danger'>[user] has hit [src] with [I]!</span>", null, null, COMBAT_MESSAGE_RANGE)
//only witnesses close by and the victim see a hit message.
log_combat(user, src, "attacked", I)
take_damage(totitemdamage, I.damtype, "melee", 1)
return TRUE
/mob/living/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
var/list/block_return = list()
var/totitemdamage = pre_attacked_by(I, user) * damage_multiplier
if((user != src) && mob_run_block(I, totitemdamage, "the [I.name]", ((attackchain_flags & ATTACKCHAIN_PARRY_COUNTERATTACK)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, null, block_return) & BLOCK_SUCCESS)
if((user != src) && mob_run_block(I, totitemdamage, "the [I.name]", ((attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK)? ATTACK_IS_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, null, block_return) & BLOCK_SUCCESS)
return FALSE
totitemdamage = block_calculate_resultant_damage(totitemdamage, block_return)
send_item_attack_message(I, user, null, totitemdamage)
@@ -155,8 +178,7 @@
/mob/living/simple_animal/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
if(I.force < force_threshold || I.damtype == STAMINA)
playsound(loc, 'sound/weapons/tap.ogg', I.get_clamped_volume(), 1, -1)
user.changeNext_move(I.click_delay) //pre_attacked_by not called
playsound(src, 'sound/weapons/tap.ogg', I.get_clamped_volume(), 1, -1)
else
return ..()
@@ -167,25 +189,21 @@
var/stamloss = user.getStaminaLoss()
var/stam_mobility_mult = 1
var/next_move_mult = 1
if(stamloss > STAMINA_NEAR_SOFTCRIT) //The more tired you are, the less damage you do.
var/penalty = (stamloss - STAMINA_NEAR_SOFTCRIT)/(STAMINA_NEAR_CRIT - STAMINA_NEAR_SOFTCRIT)*STAM_CRIT_ITEM_ATTACK_PENALTY
stam_mobility_mult -= penalty
next_move_mult += penalty*STAM_CRIT_ITEM_ATTACK_DELAY
if(stam_mobility_mult > LYING_DAMAGE_PENALTY && !CHECK_MOBILITY(user, MOBILITY_STAND)) //damage penalty for fighting prone, doesn't stack with the above.
stam_mobility_mult = LYING_DAMAGE_PENALTY
. *= stam_mobility_mult
user.changeNext_move(I.click_delay*next_move_mult)
I.attack_delay_done = TRUE
var/bad_trait
if(!(I.item_flags & NO_COMBAT_MODE_FORCE_MODIFIER))
if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
bad_trait = SKILL_COMBAT_MODE //blacklist combat skills.
if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE))
. *= 0.5
. *= 0.8
else if(SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
. *= 1.5
. *= 1.2
if(!user.mind || !I.used_skills)
return
@@ -197,8 +215,18 @@
var/datum/skill/S = GLOB.skill_datums[skill]
user.mind.auto_gain_experience(skill, I.skill_gain*S.item_skill_gain_multi)
// Proximity_flag is 1 if this afterattack was called on something adjacent, in your square, or on your person.
// Click parameters is the params string from byond Click() code, see that documentation.
/**
* Called after attacking something if the melee attack chain isn't interrupted before.
* Also called when clicking on something with an item without being in melee range
*
* WARNING: This does not automatically check clickdelay if not in a melee attack! Be sure to account for this!
*
* @params
* * target - The thing we clicked
* * user - mob of person clicking
* * proximity_flag - are we in melee range/doing it in a melee attack
* * click_parameters - mouse control parameters, check BYOND ref.
*/
/obj/item/proc/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
SEND_SIGNAL(src, COMSIG_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters)
SEND_SIGNAL(user, COMSIG_MOB_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters)
+1 -1
View File
@@ -37,7 +37,7 @@
CtrlClickOn(A)
return
if(world.time <= next_move)
if(!CheckActionCooldown())
return
// You are responsible for checking config.ghost_interaction when you override this function
// Not all of them require checking, see below
+42 -21
View File
@@ -5,7 +5,7 @@
Otherwise pretty standard.
*/
/mob/living/carbon/human/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE)
/mob/living/carbon/human/UnarmedAttack(atom/A, proximity, intent = a_intent, attackchain_flags = NONE)
if(!has_active_hand()) //can't attack without a hand.
to_chat(src, "<span class='notice'>You look at your arm and sigh.</span>")
@@ -16,33 +16,45 @@
to_chat(src, "<span class='warning'>The damage in your [check_arm.name] is preventing you from using it! Get it fixed, or at least splinted!</span>")
return
. = attackchain_flags
// Special glove functions:
// If the gloves do anything, have them return 1 to stop
// normal attack_hand() here.
var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines
if(proximity && istype(G) && G.Touch(A,1))
return
var/override = 0
if(proximity && istype(G))
. |= G.Touch(A, TRUE)
if(. & INTERRUPT_UNARMED_ATTACK)
return
for(var/datum/mutation/human/HM in dna.mutations)
override += HM.on_attack_hand(A, proximity, intent, flags)
. |= HM.on_attack_hand(A, proximity, intent, .)
if(override)
if(. & INTERRUPT_UNARMED_ATTACK)
return
SEND_SIGNAL(src, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, A)
A.attack_hand(src, intent, flags)
return . | A.attack_hand(src, intent, .)
//Return TRUE to cancel other attack hand effects that respect it.
/atom/proc/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = FALSE
/atom/proc/attack_hand(mob/user, act_intent = user.a_intent, attackchain_flags)
SHOULD_NOT_SLEEP(TRUE)
if(!(interaction_flags_atom & INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND))
add_fingerprint(user)
if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, user) & COMPONENT_NO_ATTACK_HAND)
. = TRUE
return
. = attackchain_flags
if(attack_hand_speed && !(. & ATTACK_IGNORE_CLICKDELAY))
if(!user.CheckActionCooldown(attack_hand_speed))
return
if(interaction_flags_atom & INTERACT_ATOM_ATTACK_HAND)
. = _try_interact(user)
INVOKE_ASYNC(src, .proc/on_attack_hand, user, act_intent, .)
if(!(. & ATTACK_IGNORE_ACTION))
if(attack_hand_unwieldlyness)
user.DelayNextAction(attack_hand_unwieldlyness, considered_action = attack_hand_is_action)
else if(attack_hand_is_action)
user.DelayNextAction()
/atom/proc/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
//Return a non FALSE value to cancel whatever called this from propagating, if it respects it.
/atom/proc/_try_interact(mob/user)
@@ -50,7 +62,6 @@
return interact(user)
if(can_interact(user))
return interact(user)
return FALSE
/atom/proc/can_interact(mob/user)
if(!user.can_interact_with(src))
@@ -80,8 +91,7 @@
else
add_fingerprint(user)
if(interaction_flags_atom & INTERACT_ATOM_UI_INTERACT)
return ui_interact(user)
return FALSE
ui_interact(user)
/*
/mob/living/carbon/human/RestrainedClickOn(var/atom/A) ---carbons will handle this
@@ -95,13 +105,19 @@
. = ..()
if(gloves)
var/obj/item/clothing/gloves/G = gloves
if(istype(G) && G.Touch(A,0)) // for magic gloves
. |= G.Touch(A, FALSE)
if(. & INTERRUPT_UNARMED_ATTACK)
return
if(istype(glasses))
. |= glasses.ranged_attack(src, A, mouseparams)
if(. & INTERRUPT_UNARMED_ATTACK)
return
if (istype(glasses) && glasses.ranged_attack(src,A,mouseparams))
return
for(var/datum/mutation/human/HM in dna.mutations)
HM.on_ranged_attack(A, mouseparams)
. |= HM.on_ranged_attack(A, mouseparams)
if(. & INTERRUPT_UNARMED_ATTACK)
return
if(isturf(A) && get_dist(src,A) <= 1)
src.Move_Pulled(A)
@@ -123,7 +139,9 @@
Monkeys
*/
/mob/living/carbon/monkey/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE)
A.attack_paw(src, intent, flags)
if(!CheckActionCooldown(CLICK_CD_MELEE))
return
return !isnull(A.attack_paw(src, intent, flags))
/atom/proc/attack_paw(mob/user)
if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_PAW, user) & COMPONENT_NO_ATTACK_HAND)
@@ -144,6 +162,8 @@
return
if(is_muzzled())
return
if(!CheckActionCooldown(CLICK_CD_MELEE))
return
var/mob/living/carbon/ML = A
if(istype(ML))
var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
@@ -163,6 +183,7 @@
ML.ForceContractDisease(D)
else
ML.visible_message("<span class='danger'>[src] has attempted to bite [ML]!</span>")
DelayNextAction()
/*
Aliens
@@ -243,7 +264,7 @@
/mob/living/simple_animal/hostile/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE)
target = A
if(dextrous && !ismob(A))
..()
return ..()
else
AttackingTarget()
+76
View File
@@ -0,0 +1,76 @@
/mob/proc/RightClickOn(atom/A, params) //mostly a copy-paste from ClickOn()
var/list/modifiers = params2list(params)
if(incapacitated(ignore_restraints = 1))
return
face_atom(A)
if(!CheckActionCooldown())
return
if(!modifiers["catcher"] && A.IsObscured())
return
if(ismecha(loc))
var/obj/mecha/M = loc
return M.click_action(A,src,params)
if(restrained())
DelayNextAction(CLICK_CD_HANDCUFFED)
return RestrainedClickOn(A)
if(in_throw_mode)
throw_item(A)//todo: make it plausible to lightly toss items via right-click
return
var/obj/item/W = get_active_held_item()
if(W == A)
if(!W.rightclick_attack_self(src))
W.attack_self(src)
update_inv_hands()
return
//These are always reachable.
//User itself, current loc, and user inventory
if(A in DirectAccess())
if(W)
return W.rightclick_melee_attack_chain(src, A, params)
else
if(!AltUnarmedAttack(A, TRUE))
. = UnarmedAttack(A, TRUE, a_intent)
if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A))
DelayNextAction(CLICK_CD_MELEE)
return
return
//Can't reach anything else in lockers or other weirdness
if(!loc.AllowClick())
return
//Standard reach turf to turf or reaching inside storage
if(CanReach(A,W))
if(W)
return W.rightclick_melee_attack_chain(src, A, params)
else
if(!AltUnarmedAttack(A, TRUE))
. = UnarmedAttack(A, TRUE, a_intent)
if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A))
DelayNextAction(CLICK_CD_MELEE)
return
return
else
if(W)
if(!W.altafterattack(A, src, FALSE, params))
return W.afterattack(A, src, FALSE, params)
else
if(!AltRangedAttack(A, params))
return RangedAttack(A, params)
/mob/proc/AltUnarmedAttack(atom/A, proximity_flag)
if(ismob(A))
DelayNextAction(CLICK_CD_MELEE)
return FALSE
/mob/proc/AltRangedAttack(atom/A, params)
return FALSE
+19
View File
@@ -0,0 +1,19 @@
/obj/item/proc/rightclick_melee_attack_chain(mob/user, atom/target, params)
if(!alt_pre_attack(target, user, params)) //Hey, does this item have special behavior that should override all normal right-click functionality?
if(!target.altattackby(src, user, params)) //Does the target do anything special when we right-click on it?
. = melee_attack_chain(user, target, params) //Ugh. Lame! I'm filing a legal complaint about the discrimination against the right mouse button!
else
. = altafterattack(target, user, TRUE, params)
/obj/item/proc/alt_pre_attack(atom/A, mob/living/user, params)
return FALSE //return something other than false if you wanna override attacking completely
/atom/proc/altattackby(obj/item/W, mob/user, params)
return FALSE //return something other than false if you wanna add special right-click behavior to objects.
/obj/item/proc/rightclick_attack_self(mob/user)
return FALSE
/obj/item/proc/altafterattack(atom/target, mob/user, proximity_flag, click_parameters)
SEND_SIGNAL(src, COMSIG_ITEM_ALT_AFTERATTACK, target, user, proximity_flag, click_parameters)
return FALSE
+50
View File
@@ -0,0 +1,50 @@
/mob/living/carbon/human/AltUnarmedAttack(atom/A, proximity)
if(!has_active_hand())
to_chat(src, "<span class='notice'>You look at the state of the universe and sigh.</span>") //lets face it, people rarely ever see this message in its intended condition.
return TRUE
return A.alt_attack_hand(src)
/mob/living/carbon/human/AltRangedAttack(atom/A, params)
if(isturf(A) || incapacitated()) // pretty annoying to wave your fist at floors and walls. And useless.
return
if(!CheckActionCooldown(CLICK_CD_RANGE))
return
DelayNextAction()
var/list/target_viewers = fov_viewers(11, A) //doesn't check for blindness.
if(!(src in target_viewers)) //click catcher issuing calls for out of view objects.
return TRUE
if(!has_active_hand())
to_chat(src, "<span class='notice'>You ponder your life choices and sigh.</span>")
return TRUE
var/list/src_viewers = viewers(DEFAULT_MESSAGE_RANGE, src) - src // src has a different message.
var/the_action = "waves to [A]"
var/what_action = "waves to something you can't see"
var/self_action = "wave to [A]"
switch(a_intent)
if(INTENT_DISARM)
the_action = "shoos away [A]"
what_action = "shoo away something out of your vision"
self_action = "shoo away [A]"
if(INTENT_GRAB)
the_action = "beckons [A] to come"
what_action = "beckons something out of your vision to come"
self_action = "beckon [A] to come"
if(INTENT_HARM)
var/pronoun = "[p_their()]"
the_action = "shakes [pronoun] fist at [A]"
what_action = "shakes [pronoun] fist at something out of your vision"
self_action = "shake your fist at [A]"
if(!eye_blind)
to_chat(src, "You [self_action].")
for(var/B in src_viewers)
var/mob/M = B
if(!M.eye_blind)
var/message = (M in target_viewers) ? the_action : what_action
to_chat(M, "[src] [message].")
return TRUE
/atom/proc/alt_attack_hand(mob/user)
return FALSE
+3 -2
View File
@@ -123,7 +123,8 @@
. = ..()
if(!target || !user)
return
if(!user.CheckActionCooldown(CLICK_CD_MELEE))
return
if(!focus)
focus_object(target)
return
@@ -145,7 +146,7 @@
else
apply_focus_overlay()
focus.throw_at(target, 10, 1,user)
user.changeNext_move(CLICK_CD_MELEE)
user.DelayNextAction(considered_action = TRUE, flush = TRUE)
update_icon()
/proc/tkMaxRangeCheck(mob/user, atom/target)
@@ -470,3 +470,5 @@
/datum/config_entry/flag/minimaps_enabled
config_entry_value = TRUE
/datum/config_entry/string/centcom_ban_db // URL for the CentCom Galactic Ban DB API
@@ -0,0 +1,6 @@
// Smooth HUD updates, but low priority
PROCESSING_SUBSYSTEM_DEF(huds)
name = "HUD updates"
wait = 0.5
priority = FIRE_PRIORITY_HUDS
stat_tag = "HUDS"
+1 -2
View File
@@ -103,8 +103,7 @@
. = ..()
QDEL_IN(src, 300)
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/effect/hallucination/simple/bluespace_stream/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/effect/hallucination/simple/bluespace_stream/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(user != seer || !linked_to)
return
var/slip_in_message = pick("slides sideways in an odd way, and disappears", "jumps into an unseen dimension",\
@@ -263,6 +263,14 @@
time = 30
category = CAT_CLOTHING
/datum/crafting_recipe/durathread_reinforcement_kit
name = "Durathread Reinforcement Kit"
result = /obj/item/armorkit
reqs = list(/obj/item/stack/sheet/durathread = 4)
tools = list(/obj/item/stack/sheet/mineral/titanium, TOOL_WIRECUTTER) // tough needle for a tough fabric
time = 40
category = CAT_CLOTHING
/datum/crafting_recipe/durathread_duffelbag
name = "Durathread Dufflebag"
result = /obj/item/storage/backpack/duffelbag/durathread
+4 -4
View File
@@ -98,16 +98,16 @@
/datum/component/simple_rotation/proc/HandRot(datum/source, mob/user, rotation = default_rotation_direction)
if(can_be_rotated)
if(!can_be_rotated.Invoke(user, default_rotation_direction))
if(!can_be_rotated.Invoke(user, rotation))
return
else
if(!default_can_be_rotated(user, default_rotation_direction))
if(!default_can_be_rotated(user, rotation))
return
if(can_user_rotate)
if(!can_user_rotate.Invoke(user, default_rotation_direction))
if(!can_user_rotate.Invoke(user, rotation))
return
else
if(!default_can_user_rotate(user, default_rotation_direction))
if(!default_can_user_rotate(user, rotation))
return
BaseRot(user, rotation)
return TRUE
+9
View File
@@ -102,6 +102,15 @@ GLOBAL_LIST_EMPTY(uplinks)
return //no hitting everyone/everything just to try to slot tcs in!
if(istype(I, /obj/item/stack/telecrystal))
LoadTC(user, I)
if(active)
if(I.GetComponent(/datum/component/uplink))
var/datum/component/uplink/hidden_uplink = I.GetComponent(/datum/component/uplink)
var/amt = hidden_uplink.telecrystals
hidden_uplink.telecrystals -= amt
src.telecrystals += amt
to_chat(user, "<span class='notice'>You connect the [I] to your uplink, siphoning [amt] telecrystals before quickly undoing the connection.")
else
return
for(var/category in uplink_items)
for(var/item in uplink_items[category])
var/datum/uplink_item/UI = uplink_items[category][item]
+74
View File
@@ -0,0 +1,74 @@
/datum/http_request
var/id
var/in_progress = FALSE
var/method
var/body
var/headers
var/url
var/_raw_response
/datum/http_request/proc/prepare(method, url, body = "", list/headers)
if (!length(headers))
headers = ""
else
headers = json_encode(headers)
src.method = method
src.url = url
src.body = body
src.headers = headers
/datum/http_request/proc/execute_blocking()
_raw_response = rustg_http_request_blocking(method, url, body, headers)
/datum/http_request/proc/begin_async()
if (in_progress)
CRASH("Attempted to re-use a request object.")
id = rustg_http_request_async(method, url, body, headers)
if (isnull(text2num(id)))
stack_trace("Proc error: [id]")
_raw_response = "Proc error: [id]"
else
in_progress = TRUE
/datum/http_request/proc/is_complete()
if (isnull(id))
return TRUE
if (!in_progress)
return TRUE
var/r = rustg_http_check_request(id)
if (r == RUSTG_JOB_NO_RESULTS_YET)
return FALSE
else
_raw_response = r
in_progress = FALSE
return TRUE
/datum/http_request/proc/into_response()
var/datum/http_response/R = new()
try
var/list/L = json_decode(_raw_response)
R.status_code = L["status_code"]
R.headers = L["headers"]
R.body = L["body"]
catch
R.errored = TRUE
R.error = _raw_response
return R
/datum/http_response
var/status_code
var/body
var/list/headers
var/errored = FALSE
var/error
+3 -3
View File
@@ -44,11 +44,11 @@
//Here we roll for our damage to be added into the damage var in the various attack procs. This is changed depending on whether we are in combat mode, lying down, or if our target is in combat mode.
var/damage = rand(A.dna.species.punchdamagelow, A.dna.species.punchdamagehigh)
if(SEND_SIGNAL(D, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
damage *= 1.5
damage *= 1.2
if(!CHECK_MOBILITY(A, MOBILITY_STAND))
damage *= 0.5
damage *= 0.7
if(SEND_SIGNAL(A, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
damage *= 0.25
damage *= 0.8
return damage
/datum/martial_art/proc/teach(mob/living/carbon/human/H, make_temporary = FALSE)
@@ -274,3 +274,13 @@
description = "<span class='warning'>I've produced better art than that from my ass.</span>\n"
mood_change = -2
timeout = 1200
/datum/mood_event/tripped
description = "<span class='boldwarning'>I can't believe I fell for the oldest trick in the book!</span>\n"
mood_change = -6
timeout = 2 MINUTES
/datum/mood_event/untied
description = "<span class='boldwarning'>I hate when my shoes come untied!</span>\n"
mood_change = -3
timeout = 1 MINUTES
+5 -1
View File
@@ -21,7 +21,11 @@
/datum/mutation/human/hulk/on_attack_hand(atom/target, proximity, act_intent, unarmed_attack_flags)
if(proximity && (act_intent == INTENT_HARM)) //no telekinetic hulk attack
return target.attack_hulk(owner)
if(!owner.CheckActionCooldown(CLICK_CD_MELEE))
return INTERRUPT_UNARMED_ATTACK | NO_AUTO_CLICKDELAY_HANDLING
owner.DelayNextAction()
target.attack_hulk(owner)
return INTERRUPT_UNARMED_ATTACK | NO_AUTO_CLICKDELAY_HANDLING
/datum/mutation/human/hulk/on_life()
if(owner.health < 0)
-5
View File
@@ -144,7 +144,6 @@
id = "tased"
alert_type = null
var/movespeed_mod = /datum/movespeed_modifier/status_effect/tased
var/nextmove_modifier = 1
var/stamdmg_per_ds = 0 //a 20 duration would do 20 stamdmg, disablers do 24 or something
var/last_tick = 0 //fastprocess processing speed is a goddamn sham, don't trust it.
@@ -173,13 +172,9 @@
C.adjustStaminaLoss(max(0, stamdmg_per_ds * diff)) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
last_tick = world.time
/datum/status_effect/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
return nextmove_modifier
/datum/status_effect/electrode/no_combat_mode
id = "tased_strong"
movespeed_mod = /datum/movespeed_modifier/status_effect/tased/no_combat_mode
nextmove_modifier = 2
blocks_combatmode = TRUE
stamdmg_per_ds = 1
+4 -5
View File
@@ -90,13 +90,12 @@
return
duration = world.time + original_duration
//clickdelay/nextmove modifiers!
/datum/status_effect/proc/nextmove_modifier()
/**
* Multiplied to clickdelays
*/
/datum/status_effect/proc/action_cooldown_mod()
return 1
/datum/status_effect/proc/nextmove_adjust()
return 0
////////////////
// ALERT HOOK //
////////////////
+1 -1
View File
@@ -151,7 +151,7 @@
return 1
/datum/status_effect/wound/bone/nextmove_modifier()
/datum/status_effect/wound/bone/action_cooldown_mod()
var/mob/living/carbon/C = owner
if(C.get_active_hand() == linked_limb)
+9 -1
View File
@@ -70,6 +70,9 @@
/// A luminescence-shifted value of the last color calculated for chatmessage overlays
var/chat_color_darkened
///Mobs that are currently do_after'ing this atom, to be cleared from on Destroy()
var/list/targeted_by
/atom/New(loc, ...)
//atom creation method that preloads variables at creation
if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New()
@@ -144,6 +147,11 @@
LAZYCLEARLIST(overlays)
LAZYCLEARLIST(priority_overlays)
for(var/i in targeted_by)
var/mob/M = i
LAZYREMOVE(M.do_afters, src)
targeted_by = null
QDEL_NULL(light)
return ..()
@@ -219,7 +227,7 @@
/atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
SEND_SIGNAL(src, COMSIG_ATOM_HULK_ATTACK, user)
if(does_attack_animation)
user.changeNext_move(CLICK_CD_MELEE)
user.DelayNextAction(CLICK_CD_MELEE)
log_combat(user, src, "punched", "hulk powers")
user.do_attack_animation(src, ATTACK_EFFECT_SMASH)
+20 -76
View File
@@ -38,7 +38,8 @@ Credit where due:
5. Xhuis from /tg/ for coding the first iteration of the mode, and the new, reworked version
6. ChangelingRain from /tg/ for maintaining the gamemode for months after its release prior to its rework
7. Clockwork cult code as of now, at least the one being pulled from Citadel Station's master branch, is being, or already is, fixed by Coolgat3 and Avunia.
8. Modern clockwork cult code mixed with original clockwork code, with various changes to make it less of a fustercluck, done by KeRSe. \
Fixes and assistance done by TimothyTeakettle, Kevinz000, and Deltafire15. -Very glad for the help they gave.
*/
///////////
@@ -133,7 +134,7 @@ Credit where due:
config_tag = "clockwork_cult"
antag_flag = ROLE_SERVANT_OF_RATVAR
false_report_weight = 10
required_players = 35
required_players = 24 //Fixing this directly for now since apparently config machine for forcing modes broke.
required_enemies = 3
recommended_enemies = 5
enemy_minimum_age = 7
@@ -143,13 +144,12 @@ Credit where due:
announce_text = "Servants of Ratvar are trying to summon the Justiciar!\n\
<span class='brass'>Servants</span>: Construct defenses to protect the Ark. Sabotage the station!\n\
<span class='notice'>Crew</span>: Stop the servants before they can summon the Clockwork Justiciar."
var/servants_to_serve = list()
var/list/servants_to_serve = list() //Yes this list is made out of list
var/roundstart_player_count
var/ark_time //In minutes, how long the Ark waits before activation; this is equal to 30 + (number of players / 5) (max 40 mins.)
var/datum/team/clockcult/main_clockcult
/datum/game_mode/clockwork_cult/pre_setup()
/datum/game_mode/clockwork_cult/pre_setup() //Gamemode and job code is pain. Have fun codediving all of that stuff, whoever works on this next - Delta
var/list/errorList = list()
var/list/reebes = SSmapping.LoadGroup(errorList, "Reebe", "map_files/generic", "City_of_Cogs.dmm", default_traits = ZTRAITS_REEBE, silent = TRUE)
if(errorList.len) // reebe failed to load
@@ -162,38 +162,36 @@ Credit where due:
restricted_jobs += protected_jobs
if(CONFIG_GET(flag/protect_assistant_from_antagonist))
restricted_jobs += "Assistant"
var/starter_servants = 4 //Guaranteed four servants
var/starter_servants = 4 //Try to go for at least four
var/number_players = num_players()
roundstart_player_count = number_players
if(number_players > 30) //plus one servant for every additional 10 players above 30
number_players -= 30
starter_servants += round(number_players / 10)
starter_servants = min(starter_servants, 8) //max 8 servants (that sould only happen with a ton of players)
GLOB.clockwork_vitality += 50 * starter_servants //some starter Vitality to help recover from initial fuck ups
starter_servants = min(starter_servants, 8) //max 8 servants (that sould only happen with a ton of players)
while(starter_servants)
if(!antag_candidates.len)
break //Skip setup, DO NOT RUNTIME
var/datum/mind/servant = antag_pick(antag_candidates)
servants_to_serve += servant
antag_candidates -= servant
servant.assigned_role = ROLE_SERVANT_OF_RATVAR
servant.special_role = ROLE_SERVANT_OF_RATVAR
servant.restricted_roles = restricted_jobs
starter_servants--
ark_time = 30 + round((roundstart_player_count / 5)) //In minutes, how long the Ark will wait before activation
ark_time = min(ark_time, 35) //35 minute maximum for the activation timer
return 1
if(!servants_to_serve.len) //Uh oh, something went wrong
setup_error = "There are no clockcult candidates! (Or something went very wrong)"
return FALSE
GLOB.clockwork_vitality += 50 * servants_to_serve.len //some starter Vitality to help recover from initial fuck ups
return TRUE //Haha yes it works time to not touch it any more than that.
/datum/game_mode/clockwork_cult/post_setup()
for(var/S in servants_to_serve)
var/datum/mind/servant = S
log_game("[key_name(servant)] was made an initial servant of Ratvar")
var/mob/living/L = servant.current
var/turf/T = pick(GLOB.servant_spawns)
L.forceMove(T)
GLOB.servant_spawns -= T
greet_servant(L)
equip_servant(L)
add_servant_of_ratvar(L, TRUE)
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar //that's a mouthful
G.final_countdown(ark_time)
..()
return 1
@@ -201,20 +199,18 @@ Credit where due:
if(!M)
return 0
to_chat(M, "<span class='bold large_brass'>You are a servant of Ratvar, the Clockwork Justiciar!</span>")
to_chat(M, "<span class='brass'>You have approximately <b>[ark_time]</b> minutes until the Ark activates.</span>")
to_chat(M, "<span class='brass'>Unlock <b>Script</b> scripture by converting a new servant.</span>")
to_chat(M, "<span class='brass'><b>Application</b> scripture will be unlocked halfway until the Ark's activation.</span>")
to_chat(M, "<span class='brass'>Unlock <b>Script</b> scripture by converting a new servant or when 35kw of power is reached.</span>")
to_chat(M, "<span class='brass'><b>Application</b> scripture will be unlocked when 50kw of power is reached.</span>")
M.playsound_local(get_turf(M), 'sound/ambience/antag/clockcultalr.ogg', 100, FALSE, pressure_affected = FALSE)
return 1
/datum/game_mode/proc/equip_servant(mob/living/M) //Grants a clockwork slab to the mob, with one of each component
/datum/game_mode/proc/equip_servant(mob/living/M) //Grants a clockwork slab to the mob
if(!M || !ishuman(M))
return FALSE
var/mob/living/carbon/human/L = M
L.equipOutfit(/datum/outfit/servant_of_ratvar)
var/obj/item/clockwork/slab/S = new
var/slot = "At your feet"
var/list/slots = list("In your left pocket" = SLOT_L_STORE, "In your right pocket" = SLOT_R_STORE, "In your backpack" = SLOT_IN_BACKPACK, "On your belt" = SLOT_BELT)
var/list/slots = list("In your left pocket" = SLOT_L_STORE, "In your right pocket" = SLOT_R_STORE, "In your backpack" = SLOT_IN_BACKPACK)
if(ishuman(L))
var/mob/living/carbon/human/H = L
slot = H.equip_in_one_of_slots(S, slots)
@@ -224,7 +220,6 @@ Credit where due:
if(!S.forceMove(get_turf(L)))
qdel(S)
if(S && !QDELETED(S))
to_chat(L, "<span class='bold large_brass'>There is a paper in your backpack! It'll tell you if anything's changed, as well as what to expect.</span>")
to_chat(L, "<span class='alloy'>[slot] is a <b>clockwork slab</b>, a multipurpose tool used to construct machines and invoke ancient words of power. If this is your first time \
as a servant, you can find a concise tutorial in the Recollection category of its interface.</span>")
to_chat(L, "<span class='alloy italics'>If you want more information, you can read <a href=\"https://tgstation13.org/wiki/Clockwork_Cult\">the wiki page</a> to learn more.</span>")
@@ -278,7 +273,7 @@ Credit where due:
gloves = /obj/item/clothing/gloves/color/yellow
belt = /obj/item/storage/belt/utility/servant
backpack_contents = list(/obj/item/storage/box/engineer = 1, \
/obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/paper/servant_primer = 1, /obj/item/reagent_containers/food/drinks/bottle/holyoil = 1)
/obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/reagent_containers/food/drinks/bottle/holyoil = 1)
id = /obj/item/pda
var/plasmaman //We use this to determine if we should activate internals in post_equip()
@@ -305,54 +300,3 @@ Credit where due:
PDA.update_label()
PDA.id_check(H, W)
H.sec_hud_set_ID()
//This paper serves as a quick run-down to the cult as well as a changelog to refer to.
//Check strings/clockwork_cult_changelog.txt for the changelog, and update it when you can!
/obj/item/paper/servant_primer
name = "The Ark And You: A Primer On Servitude"
color = "#DAAA18"
info = "<b>DON'T PANIC.</b><br><br>\
Here's a quick primer on what you should know here.\
<ol>\
<li>You're in a place called Reebe right now. The crew can't get here normally.</li>\
<li>In the north is your base camp, with supplies, consoles, and the Ark. In the south is an inaccessible area that the crew can walk between \
once they arrive (more on that later.) Everything between that space is an open area.</li>\
<li>Your job as a servant is to build fortifications and defenses to protect the Ark and your base once the Ark activates. You can do this \
however you like, but work with your allies and coordinate your efforts.</li>\
<li>Once the Ark activates, the station will be alerted. Portals to Reebe will open up in nearly every room. When they take these portals, \
the crewmembers will arrive in the area that you can't access, but can get through it freely - whereas you can't. Treat this as the \"spawn\" of the \
crew and defend it accordingly.</li>\
</ol>\
<hr>\
Here is the layout of Reebe, from left to right:\
<ul>\
<li><b>Dressing Room:</b> Contains clothing, a dresser, and a mirror. There are spare slabs and absconders here.</li>\
<li><b>Listening Station:</b> Contains intercoms, a telecomms relay, and a list of frequencies.</li>\
<li><b>Ark Chamber:</b> Houses the Ark.</li>\
<li><b>Observation Room:</b> Contains five camera observers. These can be used to watch the station through its cameras, as well as to teleport down \
to most areas. To do this, use the Warp action while hovering over the tile you want to warp to.</li>\
<li><b>Infirmary:</b> Contains sleepers and basic medical supplies for superficial wounds. The sleepers can consume Vitality to heal any occupants. \
This room is generally more useful during the preparation phase; when defending the Ark, scripture is more useful.</li>\
</ul>\
<hr>\
<h2>Things that have changed:</h2>\
<ul>\
CLOCKCULTCHANGELOG\
</ul>\
<hr>\
<b>Good luck!</b>"
/obj/item/paper/servant_primer/Initialize()
. = ..()
var/changelog = world.file2list("strings/clockwork_cult_changelog.txt")
var/changelog_contents = ""
for(var/entry in changelog)
changelog_contents += "<li>[entry]</li>"
info = replacetext(info, "CLOCKCULTCHANGELOG", changelog_contents)
/*
/obj/item/paper/servant_primer/oui_getcontent(mob/target)
if(!is_servant_of_ratvar(target) && !isobserver(target))
return "<HTML><HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><TITLE>[name]</TITLE></HEAD><BODY>[stars(info)]<HR>[stamps]</BODY></HTML>"
return ..()
*/
+1 -1
View File
@@ -149,7 +149,7 @@
add_fingerprint(user)
return ..()
/obj/machinery/dominator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/machinery/dominator/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(operating || (stat & BROKEN))
examine(user)
return
+1 -1
View File
@@ -7,7 +7,7 @@
/obj/structure/door_assembly
var/datum/airlock_maker/maker = null
/obj/structure/door_assembly/attack_hand()
/obj/structure/door_assembly/on_attack_hand()
. = ..()
if(.)
return
+1 -4
View File
@@ -107,10 +107,7 @@
stat |= BROKEN
update_icon()
/obj/machinery/pdapainter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/pdapainter/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!storedpda)
to_chat(user, "<span class='notice'>[src] is empty.</span>")
+1 -1
View File
@@ -313,7 +313,7 @@ Class Procs:
if(user.a_intent != INTENT_HARM)
return attack_hand(user)
else
user.changeNext_move(CLICK_CD_MELEE)
user.DelayNextAction(CLICK_CD_MELEE)
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
user.visible_message("<span class='danger'>[user.name] smashes against \the [src.name] with its paws.</span>", null, null, COMBAT_MESSAGE_RANGE)
take_damage(4, BRUTE, "melee", 1)
+1 -4
View File
@@ -122,10 +122,7 @@
else
icon_state = "airlock_sensor_off"
/obj/machinery/airlock_sensor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/airlock_sensor/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
var/datum/signal/signal = new(list(
"tag" = master_tag,
"command" = "cycle"
+1 -4
View File
@@ -100,10 +100,7 @@
stat |= BROKEN
update_icon()
/obj/machinery/aug_manipulator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/aug_manipulator/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
add_fingerprint(user)
if(storedpart)
+1 -1
View File
@@ -138,7 +138,7 @@
var/obj/item/assembly/control/A = device
A.id = "[idnum][id]"
/obj/machinery/button/attack_hand(mob/user)
/obj/machinery/button/on_attack_hand(mob/user)
. = ..()
if(.)
return
+1 -1
View File
@@ -235,7 +235,7 @@
itemname = P.name
info = P.notehtml
to_chat(U, "<span class='notice'>You hold \the [itemname] up to the camera...</span>")
U.changeNext_move(CLICK_CD_MELEE)
U.DelayNextAction(CLICK_CD_MELEE)
for(var/mob/O in GLOB.player_list)
if(isAI(O))
var/mob/living/silicon/ai/AI = O
+1 -4
View File
@@ -79,10 +79,7 @@
charging = null
update_icon()
/obj/machinery/cell_charger/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/cell_charger/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!charging)
return
@@ -8,7 +8,7 @@
icon_state = "arcade"
circuit = /obj/item/circuitboard/computer/arcade/amputation
/obj/machinery/computer/arcade/amputation/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/machinery/computer/arcade/amputation/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!iscarbon(user))
return
var/mob/living/carbon/c_user = user
+2 -113
View File
@@ -103,10 +103,7 @@
return FALSE
return ..()
/obj/machinery/computer/camera_advanced/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/computer/camera_advanced/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(current_user)
to_chat(user, "The console is already in use!")
return
@@ -276,112 +273,4 @@
C.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static)
C.clear_fullscreen("flash", 3) //Shorter flash than normal since it's an ~~advanced~~ console!
else
playsound(origin, 'sound/machines/terminal_prompt_deny.ogg', 25, 0)
//Used by servants of Ratvar! They let you beam to the station.
/obj/machinery/computer/camera_advanced/ratvar
name = "ratvarian camera observer"
desc = "A console used to snoop on the station's goings-on. A jet of steam occasionally whooshes out from slats on its sides."
use_power = FALSE
networks = list("ss13", "minisat") //:eye:
var/datum/action/innate/servant_warp/warp_action = new
/obj/machinery/computer/camera_advanced/ratvar/Initialize()
. = ..()
ratvar_act()
/obj/machinery/computer/camera_advanced/ratvar/process()
if(prob(1))
playsound(src, 'sound/machines/clockcult/steam_whoosh.ogg', 25, TRUE)
new/obj/effect/temp_visual/steam_release(get_turf(src))
/obj/machinery/computer/camera_advanced/ratvar/CreateEye()
..()
eyeobj.visible_icon = TRUE
eyeobj.icon = 'icons/mob/cameramob.dmi' //in case you still had any doubts
eyeobj.icon_state = "generic_camera"
/obj/machinery/computer/camera_advanced/ratvar/GrantActions(mob/living/carbon/user)
..()
if(warp_action)
warp_action.Grant(user)
warp_action.target = src
actions += warp_action
/obj/machinery/computer/camera_advanced/ratvar/can_use(mob/living/user)
if(!is_servant_of_ratvar(user))
to_chat(user, "<span class='warning'>[src]'s keys are in a language foreign to you, and you don't understand anything on its screen.</span>")
return
if(clockwork_ark_active())
to_chat(user, "<span class='warning'>The Ark is active, and [src] has shut down.</span>")
return
. = ..()
/datum/action/innate/servant_warp
name = "Warp"
desc = "Warps to the tile you're viewing. You can use the Abscond scripture to return. Clicking this button again cancels the warp."
icon_icon = 'icons/mob/actions/actions_clockcult.dmi'
button_icon_state = "warp_down"
background_icon_state = "bg_clock"
buttontooltipstyle = "clockcult"
var/cancel = FALSE //if TRUE, an active warp will be canceled
var/obj/effect/temp_visual/ratvar/warp_marker/warping
/datum/action/innate/servant_warp/Activate()
if(QDELETED(target) || !(ishuman(owner) || iscyborg(owner)) || !owner.canUseTopic(target))
return
if(!GLOB.servants_active) //No leaving unless there's servants from the get-go
return
if(warping)
cancel = TRUE
return
var/mob/living/carbon/human/user = owner
var/mob/camera/aiEye/remote/remote_eye = user.remote_control
var/obj/machinery/computer/camera_advanced/ratvar/R = target
var/turf/T = get_turf(remote_eye)
if(!is_reebe(user.z) || !is_station_level(T.z))
return
if(isclosedturf(T))
to_chat(user, "<span class='sevtug_small'>You can't teleport into a wall.</span>")
return
else if(isspaceturf(T))
to_chat(user, "<span class='sevtug_small'>[prob(1) ? "Servant cannot into space." : "You can't teleport into space."]</span>")
return
else if(T.flags_1 & NOJAUNT_1)
to_chat(user, "<span class='sevtug_small'>This tile is blessed by holy water and deflects the warp.</span>")
return
var/area/AR = get_area(T)
if(!AR.clockwork_warp_allowed)
to_chat(user, "<span class='sevtug_small'>[AR.clockwork_warp_fail]</span>")
return
if(alert(user, "Are you sure you want to warp to [AR]?", target.name, "Warp", "Cancel") == "Cancel" || QDELETED(R) || !user.canUseTopic(R))
return
do_sparks(5, TRUE, user)
do_sparks(5, TRUE, T)
warping = new(T)
user.visible_message("<span class='warning'>[user]'s [target.name] flares!</span>", "<span class='bold sevtug_small'>You begin warping to [AR]...</span>")
button_icon_state = "warp_cancel"
owner.update_action_buttons()
if(!do_after(user, 50, target = warping, extra_checks = CALLBACK(src, .proc/is_canceled)))
to_chat(user, "<span class='bold sevtug_small'>Warp interrupted.</span>")
QDEL_NULL(warping)
button_icon_state = "warp_down"
owner.update_action_buttons()
cancel = FALSE
return
button_icon_state = "warp_down"
owner.update_action_buttons()
QDEL_NULL(warping)
if(!do_teleport(user, T, channel = TELEPORT_CHANNEL_CULT, forced = TRUE))
to_chat(user, "<span class='bold sevtug_small'>Warp Failed. Something deflected our attempt to warp to [AR].</span>")
return
T.visible_message("<span class='warning'>[user] warps in!</span>")
playsound(user, 'sound/magic/magic_missile.ogg', 50, TRUE)
playsound(T, 'sound/magic/magic_missile.ogg', 50, TRUE)
user.setDir(SOUTH)
flash_color(user, flash_color = "#AF0AAF", flash_time = 5)
R.remove_eye_control(user)
/datum/action/innate/servant_warp/proc/is_canceled()
return !cancel
playsound(origin, 'sound/machines/terminal_prompt_deny.ogg', 25, 0)
+1 -1
View File
@@ -59,7 +59,7 @@
return defib.get_cell()
//defib interaction
/obj/machinery/defibrillator_mount/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/machinery/defibrillator_mount/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!defib)
to_chat(user, "<span class='warning'>There's no defibrillator unit loaded!</span>")
return
+1 -1
View File
@@ -31,7 +31,7 @@
if(user.Adjacent(src))
. += "<span class='notice'>Alt-click it to beam its contents to any nearby disposal bins.</span>"
/obj/machinery/dish_drive/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/machinery/dish_drive/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!contents.len)
to_chat(user, "<span class='warning'>There's nothing in [src]!</span>")
return
-2
View File
@@ -70,8 +70,6 @@
if(!locked)
open_machine()
return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
"<span class='hear'>You hear a metallic creaking from [src].</span>")
+3 -4
View File
@@ -763,10 +763,7 @@
/obj/machinery/door/airlock/attack_paw(mob/user)
return attack_hand(user)
/obj/machinery/door/airlock/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/door/airlock/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!(issilicon(user) || IsAdminGhost(user)))
if(src.isElectrified())
if(src.shock(user, 100))
@@ -783,6 +780,8 @@
H.apply_damage(10, BRUTE, BODY_ZONE_HEAD)
else
visible_message("<span class='danger'>[user] headbutts the airlock. Good thing [user.p_theyre()] wearing a helmet.</span>")
else
return ..()
/obj/machinery/door/airlock/attempt_wire_interaction(mob/user)
if(security_level)
+1 -4
View File
@@ -140,10 +140,7 @@
do_animate("deny")
return
/obj/machinery/door/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/door/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
return try_to_activate_door(user)
/obj/machinery/door/attack_tk(mob/user)
+3 -7
View File
@@ -24,6 +24,8 @@
armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 70)
interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN
air_tight = TRUE
attack_hand_is_action = TRUE
attack_hand_speed = CLICK_CD_MELEE
var/emergency_close_timer = 0
var/nextstate = null
var/boltslocked = TRUE
@@ -80,7 +82,6 @@
return TRUE
return FALSE
/obj/machinery/door/firedoor/power_change()
if(powered(power_channel))
stat &= ~NOPOWER
@@ -88,11 +89,7 @@
else
stat |= NOPOWER
/obj/machinery/door/firedoor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/door/firedoor/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!welded && !operating && !(stat & NOPOWER) && (!density || allow_hand_open(user)))
add_fingerprint(user)
if(density)
@@ -103,7 +100,6 @@
return TRUE
if(operating || !density)
return
user.changeNext_move(CLICK_CD_MELEE)
user.visible_message("[user] bangs on \the [src].",
"You bang on \the [src].")
+1 -1
View File
@@ -141,7 +141,7 @@
if(user)
log_game("[user] reset a fire alarm at [COORD(src)]")
/obj/machinery/firealarm/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/machinery/firealarm/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(buildstage != 2)
return ..()
add_fingerprint(user)
-2
View File
@@ -101,8 +101,6 @@ The console is located at computer/gulag_teleporter.dm
if(!locked)
open_machine()
return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
"<span class='italics'>You hear a metallic creaking from [src].</span>")
+1 -1
View File
@@ -50,7 +50,7 @@
harvesting = FALSE
warming_up = FALSE
/obj/machinery/harvester/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/machinery/harvester/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(state_open)
close_machine()
else if(!harvesting)
+1 -1
View File
@@ -78,7 +78,7 @@ GLOBAL_LIST_EMPTY(network_holopads)
new_disk.forceMove(src)
disk = new_disk
/obj/machinery/holopad/tutorial/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/machinery/holopad/tutorial/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!istype(user))
return
if(user.incapacitated() || !is_operational())
-2
View File
@@ -178,8 +178,6 @@
icon_state += "_occupied"
/obj/machinery/hypnochair/container_resist(mob/living/user)
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(600)].)</span>", \
"<span class='hear'>You hear a metallic creaking from [src].</span>")
+1 -4
View File
@@ -26,10 +26,7 @@
on = TRUE
icon_state = "igniter1"
/obj/machinery/igniter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/igniter/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
add_fingerprint(user)
use_power(50)
+1 -4
View File
@@ -158,10 +158,7 @@
attached.transfer_blood_to(beaker, amount)
update_icon()
/obj/machinery/iv_drip/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/iv_drip/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(attached)
visible_message("[attached] is detached from [src]")
attached = null
@@ -17,6 +17,7 @@
active_power_usage = 300 //when active, this turret takes up constant 300 Equipment power
req_access = list(ACCESS_SEC_DOORS)
power_channel = EQUIP //drains power from the EQUIPMENT channel
speed_process = TRUE
var/base_icon_state = "standard"
var/scan_range = 7
@@ -53,7 +54,7 @@
var/last_fired = 0 //world.time the turret last fired
var/shot_delay = 15 //ticks until next shot (1.5 ?)
var/shot_stagger = 0 // sleep() shots to stagger attacks
var/check_records = 1 //checks if it can use the security records
var/criminals = 1 //checks if it can shoot people on arrest
@@ -436,6 +437,9 @@
else if(!always_up)
popDown() // no valid targets, close the cover
/obj/machinery/porta_turret/proc/randomize_shot_stagger()
shot_stagger = rand(0, min(2 SECONDS, round(shot_delay/3, world.tick_lag)))
/obj/machinery/porta_turret/proc/tryToShootAt(list/atom/movable/targets)
while(targets.len > 0)
var/atom/movable/M = pick(targets)
@@ -443,7 +447,6 @@
if(target(M))
return 1
/obj/machinery/porta_turret/proc/popUp() //pops the turret up
if(!anchored)
return
@@ -525,11 +528,14 @@
if(target)
popUp() //pop the turret up if it's not already up.
setDir(get_dir(base, target))//even if you can't shoot, follow the target
shootAt(target)
INVOKE_ASYNC(src, .proc/shootAt, target)
return 1
return
/obj/machinery/porta_turret/proc/shootAt(atom/movable/target)
/obj/machinery/porta_turret/proc/shootAt(atom/movable/target, stagger_enabled = FALSE)
if(stagger_enabled)
randomize_shot_stagger()
sleep(shot_stagger)
if(!raised) //the turret has to be raised in order to fire - makes sense, right?
return
@@ -79,6 +79,9 @@
if(PTURRET_INTERNAL_ARMOUR_ON)
if(istype(I, /obj/item/gun/energy)) //the gun installation part
var/obj/item/gun/energy/E = I
if(!E.can_turret)
to_chat(user, "<span class='warning'>[src] can't be fit into turrets.</span>")
return
if(!user.transferItemToLoc(E, src))
return
installed_gun = E
@@ -168,10 +171,7 @@
return ..()
/obj/machinery/porta_turret_construct/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/porta_turret_construct/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
switch(build_step)
if(PTURRET_GUN_EQUIPPED)
build_step = PTURRET_INTERNAL_ARMOUR_ON
@@ -31,10 +31,7 @@
return parent_turret.attack_ai(user)
/obj/machinery/porta_turret_cover/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/porta_turret_cover/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
return parent_turret.attack_hand(user)
+1 -4
View File
@@ -108,10 +108,7 @@
return ..()
/obj/machinery/recharger/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/recharger/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
add_fingerprint(user)
if(charging)
-2
View File
@@ -301,8 +301,6 @@
open_machine()
dump_contents()
return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message("<span class='notice'>You see [user] kicking against the doors of [src]!</span>", \
"<span class='notice'>You start kicking against the doors... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
"<span class='italics'>You hear a thump from [src].</span>")
+1 -4
View File
@@ -68,10 +68,7 @@ GLOBAL_VAR_INIT(singularity_counter, 0)
/obj/machinery/power/singularity_beacon/attack_ai(mob/user)
return
/obj/machinery/power/singularity_beacon/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/power/singularity_beacon/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(anchored)
return active ? Deactivate(user) : Activate(user)
else
@@ -21,7 +21,7 @@
. = ..()
stored = new /obj/item/blackbox(src)
/obj/machinery/blackbox_recorder/attack_hand(mob/living/user)
/obj/machinery/blackbox_recorder/on_attack_hand(mob/living/user, act_intent, unarmed_attack_flags)
. = ..()
if(stored)
to_chat(user, "<span class='notice'>You start struggling to pry the [stored] from the [src]...</span>")
+1 -4
View File
@@ -297,10 +297,7 @@ GLOBAL_LIST_INIT(dye_registry, list(
else
return ..()
/obj/machinery/washing_machine/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/machinery/washing_machine/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(busy)
to_chat(user, "<span class='warning'>[src] is busy.</span>")
return
+3 -3
View File
@@ -10,7 +10,7 @@
var/charges = 1
var/insisting = 0
/obj/machinery/wish_granter/attack_hand(mob/living/carbon/user)
/obj/machinery/wish_granter/on_attack_hand(mob/living/carbon/user)
if(charges <= 0)
to_chat(user, "The Wish Granter lies silent.")
return
@@ -31,7 +31,7 @@
user.dna.add_mutation(XRAY)
user.dna.add_mutation(SPACEMUT)
user.dna.add_mutation(TK)
user.next_move_modifier *= 0.5 //half the delay between attacks!
user.action_cooldown_mod *= 0.5
to_chat(user, "Things around you feel slower!")
charges--
insisting = FALSE
@@ -101,7 +101,7 @@
to_chat(user, "[killreward] materializes into your hands!")
else
to_chat(user, "[killreward] materializes onto the floor.")
user.next_move_modifier *= 0.8 //20% less delay between attacks!
user.action_cooldown_mod *= 0.8
to_chat(user, "Things around you feel slightly slower!")
var/mob/living/simple_animal/hostile/venus_human_trap/killwish = new /mob/living/simple_animal/hostile/venus_human_trap(loc)
killwish.maxHealth = 1500
+4 -2
View File
@@ -15,6 +15,8 @@
internals_req_access = list()
add_req_access = 0
wreckage = /obj/structure/mecha_wreckage/durand/neovgre
stepsound = 'sound/mecha/neostep2.ogg'
turnsound = 'sound/mecha/powerloader_step.ogg'
/obj/mecha/combat/neovgre/GrantActions(mob/living/user, human_occupant = 0) //No Eject action for you sonny jim, your life for Ratvar!
internals_action.Grant(user, src)
@@ -32,7 +34,7 @@
/obj/mecha/combat/neovgre/MouseDrop_T(mob/M, mob/user)
if(!is_servant_of_ratvar(user))
to_chat(user, "<span class='brass'>BEGONE HERETIC!</span>")
to_chat(user, "<span class='neovgre'>BEGONE HEATHEN!</span>")
return
else
..()
@@ -91,7 +93,7 @@
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre
equip_cooldown = 8 //Rapid fire heavy laser cannon, simple yet elegant
energy_drain = 30
name = "Aribter Laser Cannon"
name = "Arbiter Laser Cannon"
desc = "Please re-attach this to neovgre and stop asking questions about why it looks like a normal Nanotrasen issue Solaris laser cannon - Nezbere"
fire_sound = 'sound/weapons/neovgre_laser.ogg'
+2
View File
@@ -24,6 +24,8 @@
infra_luminosity = 15 //byond implementation is bugged.
force = 5
flags_1 = HEAR_1|BLOCK_FACE_ATOM_1
attack_hand_speed = CLICK_CD_MELEE
attack_hand_is_action = TRUE
var/can_move = 0 //time of next allowed movement
var/mob/living/occupant = null
var/step_in = 10 //make a step in step_in/10 sec.
+2 -6
View File
@@ -54,11 +54,7 @@
. *= booster_damage_modifier
/obj/mecha/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
user.changeNext_move(CLICK_CD_MELEE) // Ugh. Ideally we shouldn't be setting cooldowns outside of click code.
/obj/mecha/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
playsound(loc, 'sound/weapons/tap.ogg', 40, 1, -1)
user.visible_message("<span class='danger'>[user] hits [name]. Nothing happens</span>", null, null, COMBAT_MESSAGE_RANGE)
@@ -255,7 +251,7 @@
return
else if(istype(W, /obj/item/weldingtool) && user.a_intent != INTENT_HARM)
user.changeNext_move(CLICK_CD_MELEE)
user.DelayNextAction(CLICK_CD_MELEE)
if(obj_integrity < max_integrity)
if(W.use_tool(src, user, 0, volume=50, amount=1))
if (internal_damage & MECHA_INT_TANK_BREACH)
+11 -1
View File
@@ -9,7 +9,7 @@
var/buckle_prevents_pull = FALSE
//Interaction
/atom/movable/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
/atom/movable/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
@@ -145,3 +145,13 @@
var/mob/living/L = M.pulledby
L.set_pull_offsets(M, L.grab_state)
return M
/atom/movable/proc/precise_user_unbuckle_mob(mob/user)
if(!buckled_mobs)
return
else if(length(buckled_mobs) == 1)
return user_unbuckle_mob(buckled_mobs[1], user)
else
var/unbuckled = input(user, "Who do you wish to unbuckle?","Unbuckle Who?") as null|mob in buckled_mobs
return user_unbuckle_mob(unbuckled, user)
+1 -4
View File
@@ -101,10 +101,7 @@
to_chat(user, "<span class='notice'>You carefully remove the poster from the wall.</span>")
roll_and_drop(user.loc)
/obj/structure/sign/poster/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/structure/sign/poster/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(ruined)
return
visible_message("[user] rips [src] in a single, decisive motion!" )
@@ -137,10 +137,7 @@
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
beauty = -150
/obj/effect/decal/cleanable/vomit/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/effect/decal/cleanable/vomit/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(isflyperson(H))
@@ -268,6 +268,8 @@
gender = PLURAL
max_integrity = 20
CanAtmosPass = ATMOS_PASS_DENSITY
attack_hand_speed = CLICK_CD_MELEE
attack_hand_is_action = TRUE
/obj/structure/foamedmetal/Initialize()
. = ..()
@@ -284,11 +286,7 @@
/obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
/obj/structure/foamedmetal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
user.changeNext_move(CLICK_CD_MELEE)
/obj/structure/foamedmetal/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
to_chat(user, "<span class='warning'>You hit [src] but bounce off it!</span>")
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
+1 -4
View File
@@ -60,10 +60,7 @@
/obj/effect/portal/attack_tk(mob/user)
return
/obj/effect/portal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/effect/portal/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(get_turf(user) == get_turf(src))
teleport(user)
if(Adjacent(user))
+3 -6
View File
@@ -120,6 +120,8 @@
var/poison_type = "toxin"
var/poison_per_bite = 5
var/list/faction = list("spiders")
attack_hand_speed = CLICK_CD_MELEE
attack_hand_is_action = TRUE
/obj/structure/spider/spiderling/Destroy()
new/obj/item/reagent_containers/food/snacks/spiderling(get_turf(src))
@@ -153,10 +155,9 @@
else
..()
/obj/structure/spider/spiderling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/structure/spider/spiderling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(user.a_intent != INTENT_HELP)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
user.visible_message("<span class='warning'>[user] splats [src].</span>", "<span class='warning'>You splat [src].</span>", "<span class='italics'>You hear a splat...</span>")
playsound(loc, 'sound/effects/snap.ogg', 25)
@@ -253,8 +254,6 @@
/obj/structure/spider/cocoon/container_resist(mob/living/user)
var/breakout_time = 600
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
to_chat(user, "<span class='notice'>You struggle against the tight bonds... (This will take about [DisplayTimeText(breakout_time)].)</span>")
visible_message("You see something struggling and writhing in \the [src]!")
if(do_after(user,(breakout_time), target = src))
@@ -262,8 +261,6 @@
return
qdel(src)
/obj/structure/spider/cocoon/Destroy()
var/turf/T = get_turf(src)
src.visible_message("<span class='warning'>\The [src] splits open.</span>")
+6 -13
View File
@@ -11,6 +11,10 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
name = "item"
icon = 'icons/obj/items_and_weapons.dmi'
blocks_emissive = EMISSIVE_BLOCK_GENERIC
attack_hand_speed = 0
attack_hand_is_action = FALSE
attack_hand_unwieldlyness = 0
///icon state name for inhand overlays
var/item_state = null
@@ -58,15 +62,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
/// How long, in deciseconds, this staggers for, if null it will autocalculate from w_class and force. Unlike total mass this supports 0 and negatives.
var/stagger_force
/**
* Set FALSE and then checked at the end of on mob/living/attackby(), set TRUE on living/pre_attacked_by().
* Should it be FALSE by the end of the item/attack(), that means the item overrode the standard attack behaviour
* and the user still needs the delay applied. We can't be using return values since that'll stop afterattack() from being triggered.
*/
var/attack_delay_done = FALSE
///next_move click/attack delay of this item.
var/click_delay = CLICK_CD_MELEE
var/slot_flags = 0 //This is used to determine on which slots an item can fit.
var/current_equipped_slot
pass_flags = PASSTABLE
@@ -313,10 +308,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
add_fingerprint(usr)
return ..()
/obj/item/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
/obj/item/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!user)
return
if(anchored)
@@ -473,6 +465,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
usr.UnarmedAttack(src, TRUE)
if(usr.get_active_held_item() == src)
melee_attack_chain(usr, over)
usr.FlushCurrentAction()
return TRUE //returning TRUE as a "is this overridden?" flag
if(!Adjacent(usr) || !over.Adjacent(usr))
return // should stop you from dragging through windows
+44
View File
@@ -0,0 +1,44 @@
// Armor kits! Reinforcing uniforms to maintain fashion and also armor capabilities.
/obj/item/armorkit
name = "durathread armor kit"
desc = "A glorified sewing kit with durathread sheets, thread, and a titanium needle, for reinforcing jumpsuits and uniforms."
icon = 'icons/obj/clothing/reinf_kits.dmi'
w_class = WEIGHT_CLASS_SMALL
icon_state = "durathread_kit" // shoutout to my guy Toriate for being good at sprites tho
/obj/item/armorkit/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
// yeah have fun making subtypes and modifying the afterattack if you want to make variants
// idiot
// - hatter
var/used = FALSE
if(isobj(target) && istype(target, /obj/item/clothing/under))
var/obj/item/clothing/under/C = target
if(C.armor.melee < 10)
C.armor.melee = 10
used = TRUE
if(C.armor.laser < 10)
C.armor.laser = 10
used = TRUE
if(C.armor.fire < 40)
C.armor.fire = 40
used = TRUE
if(C.armor.acid < 10)
C.armor.acid = 10
used = TRUE
if(C.armor.bomb < 5)
C.armor.bomb = 5
used = TRUE
if(used)
user.visible_message("<span class = 'notice'>[user] uses [src] on [C], reinforcing it and tossing the empty case away afterwards.</span>", \
"<span class = 'notice'>You reinforce [C] with [src], making it a little more protective! You toss the empty casing away afterwards.</span>")
C.name = "durathread [C.name]" // this disappears if it gets repaired, which is annoying
qdel(src)
return
else
to_chat(user, "<span class = 'notice'>You stare at [src] and [C], coming to the conclusion that you probably don't need to reinforce it any further.")
return
else
return
-2
View File
@@ -71,8 +71,6 @@
if(user.incapacitated())
to_chat(user, "<span class='warning'>You can't get out while you're restrained like this!</span>")
return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
to_chat(user, "<span class='notice'>You claw at the fabric of [src], trying to tear it open...</span>")
to_chat(loc, "<span class='warning'>Someone starts trying to break free of [src]!</span>")
if(!do_after(user, 200, target = src))
+3 -3
View File
@@ -6,6 +6,8 @@
icon_state = "cutout_basic"
w_class = WEIGHT_CLASS_BULKY
resistance_flags = FLAMMABLE
attack_hand_speed = CLICK_CD_MELEE
attack_hand_is_action = TRUE
/// Possible restyles for the cutout, add an entry in change_appearance() if you add to here
var/static/list/possible_appearances
/// If the cutout is pushed over and has to be righted
@@ -43,8 +45,7 @@
"Monkey" = image(icon = src.icon, icon_state = "cutout_monky"),
))
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/cardboard_cutout/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/item/cardboard_cutout/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
if(user.a_intent == INTENT_HELP || pushed_over)
return ..()
user.visible_message("<span class='warning'>[user] pushes over [src]!</span>", "<span class='danger'>You push over [src]!</span>")
@@ -81,7 +82,6 @@
else if(I.hitsound)
playsound(loc, I.hitsound, get_clamped_volume(), 1, -1)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
if(I.force)
+1 -1
View File
@@ -188,4 +188,4 @@
else
..()
else
..()
..()
+2 -2
View File
@@ -32,6 +32,6 @@
if(istype(I, /obj/item/gavelhammer))
playsound(loc, 'sound/items/gavel.ogg', 100, 1)
user.visible_message("<span class='warning'>[user] strikes [src] with [I].</span>")
user.changeNext_move(CLICK_CD_MELEE)
return TRUE
else
return ..()
return ..()
+6 -4
View File
@@ -273,7 +273,9 @@
. = ..()
if(!proximity || !check_allowed_items(target))
return
draw_on(target, user, proximity, params)
/obj/item/toy/crayon/proc/draw_on(atom/target, mob/user, proximity, params)
var/static/list/punctuation = list("!","?",".",",","/","+","-","=","%","#","&")
var/cost = 1
@@ -568,9 +570,9 @@
dye_color = DYE_RAINBOW
charges = -1
/obj/item/toy/crayon/rainbow/afterattack(atom/target, mob/user, proximity, params)
/obj/item/toy/crayon/rainbow/draw_on(atom/target, mob/user, proximity, params)
paint_color = rgb(rand(0,255), rand(0,255), rand(0,255))
. = ..()
return ..()
/*
* Crayon Box
@@ -693,7 +695,7 @@
. += "It is empty."
. += "<span class='notice'>Alt-click [src] to [ is_capped ? "take the cap off" : "put the cap on"].</span>"
/obj/item/toy/crayon/spraycan/afterattack(atom/target, mob/user, proximity, params)
/obj/item/toy/crayon/spraycan/draw_on(atom/target, mob/user, proximity, params)
if(!proximity)
return
@@ -766,7 +768,7 @@
desc = "A metallic container containing shiny synthesised paint."
charges = -1
/obj/item/toy/crayon/spraycan/borg/afterattack(atom/target,mob/user,proximity, params)
/obj/item/toy/crayon/spraycan/borg/draw_on(atom/target,mob/user,proximity, params)
var/diff = ..()
if(!iscyborg(user))
to_chat(user, "<span class='notice'>How did you get this?</span>")
+1 -2
View File
@@ -77,8 +77,7 @@
/obj/item/defibrillator/ui_action_click()
toggle_paddles()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/item/defibrillator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/item/defibrillator/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(loc == user)
if(slot_flags == ITEM_SLOT_BACK)
if(user.get_item_by_slot(SLOT_BACK) == src)
@@ -132,8 +132,7 @@
/obj/effect/dummy/chameleon/attackby()
master.disrupt()
//ATTACK HAND IGNORING PARENT RETURN VALUE
/obj/effect/dummy/chameleon/attack_hand()
/obj/effect/dummy/chameleon/on_attack_hand()
master.disrupt()
/obj/effect/dummy/chameleon/attack_animal()
@@ -116,8 +116,6 @@
if(!hound)
go_out(user)
return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
if(user.a_intent == INTENT_HELP)
return
var/voracious = TRUE
@@ -43,7 +43,7 @@
user.visible_message("<span class='warning'>[user] projects a forcefield!</span>","<span class='notice'>You project a forcefield.</span>")
var/obj/structure/projected_forcefield/F = new(T, src)
current_fields += F
user.changeNext_move(CLICK_CD_MELEE)
user.DelayNextAction(CLICK_CD_MELEE)
/obj/item/forcefield_projector/attack_self(mob/user)
if(LAZYLEN(current_fields))
@@ -263,3 +263,11 @@
icon = 'icons/obj/advancedtools.dmi'
icon_state = "multitool"
toolspeed = 0.2
/obj/item/multitool/advanced/brass
name = "clockwork multitool"
desc = "A brass...multitool? With three prongs arcing electricity between them. It vibrates subtly in your hand."
icon = 'icons/obj/tools.dmi'
icon_state = "clockitool"
toolspeed = 0.2

Some files were not shown because too many files have changed in this diff Show More