Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into upstream-merge-27442
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
#define MC_TICK_CHECK ( ( world.tick_usage > GLOB.CURRENT_TICKLIMIT || src.state != SS_RUNNING ) ? pause() : 0 )
|
||||
#define MC_TICK_CHECK ( ( world.tick_usage > Master.current_ticklimit || src.state != SS_RUNNING ) ? pause() : 0 )
|
||||
|
||||
#define MC_SPLIT_TICK_INIT(phase_count) var/original_tick_limit = GLOB.CURRENT_TICKLIMIT; var/split_tick_phases = ##phase_count
|
||||
#define MC_SPLIT_TICK_INIT(phase_count) var/original_tick_limit = Master.current_ticklimit; var/split_tick_phases = ##phase_count
|
||||
#define MC_SPLIT_TICK \
|
||||
if(split_tick_phases > 1){\
|
||||
GLOB.CURRENT_TICKLIMIT = ((original_tick_limit - world.tick_usage) / split_tick_phases) + world.tick_usage;\
|
||||
Master.current_ticklimit = ((original_tick_limit - world.tick_usage) / split_tick_phases) + world.tick_usage;\
|
||||
--split_tick_phases;\
|
||||
} else {\
|
||||
GLOB.CURRENT_TICKLIMIT = original_tick_limit;\
|
||||
Master.current_ticklimit = original_tick_limit;\
|
||||
}
|
||||
|
||||
// Used to smooth out costs to try and avoid oscillation.
|
||||
|
||||
@@ -80,6 +80,15 @@
|
||||
#define AI_IDLE 2
|
||||
#define AI_OFF 3
|
||||
|
||||
#define ENVIRONMENT_SMASH_NONE 0
|
||||
|
||||
#define ENVIRONMENT_SMASH_STRUCTURES 1
|
||||
|
||||
#define ENVIRONMENT_SMASH_WALLS 2
|
||||
|
||||
#define ENVIRONMENT_SMASH_RWALLS 3
|
||||
|
||||
|
||||
//SNPCs
|
||||
//AI defines
|
||||
#define INTERACTING 2
|
||||
|
||||
@@ -39,4 +39,5 @@
|
||||
|
||||
#define STATUS_EFFECT_HISWRATH /datum/status_effect/his_wrath //His Wrath.
|
||||
|
||||
#define STATUS_EFFECT_SUMMONEDGHOST /datum/status_effect/cultghost //is a cult ghost and can't use manifest runes
|
||||
#define STATUS_EFFECT_SUMMONEDGHOST /datum/status_effect/cultghost //is a cult ghost and can't use manifest runes
|
||||
#define STATUS_EFFECT_CRUSHERMARK /datum/status_effect/crusher_mark //if struck with a proto-kinetic crusher, takes a ton of damage
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
// Subsystem init_order, from highest priority to lowest priority
|
||||
// The numbers just define the ordering, they are meaningless otherwise.
|
||||
|
||||
#define INIT_ORDER_SERVER_MAINT 16
|
||||
#define INIT_ORDER_JOBS 15
|
||||
#define INIT_ORDER_EVENTS 14
|
||||
#define INIT_ORDER_TICKER 13
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
#define TICK_LIMIT_MC 70
|
||||
#define TICK_LIMIT_MC_INIT_DEFAULT 98
|
||||
|
||||
#define TICK_CHECK ( world.tick_usage > GLOB.CURRENT_TICKLIMIT )
|
||||
#define TICK_CHECK ( world.tick_usage > Master.current_ticklimit )
|
||||
#define CHECK_TICK if TICK_CHECK stoplag()
|
||||
|
||||
+14
-14
@@ -340,20 +340,20 @@ Proc for attack log creation, because really why not
|
||||
qdel(progbar)
|
||||
|
||||
|
||||
//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)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
//pass a list in the format list("health" = mob's health var) to check health during this
|
||||
/mob/living/break_do_after_checks(list/checked_health, check_clicks)
|
||||
if(islist(checked_health))
|
||||
if(health < checked_health["health"])
|
||||
return FALSE
|
||||
checked_health["health"] = health
|
||||
return ..()
|
||||
|
||||
//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)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
//pass a list in the format list("health" = mob's health var) to check health during this
|
||||
/mob/living/break_do_after_checks(list/checked_health, check_clicks)
|
||||
if(islist(checked_health))
|
||||
if(health < checked_health["health"])
|
||||
return FALSE
|
||||
checked_health["health"] = health
|
||||
return ..()
|
||||
|
||||
/proc/do_after(mob/user, delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null)
|
||||
if(!user)
|
||||
return 0
|
||||
|
||||
@@ -626,14 +626,13 @@ GLOBAL_DATUM_INIT(sortInstance, /datum/sortInstance, new())
|
||||
var/val2 = fetchElement(L,cursor2)
|
||||
|
||||
while(1)
|
||||
if(call(cmp)(val1,val2) < 0)
|
||||
if(call(cmp)(val1,val2) <= 0)
|
||||
if(++cursor1 >= end1)
|
||||
break
|
||||
val1 = fetchElement(L,cursor1)
|
||||
else
|
||||
moveElement(L,cursor2,cursor1)
|
||||
|
||||
++cursor2
|
||||
if(++cursor2 >= end2)
|
||||
break
|
||||
++end1
|
||||
@@ -653,4 +652,4 @@ GLOBAL_DATUM_INIT(sortInstance, /datum/sortInstance, new())
|
||||
#undef MIN_GALLOP
|
||||
#undef MIN_MERGE
|
||||
|
||||
#undef fetchElement
|
||||
#undef fetchElement
|
||||
|
||||
@@ -723,7 +723,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
//Irregular objects
|
||||
var/icon/AMicon = icon(AM.icon, AM.icon_state)
|
||||
var/icon/AMiconheight = AMicon.Height()
|
||||
var/icon/AMiconwidth = AMicon.Width()
|
||||
var/icon/AMiconwidth = AMicon.Width()
|
||||
if(AMiconheight != world.icon_size || AMiconwidth != world.icon_size)
|
||||
pixel_x_offset += ((AMicon.Width()/world.icon_size)-1)*(world.icon_size*0.5)
|
||||
pixel_y_offset += ((AMicon.Height()/world.icon_size)-1)*(world.icon_size*0.5)
|
||||
@@ -1215,7 +1215,7 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
|
||||
. += round(i*DELTA_CALC)
|
||||
sleep(i*world.tick_lag*DELTA_CALC)
|
||||
i *= 2
|
||||
while (world.tick_usage > min(TICK_LIMIT_TO_RUN, GLOB.CURRENT_TICKLIMIT))
|
||||
while (world.tick_usage > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit))
|
||||
|
||||
#undef DELTA_CALC
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
GLOBAL_VAR_INIT(master_mode, "traitor") //"extended"
|
||||
GLOBAL_VAR_INIT(master_mode, "traitor") //"extended"
|
||||
GLOBAL_VAR_INIT(secret_force_mode, "secret") // if this is anything but "secret", the secret rotation will forceably choose this mode
|
||||
|
||||
GLOBAL_VAR_INIT(wavesecret, 0) // meteor mode, delays wave progression, terrible name
|
||||
|
||||
@@ -161,3 +161,4 @@ GLOBAL_LIST_INIT(numbers_as_words, list("One", "Two", "Three", "Four",
|
||||
return L
|
||||
|
||||
GLOBAL_LIST_INIT(station_numerals, greek_letters + phonetic_alphabet + numbers_as_words + generate_number_strings())
|
||||
GLOBAL_LIST_INIT(admiral_messages, list("Do you know how expensive these stations are?","Stop wasting my time.","I was sleeping, thanks a lot.","Stand and fight you cowards!","You knew the risks coming in.","Stop being paranoid.","Whatever's broken just build a new one.","No.", "<i>null</i>","<i>Error: No comment given.</i>", "It's a good day to die!"))
|
||||
|
||||
@@ -8,7 +8,7 @@ GLOBAL_VAR_INIT(fileaccess_timer, 0)
|
||||
|
||||
GLOBAL_VAR_INIT(TAB, " ")
|
||||
|
||||
GLOBAL_DATUM(data_core, /datum/datacore)
|
||||
GLOBAL_DATUM_INIT(data_core, /datum/datacore, new)
|
||||
|
||||
GLOBAL_VAR_INIT(CELLRATE, 0.002) // multiplier for watts per tick <> cell storage (eg: .002 means if there is a load of 1000 watts, 20 units will be taken from a cell per second)
|
||||
GLOBAL_VAR_INIT(CHARGELEVEL, 0.001) // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
selected_target[1] = null
|
||||
|
||||
/client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params)
|
||||
if(selected_target[1] && over_object.IsAutoclickable())
|
||||
if(selected_target[1] && over_object && over_object.IsAutoclickable())
|
||||
selected_target[1] = over_object
|
||||
selected_target[2] = params
|
||||
|
||||
|
||||
+448
-446
@@ -1,149 +1,149 @@
|
||||
/*
|
||||
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/changeNext_move(num)
|
||||
next_move = world.time + ((num+next_move_adjust)*next_move_modifier)
|
||||
|
||||
|
||||
/*
|
||||
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.
|
||||
|
||||
Alternately, you could hardcode every mob's variation in a flat ClickOn() proc; however,
|
||||
that's a lot of code duplication and is hard to maintain.
|
||||
|
||||
Note that this proc can be overridden, and is in the case of screen objects.
|
||||
*/
|
||||
/atom/Click(location,control,params)
|
||||
if(initialized)
|
||||
usr.ClickOn(src, params)
|
||||
|
||||
/atom/DblClick(location,control,params)
|
||||
if(initialized)
|
||||
usr.DblClickOn(src,params)
|
||||
|
||||
/atom/MouseWheel(delta_x,delta_y,location,control,params)
|
||||
if(initialized)
|
||||
usr.MouseWheelOn(src, delta_x, delta_y, params)
|
||||
|
||||
/*
|
||||
Standard mob ClickOn()
|
||||
Handles exceptions: Buildmode, middle click, modified clicks, mech actions
|
||||
|
||||
After that, mostly just check your state, check whether you're holding an item,
|
||||
check whether you're adjacent to the target, then pass off the click to whoever
|
||||
is recieving it.
|
||||
The most common are:
|
||||
* mob/UnarmedAttack(atom,adjacent) - used here only when adjacent, with no item in hand; in the case of humans, checks gloves
|
||||
* atom/attackby(item,user) - used only when adjacent
|
||||
* 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 + 1
|
||||
|
||||
if(client && client.click_intercept)
|
||||
if(call(client.click_intercept, "InterceptClickOn")(src, params, A))
|
||||
return
|
||||
|
||||
var/list/modifiers = params2list(params)
|
||||
if(modifiers["shift"] && modifiers["middle"])
|
||||
ShiftMiddleClickOn(A)
|
||||
return
|
||||
if(modifiers["shift"] && modifiers["ctrl"])
|
||||
CtrlShiftClickOn(A)
|
||||
return
|
||||
if(modifiers["middle"])
|
||||
MiddleClickOn(A)
|
||||
return
|
||||
if(modifiers["shift"])
|
||||
ShiftClickOn(A)
|
||||
return
|
||||
if(modifiers["alt"]) // alt and alt-gr (rightalt)
|
||||
AltClickOn(A)
|
||||
return
|
||||
if(modifiers["ctrl"])
|
||||
CtrlClickOn(A)
|
||||
return
|
||||
|
||||
if(incapacitated(ignore_restraints = 1))
|
||||
return
|
||||
|
||||
face_atom(A)
|
||||
|
||||
if(next_move > world.time) // in the year 2000...
|
||||
return
|
||||
|
||||
/*
|
||||
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/changeNext_move(num)
|
||||
next_move = world.time + ((num+next_move_adjust)*next_move_modifier)
|
||||
|
||||
|
||||
/*
|
||||
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.
|
||||
|
||||
Alternately, you could hardcode every mob's variation in a flat ClickOn() proc; however,
|
||||
that's a lot of code duplication and is hard to maintain.
|
||||
|
||||
Note that this proc can be overridden, and is in the case of screen objects.
|
||||
*/
|
||||
/atom/Click(location,control,params)
|
||||
if(initialized)
|
||||
usr.ClickOn(src, params)
|
||||
|
||||
/atom/DblClick(location,control,params)
|
||||
if(initialized)
|
||||
usr.DblClickOn(src,params)
|
||||
|
||||
/atom/MouseWheel(delta_x,delta_y,location,control,params)
|
||||
if(initialized)
|
||||
usr.MouseWheelOn(src, delta_x, delta_y, params)
|
||||
|
||||
/*
|
||||
Standard mob ClickOn()
|
||||
Handles exceptions: Buildmode, middle click, modified clicks, mech actions
|
||||
|
||||
After that, mostly just check your state, check whether you're holding an item,
|
||||
check whether you're adjacent to the target, then pass off the click to whoever
|
||||
is recieving it.
|
||||
The most common are:
|
||||
* mob/UnarmedAttack(atom,adjacent) - used here only when adjacent, with no item in hand; in the case of humans, checks gloves
|
||||
* atom/attackby(item,user) - used only when adjacent
|
||||
* 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 + 1
|
||||
|
||||
if(client && client.click_intercept)
|
||||
if(call(client.click_intercept, "InterceptClickOn")(src, params, A))
|
||||
return
|
||||
|
||||
var/list/modifiers = params2list(params)
|
||||
if(modifiers["shift"] && modifiers["middle"])
|
||||
ShiftMiddleClickOn(A)
|
||||
return
|
||||
if(modifiers["shift"] && modifiers["ctrl"])
|
||||
CtrlShiftClickOn(A)
|
||||
return
|
||||
if(modifiers["middle"])
|
||||
MiddleClickOn(A)
|
||||
return
|
||||
if(modifiers["shift"])
|
||||
ShiftClickOn(A)
|
||||
return
|
||||
if(modifiers["alt"]) // alt and alt-gr (rightalt)
|
||||
AltClickOn(A)
|
||||
return
|
||||
if(modifiers["ctrl"])
|
||||
CtrlClickOn(A)
|
||||
return
|
||||
|
||||
if(incapacitated(ignore_restraints = 1))
|
||||
return
|
||||
|
||||
face_atom(A)
|
||||
|
||||
if(next_move > world.time) // in the year 2000...
|
||||
return
|
||||
|
||||
if(A.IsObscured())
|
||||
return
|
||||
|
||||
if(istype(loc,/obj/mecha))
|
||||
var/obj/mecha/M = loc
|
||||
return M.click_action(A,src,params)
|
||||
|
||||
if(restrained())
|
||||
changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow
|
||||
RestrainedClickOn(A)
|
||||
return
|
||||
|
||||
if(in_throw_mode)
|
||||
throw_item(A)
|
||||
return
|
||||
|
||||
var/obj/item/W = get_active_held_item()
|
||||
|
||||
if(W == A)
|
||||
W.attack_self(src)
|
||||
update_inv_hands()
|
||||
return
|
||||
|
||||
//These are always reachable.
|
||||
//User itself, current loc, and user inventory
|
||||
if(DirectAccess(A))
|
||||
if(W)
|
||||
melee_item_attack_chain(src,W,A,params)
|
||||
else
|
||||
if(ismob(A))
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
UnarmedAttack(A)
|
||||
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)
|
||||
melee_item_attack_chain(src,W,A,params)
|
||||
else
|
||||
if(ismob(A))
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
UnarmedAttack(A,1)
|
||||
else
|
||||
if(W)
|
||||
W.afterattack(A,src,0,params)
|
||||
else
|
||||
RangedAttack(A,params)
|
||||
|
||||
if(istype(loc,/obj/mecha))
|
||||
var/obj/mecha/M = loc
|
||||
return M.click_action(A,src,params)
|
||||
|
||||
if(restrained())
|
||||
changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow
|
||||
RestrainedClickOn(A)
|
||||
return
|
||||
|
||||
if(in_throw_mode)
|
||||
throw_item(A)
|
||||
return
|
||||
|
||||
var/obj/item/W = get_active_held_item()
|
||||
|
||||
if(W == A)
|
||||
W.attack_self(src)
|
||||
update_inv_hands()
|
||||
return
|
||||
|
||||
//These are always reachable.
|
||||
//User itself, current loc, and user inventory
|
||||
if(DirectAccess(A))
|
||||
if(W)
|
||||
melee_item_attack_chain(src,W,A,params)
|
||||
else
|
||||
if(ismob(A))
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
UnarmedAttack(A)
|
||||
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)
|
||||
melee_item_attack_chain(src,W,A,params)
|
||||
else
|
||||
if(ismob(A))
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
UnarmedAttack(A,1)
|
||||
else
|
||||
if(W)
|
||||
W.afterattack(A,src,0,params)
|
||||
else
|
||||
RangedAttack(A,params)
|
||||
|
||||
//Is the atom obscured by a PREVENT_CLICK_UNDER object above it
|
||||
/atom/proc/IsObscured()
|
||||
if(!isturf(loc)) //This only makes sense for things directly on turfs for now
|
||||
@@ -162,306 +162,308 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/atom/movable/proc/CanReach(atom/target,obj/item/tool,view_only = FALSE)
|
||||
if(isturf(target) || isturf(target.loc) || DirectAccess(target)) //Directly accessible atoms
|
||||
if(Adjacent(target) || (tool && CheckToolReach(src, target, tool.reach))) //Adjacent or reaching attacks
|
||||
return TRUE
|
||||
else
|
||||
//Things inside storage insde another storage
|
||||
//Eg Contents of a box in a backpack
|
||||
var/atom/outer_storage = get_atom_on_turf(target)
|
||||
if(outer_storage == target) //whatever that is we don't want infinite loop.
|
||||
return FALSE
|
||||
if(outer_storage && CanReach(outer_storage,tool) && outer_storage.CanReachStorage(target,src,view_only ? STORAGE_VIEW_DEPTH : INVENTORY_DEPTH))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//Can [target] in this container be reached by [user], can't be more than [depth] levels deep
|
||||
/atom/proc/CanReachStorage(atom/target,user,depth)
|
||||
return FALSE
|
||||
|
||||
/obj/item/weapon/storage/CanReachStorage(atom/target,user,depth)
|
||||
while(target && depth > 0)
|
||||
target = target.loc
|
||||
depth--
|
||||
if(target == src)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/atom/movable/proc/DirectAccess(atom/target)
|
||||
if(target == src)
|
||||
return TRUE
|
||||
if(target == loc)
|
||||
return TRUE
|
||||
|
||||
/mob/DirectAccess(atom/target)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(target in contents) //This could probably use moving down and restricting to inventory only
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/DirectAccess(atom/target)
|
||||
if(..()) //Lightweight checks first
|
||||
return TRUE
|
||||
if(target in GetAllContents())
|
||||
return TRUE
|
||||
|
||||
/atom/proc/AllowClick()
|
||||
return FALSE
|
||||
|
||||
/turf/AllowClick()
|
||||
return TRUE
|
||||
|
||||
/proc/CheckToolReach(atom/movable/here, atom/movable/there, reach)
|
||||
if(!here || !there)
|
||||
return
|
||||
switch(reach)
|
||||
if(0)
|
||||
return FALSE
|
||||
if(1)
|
||||
return FALSE //here.Adjacent(there)
|
||||
if(2 to INFINITY)
|
||||
var/obj/dummy = new(get_turf(here))
|
||||
dummy.pass_flags |= PASSTABLE
|
||||
dummy.invisibility = INVISIBILITY_ABSTRACT
|
||||
for(var/i in 1 to reach) //Limit it to that many tries
|
||||
var/turf/T = get_step(dummy, get_dir(dummy, there))
|
||||
if(dummy.CanReach(there))
|
||||
qdel(dummy)
|
||||
return TRUE
|
||||
if(!dummy.Move(T)) //we're blocked!
|
||||
qdel(dummy)
|
||||
return
|
||||
qdel(dummy)
|
||||
|
||||
// Default behavior: ignore double clicks (the second click that makes the doubleclick call already calls for a normal click)
|
||||
/mob/proc/DblClickOn(atom/A, params)
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
Translates into attack_hand, etc.
|
||||
|
||||
Note: proximity_flag here is used to distinguish between normal usage (flag=1),
|
||||
and usage when clicking on things telekinetically (flag=0). This proc will
|
||||
not be called at ranged except with telekinesis.
|
||||
|
||||
proximity_flag is not currently passed to attack_hand, and is instead used
|
||||
in human click code to allow glove touches only at melee range.
|
||||
*/
|
||||
/mob/proc/UnarmedAttack(atom/A, proximity_flag)
|
||||
if(ismob(A))
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
return
|
||||
|
||||
/*
|
||||
Ranged unarmed attack:
|
||||
|
||||
This currently is just a default for all mobs, involving
|
||||
laser eyes and telekinesis. You could easily add exceptions
|
||||
for things like ranged glove touches, spitting alien acid/neurotoxin,
|
||||
animals lunging, etc.
|
||||
*/
|
||||
/mob/proc/RangedAttack(atom/A, params)
|
||||
/*
|
||||
Restrained ClickOn
|
||||
|
||||
Used when you are handcuffed and click things.
|
||||
Not currently used by anything but could easily be.
|
||||
*/
|
||||
/mob/proc/RestrainedClickOn(atom/A)
|
||||
return
|
||||
|
||||
/*
|
||||
Middle click
|
||||
Only used for swapping hands
|
||||
*/
|
||||
/mob/proc/MiddleClickOn(atom/A)
|
||||
return
|
||||
|
||||
/mob/living/carbon/MiddleClickOn(atom/A)
|
||||
if(!src.stat && src.mind && src.mind.changeling && src.mind.changeling.chosen_sting && (istype(A, /mob/living/carbon)) && (A != src))
|
||||
next_click = world.time + 5
|
||||
mind.changeling.chosen_sting.try_to_sting(src, A)
|
||||
else
|
||||
swap_hand()
|
||||
|
||||
/mob/living/simple_animal/drone/MiddleClickOn(atom/A)
|
||||
swap_hand()
|
||||
|
||||
// In case of use break glass
|
||||
/*
|
||||
/atom/proc/MiddleClick(mob/M as mob)
|
||||
return
|
||||
*/
|
||||
|
||||
/*
|
||||
Shift click
|
||||
For most mobs, examine.
|
||||
This is overridden in ai.dm
|
||||
*/
|
||||
/mob/proc/ShiftClickOn(atom/A)
|
||||
A.ShiftClick(src)
|
||||
return
|
||||
/atom/proc/ShiftClick(mob/user)
|
||||
if(user.client && user.client.eye == user || user.client.eye == user.loc)
|
||||
user.examinate(src)
|
||||
return
|
||||
|
||||
/*
|
||||
Ctrl click
|
||||
For most objects, pull
|
||||
*/
|
||||
|
||||
/mob/proc/CtrlClickOn(atom/A)
|
||||
A.CtrlClick(src)
|
||||
return
|
||||
|
||||
/atom/proc/CtrlClick(mob/user)
|
||||
var/mob/living/ML = user
|
||||
if(istype(ML))
|
||||
ML.pulled(src)
|
||||
|
||||
/mob/living/carbon/human/CtrlClick(mob/user)
|
||||
if(ishuman(user) && Adjacent(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.dna.species.grab(H, src, H.martial_art)
|
||||
H.next_click = world.time + CLICK_CD_MELEE
|
||||
else
|
||||
..()
|
||||
/*
|
||||
Alt click
|
||||
Unused except for AI
|
||||
*/
|
||||
/mob/proc/AltClickOn(atom/A)
|
||||
A.AltClick(src)
|
||||
return
|
||||
|
||||
/mob/living/carbon/AltClickOn(atom/A)
|
||||
if(!src.stat && src.mind && src.mind.changeling && src.mind.changeling.chosen_sting && (istype(A, /mob/living/carbon)) && (A != src))
|
||||
next_click = world.time + 5
|
||||
mind.changeling.chosen_sting.try_to_sting(src, A)
|
||||
else
|
||||
..()
|
||||
|
||||
/atom/proc/AltClick(mob/user)
|
||||
var/turf/T = get_turf(src)
|
||||
if(T && user.TurfAdjacent(T))
|
||||
if(user.listed_turf == T)
|
||||
user.listed_turf = null
|
||||
else
|
||||
user.listed_turf = T
|
||||
user.client.statpanel = T.name
|
||||
return
|
||||
|
||||
/mob/proc/TurfAdjacent(turf/T)
|
||||
return T.Adjacent(src)
|
||||
|
||||
/*
|
||||
Control+Shift click
|
||||
Unused except for AI
|
||||
*/
|
||||
/mob/proc/CtrlShiftClickOn(atom/A)
|
||||
A.CtrlShiftClick(src)
|
||||
return
|
||||
|
||||
/mob/proc/ShiftMiddleClickOn(atom/A)
|
||||
src.pointed(A)
|
||||
return
|
||||
|
||||
/atom/proc/CtrlShiftClick(mob/user)
|
||||
return
|
||||
|
||||
/*
|
||||
Misc helpers
|
||||
|
||||
Laser Eyes: as the name implies, handles this since nothing else does currently
|
||||
face_atom: turns the mob towards what you clicked on
|
||||
*/
|
||||
/mob/proc/LaserEyes(atom/A)
|
||||
return
|
||||
|
||||
/mob/living/LaserEyes(atom/A)
|
||||
changeNext_move(CLICK_CD_RANGE)
|
||||
var/turf/T = get_turf(src)
|
||||
var/turf/U = get_turf(A)
|
||||
|
||||
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)
|
||||
|
||||
LE.firer = src
|
||||
LE.def_zone = get_organ_target()
|
||||
LE.original = A
|
||||
LE.current = T
|
||||
LE.yo = U.y - T.y
|
||||
LE.xo = U.x - T.x
|
||||
LE.fire()
|
||||
|
||||
// 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)
|
||||
if( buckled || stat != CONSCIOUS || !A || !x || !y || !A.x || !A.y )
|
||||
return
|
||||
var/dx = A.x - x
|
||||
var/dy = A.y - y
|
||||
if(!dx && !dy) // Wall items are graphically shifted but on the floor
|
||||
if(A.pixel_y > 16)
|
||||
setDir(NORTH)
|
||||
else if(A.pixel_y < -16)
|
||||
setDir(SOUTH)
|
||||
else if(A.pixel_x > 16)
|
||||
setDir(EAST)
|
||||
else if(A.pixel_x < -16)
|
||||
setDir(WEST)
|
||||
return
|
||||
|
||||
if(abs(dx) < abs(dy))
|
||||
if(dy > 0)
|
||||
setDir(NORTH)
|
||||
else
|
||||
setDir(SOUTH)
|
||||
else
|
||||
if(dx > 0)
|
||||
setDir(EAST)
|
||||
else
|
||||
setDir(WEST)
|
||||
|
||||
/obj/screen/click_catcher
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "click_catcher"
|
||||
plane = CLICKCATCHER_PLANE
|
||||
mouse_opacity = 2
|
||||
screen_loc = "CENTER"
|
||||
|
||||
/obj/screen/click_catcher/New()
|
||||
..()
|
||||
transform = matrix(200, 0, 0, 0, 200, 0)
|
||||
|
||||
/obj/screen/click_catcher/Click(location, control, params)
|
||||
var/list/modifiers = params2list(params)
|
||||
if(modifiers["middle"] && istype(usr, /mob/living/carbon))
|
||||
var/mob/living/carbon/C = usr
|
||||
C.swap_hand()
|
||||
else
|
||||
var/turf/T = params2turf(modifiers["screen-loc"], get_turf(usr))
|
||||
if(T)
|
||||
T.Click(location, control, params)
|
||||
. = 1
|
||||
|
||||
|
||||
/* MouseWheelOn */
|
||||
|
||||
/mob/proc/MouseWheelOn(atom/A, delta_x, delta_y, params)
|
||||
return
|
||||
|
||||
/mob/dead/observer/MouseWheelOn(atom/A, delta_x, delta_y, params)
|
||||
var/list/modifier = params2list(params)
|
||||
if(modifier["shift"])
|
||||
var/view = 0
|
||||
if(delta_y > 0)
|
||||
view = -1
|
||||
else
|
||||
view = 1
|
||||
add_view_range(view)
|
||||
/atom/movable/proc/CanReach(atom/target,obj/item/tool,view_only = FALSE)
|
||||
if(isturf(target) || isturf(target.loc) || DirectAccess(target)) //Directly accessible atoms
|
||||
if(Adjacent(target) || (tool && CheckToolReach(src, target, tool.reach))) //Adjacent or reaching attacks
|
||||
return TRUE
|
||||
else
|
||||
//Things inside storage insde another storage
|
||||
//Eg Contents of a box in a backpack
|
||||
var/atom/outer_storage = get_atom_on_turf(target)
|
||||
if(outer_storage == target) //whatever that is we don't want infinite loop.
|
||||
return FALSE
|
||||
if(outer_storage && CanReach(outer_storage,tool) && outer_storage.CanReachStorage(target,src,view_only ? STORAGE_VIEW_DEPTH : INVENTORY_DEPTH))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//Can [target] in this container be reached by [user], can't be more than [depth] levels deep
|
||||
/atom/proc/CanReachStorage(atom/target,user,depth)
|
||||
return FALSE
|
||||
|
||||
/obj/item/weapon/storage/CanReachStorage(atom/target,user,depth)
|
||||
while(target && depth > 0)
|
||||
target = target.loc
|
||||
depth--
|
||||
if(target == src)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/atom/movable/proc/DirectAccess(atom/target)
|
||||
if(target == src)
|
||||
return TRUE
|
||||
if(target == loc)
|
||||
return TRUE
|
||||
|
||||
/mob/DirectAccess(atom/target)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(target in contents) //This could probably use moving down and restricting to inventory only
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/DirectAccess(atom/target)
|
||||
if(..()) //Lightweight checks first
|
||||
return TRUE
|
||||
if(target in GetAllContents())
|
||||
return TRUE
|
||||
|
||||
/atom/proc/AllowClick()
|
||||
return FALSE
|
||||
|
||||
/turf/AllowClick()
|
||||
return TRUE
|
||||
|
||||
/proc/CheckToolReach(atom/movable/here, atom/movable/there, reach)
|
||||
if(!here || !there)
|
||||
return
|
||||
switch(reach)
|
||||
if(0)
|
||||
return FALSE
|
||||
if(1)
|
||||
return FALSE //here.Adjacent(there)
|
||||
if(2 to INFINITY)
|
||||
var/obj/dummy = new(get_turf(here))
|
||||
dummy.pass_flags |= PASSTABLE
|
||||
dummy.invisibility = INVISIBILITY_ABSTRACT
|
||||
for(var/i in 1 to reach) //Limit it to that many tries
|
||||
var/turf/T = get_step(dummy, get_dir(dummy, there))
|
||||
if(dummy.CanReach(there))
|
||||
qdel(dummy)
|
||||
return TRUE
|
||||
if(!dummy.Move(T)) //we're blocked!
|
||||
qdel(dummy)
|
||||
return
|
||||
qdel(dummy)
|
||||
|
||||
// Default behavior: ignore double clicks (the second click that makes the doubleclick call already calls for a normal click)
|
||||
/mob/proc/DblClickOn(atom/A, params)
|
||||
return
|
||||
|
||||
|
||||
/*
|
||||
Translates into attack_hand, etc.
|
||||
|
||||
Note: proximity_flag here is used to distinguish between normal usage (flag=1),
|
||||
and usage when clicking on things telekinetically (flag=0). This proc will
|
||||
not be called at ranged except with telekinesis.
|
||||
|
||||
proximity_flag is not currently passed to attack_hand, and is instead used
|
||||
in human click code to allow glove touches only at melee range.
|
||||
*/
|
||||
/mob/proc/UnarmedAttack(atom/A, proximity_flag)
|
||||
if(ismob(A))
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
return
|
||||
|
||||
/*
|
||||
Ranged unarmed attack:
|
||||
|
||||
This currently is just a default for all mobs, involving
|
||||
laser eyes and telekinesis. You could easily add exceptions
|
||||
for things like ranged glove touches, spitting alien acid/neurotoxin,
|
||||
animals lunging, etc.
|
||||
*/
|
||||
/mob/proc/RangedAttack(atom/A, params)
|
||||
/*
|
||||
Restrained ClickOn
|
||||
|
||||
Used when you are handcuffed and click things.
|
||||
Not currently used by anything but could easily be.
|
||||
*/
|
||||
/mob/proc/RestrainedClickOn(atom/A)
|
||||
return
|
||||
|
||||
/*
|
||||
Middle click
|
||||
Only used for swapping hands
|
||||
*/
|
||||
/mob/proc/MiddleClickOn(atom/A)
|
||||
return
|
||||
|
||||
/mob/living/carbon/MiddleClickOn(atom/A)
|
||||
if(!src.stat && src.mind && src.mind.changeling && src.mind.changeling.chosen_sting && (istype(A, /mob/living/carbon)) && (A != src))
|
||||
next_click = world.time + 5
|
||||
mind.changeling.chosen_sting.try_to_sting(src, A)
|
||||
else
|
||||
swap_hand()
|
||||
|
||||
/mob/living/simple_animal/drone/MiddleClickOn(atom/A)
|
||||
swap_hand()
|
||||
|
||||
// In case of use break glass
|
||||
/*
|
||||
/atom/proc/MiddleClick(mob/M as mob)
|
||||
return
|
||||
*/
|
||||
|
||||
/*
|
||||
Shift click
|
||||
For most mobs, examine.
|
||||
This is overridden in ai.dm
|
||||
*/
|
||||
/mob/proc/ShiftClickOn(atom/A)
|
||||
A.ShiftClick(src)
|
||||
return
|
||||
/atom/proc/ShiftClick(mob/user)
|
||||
if(user.client && user.client.eye == user || user.client.eye == user.loc)
|
||||
user.examinate(src)
|
||||
return
|
||||
|
||||
/*
|
||||
Ctrl click
|
||||
For most objects, pull
|
||||
*/
|
||||
|
||||
/mob/proc/CtrlClickOn(atom/A)
|
||||
A.CtrlClick(src)
|
||||
return
|
||||
|
||||
/atom/proc/CtrlClick(mob/user)
|
||||
var/mob/living/ML = user
|
||||
if(istype(ML))
|
||||
ML.pulled(src)
|
||||
|
||||
/mob/living/carbon/human/CtrlClick(mob/user)
|
||||
if(ishuman(user) && Adjacent(user))
|
||||
if(world.time < user.next_move)
|
||||
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)
|
||||
else
|
||||
..()
|
||||
/*
|
||||
Alt click
|
||||
Unused except for AI
|
||||
*/
|
||||
/mob/proc/AltClickOn(atom/A)
|
||||
A.AltClick(src)
|
||||
return
|
||||
|
||||
/mob/living/carbon/AltClickOn(atom/A)
|
||||
if(!src.stat && src.mind && src.mind.changeling && src.mind.changeling.chosen_sting && (istype(A, /mob/living/carbon)) && (A != src))
|
||||
next_click = world.time + 5
|
||||
mind.changeling.chosen_sting.try_to_sting(src, A)
|
||||
else
|
||||
..()
|
||||
|
||||
/atom/proc/AltClick(mob/user)
|
||||
var/turf/T = get_turf(src)
|
||||
if(T && user.TurfAdjacent(T))
|
||||
if(user.listed_turf == T)
|
||||
user.listed_turf = null
|
||||
else
|
||||
user.listed_turf = T
|
||||
user.client.statpanel = T.name
|
||||
return
|
||||
|
||||
/mob/proc/TurfAdjacent(turf/T)
|
||||
return T.Adjacent(src)
|
||||
|
||||
/*
|
||||
Control+Shift click
|
||||
Unused except for AI
|
||||
*/
|
||||
/mob/proc/CtrlShiftClickOn(atom/A)
|
||||
A.CtrlShiftClick(src)
|
||||
return
|
||||
|
||||
/mob/proc/ShiftMiddleClickOn(atom/A)
|
||||
src.pointed(A)
|
||||
return
|
||||
|
||||
/atom/proc/CtrlShiftClick(mob/user)
|
||||
return
|
||||
|
||||
/*
|
||||
Misc helpers
|
||||
|
||||
Laser Eyes: as the name implies, handles this since nothing else does currently
|
||||
face_atom: turns the mob towards what you clicked on
|
||||
*/
|
||||
/mob/proc/LaserEyes(atom/A)
|
||||
return
|
||||
|
||||
/mob/living/LaserEyes(atom/A)
|
||||
changeNext_move(CLICK_CD_RANGE)
|
||||
var/turf/T = get_turf(src)
|
||||
var/turf/U = get_turf(A)
|
||||
|
||||
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)
|
||||
|
||||
LE.firer = src
|
||||
LE.def_zone = get_organ_target()
|
||||
LE.original = A
|
||||
LE.current = T
|
||||
LE.yo = U.y - T.y
|
||||
LE.xo = U.x - T.x
|
||||
LE.fire()
|
||||
|
||||
// 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)
|
||||
if( buckled || stat != CONSCIOUS || !A || !x || !y || !A.x || !A.y )
|
||||
return
|
||||
var/dx = A.x - x
|
||||
var/dy = A.y - y
|
||||
if(!dx && !dy) // Wall items are graphically shifted but on the floor
|
||||
if(A.pixel_y > 16)
|
||||
setDir(NORTH)
|
||||
else if(A.pixel_y < -16)
|
||||
setDir(SOUTH)
|
||||
else if(A.pixel_x > 16)
|
||||
setDir(EAST)
|
||||
else if(A.pixel_x < -16)
|
||||
setDir(WEST)
|
||||
return
|
||||
|
||||
if(abs(dx) < abs(dy))
|
||||
if(dy > 0)
|
||||
setDir(NORTH)
|
||||
else
|
||||
setDir(SOUTH)
|
||||
else
|
||||
if(dx > 0)
|
||||
setDir(EAST)
|
||||
else
|
||||
setDir(WEST)
|
||||
|
||||
/obj/screen/click_catcher
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "click_catcher"
|
||||
plane = CLICKCATCHER_PLANE
|
||||
mouse_opacity = 2
|
||||
screen_loc = "CENTER"
|
||||
|
||||
/obj/screen/click_catcher/New()
|
||||
..()
|
||||
transform = matrix(200, 0, 0, 0, 200, 0)
|
||||
|
||||
/obj/screen/click_catcher/Click(location, control, params)
|
||||
var/list/modifiers = params2list(params)
|
||||
if(modifiers["middle"] && istype(usr, /mob/living/carbon))
|
||||
var/mob/living/carbon/C = usr
|
||||
C.swap_hand()
|
||||
else
|
||||
var/turf/T = params2turf(modifiers["screen-loc"], get_turf(usr))
|
||||
if(T)
|
||||
T.Click(location, control, params)
|
||||
. = 1
|
||||
|
||||
|
||||
/* MouseWheelOn */
|
||||
|
||||
/mob/proc/MouseWheelOn(atom/A, delta_x, delta_y, params)
|
||||
return
|
||||
|
||||
/mob/dead/observer/MouseWheelOn(atom/A, delta_x, delta_y, params)
|
||||
var/list/modifier = params2list(params)
|
||||
if(modifier["shift"])
|
||||
var/view = 0
|
||||
if(delta_y > 0)
|
||||
view = -1
|
||||
else
|
||||
view = 1
|
||||
add_view_range(view)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
/atom/proc/attack_tk(mob/user)
|
||||
if(user.stat)
|
||||
return
|
||||
new /obj/effect/overlay/temp/telekinesis(loc)
|
||||
new /obj/effect/temp_visual/telekinesis(loc)
|
||||
user.UnarmedAttack(src,0) // attack_hand, attack_paw, etc
|
||||
return
|
||||
|
||||
@@ -163,7 +163,7 @@
|
||||
/obj/item/tk_grab/proc/apply_focus_overlay()
|
||||
if(!focus)
|
||||
return
|
||||
new /obj/effect/overlay/temp/telekinesis(get_turf(focus))
|
||||
new /obj/effect/temp_visual/telekinesis(get_turf(focus))
|
||||
|
||||
/obj/item/tk_grab/update_icon()
|
||||
cut_overlays()
|
||||
|
||||
@@ -254,16 +254,34 @@
|
||||
"<span class='green'>You cum into [SC].</span>", \
|
||||
"<span class='green'>You have relieved yourself.</span>")
|
||||
finished = 1
|
||||
|
||||
|
||||
if(/obj/item/organ/genital/vagina)
|
||||
var/obj/item/organ/genital/vagina/V = SG
|
||||
if(!V.linked_womb)
|
||||
src << "<span class='warning'>No womb!</span>"
|
||||
return
|
||||
fluid_source = V.linked_womb.reagents
|
||||
total_cum = fluid_source.total_volume
|
||||
if(into_container)//into a glass or beaker or whatever
|
||||
src.visible_message("<span class='danger'>[src] starts fingering their vagina over [SC].</span>", \
|
||||
"<span class='userdanger'>You start fingering over [SC.name].</span>", \
|
||||
"<span class='userdanger'>You start masturbating.</span>")
|
||||
if(do_after(src, mb_time, target = src) && in_range(src, SC))
|
||||
fluid_source.trans_to(SC, total_cum)
|
||||
src.visible_message("<span class='danger'>[src] orgasms, [pick("cumming into", "emptying themself into")] [SC]!</span>", \
|
||||
"<span class='green'>You cum into [SC].</span>", \
|
||||
"<span class='green'>You have relieved yourself.</span>")
|
||||
finished = 1
|
||||
|
||||
else//not into a container
|
||||
src.visible_message("<span class='danger'>[src] starts [pick("jerking off","stroking")] their [pick(GLOB.dick_nouns)].</span>", \
|
||||
"<span class='userdanger'>You start jerking off your [pick(GLOB.dick_nouns)].</span>", \
|
||||
src.visible_message("<span class='danger'>[src] starts fingering their vagina.</span>", \
|
||||
"<span class='userdanger'>You start fingering your vagina.</span>", \
|
||||
"<span class='userdanger'>You start masturbating.</span>")
|
||||
if(do_after(src, mb_time, target = src))
|
||||
if(total_cum > 5)
|
||||
fluid_source.reaction(src.loc, TOUCH, 1, 0)
|
||||
fluid_source.clear_reagents()
|
||||
src.visible_message("<span class='danger'>[src] orgasms, [pick("shooting cum", "draining their balls")][istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!</span>", \
|
||||
src.visible_message("<span class='danger'>[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!</span>", \
|
||||
"<span class='green'>You cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""].</span>", \
|
||||
"<span class='green'>You have relieved yourself.</span>")
|
||||
finished = 1
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
var/obj/effect/decal/cleanable/femcum/S = locate() in T
|
||||
if(!S)
|
||||
S = new(T)
|
||||
S.reagents.add_reagent("semen", reac_volume)
|
||||
S.reagents.add_reagent("femcum", reac_volume)
|
||||
if(data["blood_DNA"])
|
||||
S.blood_DNA[data["blood_DNA"]] = data["blood_type"]
|
||||
|
||||
@@ -219,4 +219,4 @@
|
||||
results = list("anaphro+" = 1)
|
||||
required_reagents = list("anaphro" = 5, "acetone" = 1)
|
||||
required_temp = 300
|
||||
mix_message = "The mixture thickens and heats up slighty..."
|
||||
mix_message = "The mixture thickens and heats up slighty..."
|
||||
|
||||
@@ -6,8 +6,28 @@
|
||||
zone = "groin"
|
||||
slot = "womb"
|
||||
w_class = 3
|
||||
var/internal = FALSE
|
||||
fluid_id = "femcum"
|
||||
producing = TRUE
|
||||
var/obj/item/organ/genital/vagina/linked_vag
|
||||
|
||||
/obj/item/organ/genital/womb/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent(fluid_id, fluid_max_volume)
|
||||
|
||||
/obj/item/organ/genital/womb/on_life()
|
||||
if(QDELETED(src))
|
||||
return
|
||||
if(reagents && producing)
|
||||
generate_femcum()
|
||||
|
||||
/obj/item/organ/genital/womb/proc/generate_femcum()
|
||||
reagents.maximum_volume = fluid_max_volume
|
||||
update_link()
|
||||
if(!linked_vag)
|
||||
return FALSE
|
||||
reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally
|
||||
reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))//generate the cum
|
||||
|
||||
/obj/item/organ/genital/womb/update_link()
|
||||
if(owner)
|
||||
@@ -25,4 +45,4 @@
|
||||
linked_vag = null
|
||||
|
||||
/obj/item/organ/genital/womb/Destroy()
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
+24
-23
@@ -14,15 +14,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
//Master -> SSPreInit -> GLOB -> world -> config -> SSInit -> Failsafe
|
||||
//GOT IT MEMORIZED?
|
||||
|
||||
GLOBAL_VAR_INIT(MC_restart_clear, 0)
|
||||
GLOBAL_VAR_INIT(MC_restart_timeout, 0)
|
||||
GLOBAL_VAR_INIT(MC_restart_count, 0)
|
||||
|
||||
|
||||
//current tick limit, assigned by the queue controller before running a subsystem.
|
||||
//used by check_tick as well so that the procs subsystems call can obey that SS's tick limits
|
||||
GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
|
||||
/datum/controller/master
|
||||
name = "Master"
|
||||
|
||||
@@ -59,6 +50,14 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
|
||||
var/current_runlevel //for scheduling different subsystems for different stages of the round
|
||||
|
||||
var/static/restart_clear = 0
|
||||
var/static/restart_timeout = 0
|
||||
var/static/restart_count = 0
|
||||
|
||||
//current tick limit, assigned before running a subsystem.
|
||||
//used by CHECK_TICK as well so that the procs subsystems call can obey that SS's tick limits
|
||||
var/static/current_ticklimit = TICK_LIMIT_RUNNING
|
||||
|
||||
/datum/controller/master/New()
|
||||
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
|
||||
subsystems = list()
|
||||
@@ -83,20 +82,21 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
sortTim(subsystems, /proc/cmp_subsystem_init)
|
||||
reverseRange(subsystems)
|
||||
for(var/datum/controller/subsystem/ss in subsystems)
|
||||
testing("Shutdown [ss.name] subsystem")
|
||||
ss.Shutdown()
|
||||
|
||||
// Returns 1 if we created a new mc, 0 if we couldn't due to a recent restart,
|
||||
// -1 if we encountered a runtime trying to recreate it
|
||||
/proc/Recreate_MC()
|
||||
. = -1 //so if we runtime, things know we failed
|
||||
if (world.time < GLOB.MC_restart_timeout)
|
||||
if (world.time < Master.restart_timeout)
|
||||
return 0
|
||||
if (world.time < GLOB.MC_restart_clear)
|
||||
GLOB.MC_restart_count *= 0.5
|
||||
if (world.time < Master.restart_clear)
|
||||
Master.restart_count *= 0.5
|
||||
|
||||
var/delay = 50 * ++GLOB.MC_restart_count
|
||||
GLOB.MC_restart_timeout = world.time + delay
|
||||
GLOB.MC_restart_clear = world.time + (delay * 2)
|
||||
var/delay = 50 * ++Master.restart_count
|
||||
Master.restart_timeout = world.time + delay
|
||||
Master.restart_clear = world.time + (delay * 2)
|
||||
Master.processing = 0 //stop ticking this one
|
||||
try
|
||||
new/datum/controller/master()
|
||||
@@ -164,13 +164,13 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
|
||||
var/start_timeofday = REALTIMEOFDAY
|
||||
// Initialize subsystems.
|
||||
GLOB.CURRENT_TICKLIMIT = config.tick_limit_mc_init
|
||||
current_ticklimit = config.tick_limit_mc_init
|
||||
for (var/datum/controller/subsystem/SS in subsystems)
|
||||
if (SS.flags & SS_NO_INIT)
|
||||
continue
|
||||
SS.Initialize(REALTIMEOFDAY)
|
||||
CHECK_TICK
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
current_ticklimit = TICK_LIMIT_RUNNING
|
||||
var/time = (REALTIMEOFDAY - start_timeofday) / 10
|
||||
|
||||
var/msg = "Initializations complete within [time] second[time == 1 ? "" : "s"]!"
|
||||
@@ -205,6 +205,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
set waitfor = 0
|
||||
if(delay)
|
||||
sleep(delay)
|
||||
testing("Master starting processing")
|
||||
var/rtn = Loop()
|
||||
if (rtn > 0 || processing < 0)
|
||||
return //this was suppose to happen.
|
||||
@@ -275,7 +276,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
while (1)
|
||||
tickdrift = max(0, MC_AVERAGE_FAST(tickdrift, (((REALTIMEOFDAY - init_timeofday) - (world.time - init_time)) / world.tick_lag)))
|
||||
if (processing <= 0)
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
current_ticklimit = TICK_LIMIT_RUNNING
|
||||
sleep(10)
|
||||
continue
|
||||
|
||||
@@ -283,7 +284,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
// because sleeps are processed in the order received, so longer sleeps are more likely to run first
|
||||
if (world.tick_usage > TICK_LIMIT_MC)
|
||||
sleep_delta += 2
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING * 0.5
|
||||
current_ticklimit = TICK_LIMIT_RUNNING * 0.5
|
||||
sleep(world.tick_lag * (processing + sleep_delta))
|
||||
continue
|
||||
|
||||
@@ -321,7 +322,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
if (!error_level)
|
||||
iteration++
|
||||
error_level++
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
current_ticklimit = TICK_LIMIT_RUNNING
|
||||
sleep(10)
|
||||
continue
|
||||
|
||||
@@ -333,7 +334,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
if (!error_level)
|
||||
iteration++
|
||||
error_level++
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
|
||||
current_ticklimit = TICK_LIMIT_RUNNING
|
||||
sleep(10)
|
||||
continue
|
||||
error_level--
|
||||
@@ -344,7 +345,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
iteration++
|
||||
last_run = world.time
|
||||
src.sleep_delta = MC_AVERAGE_FAST(src.sleep_delta, sleep_delta)
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING - (TICK_LIMIT_RUNNING * 0.25) //reserve the tail 1/4 of the next tick for the mc.
|
||||
current_ticklimit = TICK_LIMIT_RUNNING - (TICK_LIMIT_RUNNING * 0.25) //reserve the tail 1/4 of the next tick for the mc.
|
||||
sleep(world.tick_lag * (processing + sleep_delta))
|
||||
|
||||
|
||||
@@ -435,7 +436,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
|
||||
tick_precentage = max(tick_precentage*0.5, tick_precentage-queue_node.tick_overrun)
|
||||
|
||||
GLOB.CURRENT_TICKLIMIT = round(world.tick_usage + tick_precentage)
|
||||
current_ticklimit = round(world.tick_usage + tick_precentage)
|
||||
|
||||
if (!(queue_node_flags & SS_TICKER))
|
||||
ran_non_ticker = TRUE
|
||||
|
||||
@@ -150,7 +150,7 @@ SUBSYSTEM_DEF(atoms)
|
||||
/datum/controller/subsystem/atoms/Shutdown()
|
||||
var/initlog = InitLog()
|
||||
if(initlog)
|
||||
text2file("[GLOB.log_directory]/initialize.log", initlog)
|
||||
text2file(initlog, "[GLOB.log_directory]/initialize.log")
|
||||
|
||||
#undef BAD_INIT_QDEL_BEFORE
|
||||
#undef BAD_INIT_DIDNT_INIT
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
SUBSYSTEM_DEF(blackbox)
|
||||
name = "Blackbox"
|
||||
wait = 6000
|
||||
flags = SS_NO_TICK_CHECK
|
||||
|
||||
flags = SS_NO_TICK_CHECK | SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
|
||||
var/list/msg_common = list()
|
||||
var/list/msg_science = list()
|
||||
var/list/msg_command = list()
|
||||
@@ -42,7 +43,6 @@ SUBSYSTEM_DEF(blackbox)
|
||||
msg_cargo = SSblackbox.msg_cargo
|
||||
msg_other = SSblackbox.msg_other
|
||||
|
||||
|
||||
feedback = SSblackbox.feedback
|
||||
|
||||
//no touchie
|
||||
@@ -55,6 +55,8 @@ SUBSYSTEM_DEF(blackbox)
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/blackbox/Shutdown()
|
||||
set_val("ahelp_unresolved", GLOB.ahelp_tickets.active_tickets.len)
|
||||
|
||||
var/pda_msg_amt = 0
|
||||
var/rc_msg_amt = 0
|
||||
|
||||
@@ -84,20 +86,16 @@ SUBSYSTEM_DEF(blackbox)
|
||||
|
||||
if (!SSdbcore.Connect())
|
||||
return
|
||||
|
||||
var/sqlrowlist = ""
|
||||
|
||||
var/list/sqlrowlist = list()
|
||||
|
||||
for (var/datum/feedback_variable/FV in feedback)
|
||||
if (sqlrowlist != "")
|
||||
sqlrowlist += ", " //a comma (,) at the start of the first row to insert will trigger a SQL error
|
||||
sqlrowlist += list("time" = "Now()", "round_id" = GLOB.round_id, "var_name" = "'[sanitizeSQL(FV.get_variable())]'", "var_value" = FV.get_value(), "details" = "'[sanitizeSQL(FV.get_details())]'")
|
||||
|
||||
sqlrowlist += list(list("time" = "Now()", "round_id" = GLOB.round_id, "var_name" = "'[sanitizeSQL(FV.get_variable())]'", "var_value" = FV.get_value(), "details" = "'[sanitizeSQL(FV.get_details())]'"))
|
||||
|
||||
if (sqlrowlist == "")
|
||||
if (!length(sqlrowlist))
|
||||
return
|
||||
|
||||
var/datum/DBQuery/query_feedback_save = SSdbcore.NewQuery("INSERT DELAYED IGNORE INTO [format_table_name("feedback")] VALUES " + sqlrowlist)
|
||||
query_feedback_save.Execute()
|
||||
SSdbcore.MassInsert(format_table_name("feedback"), sqlrowlist, ignore_errors = TRUE, delayed = TRUE)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/LogBroadcast(blackbox_msg, freq)
|
||||
switch(freq)
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
|
||||
SUBSYSTEM_DEF(fields)
|
||||
name = "Fields"
|
||||
wait = 2
|
||||
priority = 40
|
||||
flags = SS_KEEP_TIMING
|
||||
var/list/datum/proximity_monitor/advanced/running = list()
|
||||
var/list/datum/proximity_monitor/advanced/currentrun = list()
|
||||
|
||||
/datum/controller/subsystem/fields/fire(resumed = 0)
|
||||
if(!resumed)
|
||||
src.currentrun = running.Copy()
|
||||
var/list/currentrun = src.currentrun
|
||||
while(currentrun.len)
|
||||
var/datum/proximity_monitor/advanced/F = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(!F.requires_processing)
|
||||
continue
|
||||
F.process()
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/fields/proc/register_new_field(datum/proximity_monitor/advanced/F)
|
||||
running += F
|
||||
|
||||
/datum/controller/subsystem/fields/proc/unregister_field(datum/proximity_monitor/advanced/F)
|
||||
running -= F
|
||||
@@ -61,7 +61,7 @@ SUBSYSTEM_DEF(garbage)
|
||||
for(var/path in sleptDestroy)
|
||||
dellog += "Path : [path] \n"
|
||||
dellog += "Sleeps : [sleptDestroy[path]] \n"
|
||||
text2file("[GLOB.log_directory]/qdel.log", dellog.Join())
|
||||
text2file(dellog.Join(), "[GLOB.log_directory]/qdel.log")
|
||||
|
||||
/datum/controller/subsystem/garbage/fire()
|
||||
HandleToBeQueued()
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(fields)
|
||||
name = "Fields"
|
||||
wait = 2
|
||||
priority = 40
|
||||
flags = SS_KEEP_TIMING | SS_NO_INIT
|
||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
@@ -5,6 +5,7 @@ SUBSYSTEM_DEF(server_maint)
|
||||
wait = 6
|
||||
flags = SS_POST_FIRE_TIMING
|
||||
priority = 10
|
||||
init_order = INIT_ORDER_SERVER_MAINT
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
var/list/currentrun
|
||||
|
||||
@@ -16,7 +17,7 @@ SUBSYSTEM_DEF(server_maint)
|
||||
/datum/controller/subsystem/server_maint/fire(resumed = FALSE)
|
||||
if(!resumed)
|
||||
src.currentrun = GLOB.clients.Copy()
|
||||
|
||||
|
||||
var/list/currentrun = src.currentrun
|
||||
var/round_started = SSticker.HasRoundStarted()
|
||||
|
||||
@@ -37,4 +38,11 @@ SUBSYSTEM_DEF(server_maint)
|
||||
if (MC_TICK_CHECK) //one day, when ss13 has 1000 people per server, you guys are gonna be glad I added this tick check
|
||||
return
|
||||
|
||||
#undef PING_BUFFER_TIME
|
||||
/datum/controller/subsystem/server_maint/Shutdown()
|
||||
kick_clients_in_lobby("<span class='boldannounce'>The round came to an end with you in the lobby.</span>", TRUE) //second parameter ensures only afk clients are kicked
|
||||
for(var/thing in GLOB.clients)
|
||||
var/client/C = thing
|
||||
if(C && config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
|
||||
C << link("byond://[config.server]")
|
||||
|
||||
#undef PING_BUFFER_TIME
|
||||
@@ -217,7 +217,27 @@ SUBSYSTEM_DEF(shuttle)
|
||||
emergency.request(null, signal_origin, html_decode(emergency_reason), 0)
|
||||
|
||||
log_game("[key_name(user)] has called the shuttle.")
|
||||
message_admins("[key_name_admin(user)] has called the shuttle.")
|
||||
message_admins("[key_name_admin(user)] has called the shuttle. (<A HREF='?_src_=holder;trigger_centcom_recall=1'>TRIGGER CENTCOM RECALL</A>)")
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/centcom_recall(old_timer, admiral_message)
|
||||
if(emergency.mode != SHUTTLE_CALL || emergency.timer != old_timer)
|
||||
return
|
||||
emergency.cancel(/area/centcom)
|
||||
|
||||
if(!admiral_message)
|
||||
admiral_message = pick(GLOB.admiral_messages)
|
||||
var/intercepttext = "<font size = 3><b>NanoTrasen Update</b>: Request For Shuttle.</font><hr>\
|
||||
To whom it may concern:<br><br>\
|
||||
We have taken note of the situation upon [station_name()] and have come to the \
|
||||
conclusion that it does not warrant the abandonment of the station.<br>\
|
||||
If you do not agree with our opinion we suggest that you open a direct \
|
||||
line with us and explain the nature of your crisis.<br><br>\
|
||||
<i>This message has been automatically generated based upon readings from long \
|
||||
range diagnostic tools. To assure the quality of your request every finalized report \
|
||||
is reviewed by an on-call rear admiral.<br>\
|
||||
<b>Rear Admiral's Notes:</b> \
|
||||
[admiral_message]"
|
||||
print_command_report(intercepttext, announce = TRUE)
|
||||
|
||||
// Called when an emergency shuttle mobile docking port is
|
||||
// destroyed, which will only happen with admin intervention
|
||||
@@ -523,4 +543,3 @@ SUBSYSTEM_DEF(shuttle)
|
||||
for(var/obj/docking_port/mobile/M in mobile)
|
||||
if(M.is_in_shuttle_bounds(A))
|
||||
return TRUE
|
||||
|
||||
@@ -20,6 +20,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
|
||||
var/login_music //music played in pregame lobby
|
||||
var/round_end_sound //music/jingle played when the world reboots
|
||||
var/round_end_sound_sent = TRUE //If all clients have loaded it
|
||||
|
||||
var/list/datum/mind/minds = list() //The characters in the game. Used for objective tracking.
|
||||
|
||||
@@ -63,6 +64,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/modevoted = FALSE //Have we sent a vote for the gamemode?
|
||||
|
||||
/datum/controller/subsystem/ticker/Initialize(timeofday)
|
||||
load_mode()
|
||||
var/list/music = world.file2list(ROUND_START_MUSIC_LIST, "\n")
|
||||
login_music = pick(music)
|
||||
|
||||
@@ -637,9 +639,9 @@ SUBSYSTEM_DEF(ticker)
|
||||
|
||||
sleep(50)
|
||||
if(mode.station_was_nuked)
|
||||
world.Reboot("Station destroyed by Nuclear Device.", "end_proper", "nuke")
|
||||
Reboot("Station destroyed by Nuclear Device.", "end_proper", "nuke")
|
||||
else
|
||||
world.Reboot("Round ended.", "end_proper", "proper completion")
|
||||
Reboot("Round ended.", "end_proper", "proper completion")
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/send_tip_of_the_round()
|
||||
var/m
|
||||
@@ -806,3 +808,69 @@ SUBSYSTEM_DEF(ticker)
|
||||
start_at = world.time + newtime
|
||||
else
|
||||
timeLeft = newtime
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/load_mode()
|
||||
var/mode = trim(file2text("data/mode.txt"))
|
||||
if(mode)
|
||||
GLOB.master_mode = mode
|
||||
else
|
||||
GLOB.master_mode = "extended"
|
||||
log_game("Saved mode is '[GLOB.master_mode]'")
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/save_mode(the_mode)
|
||||
var/F = file("data/mode.txt")
|
||||
fdel(F)
|
||||
F << the_mode
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/SetRoundEndSound(the_sound)
|
||||
set waitfor = FALSE
|
||||
round_end_sound_sent = FALSE
|
||||
round_end_sound = fcopy_rsc(the_sound)
|
||||
for(var/thing in GLOB.clients)
|
||||
var/client/C = thing
|
||||
if (!C)
|
||||
continue
|
||||
C.Export("##action=load_rsc", round_end_sound)
|
||||
round_end_sound_sent = TRUE
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/Reboot(reason, feedback_c, feedback_r, delay)
|
||||
set waitfor = FALSE
|
||||
if(usr && !check_rights(R_SERVER, TRUE))
|
||||
return
|
||||
|
||||
if(!delay)
|
||||
delay = config.round_end_countdown * 10
|
||||
|
||||
if(delay_end)
|
||||
to_chat(world, "<span class='boldannounce'>An admin has delayed the round end.</span>")
|
||||
return
|
||||
|
||||
to_chat(world, "<span class='boldannounce'>Rebooting World in [delay/10] [(delay >= 10 && delay < 20) ? "second" : "seconds"]. [reason]</span>")
|
||||
|
||||
var/start_wait = world.time
|
||||
UNTIL(round_end_sound_sent && (world.time - start_wait) > (delay * 2)) //don't wait forever
|
||||
sleep(delay - (world.time - start_wait))
|
||||
|
||||
if(delay_end)
|
||||
to_chat(world, "<span class='boldannounce'>Reboot was cancelled by an admin.</span>")
|
||||
return
|
||||
|
||||
SSblackbox.set_details("[feedback_c]","[feedback_r]")
|
||||
|
||||
log_game("<span class='boldannounce'>Rebooting World. [reason]</span>")
|
||||
|
||||
world.Reboot()
|
||||
|
||||
/datum/controller/subsystem/ticker/Shutdown()
|
||||
if(!round_end_sound)
|
||||
round_end_sound = pick(\
|
||||
'sound/roundend/newroundsexy.ogg',
|
||||
'sound/roundend/apcdestroyed.ogg',
|
||||
'sound/roundend/bangindonk.ogg',
|
||||
'sound/roundend/leavingtg.ogg',
|
||||
'sound/roundend/its_only_game.ogg',
|
||||
'sound/roundend/yeehaw.ogg',
|
||||
'sound/roundend/disappointed.ogg'\
|
||||
)
|
||||
|
||||
world << sound(round_end_sound)
|
||||
@@ -55,6 +55,12 @@ SUBSYSTEM_DEF(title)
|
||||
var/F = file("data/previous_title.dat")
|
||||
F << file_path
|
||||
|
||||
for(var/thing in GLOB.clients)
|
||||
if(!thing)
|
||||
continue
|
||||
var/obj/screen/splash/S = new(thing, FALSE)
|
||||
S.Fade(FALSE,FALSE)
|
||||
|
||||
/datum/controller/subsystem/title/Recover()
|
||||
icon = SStitle.icon
|
||||
splash_turf = SStitle.splash_turf
|
||||
|
||||
@@ -2,9 +2,9 @@ SUBSYSTEM_DEF(vote)
|
||||
name = "Vote"
|
||||
wait = 10
|
||||
|
||||
flags = SS_KEEP_TIMING|SS_NO_INIT
|
||||
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
flags = SS_KEEP_TIMING|SS_NO_INIT
|
||||
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
|
||||
var/initiator = null
|
||||
var/started_time = null
|
||||
@@ -120,13 +120,13 @@ SUBSYSTEM_DEF(vote)
|
||||
if(SSticker && SSticker.mode)//Don't change the mode if the round already started.
|
||||
return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.")
|
||||
GLOB.master_mode = .
|
||||
world.save_mode(.)
|
||||
SSticker.save_mode(.)
|
||||
to_chat(world, "<span class='adminnotice'><b>The mode is now: [GLOB.master_mode]</b></span>")
|
||||
log_admin("Gamemode has been voted for and switched to: [GLOB.master_mode].")
|
||||
if("gamemode")
|
||||
if(GLOB.master_mode != .)
|
||||
world.save_mode(.)
|
||||
if(SSticker.HasRoundStarted())
|
||||
SSticker.save_mode(.)
|
||||
if(SSticker.HasRoundStarted())
|
||||
restart = 1
|
||||
else
|
||||
GLOB.master_mode = .
|
||||
@@ -137,7 +137,7 @@ SUBSYSTEM_DEF(vote)
|
||||
active_admins = 1
|
||||
break
|
||||
if(!active_admins)
|
||||
world.Reboot("Restart vote successful.", "end_error", "restart vote")
|
||||
SSticker.Reboot("Restart vote successful.", "end_error", "restart vote")
|
||||
else
|
||||
to_chat(world, "<span style='boldannounce'>Notice:Restart vote will not restart the server automatically because there are active admins on.</span>")
|
||||
message_admins("A restart vote has passed, but there are active admins on with +server, so it has been canceled. If you wish, you may restart the server.")
|
||||
|
||||
@@ -36,7 +36,7 @@ Bonus
|
||||
/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A)
|
||||
var/heal_amt = 0.5
|
||||
if(M.toxloss > 0 && prob(20))
|
||||
new /obj/effect/overlay/temp/heal(get_turf(M), "#66FF99")
|
||||
new /obj/effect/temp_visual/heal(get_turf(M), "#66FF99")
|
||||
M.adjustToxLoss(-heal_amt)
|
||||
return 1
|
||||
|
||||
@@ -67,7 +67,7 @@ Bonus
|
||||
/datum/symptom/heal/plus/Heal(mob/living/M, datum/disease/advance/A)
|
||||
var/heal_amt = 1
|
||||
if(M.toxloss > 0 && prob(20))
|
||||
new /obj/effect/overlay/temp/heal(get_turf(M), "#00FF00")
|
||||
new /obj/effect/temp_visual/heal(get_turf(M), "#00FF00")
|
||||
M.adjustToxLoss(-heal_amt)
|
||||
return 1
|
||||
|
||||
@@ -110,7 +110,7 @@ Bonus
|
||||
M.update_damage_overlays()
|
||||
|
||||
if(prob(20))
|
||||
new /obj/effect/overlay/temp/heal(get_turf(M), "#FF3333")
|
||||
new /obj/effect/temp_visual/heal(get_turf(M), "#FF3333")
|
||||
|
||||
return 1
|
||||
|
||||
@@ -148,7 +148,7 @@ Bonus
|
||||
if(M.getCloneLoss() > 0)
|
||||
M.adjustCloneLoss(-1)
|
||||
M.take_bodypart_damage(0, 1) //Deals BURN damage, which is not cured by this symptom
|
||||
new /obj/effect/overlay/temp/heal(get_turf(M), "#33FFCC")
|
||||
new /obj/effect/temp_visual/heal(get_turf(M), "#33FFCC")
|
||||
|
||||
if(!parts.len)
|
||||
return
|
||||
@@ -158,7 +158,7 @@ Bonus
|
||||
M.update_damage_overlays()
|
||||
|
||||
if(prob(20))
|
||||
new /obj/effect/overlay/temp/heal(get_turf(M), "#CC1100")
|
||||
new /obj/effect/temp_visual/heal(get_turf(M), "#CC1100")
|
||||
|
||||
return 1
|
||||
|
||||
@@ -201,7 +201,7 @@ Bonus
|
||||
M.update_damage_overlays()
|
||||
|
||||
if(prob(20))
|
||||
new /obj/effect/overlay/temp/heal(get_turf(M), "#FF9933")
|
||||
new /obj/effect/temp_visual/heal(get_turf(M), "#FF9933")
|
||||
return 1
|
||||
|
||||
|
||||
@@ -248,7 +248,7 @@ Bonus
|
||||
M.update_damage_overlays()
|
||||
|
||||
if(prob(20))
|
||||
new /obj/effect/overlay/temp/heal(get_turf(M), "#CC6600")
|
||||
new /obj/effect/temp_visual/heal(get_turf(M), "#CC6600")
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
+6
-670
@@ -79,681 +79,17 @@
|
||||
/datum/martial_art/proc/teach(mob/living/carbon/human/H,make_temporary=0)
|
||||
if(make_temporary)
|
||||
temporary = 1
|
||||
if(temporary && H.martial_art)
|
||||
if(!H.martial_art.allow_temp_override)
|
||||
if(temporary && H.mind.martial_art)
|
||||
if(!H.mind.martial_art.allow_temp_override)
|
||||
return
|
||||
base = H.martial_art
|
||||
base = H.mind.martial_art
|
||||
if(help_verb)
|
||||
H.verbs += help_verb
|
||||
H.martial_art = src
|
||||
H.mind.martial_art = src
|
||||
|
||||
/datum/martial_art/proc/remove(mob/living/carbon/human/H)
|
||||
if(H.martial_art != src)
|
||||
if(H.mind.martial_art != src)
|
||||
return
|
||||
H.martial_art = base
|
||||
H.mind.martial_art = base
|
||||
if(help_verb)
|
||||
H.verbs -= help_verb
|
||||
|
||||
/datum/martial_art/boxing
|
||||
name = "Boxing"
|
||||
|
||||
/datum/martial_art/boxing/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
to_chat(A, "<span class='warning'>Can't disarm while boxing!</span>")
|
||||
return 1
|
||||
|
||||
/datum/martial_art/boxing/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
to_chat(A, "<span class='warning'>Can't grab while boxing!</span>")
|
||||
return 1
|
||||
|
||||
/datum/martial_art/boxing/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
|
||||
var/atk_verb = pick("left hook","right hook","straight punch")
|
||||
|
||||
var/damage = rand(5, 8) + A.dna.species.punchdamagelow
|
||||
if(!damage)
|
||||
playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1)
|
||||
D.visible_message("<span class='warning'>[A] has attempted to [atk_verb] [D]!</span>", \
|
||||
"<span class='userdanger'>[A] has attempted to [atk_verb] [D]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(A, D, "attempted to hit", atk_verb)
|
||||
return 0
|
||||
|
||||
|
||||
var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected))
|
||||
var/armor_block = D.run_armor_check(affecting, "melee")
|
||||
|
||||
playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1)
|
||||
|
||||
D.visible_message("<span class='danger'>[A] has [atk_verb]ed [D]!</span>", \
|
||||
"<span class='userdanger'>[A] has [atk_verb]ed [D]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
D.apply_damage(damage, STAMINA, affecting, armor_block)
|
||||
add_logs(A, D, "punched (boxing) ")
|
||||
if(D.getStaminaLoss() > 50)
|
||||
var/knockout_prob = D.getStaminaLoss() + rand(-15,15)
|
||||
if((D.stat != DEAD) && prob(knockout_prob))
|
||||
D.visible_message("<span class='danger'>[A] has knocked [D] out with a haymaker!</span>", \
|
||||
"<span class='userdanger'>[A] has knocked [D] out with a haymaker!</span>")
|
||||
D.apply_effect(10,WEAKEN,armor_block)
|
||||
D.SetSleeping(5)
|
||||
D.forcesay(GLOB.hit_appends)
|
||||
add_logs(A, D, "knocked out (boxing) ")
|
||||
else if(D.lying)
|
||||
D.forcesay(GLOB.hit_appends)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/wrestling_help()
|
||||
set name = "Recall Teachings"
|
||||
set desc = "Remember how to wrestle."
|
||||
set category = "Wrestling"
|
||||
|
||||
to_chat(usr, "<b><i>You flex your muscles and have a revelation...</i></b>")
|
||||
to_chat(usr, "<span class='notice'>Clinch</span>: Grab. Passively gives you a chance to immediately aggressively grab someone. Not always successful.")
|
||||
to_chat(usr, "<span class='notice'>Suplex</span>: Disarm someone you are grabbing. Suplexes your target to the floor. Greatly injures them and leaves both you and your target on the floor.")
|
||||
to_chat(usr, "<span class='notice'>Advanced grab</span>: Grab. Passively causes stamina damage when grabbing someone.")
|
||||
|
||||
#define TORNADO_COMBO "HHD"
|
||||
#define THROWBACK_COMBO "DHD"
|
||||
#define PLASMA_COMBO "HDDDH"
|
||||
|
||||
/datum/martial_art/plasma_fist
|
||||
name = "Plasma Fist"
|
||||
help_verb = /mob/living/carbon/human/proc/plasma_fist_help
|
||||
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(findtext(streak,TORNADO_COMBO))
|
||||
streak = ""
|
||||
Tornado(A,D)
|
||||
return 1
|
||||
if(findtext(streak,THROWBACK_COMBO))
|
||||
streak = ""
|
||||
Throwback(A,D)
|
||||
return 1
|
||||
if(findtext(streak,PLASMA_COMBO))
|
||||
streak = ""
|
||||
Plasma(A,D)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/TornadoAnimate(mob/living/carbon/human/A)
|
||||
set waitfor = FALSE
|
||||
for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH))
|
||||
if(!A)
|
||||
break
|
||||
A.setDir(i)
|
||||
playsound(A.loc, 'sound/weapons/punch1.ogg', 15, 1, -1)
|
||||
sleep(1)
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/Tornado(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
A.say("TORNADO SWEEP!")
|
||||
TornadoAnimate(A)
|
||||
var/obj/effect/proc_holder/spell/aoe_turf/repulse/R = new(null)
|
||||
var/list/turfs = list()
|
||||
for(var/turf/T in range(1,A))
|
||||
turfs.Add(T)
|
||||
R.cast(turfs)
|
||||
add_logs(A, D, "tornado sweeped(Plasma Fist)")
|
||||
return
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/Throwback(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
D.visible_message("<span class='danger'>[A] has hit [D] with Plasma Punch!</span>", \
|
||||
"<span class='userdanger'>[A] has hit [D] with Plasma Punch!</span>")
|
||||
playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
var/atom/throw_target = get_edge_target_turf(D, get_dir(D, get_step_away(D, A)))
|
||||
D.throw_at(throw_target, 200, 4,A)
|
||||
A.say("HYAH!")
|
||||
add_logs(A, D, "threw back (Plasma Fist)")
|
||||
return
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/Plasma(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
A.say("PLASMA FIST!")
|
||||
D.visible_message("<span class='danger'>[A] has hit [D] with THE PLASMA FIST TECHNIQUE!</span>", \
|
||||
"<span class='userdanger'>[A] has hit [D] with THE PLASMA FIST TECHNIQUE!</span>")
|
||||
D.gib()
|
||||
add_logs(A, D, "gibbed (Plasma Fist)")
|
||||
return
|
||||
|
||||
/datum/martial_art/plasma_fist/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("H",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
basic_hit(A,D)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/plasma_fist/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("D",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
basic_hit(A,D)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/plasma_fist/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("G",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
basic_hit(A,D)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/plasma_fist_help()
|
||||
set name = "Recall Teachings"
|
||||
set desc = "Remember the martial techniques of the Plasma Fist."
|
||||
set category = "Plasma Fist"
|
||||
|
||||
to_chat(usr, "<b><i>You clench your fists and have a flashback of knowledge...</i></b>")
|
||||
to_chat(usr, "<span class='notice'>Tornado Sweep</span>: Harm Harm Disarm. Repulses target and everyone back.")
|
||||
to_chat(usr, "<span class='notice'>Throwback</span>: Disarm Harm Disarm. Throws the target and an item at them.")
|
||||
to_chat(usr, "<span class='notice'>The Plasma Fist</span>: Harm Disarm Disarm Disarm Harm. Knocks the brain out of the opponent and gibs their body.")
|
||||
|
||||
//Used by the gang of the same name. Uses combos. Basic attacks bypass armor and never miss
|
||||
#define WRIST_WRENCH_COMBO "DD"
|
||||
#define BACK_KICK_COMBO "HG"
|
||||
#define STOMACH_KNEE_COMBO "GH"
|
||||
#define HEAD_KICK_COMBO "DHH"
|
||||
#define ELBOW_DROP_COMBO "HDHDH"
|
||||
/datum/martial_art/the_sleeping_carp
|
||||
name = "The Sleeping Carp"
|
||||
deflection_chance = 100
|
||||
no_guns = TRUE
|
||||
allow_temp_override = FALSE
|
||||
help_verb = /mob/living/carbon/human/proc/sleeping_carp_help
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(findtext(streak,WRIST_WRENCH_COMBO))
|
||||
streak = ""
|
||||
wristWrench(A,D)
|
||||
return 1
|
||||
if(findtext(streak,BACK_KICK_COMBO))
|
||||
streak = ""
|
||||
backKick(A,D)
|
||||
return 1
|
||||
if(findtext(streak,STOMACH_KNEE_COMBO))
|
||||
streak = ""
|
||||
kneeStomach(A,D)
|
||||
return 1
|
||||
if(findtext(streak,HEAD_KICK_COMBO))
|
||||
streak = ""
|
||||
headKick(A,D)
|
||||
return 1
|
||||
if(findtext(streak,ELBOW_DROP_COMBO))
|
||||
streak = ""
|
||||
elbowDrop(A,D)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/wristWrench(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.stat && !D.stunned && !D.weakened)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
D.visible_message("<span class='warning'>[A] grabs [D]'s wrist and wrenches it sideways!</span>", \
|
||||
"<span class='userdanger'>[A] grabs your wrist and violently wrenches it to the side!</span>")
|
||||
playsound(get_turf(A), 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
D.emote("scream")
|
||||
D.drop_item()
|
||||
D.apply_damage(5, BRUTE, pick("l_arm", "r_arm"))
|
||||
D.Stun(3)
|
||||
return 1
|
||||
add_logs(A, D, "wrist wrenched (Sleeping Carp)")
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/backKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(A.dir == D.dir && !D.stat && !D.weakened)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
D.visible_message("<span class='warning'>[A] kicks [D] in the back!</span>", \
|
||||
"<span class='userdanger'>[A] kicks you in the back, making you stumble and fall!</span>")
|
||||
step_to(D,get_step(D,D.dir),1)
|
||||
D.Weaken(4)
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
return 1
|
||||
add_logs(A, D, "back-kicked (Sleeping Carp)")
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/kneeStomach(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.stat && !D.weakened)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
|
||||
D.visible_message("<span class='warning'>[A] knees [D] in the stomach!</span>", \
|
||||
"<span class='userdanger'>[A] winds you with a knee in the stomach!</span>")
|
||||
D.audible_message("<b>[D]</b> gags!")
|
||||
D.losebreath += 3
|
||||
D.Stun(2)
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
return 1
|
||||
add_logs(A, D, "stomach kneed (Sleeping Carp)")
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/headKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.stat && !D.weakened)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
|
||||
D.visible_message("<span class='warning'>[A] kicks [D] in the head!</span>", \
|
||||
"<span class='userdanger'>[A] kicks you in the jaw!</span>")
|
||||
D.apply_damage(20, BRUTE, "head")
|
||||
D.drop_item()
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
D.Stun(4)
|
||||
return 1
|
||||
add_logs(A, D, "head kicked (Sleeping Carp)")
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/elbowDrop(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(D.weakened || D.resting || D.stat)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
D.visible_message("<span class='warning'>[A] elbow drops [D]!</span>", \
|
||||
"<span class='userdanger'>[A] piledrives you with their elbow!</span>")
|
||||
if(D.stat)
|
||||
D.death() //FINISH HIM!
|
||||
D.apply_damage(50, BRUTE, "chest")
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 75, 1, -1)
|
||||
return 1
|
||||
add_logs(A, D, "elbow dropped (Sleeping Carp)")
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("G",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
if(A.grab_state >= GRAB_AGGRESSIVE)
|
||||
D.grabbedby(A, 1)
|
||||
else
|
||||
A.start_pulling(D, 1)
|
||||
if(A.pulling)
|
||||
D.drop_all_held_items()
|
||||
D.stop_pulling()
|
||||
if(A.a_intent == INTENT_GRAB)
|
||||
add_logs(A, D, "grabbed", addition="aggressively")
|
||||
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
|
||||
else
|
||||
add_logs(A, D, "grabbed", addition="passively")
|
||||
A.grab_state = GRAB_PASSIVE
|
||||
return 1
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("H",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
var/atk_verb = pick("punches", "kicks", "chops", "hits", "slams")
|
||||
D.visible_message("<span class='danger'>[A] [atk_verb] [D]!</span>", \
|
||||
"<span class='userdanger'>[A] [atk_verb] you!</span>")
|
||||
D.apply_damage(rand(10,15), BRUTE)
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 25, 1, -1)
|
||||
if(prob(D.getBruteLoss()) && !D.lying)
|
||||
D.visible_message("<span class='warning'>[D] stumbles and falls!</span>", "<span class='userdanger'>The blow sends you to the ground!</span>")
|
||||
D.Weaken(4)
|
||||
add_logs(A, D, "[atk_verb] (Sleeping Carp)")
|
||||
return 1
|
||||
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("D",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/proc/sleeping_carp_help()
|
||||
set name = "Recall Teachings"
|
||||
set desc = "Remember the martial techniques of the Sleeping Carp clan."
|
||||
set category = "Sleeping Carp"
|
||||
|
||||
to_chat(usr, "<b><i>You retreat inward and recall the teachings of the Sleeping Carp...</i></b>")
|
||||
|
||||
to_chat(usr, "<span class='notice'>Wrist Wrench</span>: Disarm Disarm. Forces opponent to drop item in hand.")
|
||||
to_chat(usr, "<span class='notice'>Back Kick</span>: Harm Grab. Opponent must be facing away. Knocks down.")
|
||||
to_chat(usr, "<span class='notice'>Stomach Knee</span>: Grab Harm. Knocks the wind out of opponent and stuns.")
|
||||
to_chat(usr, "<span class='notice'>Head Kick</span>: Disarm Harm Harm. Decent damage, forces opponent to drop item in hand.")
|
||||
to_chat(usr, "<span class='notice'>Elbow Drop</span>: Harm Disarm Harm Disarm Harm. Opponent must be on the ground. Deals huge damage, instantly kills anyone in critical condition.")
|
||||
|
||||
//CQC
|
||||
#define SLAM_COMBO "GH"
|
||||
#define KICK_COMBO "HH"
|
||||
#define RESTRAIN_COMBO "GG"
|
||||
#define PRESSURE_COMBO "DG"
|
||||
#define CONSECUTIVE_COMBO "DDH"
|
||||
/datum/martial_art/cqc
|
||||
name = "CQC"
|
||||
help_verb = /mob/living/carbon/human/proc/CQC_help
|
||||
block_chance = 75
|
||||
|
||||
/datum/martial_art/cqc/proc/drop_restraining()
|
||||
restraining = 0
|
||||
|
||||
/datum/martial_art/cqc/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(findtext(streak,SLAM_COMBO))
|
||||
streak = ""
|
||||
Slam(A,D)
|
||||
return 1
|
||||
if(findtext(streak,KICK_COMBO))
|
||||
streak = ""
|
||||
Kick(A,D)
|
||||
return 1
|
||||
if(findtext(streak,RESTRAIN_COMBO))
|
||||
streak = ""
|
||||
Restrain(A,D)
|
||||
return 1
|
||||
if(findtext(streak,PRESSURE_COMBO))
|
||||
streak = ""
|
||||
Pressure(A,D)
|
||||
return 1
|
||||
if(findtext(streak,CONSECUTIVE_COMBO))
|
||||
streak = ""
|
||||
Consecutive(A,D)
|
||||
return 0
|
||||
|
||||
/datum/martial_art/cqc/proc/Slam(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.stat || !D.weakened)
|
||||
D.visible_message("<span class='warning'>[A] slams [D] into the ground!</span>", \
|
||||
"<span class='userdanger'>[A] slams you into the ground!</span>")
|
||||
playsound(get_turf(A), 'sound/weapons/slam.ogg', 50, 1, -1)
|
||||
D.apply_damage(10, BRUTE)
|
||||
D.Weaken(6)
|
||||
add_logs(A, D, "cqc slammed")
|
||||
return 1
|
||||
|
||||
/datum/martial_art/cqc/proc/Kick(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.stat || !D.weakened)
|
||||
D.visible_message("<span class='warning'>[A] kicks [D] back!</span>", \
|
||||
"<span class='userdanger'>[A] kicks you back!</span>")
|
||||
playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
|
||||
var/atom/throw_target = get_edge_target_turf(D, A.dir)
|
||||
D.throw_at(throw_target, 1, 14, A)
|
||||
D.apply_damage(10, BRUTE)
|
||||
add_logs(A, D, "cqc kicked")
|
||||
if(D.weakened && !D.stat)
|
||||
D.visible_message("<span class='warning'>[A] kicks [D]'s head, knocking them out!</span>", \
|
||||
"<span class='userdanger'>[A] kicks your head, knocking you out!</span>")
|
||||
playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1)
|
||||
D.SetSleeping(15)
|
||||
D.adjustBrainLoss(25)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/cqc/proc/Pressure(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
D.visible_message("<span class='warning'>[A] forces their arm on [D]'s neck!</span>")
|
||||
D.adjustStaminaLoss(60)
|
||||
playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/cqc/proc/Restrain(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(restraining)
|
||||
return
|
||||
if(!D.stat)
|
||||
D.visible_message("<span class='warning'>[A] locks [D] into a restraining position!</span>", \
|
||||
"<span class='userdanger'>[A] locks you into a restraining position!</span>")
|
||||
D.adjustStaminaLoss(20)
|
||||
D.Stun(5)
|
||||
restraining = 1
|
||||
addtimer(CALLBACK(src, .proc/drop_restraining), 50, TIMER_UNIQUE)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/cqc/proc/Consecutive(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.stat)
|
||||
D.visible_message("<span class='warning'>[A] strikes [D]'s abdomen, neck and back consecutively</span>", \
|
||||
"<span class='userdanger'>[A] strikes your abdomen, neck and back consecutively!</span>")
|
||||
playsound(get_turf(D), 'sound/weapons/cqchit2.ogg', 50, 1, -1)
|
||||
var/obj/item/I = D.get_active_held_item()
|
||||
if(I && D.drop_item())
|
||||
A.put_in_hands(I)
|
||||
D.adjustStaminaLoss(50)
|
||||
D.apply_damage(25, BRUTE)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/cqc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("G",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
if(A.grab_state >= GRAB_AGGRESSIVE)
|
||||
D.grabbedby(A, 1)
|
||||
else
|
||||
A.start_pulling(D, 1)
|
||||
if(A.pulling)
|
||||
D.stop_pulling()
|
||||
add_logs(A, D, "grabbed", addition="aggressively")
|
||||
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
|
||||
|
||||
return 1
|
||||
|
||||
/datum/martial_art/cqc/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("H",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
add_logs(A, D, "CQC'd")
|
||||
A.do_attack_animation(D)
|
||||
var/picked_hit_type = pick("CQC'd", "Big Bossed")
|
||||
var/bonus_damage = 13
|
||||
if(D.weakened || D.resting || D.lying)
|
||||
bonus_damage += 5
|
||||
picked_hit_type = "stomps on"
|
||||
D.apply_damage(bonus_damage, BRUTE)
|
||||
if(picked_hit_type == "kicks" || picked_hit_type == "stomps on")
|
||||
playsound(get_turf(D), 'sound/weapons/cqchit2.ogg', 50, 1, -1)
|
||||
else
|
||||
playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
|
||||
D.visible_message("<span class='danger'>[A] [picked_hit_type] [D]!</span>", \
|
||||
"<span class='userdanger'>[A] [picked_hit_type] you!</span>")
|
||||
add_logs(A, D, "[picked_hit_type] with CQC")
|
||||
if(A.resting && !D.stat && !D.weakened)
|
||||
D.visible_message("<span class='warning'>[A] leg sweeps [D]!", \
|
||||
"<span class='userdanger'>[A] leg sweeps you!</span>")
|
||||
playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1)
|
||||
D.apply_damage(10, BRUTE)
|
||||
D.Weaken(3)
|
||||
add_logs(A, D, "cqc sweeped")
|
||||
return 1
|
||||
|
||||
/datum/martial_art/cqc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("D",D)
|
||||
var/obj/item/I = null
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
if(prob(65))
|
||||
if(!D.stat || !D.weakened || !restraining)
|
||||
I = D.get_active_held_item()
|
||||
D.visible_message("<span class='warning'>[A] strikes [D]'s jaw with their hand!</span>", \
|
||||
"<span class='userdanger'>[A] strikes your jaw, disorienting you!</span>")
|
||||
playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
|
||||
if(I && D.drop_item())
|
||||
A.put_in_hands(I)
|
||||
D.Jitter(2)
|
||||
D.apply_damage(5, BRUTE)
|
||||
else
|
||||
D.visible_message("<span class='danger'>[A] attempted to disarm [D]!</span>", \
|
||||
"<span class='userdanger'>[A] attempted to disarm [D]!</span>")
|
||||
playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
add_logs(A, D, "disarmed with CQC", "[I ? " grabbing \the [I]" : ""]")
|
||||
if(restraining && A.pulling == D)
|
||||
D.visible_message("<span class='danger'>[A] puts [D] into a chokehold!</span>", \
|
||||
"<span class='userdanger'>[A] puts you into a chokehold!</span>")
|
||||
D.SetSleeping(20)
|
||||
restraining = 0
|
||||
if(A.grab_state < GRAB_NECK)
|
||||
A.grab_state = GRAB_NECK
|
||||
else
|
||||
restraining = 0
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/CQC_help()
|
||||
set name = "Remember The Basics"
|
||||
set desc = "You try to remember some of the basics of CQC."
|
||||
set category = "CQC"
|
||||
|
||||
to_chat(usr, "<b><i>You try to remember some of the basics of CQC.</i></b>")
|
||||
|
||||
to_chat(usr, "<span class='notice'>Slam</span>: Grab Harm. Slam opponent into the ground, weakens and knocks down.")
|
||||
to_chat(usr, "<span class='notice'>CQC Kick</span>: Harm Disarm Harm. Knocks opponent away. Knocks out stunned or weakened opponents.")
|
||||
to_chat(usr, "<span class='notice'>Restrain</span>: Grab Grab. Locks opponents into a restraining position, disarm to knock them out with a choke hold.")
|
||||
to_chat(usr, "<span class='notice'>Pressure</span>: Disarm Grab. Decent stamina damage.")
|
||||
to_chat(usr, "<span class='notice'>Consecutive CQC</span>: Disarm Disarm Harm. Mainly offensive move, huge damage and decent stamina damage.")
|
||||
|
||||
to_chat(usr, "<b><i>In addition, by having your throw mode on when being attacked, you enter an active defense mode where you have a chance to block and sometimes even counter attacks done to you.</i></b>")
|
||||
|
||||
//ITEMS
|
||||
|
||||
/obj/item/clothing/gloves/boxing
|
||||
var/datum/martial_art/boxing/style = new
|
||||
|
||||
/obj/item/clothing/gloves/boxing/equipped(mob/user, slot)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot == slot_gloves)
|
||||
var/mob/living/carbon/human/H = user
|
||||
style.teach(H,1)
|
||||
return
|
||||
|
||||
/obj/item/clothing/gloves/boxing/dropped(mob/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.get_item_by_slot(slot_gloves) == src)
|
||||
style.remove(H)
|
||||
return
|
||||
|
||||
/obj/item/weapon/storage/belt/champion/wrestling
|
||||
name = "Wrestling Belt"
|
||||
var/datum/martial_art/wrestling/style = new
|
||||
|
||||
/obj/item/weapon/storage/belt/champion/wrestling/equipped(mob/user, slot)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot == slot_belt)
|
||||
var/mob/living/carbon/human/H = user
|
||||
style.teach(H,1)
|
||||
return
|
||||
|
||||
/obj/item/weapon/storage/belt/champion/wrestling/dropped(mob/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.get_item_by_slot(slot_belt) == src)
|
||||
style.remove(H)
|
||||
return
|
||||
|
||||
/obj/item/weapon/plasma_fist_scroll
|
||||
name = "frayed scroll"
|
||||
desc = "An aged and frayed scrap of paper written in shifting runes. There are hand-drawn illustrations of pugilism."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state ="scroll2"
|
||||
var/used = 0
|
||||
|
||||
/obj/item/weapon/plasma_fist_scroll/attack_self(mob/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(!used)
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/datum/martial_art/plasma_fist/F = new/datum/martial_art/plasma_fist(null)
|
||||
F.teach(H)
|
||||
to_chat(H, "<span class='boldannounce'>You have learned the ancient martial art of Plasma Fist.</span>")
|
||||
used = 1
|
||||
desc = "It's completely blank."
|
||||
name = "empty scroll"
|
||||
icon_state = "blankscroll"
|
||||
|
||||
/obj/item/weapon/cqc_manual
|
||||
name = "old manual"
|
||||
desc = "A small, black manual. There are drawn instructions of tactical hand-to-hand combat."
|
||||
icon = 'icons/obj/library.dmi'
|
||||
icon_state ="cqcmanual"
|
||||
|
||||
/obj/item/weapon/cqc_manual/attack_self(mob/living/carbon/human/user)
|
||||
if(!istype(user) || !user)
|
||||
return
|
||||
to_chat(user, "<span class='boldannounce'>You remember the basics of CQC.</span>")
|
||||
var/datum/martial_art/cqc/D = new(null)
|
||||
D.teach(user)
|
||||
user.drop_item()
|
||||
visible_message("<span class='warning'>[src] beeps ominously, and a moment later it bursts up in flames.</span>")
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/sleeping_carp_scroll
|
||||
name = "mysterious scroll"
|
||||
desc = "A scroll filled with strange markings. It seems to be drawings of some sort of martial art."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "scroll2"
|
||||
|
||||
/obj/item/weapon/sleeping_carp_scroll/attack_self(mob/living/carbon/human/user)
|
||||
if(!istype(user) || !user)
|
||||
return
|
||||
var/message = "<span class='sciradio'>You have learned the ancient martial art of the Sleeping Carp! Your hand-to-hand combat has become much more effective, and you are now able to deflect any projectiles \
|
||||
directed toward you. However, you are also unable to use any ranged weaponry. You can learn more about your newfound art by using the Recall Teachings verb in the Sleeping Carp tab.</span>"
|
||||
to_chat(user, message)
|
||||
var/datum/martial_art/the_sleeping_carp/theSleepingCarp = new(null)
|
||||
theSleepingCarp.teach(user)
|
||||
user.drop_item()
|
||||
visible_message("<span class='warning'>[src] lights up in fire and quickly burns to ash.</span>")
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/twohanded/bostaff
|
||||
name = "bo staff"
|
||||
desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts. Can be wielded to both kill and incapacitate."
|
||||
force = 10
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = SLOT_BACK
|
||||
force_unwielded = 10
|
||||
force_wielded = 24
|
||||
throwforce = 20
|
||||
throw_speed = 2
|
||||
attack_verb = list("smashed", "slammed", "whacked", "thwacked")
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "bostaff0"
|
||||
block_chance = 50
|
||||
|
||||
/obj/item/weapon/twohanded/bostaff/update_icon()
|
||||
icon_state = "bostaff[wielded]"
|
||||
return
|
||||
|
||||
/obj/item/weapon/twohanded/bostaff/attack(mob/target, mob/living/user)
|
||||
add_fingerprint(user)
|
||||
if((CLUMSY in user.disabilities) && prob(50))
|
||||
to_chat(user, "<span class ='warning'>You club yourself over the head with [src].</span>")
|
||||
user.Weaken(3)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.apply_damage(2*force, BRUTE, "head")
|
||||
else
|
||||
user.take_bodypart_damage(2*force)
|
||||
return
|
||||
if(iscyborg(target))
|
||||
return ..()
|
||||
if(!isliving(target))
|
||||
return ..()
|
||||
var/mob/living/carbon/C = target
|
||||
if(C.stat)
|
||||
to_chat(user, "<span class='warning'>It would be dishonorable to attack a foe while they cannot retaliate.</span>")
|
||||
return
|
||||
if(user.a_intent == INTENT_DISARM)
|
||||
if(!wielded)
|
||||
return ..()
|
||||
if(!ishuman(target))
|
||||
return ..()
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/list/fluffmessages = list("[user] clubs [H] with [src]!", \
|
||||
"[user] smacks [H] with the butt of [src]!", \
|
||||
"[user] broadsides [H] with [src]!", \
|
||||
"[user] smashes [H]'s head with [src]!", \
|
||||
"[user] beats [H] with front of [src]!", \
|
||||
"[user] twirls and slams [H] with [src]!")
|
||||
H.visible_message("<span class='warning'>[pick(fluffmessages)]</span>", \
|
||||
"<span class='userdanger'>[pick(fluffmessages)]</span>")
|
||||
playsound(get_turf(user), 'sound/effects/woodhit.ogg', 75, 1, -1)
|
||||
H.adjustStaminaLoss(rand(13,20))
|
||||
if(prob(10))
|
||||
H.visible_message("<span class='warning'>[H] collapses!</span>", \
|
||||
"<span class='userdanger'>Your legs give out!</span>")
|
||||
H.Weaken(4)
|
||||
if(H.staminaloss && !H.sleeping)
|
||||
var/total_health = (H.health - H.staminaloss)
|
||||
if(total_health <= HEALTH_THRESHOLD_CRIT && !H.stat)
|
||||
H.visible_message("<span class='warning'>[user] delivers a heavy hit to [H]'s head, knocking them out cold!</span>", \
|
||||
"<span class='userdanger'>[user] knocks you unconscious!</span>")
|
||||
H.SetSleeping(30)
|
||||
H.adjustBrainLoss(25)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/twohanded/bostaff/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
|
||||
if(wielded)
|
||||
return ..()
|
||||
return 0
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/datum/martial_art/boxing
|
||||
name = "Boxing"
|
||||
|
||||
/datum/martial_art/boxing/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
to_chat(A, "<span class='warning'>Can't disarm while boxing!</span>")
|
||||
return 1
|
||||
|
||||
/datum/martial_art/boxing/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
to_chat(A, "<span class='warning'>Can't grab while boxing!</span>")
|
||||
return 1
|
||||
|
||||
/datum/martial_art/boxing/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
|
||||
var/atk_verb = pick("left hook","right hook","straight punch")
|
||||
|
||||
var/damage = rand(5, 8) + A.dna.species.punchdamagelow
|
||||
if(!damage)
|
||||
playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1)
|
||||
D.visible_message("<span class='warning'>[A] has attempted to [atk_verb] [D]!</span>", \
|
||||
"<span class='userdanger'>[A] has attempted to [atk_verb] [D]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(A, D, "attempted to hit", atk_verb)
|
||||
return 0
|
||||
|
||||
|
||||
var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected))
|
||||
var/armor_block = D.run_armor_check(affecting, "melee")
|
||||
|
||||
playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1)
|
||||
|
||||
D.visible_message("<span class='danger'>[A] has [atk_verb]ed [D]!</span>", \
|
||||
"<span class='userdanger'>[A] has [atk_verb]ed [D]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
D.apply_damage(damage, STAMINA, affecting, armor_block)
|
||||
add_logs(A, D, "punched (boxing) ")
|
||||
if(D.getStaminaLoss() > 50)
|
||||
var/knockout_prob = D.getStaminaLoss() + rand(-15,15)
|
||||
if((D.stat != DEAD) && prob(knockout_prob))
|
||||
D.visible_message("<span class='danger'>[A] has knocked [D] out with a haymaker!</span>", \
|
||||
"<span class='userdanger'>[A] has knocked [D] out with a haymaker!</span>")
|
||||
D.apply_effect(10,WEAKEN,armor_block)
|
||||
D.SetSleeping(5)
|
||||
D.forcesay(GLOB.hit_appends)
|
||||
add_logs(A, D, "knocked out (boxing) ")
|
||||
else if(D.lying)
|
||||
D.forcesay(GLOB.hit_appends)
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/gloves/boxing
|
||||
var/datum/martial_art/boxing/style = new
|
||||
|
||||
/obj/item/clothing/gloves/boxing/equipped(mob/user, slot)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot == slot_gloves)
|
||||
var/mob/living/carbon/human/H = user
|
||||
style.teach(H,1)
|
||||
return
|
||||
|
||||
/obj/item/clothing/gloves/boxing/dropped(mob/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.get_item_by_slot(slot_gloves) == src)
|
||||
style.remove(H)
|
||||
return
|
||||
@@ -0,0 +1,199 @@
|
||||
#define SLAM_COMBO "GH"
|
||||
#define KICK_COMBO "HH"
|
||||
#define RESTRAIN_COMBO "GG"
|
||||
#define PRESSURE_COMBO "DG"
|
||||
#define CONSECUTIVE_COMBO "DDH"
|
||||
|
||||
/datum/martial_art/cqc
|
||||
name = "CQC"
|
||||
help_verb = /mob/living/carbon/human/proc/CQC_help
|
||||
block_chance = 75
|
||||
|
||||
/datum/martial_art/cqc/proc/drop_restraining()
|
||||
restraining = 0
|
||||
|
||||
/datum/martial_art/cqc/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(findtext(streak,SLAM_COMBO))
|
||||
streak = ""
|
||||
Slam(A,D)
|
||||
return 1
|
||||
if(findtext(streak,KICK_COMBO))
|
||||
streak = ""
|
||||
Kick(A,D)
|
||||
return 1
|
||||
if(findtext(streak,RESTRAIN_COMBO))
|
||||
streak = ""
|
||||
Restrain(A,D)
|
||||
return 1
|
||||
if(findtext(streak,PRESSURE_COMBO))
|
||||
streak = ""
|
||||
Pressure(A,D)
|
||||
return 1
|
||||
if(findtext(streak,CONSECUTIVE_COMBO))
|
||||
streak = ""
|
||||
Consecutive(A,D)
|
||||
return 0
|
||||
|
||||
/datum/martial_art/cqc/proc/Slam(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.stat || !D.weakened)
|
||||
D.visible_message("<span class='warning'>[A] slams [D] into the ground!</span>", \
|
||||
"<span class='userdanger'>[A] slams you into the ground!</span>")
|
||||
playsound(get_turf(A), 'sound/weapons/slam.ogg', 50, 1, -1)
|
||||
D.apply_damage(10, BRUTE)
|
||||
D.Weaken(6)
|
||||
add_logs(A, D, "cqc slammed")
|
||||
return 1
|
||||
|
||||
/datum/martial_art/cqc/proc/Kick(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.stat || !D.weakened)
|
||||
D.visible_message("<span class='warning'>[A] kicks [D] back!</span>", \
|
||||
"<span class='userdanger'>[A] kicks you back!</span>")
|
||||
playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
|
||||
var/atom/throw_target = get_edge_target_turf(D, A.dir)
|
||||
D.throw_at(throw_target, 1, 14, A)
|
||||
D.apply_damage(10, BRUTE)
|
||||
add_logs(A, D, "cqc kicked")
|
||||
if(D.weakened && !D.stat)
|
||||
D.visible_message("<span class='warning'>[A] kicks [D]'s head, knocking them out!</span>", \
|
||||
"<span class='userdanger'>[A] kicks your head, knocking you out!</span>")
|
||||
playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1)
|
||||
D.SetSleeping(15)
|
||||
D.adjustBrainLoss(25)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/cqc/proc/Pressure(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
D.visible_message("<span class='warning'>[A] forces their arm on [D]'s neck!</span>")
|
||||
D.adjustStaminaLoss(60)
|
||||
playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/cqc/proc/Restrain(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(restraining)
|
||||
return
|
||||
if(!D.stat)
|
||||
D.visible_message("<span class='warning'>[A] locks [D] into a restraining position!</span>", \
|
||||
"<span class='userdanger'>[A] locks you into a restraining position!</span>")
|
||||
D.adjustStaminaLoss(20)
|
||||
D.Stun(5)
|
||||
restraining = 1
|
||||
addtimer(CALLBACK(src, .proc/drop_restraining), 50, TIMER_UNIQUE)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/cqc/proc/Consecutive(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.stat)
|
||||
D.visible_message("<span class='warning'>[A] strikes [D]'s abdomen, neck and back consecutively</span>", \
|
||||
"<span class='userdanger'>[A] strikes your abdomen, neck and back consecutively!</span>")
|
||||
playsound(get_turf(D), 'sound/weapons/cqchit2.ogg', 50, 1, -1)
|
||||
var/obj/item/I = D.get_active_held_item()
|
||||
if(I && D.drop_item())
|
||||
A.put_in_hands(I)
|
||||
D.adjustStaminaLoss(50)
|
||||
D.apply_damage(25, BRUTE)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/cqc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("G",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
if(A.grab_state >= GRAB_AGGRESSIVE)
|
||||
D.grabbedby(A, 1)
|
||||
else
|
||||
A.start_pulling(D, 1)
|
||||
if(A.pulling)
|
||||
D.stop_pulling()
|
||||
add_logs(A, D, "grabbed", addition="aggressively")
|
||||
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
|
||||
|
||||
return 1
|
||||
|
||||
/datum/martial_art/cqc/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("H",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
add_logs(A, D, "CQC'd")
|
||||
A.do_attack_animation(D)
|
||||
var/picked_hit_type = pick("CQC'd", "Big Bossed")
|
||||
var/bonus_damage = 13
|
||||
if(D.weakened || D.resting || D.lying)
|
||||
bonus_damage += 5
|
||||
picked_hit_type = "stomps on"
|
||||
D.apply_damage(bonus_damage, BRUTE)
|
||||
if(picked_hit_type == "kicks" || picked_hit_type == "stomps on")
|
||||
playsound(get_turf(D), 'sound/weapons/cqchit2.ogg', 50, 1, -1)
|
||||
else
|
||||
playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
|
||||
D.visible_message("<span class='danger'>[A] [picked_hit_type] [D]!</span>", \
|
||||
"<span class='userdanger'>[A] [picked_hit_type] you!</span>")
|
||||
add_logs(A, D, "[picked_hit_type] with CQC")
|
||||
if(A.resting && !D.stat && !D.weakened)
|
||||
D.visible_message("<span class='warning'>[A] leg sweeps [D]!", \
|
||||
"<span class='userdanger'>[A] leg sweeps you!</span>")
|
||||
playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1)
|
||||
D.apply_damage(10, BRUTE)
|
||||
D.Weaken(3)
|
||||
add_logs(A, D, "cqc sweeped")
|
||||
return 1
|
||||
|
||||
/datum/martial_art/cqc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("D",D)
|
||||
var/obj/item/I = null
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
if(prob(65))
|
||||
if(!D.stat || !D.weakened || !restraining)
|
||||
I = D.get_active_held_item()
|
||||
D.visible_message("<span class='warning'>[A] strikes [D]'s jaw with their hand!</span>", \
|
||||
"<span class='userdanger'>[A] strikes your jaw, disorienting you!</span>")
|
||||
playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
|
||||
if(I && D.drop_item())
|
||||
A.put_in_hands(I)
|
||||
D.Jitter(2)
|
||||
D.apply_damage(5, BRUTE)
|
||||
else
|
||||
D.visible_message("<span class='danger'>[A] attempted to disarm [D]!</span>", \
|
||||
"<span class='userdanger'>[A] attempted to disarm [D]!</span>")
|
||||
playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
add_logs(A, D, "disarmed with CQC", "[I ? " grabbing \the [I]" : ""]")
|
||||
if(restraining && A.pulling == D)
|
||||
D.visible_message("<span class='danger'>[A] puts [D] into a chokehold!</span>", \
|
||||
"<span class='userdanger'>[A] puts you into a chokehold!</span>")
|
||||
D.SetSleeping(20)
|
||||
restraining = 0
|
||||
if(A.grab_state < GRAB_NECK)
|
||||
A.grab_state = GRAB_NECK
|
||||
else
|
||||
restraining = 0
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/CQC_help()
|
||||
set name = "Remember The Basics"
|
||||
set desc = "You try to remember some of the basics of CQC."
|
||||
set category = "CQC"
|
||||
|
||||
to_chat(usr, "<b><i>You try to remember some of the basics of CQC.</i></b>")
|
||||
|
||||
to_chat(usr, "<span class='notice'>Slam</span>: Grab Harm. Slam opponent into the ground, weakens and knocks down.")
|
||||
to_chat(usr, "<span class='notice'>CQC Kick</span>: Harm Disarm Harm. Knocks opponent away. Knocks out stunned or weakened opponents.")
|
||||
to_chat(usr, "<span class='notice'>Restrain</span>: Grab Grab. Locks opponents into a restraining position, disarm to knock them out with a choke hold.")
|
||||
to_chat(usr, "<span class='notice'>Pressure</span>: Disarm Grab. Decent stamina damage.")
|
||||
to_chat(usr, "<span class='notice'>Consecutive CQC</span>: Disarm Disarm Harm. Mainly offensive move, huge damage and decent stamina damage.")
|
||||
|
||||
to_chat(usr, "<b><i>In addition, by having your throw mode on when being attacked, you enter an active defense mode where you have a chance to block and sometimes even counter attacks done to you.</i></b>")
|
||||
|
||||
/obj/item/weapon/cqc_manual
|
||||
name = "old manual"
|
||||
desc = "A small, black manual. There are drawn instructions of tactical hand-to-hand combat."
|
||||
icon = 'icons/obj/library.dmi'
|
||||
icon_state ="cqcmanual"
|
||||
|
||||
/obj/item/weapon/cqc_manual/attack_self(mob/living/carbon/human/user)
|
||||
if(!istype(user) || !user)
|
||||
return
|
||||
to_chat(user, "<span class='boldannounce'>You remember the basics of CQC.</span>")
|
||||
var/datum/martial_art/cqc/D = new(null)
|
||||
D.teach(user)
|
||||
user.drop_item()
|
||||
visible_message("<span class='warning'>[src] beeps ominously, and a moment later it bursts up in flames.</span>")
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(src))
|
||||
qdel(src)
|
||||
@@ -13,12 +13,12 @@
|
||||
to_chat(owner, "<span class='warning'>You can't use Krav Maga while you're incapacitated.</span>")
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if (H.martial_art.streak == "neck_chop")
|
||||
if (H.mind.martial_art.streak == "neck_chop")
|
||||
owner.visible_message("<span class='danger'>[owner] assumes a neutral stance.</span>", "<b><i>Your next attack is cleared.</i></b>")
|
||||
H.martial_art.streak = ""
|
||||
H.mind.martial_art.streak = ""
|
||||
else
|
||||
owner.visible_message("<span class='danger'>[owner] assumes the Neck Chop stance!</span>", "<b><i>Your next attack will be a Neck Chop.</i></b>")
|
||||
H.martial_art.streak = "neck_chop"
|
||||
H.mind.martial_art.streak = "neck_chop"
|
||||
|
||||
/datum/action/leg_sweep
|
||||
name = "Leg Sweep - Trips the victim, knocking them down for a brief moment."
|
||||
@@ -29,12 +29,12 @@
|
||||
to_chat(owner, "<span class='warning'>You can't use Krav Maga while you're incapacitated.</span>")
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if (H.martial_art.streak == "leg_sweep")
|
||||
if (H.mind.martial_art.streak == "leg_sweep")
|
||||
owner.visible_message("<span class='danger'>[owner] assumes a neutral stance.</span>", "<b><i>Your next attack is cleared.</i></b>")
|
||||
H.martial_art.streak = ""
|
||||
H.mind.martial_art.streak = ""
|
||||
else
|
||||
owner.visible_message("<span class='danger'>[owner] assumes the Leg Sweep stance!</span>", "<b><i>Your next attack will be a Leg Sweep.</i></b>")
|
||||
H.martial_art.streak = "leg_sweep"
|
||||
H.mind.martial_art.streak = "leg_sweep"
|
||||
|
||||
/datum/action/lung_punch//referred to internally as 'quick choke'
|
||||
name = "Lung Punch - Delivers a strong punch just above the victim's abdomen, constraining the lungs. The victim will be unable to breathe for a short time."
|
||||
@@ -45,12 +45,12 @@
|
||||
to_chat(owner, "<span class='warning'>You can't use Krav Maga while you're incapacitated.</span>")
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if (H.martial_art.streak == "quick_choke")
|
||||
if (H.mind.martial_art.streak == "quick_choke")
|
||||
owner.visible_message("<span class='danger'>[owner] assumes a neutral stance.</span>", "<b><i>Your next attack is cleared.</i></b>")
|
||||
H.martial_art.streak = ""
|
||||
H.mind.martial_art.streak = ""
|
||||
else
|
||||
owner.visible_message("<span class='danger'>[owner] assumes the Lung Punch stance!</span>", "<b><i>Your next attack will be a Lung Punch.</i></b>")
|
||||
H.martial_art.streak = "quick_choke"//internal name for lung punch
|
||||
H.mind.martial_art.streak = "quick_choke"//internal name for lung punch
|
||||
|
||||
/datum/martial_art/krav_maga/teach(var/mob/living/carbon/human/H,var/make_temporary=0)
|
||||
..()
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
#define TORNADO_COMBO "HHD"
|
||||
#define THROWBACK_COMBO "DHD"
|
||||
#define PLASMA_COMBO "HDDDH"
|
||||
|
||||
/datum/martial_art/plasma_fist
|
||||
name = "Plasma Fist"
|
||||
help_verb = /mob/living/carbon/human/proc/plasma_fist_help
|
||||
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(findtext(streak,TORNADO_COMBO))
|
||||
streak = ""
|
||||
Tornado(A,D)
|
||||
return 1
|
||||
if(findtext(streak,THROWBACK_COMBO))
|
||||
streak = ""
|
||||
Throwback(A,D)
|
||||
return 1
|
||||
if(findtext(streak,PLASMA_COMBO))
|
||||
streak = ""
|
||||
Plasma(A,D)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/TornadoAnimate(mob/living/carbon/human/A)
|
||||
set waitfor = FALSE
|
||||
for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH))
|
||||
if(!A)
|
||||
break
|
||||
A.setDir(i)
|
||||
playsound(A.loc, 'sound/weapons/punch1.ogg', 15, 1, -1)
|
||||
sleep(1)
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/Tornado(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
A.say("TORNADO SWEEP!")
|
||||
TornadoAnimate(A)
|
||||
var/obj/effect/proc_holder/spell/aoe_turf/repulse/R = new(null)
|
||||
var/list/turfs = list()
|
||||
for(var/turf/T in range(1,A))
|
||||
turfs.Add(T)
|
||||
R.cast(turfs)
|
||||
add_logs(A, D, "tornado sweeped(Plasma Fist)")
|
||||
return
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/Throwback(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
D.visible_message("<span class='danger'>[A] has hit [D] with Plasma Punch!</span>", \
|
||||
"<span class='userdanger'>[A] has hit [D] with Plasma Punch!</span>")
|
||||
playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
var/atom/throw_target = get_edge_target_turf(D, get_dir(D, get_step_away(D, A)))
|
||||
D.throw_at(throw_target, 200, 4,A)
|
||||
A.say("HYAH!")
|
||||
add_logs(A, D, "threw back (Plasma Fist)")
|
||||
return
|
||||
|
||||
/datum/martial_art/plasma_fist/proc/Plasma(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
A.say("PLASMA FIST!")
|
||||
D.visible_message("<span class='danger'>[A] has hit [D] with THE PLASMA FIST TECHNIQUE!</span>", \
|
||||
"<span class='userdanger'>[A] has hit [D] with THE PLASMA FIST TECHNIQUE!</span>")
|
||||
D.gib()
|
||||
add_logs(A, D, "gibbed (Plasma Fist)")
|
||||
return
|
||||
|
||||
/datum/martial_art/plasma_fist/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("H",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
basic_hit(A,D)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/plasma_fist/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("D",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
basic_hit(A,D)
|
||||
return 1
|
||||
|
||||
/datum/martial_art/plasma_fist/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("G",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
basic_hit(A,D)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/proc/plasma_fist_help()
|
||||
set name = "Recall Teachings"
|
||||
set desc = "Remember the martial techniques of the Plasma Fist."
|
||||
set category = "Plasma Fist"
|
||||
|
||||
to_chat(usr, "<b><i>You clench your fists and have a flashback of knowledge...</i></b>")
|
||||
to_chat(usr, "<span class='notice'>Tornado Sweep</span>: Harm Harm Disarm. Repulses target and everyone back.")
|
||||
to_chat(usr, "<span class='notice'>Throwback</span>: Disarm Harm Disarm. Throws the target and an item at them.")
|
||||
to_chat(usr, "<span class='notice'>The Plasma Fist</span>: Harm Disarm Disarm Disarm Harm. Knocks the brain out of the opponent and gibs their body.")
|
||||
|
||||
/obj/item/weapon/plasma_fist_scroll
|
||||
name = "frayed scroll"
|
||||
desc = "An aged and frayed scrap of paper written in shifting runes. There are hand-drawn illustrations of pugilism."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state ="scroll2"
|
||||
var/used = 0
|
||||
|
||||
/obj/item/weapon/plasma_fist_scroll/attack_self(mob/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(!used)
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/datum/martial_art/plasma_fist/F = new/datum/martial_art/plasma_fist(null)
|
||||
F.teach(H)
|
||||
to_chat(H, "<span class='boldannounce'>You have learned the ancient martial art of Plasma Fist.</span>")
|
||||
used = 1
|
||||
desc = "It's completely blank."
|
||||
name = "empty scroll"
|
||||
icon_state = "blankscroll"
|
||||
@@ -0,0 +1,247 @@
|
||||
#define WRIST_WRENCH_COMBO "DD"
|
||||
#define BACK_KICK_COMBO "HG"
|
||||
#define STOMACH_KNEE_COMBO "GH"
|
||||
#define HEAD_KICK_COMBO "DHH"
|
||||
#define ELBOW_DROP_COMBO "HDHDH"
|
||||
|
||||
/datum/martial_art/the_sleeping_carp
|
||||
name = "The Sleeping Carp"
|
||||
deflection_chance = 100
|
||||
no_guns = TRUE
|
||||
allow_temp_override = FALSE
|
||||
help_verb = /mob/living/carbon/human/proc/sleeping_carp_help
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(findtext(streak,WRIST_WRENCH_COMBO))
|
||||
streak = ""
|
||||
wristWrench(A,D)
|
||||
return 1
|
||||
if(findtext(streak,BACK_KICK_COMBO))
|
||||
streak = ""
|
||||
backKick(A,D)
|
||||
return 1
|
||||
if(findtext(streak,STOMACH_KNEE_COMBO))
|
||||
streak = ""
|
||||
kneeStomach(A,D)
|
||||
return 1
|
||||
if(findtext(streak,HEAD_KICK_COMBO))
|
||||
streak = ""
|
||||
headKick(A,D)
|
||||
return 1
|
||||
if(findtext(streak,ELBOW_DROP_COMBO))
|
||||
streak = ""
|
||||
elbowDrop(A,D)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/wristWrench(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.stat && !D.stunned && !D.weakened)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
D.visible_message("<span class='warning'>[A] grabs [D]'s wrist and wrenches it sideways!</span>", \
|
||||
"<span class='userdanger'>[A] grabs your wrist and violently wrenches it to the side!</span>")
|
||||
playsound(get_turf(A), 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
D.emote("scream")
|
||||
D.drop_item()
|
||||
D.apply_damage(5, BRUTE, pick("l_arm", "r_arm"))
|
||||
D.Stun(3)
|
||||
return 1
|
||||
add_logs(A, D, "wrist wrenched (Sleeping Carp)")
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/backKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(A.dir == D.dir && !D.stat && !D.weakened)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
D.visible_message("<span class='warning'>[A] kicks [D] in the back!</span>", \
|
||||
"<span class='userdanger'>[A] kicks you in the back, making you stumble and fall!</span>")
|
||||
step_to(D,get_step(D,D.dir),1)
|
||||
D.Weaken(4)
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
return 1
|
||||
add_logs(A, D, "back-kicked (Sleeping Carp)")
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/kneeStomach(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.stat && !D.weakened)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
|
||||
D.visible_message("<span class='warning'>[A] knees [D] in the stomach!</span>", \
|
||||
"<span class='userdanger'>[A] winds you with a knee in the stomach!</span>")
|
||||
D.audible_message("<b>[D]</b> gags!")
|
||||
D.losebreath += 3
|
||||
D.Stun(2)
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
return 1
|
||||
add_logs(A, D, "stomach kneed (Sleeping Carp)")
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/headKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(!D.stat && !D.weakened)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
|
||||
D.visible_message("<span class='warning'>[A] kicks [D] in the head!</span>", \
|
||||
"<span class='userdanger'>[A] kicks you in the jaw!</span>")
|
||||
D.apply_damage(20, BRUTE, "head")
|
||||
D.drop_item()
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
|
||||
D.Stun(4)
|
||||
return 1
|
||||
add_logs(A, D, "head kicked (Sleeping Carp)")
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/proc/elbowDrop(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
if(D.weakened || D.resting || D.stat)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
D.visible_message("<span class='warning'>[A] elbow drops [D]!</span>", \
|
||||
"<span class='userdanger'>[A] piledrives you with their elbow!</span>")
|
||||
if(D.stat)
|
||||
D.death() //FINISH HIM!
|
||||
D.apply_damage(50, BRUTE, "chest")
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 75, 1, -1)
|
||||
return 1
|
||||
add_logs(A, D, "elbow dropped (Sleeping Carp)")
|
||||
return basic_hit(A,D)
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("G",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
if(A.grab_state >= GRAB_AGGRESSIVE)
|
||||
D.grabbedby(A, 1)
|
||||
else
|
||||
A.start_pulling(D, 1)
|
||||
if(A.pulling)
|
||||
D.drop_all_held_items()
|
||||
D.stop_pulling()
|
||||
if(A.a_intent == INTENT_GRAB)
|
||||
add_logs(A, D, "grabbed", addition="aggressively")
|
||||
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
|
||||
else
|
||||
add_logs(A, D, "grabbed", addition="passively")
|
||||
A.grab_state = GRAB_PASSIVE
|
||||
return 1
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("H",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
var/atk_verb = pick("punches", "kicks", "chops", "hits", "slams")
|
||||
D.visible_message("<span class='danger'>[A] [atk_verb] [D]!</span>", \
|
||||
"<span class='userdanger'>[A] [atk_verb] you!</span>")
|
||||
D.apply_damage(rand(10,15), BRUTE)
|
||||
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 25, 1, -1)
|
||||
if(prob(D.getBruteLoss()) && !D.lying)
|
||||
D.visible_message("<span class='warning'>[D] stumbles and falls!</span>", "<span class='userdanger'>The blow sends you to the ground!</span>")
|
||||
D.Weaken(4)
|
||||
add_logs(A, D, "[atk_verb] (Sleeping Carp)")
|
||||
return 1
|
||||
|
||||
|
||||
/datum/martial_art/the_sleeping_carp/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
||||
add_to_streak("D",D)
|
||||
if(check_streak(A,D))
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/proc/sleeping_carp_help()
|
||||
set name = "Recall Teachings"
|
||||
set desc = "Remember the martial techniques of the Sleeping Carp clan."
|
||||
set category = "Sleeping Carp"
|
||||
|
||||
to_chat(usr, "<b><i>You retreat inward and recall the teachings of the Sleeping Carp...</i></b>")
|
||||
|
||||
to_chat(usr, "<span class='notice'>Wrist Wrench</span>: Disarm Disarm. Forces opponent to drop item in hand.")
|
||||
to_chat(usr, "<span class='notice'>Back Kick</span>: Harm Grab. Opponent must be facing away. Knocks down.")
|
||||
to_chat(usr, "<span class='notice'>Stomach Knee</span>: Grab Harm. Knocks the wind out of opponent and stuns.")
|
||||
to_chat(usr, "<span class='notice'>Head Kick</span>: Disarm Harm Harm. Decent damage, forces opponent to drop item in hand.")
|
||||
to_chat(usr, "<span class='notice'>Elbow Drop</span>: Harm Disarm Harm Disarm Harm. Opponent must be on the ground. Deals huge damage, instantly kills anyone in critical condition.")
|
||||
|
||||
/obj/item/weapon/sleeping_carp_scroll
|
||||
name = "mysterious scroll"
|
||||
desc = "A scroll filled with strange markings. It seems to be drawings of some sort of martial art."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "scroll2"
|
||||
|
||||
/obj/item/weapon/sleeping_carp_scroll/attack_self(mob/living/carbon/human/user)
|
||||
if(!istype(user) || !user)
|
||||
return
|
||||
var/message = "<span class='sciradio'>You have learned the ancient martial art of the Sleeping Carp! Your hand-to-hand combat has become much more effective, and you are now able to deflect any projectiles \
|
||||
directed toward you. However, you are also unable to use any ranged weaponry. You can learn more about your newfound art by using the Recall Teachings verb in the Sleeping Carp tab.</span>"
|
||||
to_chat(user, message)
|
||||
var/datum/martial_art/the_sleeping_carp/theSleepingCarp = new(null)
|
||||
theSleepingCarp.teach(user)
|
||||
user.drop_item()
|
||||
visible_message("<span class='warning'>[src] lights up in fire and quickly burns to ash.</span>")
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/twohanded/bostaff
|
||||
name = "bo staff"
|
||||
desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts. Can be wielded to both kill and incapacitate."
|
||||
force = 10
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
slot_flags = SLOT_BACK
|
||||
force_unwielded = 10
|
||||
force_wielded = 24
|
||||
throwforce = 20
|
||||
throw_speed = 2
|
||||
attack_verb = list("smashed", "slammed", "whacked", "thwacked")
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "bostaff0"
|
||||
block_chance = 50
|
||||
|
||||
/obj/item/weapon/twohanded/bostaff/update_icon()
|
||||
icon_state = "bostaff[wielded]"
|
||||
return
|
||||
|
||||
/obj/item/weapon/twohanded/bostaff/attack(mob/target, mob/living/user)
|
||||
add_fingerprint(user)
|
||||
if((CLUMSY in user.disabilities) && prob(50))
|
||||
to_chat(user, "<span class ='warning'>You club yourself over the head with [src].</span>")
|
||||
user.Weaken(3)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.apply_damage(2*force, BRUTE, "head")
|
||||
else
|
||||
user.take_bodypart_damage(2*force)
|
||||
return
|
||||
if(iscyborg(target))
|
||||
return ..()
|
||||
if(!isliving(target))
|
||||
return ..()
|
||||
var/mob/living/carbon/C = target
|
||||
if(C.stat)
|
||||
to_chat(user, "<span class='warning'>It would be dishonorable to attack a foe while they cannot retaliate.</span>")
|
||||
return
|
||||
if(user.a_intent == INTENT_DISARM)
|
||||
if(!wielded)
|
||||
return ..()
|
||||
if(!ishuman(target))
|
||||
return ..()
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/list/fluffmessages = list("[user] clubs [H] with [src]!", \
|
||||
"[user] smacks [H] with the butt of [src]!", \
|
||||
"[user] broadsides [H] with [src]!", \
|
||||
"[user] smashes [H]'s head with [src]!", \
|
||||
"[user] beats [H] with front of [src]!", \
|
||||
"[user] twirls and slams [H] with [src]!")
|
||||
H.visible_message("<span class='warning'>[pick(fluffmessages)]</span>", \
|
||||
"<span class='userdanger'>[pick(fluffmessages)]</span>")
|
||||
playsound(get_turf(user), 'sound/effects/woodhit.ogg', 75, 1, -1)
|
||||
H.adjustStaminaLoss(rand(13,20))
|
||||
if(prob(10))
|
||||
H.visible_message("<span class='warning'>[H] collapses!</span>", \
|
||||
"<span class='userdanger'>Your legs give out!</span>")
|
||||
H.Weaken(4)
|
||||
if(H.staminaloss && !H.sleeping)
|
||||
var/total_health = (H.health - H.staminaloss)
|
||||
if(total_health <= HEALTH_THRESHOLD_CRIT && !H.stat)
|
||||
H.visible_message("<span class='warning'>[user] delivers a heavy hit to [H]'s head, knocking them out cold!</span>", \
|
||||
"<span class='userdanger'>[user] knocks you unconscious!</span>")
|
||||
H.SetSleeping(30)
|
||||
H.adjustBrainLoss(25)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/twohanded/bostaff/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
|
||||
if(wielded)
|
||||
return ..()
|
||||
return 0
|
||||
@@ -1,3 +1,13 @@
|
||||
/mob/living/carbon/human/proc/wrestling_help()
|
||||
set name = "Recall Teachings"
|
||||
set desc = "Remember how to wrestle."
|
||||
set category = "Wrestling"
|
||||
|
||||
to_chat(usr, "<b><i>You flex your muscles and have a revelation...</i></b>")
|
||||
to_chat(usr, "<span class='notice'>Clinch</span>: Grab. Passively gives you a chance to immediately aggressively grab someone. Not always successful.")
|
||||
to_chat(usr, "<span class='notice'>Suplex</span>: Disarm someone you are grabbing. Suplexes your target to the floor. Greatly injures them and leaves both you and your target on the floor.")
|
||||
to_chat(usr, "<span class='notice'>Advanced grab</span>: Grab. Passively causes stamina damage when grabbing someone.")
|
||||
|
||||
/datum/martial_art/wrestling
|
||||
name = "Wrestling"
|
||||
var/datum/action/slam/slam = new/datum/action/slam()
|
||||
@@ -40,7 +50,7 @@
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[owner] prepares to BODY SLAM!</span>", "<b><i>Your next attack will be a BODY SLAM.</i></b>")
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.martial_art.streak = "slam"
|
||||
H.mind.martial_art.streak = "slam"
|
||||
|
||||
/datum/action/throw_wrassle
|
||||
name = "Throw (Cinch) - Spin a cinched opponent around and throw them."
|
||||
@@ -52,7 +62,7 @@
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[owner] prepares to THROW!</span>", "<b><i>Your next attack will be a THROW.</i></b>")
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.martial_art.streak = "throw"
|
||||
H.mind.martial_art.streak = "throw"
|
||||
|
||||
/datum/action/kick
|
||||
name = "Kick - A powerful kick, sends people flying away from you. Also useful for escaping from bad situations."
|
||||
@@ -64,7 +74,7 @@
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[owner] prepares to KICK!</span>", "<b><i>Your next attack will be a KICK.</i></b>")
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.martial_art.streak = "kick"
|
||||
H.mind.martial_art.streak = "kick"
|
||||
|
||||
/datum/action/strike
|
||||
name = "Strike - Hit a neaby opponent with a quick attack."
|
||||
@@ -76,7 +86,7 @@
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[owner] prepares to STRIKE!</span>", "<b><i>Your next attack will be a STRIKE.</i></b>")
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.martial_art.streak = "strike"
|
||||
H.mind.martial_art.streak = "strike"
|
||||
|
||||
/datum/action/drop
|
||||
name = "Drop - Smash down onto an opponent."
|
||||
@@ -88,7 +98,7 @@
|
||||
return
|
||||
owner.visible_message("<span class='danger'>[owner] prepares to LEG DROP!</span>", "<b><i>Your next attack will be a LEG DROP.</i></b>")
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.martial_art.streak = "drop"
|
||||
H.mind.martial_art.streak = "drop"
|
||||
|
||||
/datum/martial_art/wrestling/teach(var/mob/living/carbon/human/H,var/make_temporary=0)
|
||||
..()
|
||||
@@ -430,3 +440,23 @@
|
||||
D.Stun(rand(3,5))
|
||||
add_logs(A, D, "cinched")
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/storage/belt/champion/wrestling
|
||||
name = "Wrestling Belt"
|
||||
var/datum/martial_art/wrestling/style = new
|
||||
|
||||
/obj/item/weapon/storage/belt/champion/wrestling/equipped(mob/user, slot)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(slot == slot_belt)
|
||||
var/mob/living/carbon/human/H = user
|
||||
style.teach(H,1)
|
||||
return
|
||||
|
||||
/obj/item/weapon/storage/belt/champion/wrestling/dropped(mob/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.get_item_by_slot(slot_belt) == src)
|
||||
style.remove(H)
|
||||
return
|
||||
|
||||
+2
-1
@@ -50,7 +50,8 @@
|
||||
var/datum/faction/faction //associated faction
|
||||
var/datum/changeling/changeling //changeling holder
|
||||
var/linglink
|
||||
|
||||
var/datum/martial_art/martial_art = null
|
||||
var/static/default_martial_art = new/datum/martial_art
|
||||
var/miming = 0 // Mime's vow of silence
|
||||
var/list/antag_datums
|
||||
var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state
|
||||
|
||||
@@ -166,4 +166,30 @@
|
||||
/datum/status_effect/cultghost //is a cult ghost and can't use manifest runes
|
||||
id = "cult_ghost"
|
||||
duration = -1
|
||||
alert_type = null
|
||||
alert_type = null
|
||||
/datum/status_effect/crusher_mark
|
||||
id = "crusher_mark"
|
||||
duration = 30 //if you leave for 30 seconds you lose the mark, deal with it
|
||||
status_type = STATUS_EFFECT_REPLACE
|
||||
alert_type = null
|
||||
var/mutable_appearance/marked_underlay
|
||||
var/obj/item/weapon/twohanded/required/mining_hammer/hammer_synced
|
||||
|
||||
/datum/status_effect/crusher_mark/on_apply()
|
||||
if(owner.mob_size >= MOB_SIZE_LARGE)
|
||||
marked_underlay = mutable_appearance('icons/effects/effects.dmi', "shield2")
|
||||
marked_underlay.pixel_x = -owner.pixel_x
|
||||
marked_underlay.pixel_y = -owner.pixel_y
|
||||
owner.underlays += marked_underlay
|
||||
return FALSE
|
||||
|
||||
/datum/status_effect/crusher_mark/Destroy()
|
||||
hammer_synced = null
|
||||
if(owner)
|
||||
owner.underlays -= marked_underlay
|
||||
QDEL_NULL(marked_underlay)
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/crusher_mark/be_replaced()
|
||||
owner.underlays -= marked_underlay //if this is being called, we should have an owner at this point.
|
||||
..()
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
/mob/living/simple_animal/hostile/blob/blob_act(obj/structure/blob/B)
|
||||
if(stat != DEAD && health < maxHealth)
|
||||
for(var/i in 1 to 2)
|
||||
var/obj/effect/overlay/temp/heal/H = new /obj/effect/overlay/temp/heal(get_turf(src)) //hello yes you are being healed
|
||||
var/obj/effect/temp_visual/heal/H = new /obj/effect/temp_visual/heal(get_turf(src)) //hello yes you are being healed
|
||||
if(overmind)
|
||||
H.color = overmind.blob_reagent_datum.complementary_color
|
||||
else
|
||||
@@ -91,7 +91,7 @@
|
||||
melee_damage_lower = 2
|
||||
melee_damage_upper = 4
|
||||
obj_damage = 20
|
||||
environment_smash = 1
|
||||
environment_smash = ENVIRONMENT_SMASH_STRUCTURES
|
||||
attacktext = "hits"
|
||||
attack_sound = 'sound/weapons/genhit1.ogg'
|
||||
movement_type = FLYING
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
loc.blob_act(src) //don't ask how a wall got on top of the core, just eat it
|
||||
|
||||
/obj/structure/blob/proc/blob_attack_animation(atom/A = null, controller) //visually attacks an atom
|
||||
var/obj/effect/overlay/temp/blob/O = new /obj/effect/overlay/temp/blob(src.loc)
|
||||
var/obj/effect/temp_visual/blob/O = new /obj/effect/temp_visual/blob(src.loc)
|
||||
O.setDir(dir)
|
||||
if(controller)
|
||||
var/mob/camera/blob/BO = controller
|
||||
@@ -208,7 +208,7 @@
|
||||
if(overmind)
|
||||
overmind.blob_reagent_datum.emp_reaction(src, severity)
|
||||
if(prob(100 - severity * 30))
|
||||
new /obj/effect/overlay/temp/emp(get_turf(src))
|
||||
new /obj/effect/temp_visual/emp(get_turf(src))
|
||||
|
||||
/obj/structure/blob/tesla_act(power)
|
||||
..()
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
L.visible_message("<span class='warning'>[src] appears around [L] in a burst of light!</span>", \
|
||||
"<span class='userdanger'>[target_flashed ? "An unseen force":"The glowing sigil around you"] holds you in place!</span>")
|
||||
L.Stun(5)
|
||||
new /obj/effect/overlay/temp/ratvar/sigil/transgression(get_turf(src))
|
||||
new /obj/effect/temp_visual/ratvar/sigil/transgression(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
L.visible_message("<span class='warning'>[src] begins to glow a piercing magenta!</span>", "<span class='sevtug'>You feel something start to invade your mind...</span>")
|
||||
var/oldcolor = color
|
||||
animate(src, color = "#AF0AAF", time = convert_time)
|
||||
var/obj/effect/overlay/temp/ratvar/sigil/glow
|
||||
var/obj/effect/temp_visual/ratvar/sigil/glow
|
||||
if(glow_type)
|
||||
glow = new glow_type(get_turf(src))
|
||||
animate(glow, alpha = 255, time = convert_time)
|
||||
@@ -158,7 +158,7 @@
|
||||
light_color = "#A97F1B"
|
||||
delete_on_finish = FALSE
|
||||
sigil_name = "Sigil of Accession"
|
||||
glow_type = /obj/effect/overlay/temp/ratvar/sigil/accession
|
||||
glow_type = /obj/effect/temp_visual/ratvar/sigil/accession
|
||||
resist_string = "glows bright orange"
|
||||
|
||||
/obj/effect/clockwork/sigil/submission/accession/post_channel(mob/living/L)
|
||||
@@ -321,14 +321,14 @@
|
||||
while(L && (!is_servant_of_ratvar(L) || (is_servant_of_ratvar(L) && (GLOB.ratvar_awakens || vitality))) && get_turf(L) == get_turf(src))
|
||||
sigil_active = TRUE
|
||||
if(animation_number >= 4)
|
||||
new /obj/effect/overlay/temp/ratvar/sigil/vitality(get_turf(src))
|
||||
new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src))
|
||||
animation_number = 0
|
||||
animation_number++
|
||||
if(!is_servant_of_ratvar(L))
|
||||
var/vitality_drained = 0
|
||||
if(L.stat == DEAD)
|
||||
vitality_drained = L.maxHealth
|
||||
var/obj/effect/overlay/temp/ratvar/sigil/vitality/V = new /obj/effect/overlay/temp/ratvar/sigil/vitality(get_turf(src))
|
||||
var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src))
|
||||
animate(V, alpha = 0, transform = matrix()*2, time = 8)
|
||||
playsound(L, 'sound/magic/WandODeath.ogg', 50, 1)
|
||||
L.visible_message("<span class='warning'>[L] collapses in on [L.p_them()]self as [src] flares bright blue!</span>")
|
||||
@@ -356,7 +356,7 @@
|
||||
if(ghost)
|
||||
ghost.reenter_corpse()
|
||||
L.revive(1, 1)
|
||||
var/obj/effect/overlay/temp/ratvar/sigil/vitality/V = new /obj/effect/overlay/temp/ratvar/sigil/vitality(get_turf(src))
|
||||
var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src))
|
||||
animate(V, alpha = 0, transform = matrix()*2, time = 8)
|
||||
playsound(L, 'sound/magic/Staff_Healing.ogg', 50, 1)
|
||||
L.visible_message("<span class='warning'>[L] suddenly gets back up, [GLOB.ratvar_awakens ? "[L.p_their()] body dripping blue ichor":"even as [src] scatters into blue sparks around [L.p_them()]"]!</span>", \
|
||||
|
||||
@@ -124,15 +124,15 @@
|
||||
/proc/get_component_animation_type(id)
|
||||
switch(id)
|
||||
if(BELLIGERENT_EYE)
|
||||
return /obj/effect/overlay/temp/ratvar/component
|
||||
return /obj/effect/temp_visual/ratvar/component
|
||||
if(VANGUARD_COGWHEEL)
|
||||
return /obj/effect/overlay/temp/ratvar/component/cogwheel
|
||||
return /obj/effect/temp_visual/ratvar/component/cogwheel
|
||||
if(GEIS_CAPACITOR)
|
||||
return /obj/effect/overlay/temp/ratvar/component/capacitor
|
||||
return /obj/effect/temp_visual/ratvar/component/capacitor
|
||||
if(REPLICANT_ALLOY)
|
||||
return /obj/effect/overlay/temp/ratvar/component/alloy
|
||||
return /obj/effect/temp_visual/ratvar/component/alloy
|
||||
if(HIEROPHANT_ANSIBLE)
|
||||
return /obj/effect/overlay/temp/ratvar/component/ansible
|
||||
return /obj/effect/temp_visual/ratvar/component/ansible
|
||||
else
|
||||
return null
|
||||
|
||||
|
||||
@@ -5,60 +5,60 @@
|
||||
//otherwise, return literally any non-list thing but preferably FALSE
|
||||
//returning TRUE won't produce the "cannot be proselytized" message and will still prevent proselytizing
|
||||
|
||||
/atom/proc/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/atom/proc/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
//Turf conversion
|
||||
/turf/closed/wall/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent) //four sheets of metal
|
||||
/turf/closed/wall/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer) //four sheets of metal
|
||||
return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 4), "spawn_dir" = SOUTH)
|
||||
|
||||
/turf/closed/wall/mineral/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent) //two sheets of metal
|
||||
/turf/closed/wall/mineral/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer) //two sheets of metal
|
||||
return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 2), "spawn_dir" = SOUTH)
|
||||
|
||||
/turf/closed/wall/mineral/iron/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent) //two sheets of metal, five rods
|
||||
/turf/closed/wall/mineral/iron/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer) //two sheets of metal, five rods
|
||||
return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 2) - (POWER_ROD * 5), "spawn_dir" = SOUTH)
|
||||
|
||||
/turf/closed/wall/mineral/cult/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent) //no metal
|
||||
/turf/closed/wall/mineral/cult/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer) //no metal
|
||||
return list("operation_time" = 80, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL, "spawn_dir" = SOUTH)
|
||||
|
||||
/turf/closed/wall/shuttle/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent) //two sheets of metal
|
||||
/turf/closed/wall/shuttle/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer) //two sheets of metal
|
||||
return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 2), "spawn_dir" = SOUTH)
|
||||
|
||||
/turf/closed/wall/r_wall/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/turf/closed/wall/r_wall/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
/turf/closed/wall/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/turf/closed/wall/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 50, "new_obj_type" = /turf/open/floor/clockwork, "power_cost" = -POWER_WALL_MINUS_FLOOR, "spawn_dir" = SOUTH)
|
||||
|
||||
/turf/open/floor/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/turf/open/floor/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
if(floor_tile == /obj/item/stack/tile/plasteel)
|
||||
new floor_tile(src)
|
||||
make_plating()
|
||||
playsound(src, 'sound/items/Crowbar.ogg', 10, 1) //clink
|
||||
return list("operation_time" = 30, "new_obj_type" = /turf/open/floor/clockwork, "power_cost" = POWER_FLOOR, "spawn_dir" = SOUTH)
|
||||
|
||||
/turf/open/floor/plating/asteroid/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/turf/open/floor/plating/asteroid/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
/turf/open/floor/plating/ashplanet/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/turf/open/floor/plating/ashplanet/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
/turf/open/floor/plating/lava/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/turf/open/floor/plating/lava/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
/turf/open/floor/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/turf/open/floor/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
if(locate(/obj/structure/table) in src)
|
||||
return FALSE
|
||||
if(is_blocked_turf(src, TRUE))
|
||||
to_chat(user, "<span class='warning'>Something is in the way, preventing you from proselytizing [src] into a clockwork wall.</span>")
|
||||
return TRUE
|
||||
var/operation_time = 100
|
||||
if(!GLOB.ratvar_awakens && proselytizer.speed_multiplier > 0) //if ratvar isn't awake, this always takes 10 seconds
|
||||
if(proselytizer.speed_multiplier > 0)
|
||||
operation_time /= proselytizer.speed_multiplier
|
||||
return list("operation_time" = operation_time, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_MINUS_FLOOR, "spawn_dir" = SOUTH)
|
||||
|
||||
//False wall conversion
|
||||
/obj/structure/falsewall/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/falsewall/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
var/cost = POWER_WALL_MINUS_FLOOR
|
||||
if(ispath(mineral, /obj/item/stack/sheet/metal))
|
||||
cost -= (POWER_METAL * (2 + mineral_amount)) //four sheets of metal, plus an assumption that the girder is also two
|
||||
@@ -66,17 +66,17 @@
|
||||
cost -= (POWER_METAL * 2) //anything that doesn't use metal just has the girder
|
||||
return list("operation_time" = 50, "new_obj_type" = /obj/structure/falsewall/brass, "power_cost" = cost, "spawn_dir" = SOUTH)
|
||||
|
||||
/obj/structure/falsewall/iron/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent) //two sheets of metal, two rods; special assumption
|
||||
/obj/structure/falsewall/iron/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer) //two sheets of metal, two rods; special assumption
|
||||
return list("operation_time" = 50, "new_obj_type" = /obj/structure/falsewall/brass, "power_cost" = POWER_WALL_MINUS_FLOOR - (POWER_METAL * 2) - (POWER_ROD * 2), "spawn_dir" = SOUTH)
|
||||
|
||||
/obj/structure/falsewall/reinforced/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/falsewall/reinforced/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
/obj/structure/falsewall/brass/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/falsewall/brass/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
//Metal conversion
|
||||
/obj/item/stack/tile/plasteel/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/item/stack/tile/plasteel/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
if(source)
|
||||
return FALSE
|
||||
var/amount_temp = get_amount()
|
||||
@@ -90,7 +90,7 @@
|
||||
no_delete = TRUE
|
||||
use(amount_temp)
|
||||
amount_temp *= 12.5 //each tile is 12.5 power so this is 2 tiles to 25 power
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "power_cost" = -amount_temp, "spawn_dir" = SOUTH, "no_target_deletion" = no_delete)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -amount_temp, "spawn_dir" = SOUTH, "no_target_deletion" = no_delete)
|
||||
if(amount_temp >= 20)
|
||||
var/sheets_to_make = round(amount_temp * 0.05) //and 20 to 1 brass
|
||||
var/used = sheets_to_make * 20
|
||||
@@ -104,11 +104,11 @@
|
||||
to_chat(user, "<span class='warning'>You need at least <b>20</b> floor tiles to convert into brass.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/stack/rods/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/item/stack/rods/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
if(source)
|
||||
return FALSE
|
||||
if(proselytizer.metal_to_power)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "power_cost" = -(amount*POWER_ROD), "spawn_dir" = SOUTH)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(amount*POWER_ROD), "spawn_dir" = SOUTH)
|
||||
if(get_amount() >= 10)
|
||||
var/sheets_to_make = round(get_amount() * 0.1)
|
||||
var/used = sheets_to_make * 10
|
||||
@@ -122,11 +122,11 @@
|
||||
to_chat(user, "<span class='warning'>You need at least <b>10</b> rods to convert into brass.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/stack/sheet/metal/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/item/stack/sheet/metal/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
if(source)
|
||||
return FALSE
|
||||
if(proselytizer.metal_to_power)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "power_cost" = -(amount*POWER_METAL), "spawn_dir" = SOUTH)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(amount*POWER_METAL), "spawn_dir" = SOUTH)
|
||||
if(get_amount() >= 5)
|
||||
var/sheets_to_make = round(get_amount() * 0.2)
|
||||
var/used = sheets_to_make * 5
|
||||
@@ -140,11 +140,11 @@
|
||||
to_chat(user, "<span class='warning'>You need at least <b>5</b> sheets of metal to convert into brass.</span>")
|
||||
return TRUE
|
||||
|
||||
/obj/item/stack/sheet/plasteel/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/item/stack/sheet/plasteel/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
if(source)
|
||||
return FALSE
|
||||
if(proselytizer.metal_to_power)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "power_cost" = -(amount*POWER_PLASTEEL), "spawn_dir" = SOUTH)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(amount*POWER_PLASTEEL), "spawn_dir" = SOUTH)
|
||||
if(get_amount() >= 2)
|
||||
var/sheets_to_make = round(get_amount() * 0.5)
|
||||
var/used = sheets_to_make * 2
|
||||
@@ -159,23 +159,23 @@
|
||||
return TRUE
|
||||
|
||||
//Brass directly to power
|
||||
/obj/item/stack/tile/brass/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/item/stack/tile/brass/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
if(source)
|
||||
return FALSE
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "power_cost" = -(amount*POWER_FLOOR), "spawn_dir" = SOUTH)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(amount*POWER_FLOOR), "spawn_dir" = SOUTH)
|
||||
|
||||
//Airlock conversion
|
||||
/obj/machinery/door/airlock/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/machinery/door/airlock/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
var/doortype = /obj/machinery/door/airlock/clockwork
|
||||
if(glass)
|
||||
doortype = /obj/machinery/door/airlock/clockwork/brass
|
||||
return list("operation_time" = 60, "new_obj_type" = doortype, "power_cost" = POWER_WALL_TOTAL, "spawn_dir" = dir)
|
||||
|
||||
/obj/machinery/door/airlock/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/machinery/door/airlock/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
//Table conversion
|
||||
/obj/structure/table/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/table/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
var/prosel_cost = POWER_STANDARD
|
||||
if(framestack == /obj/item/stack/rods)
|
||||
prosel_cost -= POWER_ROD*framestackamount
|
||||
@@ -187,10 +187,10 @@
|
||||
prosel_cost -= POWER_PLASTEEL*buildstackamount
|
||||
return list("operation_time" = 20, "new_obj_type" = /obj/structure/table/reinforced/brass, "power_cost" = prosel_cost, "spawn_dir" = SOUTH)
|
||||
|
||||
/obj/structure/table/reinforced/brass/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/table/reinforced/brass/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
/obj/structure/table_frame/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/table_frame/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
var/prosel_cost = POWER_FLOOR
|
||||
if(framestack == /obj/item/stack/rods)
|
||||
prosel_cost -= POWER_ROD*framestackamount
|
||||
@@ -198,11 +198,11 @@
|
||||
prosel_cost -= POWER_FLOOR*framestackamount
|
||||
return list("operation_time" = 10, "new_obj_type" = /obj/structure/table_frame/brass, "power_cost" = prosel_cost, "spawn_dir" = SOUTH)
|
||||
|
||||
/obj/structure/table_frame/brass/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/table_frame/brass/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
//Window conversion
|
||||
/obj/structure/window/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/window/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
var/windowtype = /obj/structure/window/reinforced/clockwork
|
||||
var/new_dir = TRUE
|
||||
var/prosel_time = 15
|
||||
@@ -220,18 +220,18 @@
|
||||
INVOKE_ASYNC(proselytizer, /obj/item/clockwork/clockwork_proselytizer.proc/proselytize, G, user)
|
||||
return list("operation_time" = prosel_time, "new_obj_type" = windowtype, "power_cost" = prosel_cost, "spawn_dir" = dir, "dir_in_new" = new_dir)
|
||||
|
||||
/obj/structure/window/reinforced/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/window/reinforced/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
//Windoor conversion
|
||||
/obj/machinery/door/window/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/machinery/door/window/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 30, "new_obj_type" = /obj/machinery/door/window/clockwork, "power_cost" = POWER_STANDARD, "spawn_dir" = dir, "dir_in_new" = TRUE)
|
||||
|
||||
/obj/machinery/door/window/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/machinery/door/window/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
//Grille conversion
|
||||
/obj/structure/grille/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/grille/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
var/grilletype = /obj/structure/grille/ratvar
|
||||
var/prosel_time = 15
|
||||
if(broken)
|
||||
@@ -239,32 +239,32 @@
|
||||
prosel_time = 5
|
||||
return list("operation_time" = prosel_time, "new_obj_type" = grilletype, "power_cost" = 0, "spawn_dir" = dir)
|
||||
|
||||
/obj/structure/grille/ratvar/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/grille/ratvar/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
//Lattice conversion
|
||||
/obj/structure/lattice/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/lattice/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/structure/lattice/clockwork, "power_cost" = 0, "spawn_dir" = SOUTH, "no_target_deletion" = TRUE)
|
||||
|
||||
/obj/structure/lattice/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/lattice/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
ratvar_act() //just in case we're the wrong type for some reason??
|
||||
return FALSE
|
||||
|
||||
/obj/structure/lattice/catwalk/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/lattice/catwalk/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/structure/lattice/catwalk/clockwork, "power_cost" = 0, "spawn_dir" = SOUTH, "no_target_deletion" = TRUE)
|
||||
|
||||
/obj/structure/lattice/catwalk/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/lattice/catwalk/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return FALSE
|
||||
|
||||
//Girder conversion
|
||||
/obj/structure/girder/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/girder/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
var/prosel_cost = POWER_GEAR - (POWER_METAL * 2)
|
||||
if(state == GIRDER_REINF_STRUTS || state == GIRDER_REINF)
|
||||
prosel_cost -= POWER_PLASTEEL
|
||||
return list("operation_time" = 20, "new_obj_type" = /obj/structure/destructible/clockwork/wall_gear, "power_cost" = prosel_cost, "spawn_dir" = SOUTH)
|
||||
|
||||
//Hitting a clockwork structure will try to repair it.
|
||||
/obj/structure/destructible/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/structure/destructible/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
. = TRUE
|
||||
var/list/repair_values = list()
|
||||
if(!proselytizer.proselytizer_repair_checks(repair_values, src, user))
|
||||
@@ -287,7 +287,7 @@
|
||||
"<span class='alloy'>You finish repairing [src]. It is now at <b>[obj_integrity]/[max_integrity]</b> integrity.</span>")
|
||||
|
||||
//Hitting a sigil of transmission will try to charge from it.
|
||||
/obj/effect/clockwork/sigil/transmission/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/obj/effect/clockwork/sigil/transmission/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
. = TRUE
|
||||
var/list/charge_values = list()
|
||||
if(!proselytizer.sigil_charge_checks(charge_values, src, user))
|
||||
@@ -337,7 +337,7 @@
|
||||
adjustHealth(-amount)
|
||||
|
||||
//Hitting a ratvar'd silicon will also try to repair it.
|
||||
/mob/living/silicon/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/mob/living/silicon/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
. = TRUE
|
||||
if(health == maxHealth) //if we're at maximum health, prosel the turf under us
|
||||
return FALSE
|
||||
@@ -346,7 +346,7 @@
|
||||
"<span class='alloy'>You finish repairin[src == user ? "g yourself. You are":"g [src]. [p_they(TRUE)] [p_are()]"] now at <b>[abs(HEALTH_THRESHOLD_DEAD - health)]/[abs(HEALTH_THRESHOLD_DEAD - maxHealth)]</b> health.</span>")
|
||||
|
||||
//Same with clockwork mobs.
|
||||
/mob/living/simple_animal/hostile/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/mob/living/simple_animal/hostile/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
. = TRUE
|
||||
if(health == maxHealth) //if we're at maximum health, prosel the turf under us
|
||||
return FALSE
|
||||
@@ -355,7 +355,7 @@
|
||||
"<span class='alloy'>You finish repairin[src == user ? "g yourself. You are":"g [src]. [p_they(TRUE)] [p_are()]"] now at <b>[health]/[maxHealth]</b> health.</span>")
|
||||
|
||||
//Cogscarabs get special interaction because they're drones and have innate self-heals/revives.
|
||||
/mob/living/simple_animal/drone/cogscarab/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent)
|
||||
/mob/living/simple_animal/drone/cogscarab/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
. = TRUE
|
||||
if(stat == DEAD)
|
||||
try_reactivate(user) //if we're at maximum health, prosel the turf under us
|
||||
@@ -374,36 +374,17 @@
|
||||
proselytizer.repairing = null
|
||||
|
||||
//Convert shards and gear bits directly to power
|
||||
/obj/item/clockwork/alloy_shards/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent, power_amount)
|
||||
if(!power_amount)
|
||||
power_amount = -POWER_STANDARD
|
||||
if(proselytizer.can_use_power(power_amount))
|
||||
var/obj/effect/overlay/temp/ratvar/beam/itemconsume/B = new /obj/effect/overlay/temp/ratvar/beam/itemconsume(get_turf(src))
|
||||
B.pixel_x = pixel_x
|
||||
B.pixel_y = pixel_y
|
||||
if(!silent) //looper no looping
|
||||
for(var/obj/item/clockwork/alloy_shards/S in get_turf(src)) //convert all other shards in the turf if we can
|
||||
if(S == src)
|
||||
continue //we want the shards to be proselytized after the main shard, thus this delay
|
||||
addtimer(CALLBACK(proselytizer, /obj/item/clockwork/clockwork_proselytizer.proc/proselytize, S, user, TRUE), 0)
|
||||
return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH)
|
||||
/obj/item/clockwork/alloy_shards/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -POWER_STANDARD, "spawn_dir" = SOUTH)
|
||||
|
||||
/obj/item/clockwork/alloy_shards/medium/gear_bit/large/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent, power_amount)
|
||||
if(!power_amount)
|
||||
power_amount = -(CLOCKCULT_POWER_UNIT*0.08)
|
||||
return ..()
|
||||
/obj/item/clockwork/alloy_shards/medium/gear_bit/large/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(CLOCKCULT_POWER_UNIT*0.08), "spawn_dir" = SOUTH)
|
||||
|
||||
/obj/item/clockwork/alloy_shards/large/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent, power_amount)
|
||||
if(!power_amount)
|
||||
power_amount = -(CLOCKCULT_POWER_UNIT*0.06)
|
||||
return ..()
|
||||
/obj/item/clockwork/alloy_shards/large/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(CLOCKCULT_POWER_UNIT*0.06), "spawn_dir" = SOUTH)
|
||||
|
||||
/obj/item/clockwork/alloy_shards/medium/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent, power_amount)
|
||||
if(!power_amount)
|
||||
power_amount = -(CLOCKCULT_POWER_UNIT*0.04)
|
||||
return ..()
|
||||
/obj/item/clockwork/alloy_shards/medium/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(CLOCKCULT_POWER_UNIT*0.04), "spawn_dir" = SOUTH)
|
||||
|
||||
/obj/item/clockwork/alloy_shards/small/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer, silent, power_amount)
|
||||
if(!power_amount)
|
||||
power_amount = -(CLOCKCULT_POWER_UNIT*0.02)
|
||||
return ..()
|
||||
/obj/item/clockwork/alloy_shards/small/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
|
||||
return list("operation_time" = 0, "new_obj_type" = /obj/effect/temp_visual/ratvar/beam/itemconsume, "power_cost" = -(CLOCKCULT_POWER_UNIT*0.02), "spawn_dir" = SOUTH)
|
||||
@@ -124,7 +124,7 @@
|
||||
L.adjustToxLoss(totaldamage * 0.5, TRUE, TRUE)
|
||||
var/healseverity = max(round(totaldamage*0.05, 1), 1) //shows the general severity of the damage you just healed, 1 glow per 20
|
||||
for(var/i in 1 to healseverity)
|
||||
new /obj/effect/overlay/temp/heal(targetturf, "#1E8CE1")
|
||||
new /obj/effect/temp_visual/heal(targetturf, "#1E8CE1")
|
||||
clockwork_say(ranged_ability_user, text2ratvar("Mend wounded flesh!"))
|
||||
add_logs(ranged_ability_user, L, "healed with Sentinel's Compromise")
|
||||
else
|
||||
@@ -173,7 +173,7 @@
|
||||
if(usable_power > 0 && C.cell.use(usable_power))
|
||||
multiplier += (usable_power * 0.001)
|
||||
qdel(VC)
|
||||
new/obj/effect/overlay/temp/ratvar/volt_hit/true(targetturf, ranged_ability_user, multiplier)
|
||||
new/obj/effect/temp_visual/ratvar/volt_hit/true(targetturf, ranged_ability_user, multiplier)
|
||||
add_logs(ranged_ability_user, targetturf, "fired a volt ray")
|
||||
remove_ranged_ability()
|
||||
|
||||
|
||||
@@ -96,13 +96,13 @@
|
||||
impale_cooldown = world.time + initial(impale_cooldown)
|
||||
attack_cooldown = world.time + initial(attack_cooldown) //can't attack until we're done impaling
|
||||
if(target)
|
||||
new /obj/effect/overlay/temp/dir_setting/bloodsplatter(get_turf(target), get_dir(user, target))
|
||||
new /obj/effect/temp_visual/dir_setting/bloodsplatter(get_turf(target), get_dir(user, target))
|
||||
target.Stun(2) //brief stun
|
||||
to_chat(user, "<span class='brass'>You prepare to remove your ratvarian spear from [target]...</span>")
|
||||
var/remove_verb = pick("pull", "yank", "drag")
|
||||
if(do_after(user, 10, 1, target))
|
||||
var/turf/T = get_turf(target)
|
||||
var/obj/effect/overlay/temp/dir_setting/bloodsplatter/B = new /obj/effect/overlay/temp/dir_setting/bloodsplatter(T, get_dir(target, user))
|
||||
var/obj/effect/temp_visual/dir_setting/bloodsplatter/B = new /obj/effect/temp_visual/dir_setting/bloodsplatter(T, get_dir(target, user))
|
||||
playsound(T, 'sound/misc/splort.ogg', 200, 1)
|
||||
playsound(T, 'sound/weapons/pierce.ogg', 200, 1)
|
||||
if(target.stat != CONSCIOUS)
|
||||
@@ -151,5 +151,5 @@
|
||||
T = get_turf(src)
|
||||
if(T) //make sure we're not in null or something
|
||||
T.visible_message("<span class='warning'>[src] [pick("cracks in two and fades away", "snaps in two and dematerializes")]!</span>")
|
||||
new /obj/effect/overlay/temp/ratvar/spearbreak(T)
|
||||
new /obj/effect/temp_visual/ratvar/spearbreak(T)
|
||||
qdel(src)
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
if(iscarbon(host))
|
||||
resulthealth = round((abs(HEALTH_THRESHOLD_DEAD - host.health) / abs(HEALTH_THRESHOLD_DEAD - host.maxHealth)) * 100)
|
||||
if(GLOB.ratvar_awakens || resulthealth <= MARAUDER_EMERGE_THRESHOLD)
|
||||
new /obj/effect/overlay/temp/heal(host.loc, "#AF0AAF")
|
||||
new /obj/effect/temp_visual/heal(host.loc, "#AF0AAF")
|
||||
host.heal_ordered_damage(4, damage_heal_order)
|
||||
|
||||
/mob/living/simple_animal/hostile/clockwork/marauder/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
for(var/i in 1 to heal_attempts)
|
||||
if(S.health < S.maxHealth)
|
||||
S.adjustHealth(-heal_amount)
|
||||
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
|
||||
new /obj/effect/temp_visual/heal(T, "#1E8CE1")
|
||||
if(i == heal_attempts && S.health >= S.maxHealth) //we finished healing on the last tick, give them the message
|
||||
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
|
||||
break
|
||||
@@ -129,7 +129,7 @@
|
||||
for(var/i in 1 to heal_attempts)
|
||||
if(S.health < S.maxHealth)
|
||||
S.heal_ordered_damage(heal_amount, damage_heal_order)
|
||||
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
|
||||
new /obj/effect/temp_visual/heal(T, "#1E8CE1")
|
||||
if(i == heal_attempts && S.health >= S.maxHealth)
|
||||
to_chat(S, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
|
||||
break
|
||||
@@ -158,7 +158,7 @@
|
||||
for(var/i in 1 to heal_ticks)
|
||||
if(H.health < H.maxHealth)
|
||||
H.heal_ordered_damage(heal_amount, damage_heal_order)
|
||||
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
|
||||
new /obj/effect/temp_visual/heal(T, "#1E8CE1")
|
||||
if(i == heal_ticks && H.health >= H.maxHealth)
|
||||
to_chat(H, "<span class='inathneq'>\"[text2ratvar(pick(heal_finish_messages))]\"</span>")
|
||||
break
|
||||
@@ -174,10 +174,10 @@
|
||||
if(C.obj_integrity < C.max_integrity)
|
||||
C.obj_integrity = min(C.obj_integrity + 5, C.max_integrity)
|
||||
C.update_icon()
|
||||
new /obj/effect/overlay/temp/heal(T, "#1E8CE1")
|
||||
new /obj/effect/temp_visual/heal(T, "#1E8CE1")
|
||||
else
|
||||
break
|
||||
new /obj/effect/overlay/temp/ratvar/mending_mantra(get_turf(invoker))
|
||||
new /obj/effect/temp_visual/ratvar/mending_mantra(get_turf(invoker))
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -389,7 +389,7 @@
|
||||
usable_power = min(Floor(C.cell.charge * 0.2, MIN_CLOCKCULT_POWER), 1000) - prev_power
|
||||
if(usable_power > 0 && C.cell.use(usable_power))
|
||||
multiplier += (usable_power * 0.0005)
|
||||
var/obj/effect/overlay/temp/ratvar/volt_hit/VH = new /obj/effect/overlay/temp/ratvar/volt_hit(get_turf(invoker), null, multiplier)
|
||||
var/obj/effect/temp_visual/ratvar/volt_hit/VH = new /obj/effect/temp_visual/ratvar/volt_hit(get_turf(invoker), null, multiplier)
|
||||
invoker.visible_message("<span class='warning'>[invoker] is struck by [invoker.p_their()] own [VH.name]!</span>", "<span class='userdanger'>You're struck by your own [VH.name]!</span>")
|
||||
invoker.adjustFireLoss(VH.damage) //you have to fail all five blasts to die to this
|
||||
playsound(invoker, 'sound/machines/defib_zap.ogg', VH.damage, 1, -1)
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
if(anchored && unanchored_icon)
|
||||
anchored = FALSE
|
||||
update_anchored(null, obj_integrity > max_integrity * 0.25)
|
||||
new /obj/effect/overlay/temp/emp(loc)
|
||||
new /obj/effect/temp_visual/emp(loc)
|
||||
|
||||
|
||||
//for the ark and Ratvar
|
||||
@@ -222,7 +222,7 @@
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/emp_act(severity)
|
||||
if(forced_disable(TRUE))
|
||||
new /obj/effect/overlay/temp/emp(loc)
|
||||
new /obj/effect/temp_visual/emp(loc)
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/proc/total_accessable_power() //how much power we have and can use
|
||||
if(!needs_power || GLOB.ratvar_awakens)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
return
|
||||
|
||||
/obj/structure/destructible/clockwork/geis_binding/emp_act(severity)
|
||||
new /obj/effect/overlay/temp/emp(loc)
|
||||
new /obj/effect/temp_visual/emp(loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/destructible/clockwork/geis_binding/post_buckle_mob(mob/living/M)
|
||||
@@ -54,8 +54,8 @@
|
||||
if(!can_resist)
|
||||
repair_and_interrupt()
|
||||
else
|
||||
var/obj/effect/overlay/temp/ratvar/geis_binding/G = new /obj/effect/overlay/temp/ratvar/geis_binding(M.loc)
|
||||
var/obj/effect/overlay/temp/ratvar/geis_binding/T = new /obj/effect/overlay/temp/ratvar/geis_binding/top(M.loc)
|
||||
var/obj/effect/temp_visual/ratvar/geis_binding/G = new /obj/effect/temp_visual/ratvar/geis_binding(M.loc)
|
||||
var/obj/effect/temp_visual/ratvar/geis_binding/T = new /obj/effect/temp_visual/ratvar/geis_binding/top(M.loc)
|
||||
G.layer = mob_layer - 0.01
|
||||
T.layer = mob_layer + 0.01
|
||||
G.alpha = alpha
|
||||
@@ -93,10 +93,10 @@
|
||||
var/mob/living/carbon/C = L
|
||||
C.silent += 4
|
||||
visible_message("<span class='sevtug'>[src] flares brightly!</span>")
|
||||
var/obj/effect/overlay/temp/ratvar/geis_binding/G1 = new /obj/effect/overlay/temp/ratvar/geis_binding(loc)
|
||||
var/obj/effect/overlay/temp/ratvar/geis_binding/G2 = new /obj/effect/overlay/temp/ratvar/geis_binding(loc)
|
||||
var/obj/effect/overlay/temp/ratvar/geis_binding/T1 = new /obj/effect/overlay/temp/ratvar/geis_binding/top(loc)
|
||||
var/obj/effect/overlay/temp/ratvar/geis_binding/T2 = new /obj/effect/overlay/temp/ratvar/geis_binding/top(loc)
|
||||
var/obj/effect/temp_visual/ratvar/geis_binding/G1 = new /obj/effect/temp_visual/ratvar/geis_binding(loc)
|
||||
var/obj/effect/temp_visual/ratvar/geis_binding/G2 = new /obj/effect/temp_visual/ratvar/geis_binding(loc)
|
||||
var/obj/effect/temp_visual/ratvar/geis_binding/T1 = new /obj/effect/temp_visual/ratvar/geis_binding/top(loc)
|
||||
var/obj/effect/temp_visual/ratvar/geis_binding/T2 = new /obj/effect/temp_visual/ratvar/geis_binding/top(loc)
|
||||
G1.layer = mob_layer - 0.01
|
||||
G2.layer = mob_layer - 0.01
|
||||
T1.layer = mob_layer + 0.01
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
var/obj/mecha/M = target
|
||||
M.take_damage(damage_per_tick * get_efficiency_mod(), BURN, "melee", 1, get_dir(src, M))
|
||||
|
||||
new /obj/effect/overlay/temp/ratvar/ocular_warden(get_turf(target))
|
||||
new /obj/effect/temp_visual/ratvar/ocular_warden(get_turf(target))
|
||||
|
||||
setDir(get_dir(get_turf(src), get_turf(target)))
|
||||
if(!target)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
/obj/structure/destructible/clockwork/wall_gear/Initialize()
|
||||
. = ..()
|
||||
new /obj/effect/overlay/temp/ratvar/gear(get_turf(src))
|
||||
new /obj/effect/temp_visual/ratvar/gear(get_turf(src))
|
||||
|
||||
/obj/structure/destructible/clockwork/wall_gear/emp_act(severity)
|
||||
return
|
||||
|
||||
@@ -177,13 +177,13 @@
|
||||
var/turf/mobloc = get_turf(B.current)
|
||||
switch(i)
|
||||
if(1)
|
||||
new /obj/effect/overlay/temp/cult/sparks(mobloc, B.current.dir)
|
||||
new /obj/effect/temp_visual/cult/sparks(mobloc, B.current.dir)
|
||||
playsound(mobloc, "sparks", 50, 1)
|
||||
if(2)
|
||||
new /obj/effect/overlay/temp/dir_setting/cult/phase/out(mobloc, B.current.dir)
|
||||
new /obj/effect/temp_visual/dir_setting/cult/phase/out(mobloc, B.current.dir)
|
||||
playsound(mobloc, "sparks", 75, 1)
|
||||
if(3)
|
||||
new /obj/effect/overlay/temp/dir_setting/cult/phase(mobloc, B.current.dir)
|
||||
new /obj/effect/temp_visual/dir_setting/cult/phase(mobloc, B.current.dir)
|
||||
playsound(mobloc, "sparks", 100, 1)
|
||||
if(4)
|
||||
playsound(mobloc, 'sound/magic/exit_blood.ogg', 100, 1)
|
||||
@@ -193,7 +193,7 @@
|
||||
var/obj/item/device/soulstone/S = B.current.loc
|
||||
S.release_shades(owner)
|
||||
B.current.setDir(SOUTH)
|
||||
new /obj/effect/overlay/temp/cult/blood(final)
|
||||
new /obj/effect/temp_visual/cult/blood(final)
|
||||
addtimer(CALLBACK(B.current, /mob/.proc/reckon, final), 10)
|
||||
else
|
||||
return
|
||||
@@ -201,7 +201,7 @@
|
||||
Remove(owner)
|
||||
|
||||
/mob/proc/reckon(turf/final)
|
||||
new /obj/effect/overlay/temp/cult/blood/out(get_turf(src))
|
||||
new /obj/effect/temp_visual/cult/blood/out(get_turf(src))
|
||||
forceMove(final)
|
||||
|
||||
/datum/action/innate/cult/master/finalreck/proc/chant(chant_number)
|
||||
|
||||
@@ -204,7 +204,7 @@
|
||||
if(current_charges)
|
||||
owner.visible_message("<span class='danger'>\The [attack_text] is deflected in a burst of blood-red sparks!</span>")
|
||||
current_charges--
|
||||
new /obj/effect/overlay/temp/cult/sparks(get_turf(owner))
|
||||
new /obj/effect/temp_visual/cult/sparks(get_turf(owner))
|
||||
if(!current_charges)
|
||||
owner.visible_message("<span class='danger'>The runed shield around [owner] suddenly disappears!</span>")
|
||||
owner.update_inv_wear_suit()
|
||||
@@ -356,14 +356,14 @@
|
||||
if(uses <= 0)
|
||||
icon_state ="shifter_drained"
|
||||
playsound(mobloc, "sparks", 50, 1)
|
||||
new /obj/effect/overlay/temp/dir_setting/cult/phase/out(mobloc, C.dir)
|
||||
new /obj/effect/temp_visual/dir_setting/cult/phase/out(mobloc, C.dir)
|
||||
|
||||
var/atom/movable/pulled = handle_teleport_grab(destination, C)
|
||||
C.forceMove(destination)
|
||||
if(pulled)
|
||||
C.start_pulling(pulled) //forcemove resets pulls, so we need to re-pull
|
||||
|
||||
new /obj/effect/overlay/temp/dir_setting/cult/phase(destination, C.dir)
|
||||
new /obj/effect/temp_visual/dir_setting/cult/phase(destination, C.dir)
|
||||
playsound(destination, 'sound/effects/phasein.ogg', 25, 1)
|
||||
playsound(destination, "sparks", 50, 1)
|
||||
|
||||
@@ -375,8 +375,8 @@
|
||||
desc = "Used by veteran cultists to instantly transport items to their needful bretheren."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
brightness_on = 1
|
||||
icon_state = "torch-on"
|
||||
item_state = "torch-on"
|
||||
icon_state = "torch"
|
||||
item_state = "torch"
|
||||
color = "#ff0000"
|
||||
on_damage = 15
|
||||
slot_flags = null
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
for(var/mob/living/L in range(5, src))
|
||||
if(iscultist(L) || isshade(L) || isconstruct(L))
|
||||
if(L.health != L.maxHealth)
|
||||
new /obj/effect/overlay/temp/heal(get_turf(src), "#960000")
|
||||
new /obj/effect/temp_visual/heal(get_turf(src), "#960000")
|
||||
if(ishuman(L))
|
||||
L.adjustBruteLoss(-1, 0)
|
||||
L.adjustFireLoss(-1, 0)
|
||||
@@ -190,7 +190,7 @@
|
||||
else
|
||||
var/turf/open/floor/engine/cult/F = safepick(cultturfs)
|
||||
if(F)
|
||||
new /obj/effect/overlay/temp/cult/turf/floor(F)
|
||||
new /obj/effect/temp_visual/cult/turf/floor(F)
|
||||
else
|
||||
// Are we in space or something? No cult turfs or
|
||||
// convertable turfs?
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
var/scribe_time = 100
|
||||
var/damage_interrupt = TRUE
|
||||
var/action_interrupt = TRUE
|
||||
var/obj/effect/overlay/temp/cult/rune_spawn/rune_word_type
|
||||
var/obj/effect/overlay/temp/cult/rune_spawn/rune_innerring_type
|
||||
var/obj/effect/overlay/temp/cult/rune_spawn/rune_center_type
|
||||
var/obj/effect/temp_visual/cult/rune_spawn/rune_word_type
|
||||
var/obj/effect/temp_visual/cult/rune_spawn/rune_innerring_type
|
||||
var/obj/effect/temp_visual/cult/rune_spawn/rune_center_type
|
||||
var/rune_color
|
||||
|
||||
/datum/action/innate/cult/create_rune/IsAvailable()
|
||||
@@ -27,15 +27,15 @@
|
||||
if(!chosen_keyword)
|
||||
return
|
||||
//the outer ring is always the same across all runes
|
||||
var/obj/effect/overlay/temp/cult/rune_spawn/R1 = new(owner.loc, scribe_time, rune_color)
|
||||
var/obj/effect/temp_visual/cult/rune_spawn/R1 = new(owner.loc, scribe_time, rune_color)
|
||||
//the rest are not always the same, so we need types for em
|
||||
var/obj/effect/overlay/temp/cult/rune_spawn/R2
|
||||
var/obj/effect/temp_visual/cult/rune_spawn/R2
|
||||
if(rune_word_type)
|
||||
R2 = new rune_word_type(owner.loc, scribe_time, rune_color)
|
||||
var/obj/effect/overlay/temp/cult/rune_spawn/R3
|
||||
var/obj/effect/temp_visual/cult/rune_spawn/R3
|
||||
if(rune_innerring_type)
|
||||
R3 = new rune_innerring_type(owner.loc, scribe_time, rune_color)
|
||||
var/obj/effect/overlay/temp/cult/rune_spawn/R4
|
||||
var/obj/effect/temp_visual/cult/rune_spawn/R4
|
||||
if(rune_center_type)
|
||||
R4 = new rune_center_type(owner.loc, scribe_time, rune_color)
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
/datum/action/innate/cult/create_rune/tele
|
||||
button_icon_state = "telerune"
|
||||
rune_type = /obj/effect/rune/teleport
|
||||
rune_word_type = /obj/effect/overlay/temp/cult/rune_spawn/rune2
|
||||
rune_innerring_type = /obj/effect/overlay/temp/cult/rune_spawn/rune2/inner
|
||||
rune_center_type = /obj/effect/overlay/temp/cult/rune_spawn/rune2/center
|
||||
rune_word_type = /obj/effect/temp_visual/cult/rune_spawn/rune2
|
||||
rune_innerring_type = /obj/effect/temp_visual/cult/rune_spawn/rune2/inner
|
||||
rune_center_type = /obj/effect/temp_visual/cult/rune_spawn/rune2/center
|
||||
rune_color = RUNE_COLOR_TELEPORT
|
||||
|
||||
@@ -410,7 +410,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
else
|
||||
GLOB.sacrificed += sacrificial
|
||||
|
||||
new /obj/effect/overlay/temp/cult/sac(get_turf(src))
|
||||
new /obj/effect/temp_visual/cult/sac(get_turf(src))
|
||||
for(var/M in invokers)
|
||||
if(big_sac)
|
||||
to_chat(M, "<span class='cultlarge'>\"Yes! This is the one I desire! You have done well.\"</span>")
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
maxHealth = 200
|
||||
health = 200
|
||||
healable = 0
|
||||
environment_smash = 1
|
||||
environment_smash = ENVIRONMENT_SMASH_STRUCTURES
|
||||
obj_damage = 40
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 15
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
//Gang War Game Mode
|
||||
|
||||
GLOBAL_LIST_INIT(gang_name_pool, list("Clandestine", "Prima", "Zero-G", "Max", "Blasto", "Waffle", "North", "Omni", "Newton", "Cyber", "Donk", "Gene", "Gib", "Tunnel", "Diablo", "Psyke", "Osiron", "Sirius", "Sleeping Carp"))
|
||||
GLOBAL_LIST_INIT(gang_colors_pool, list("red","orange","yellow","green","blue","purple"))
|
||||
GLOBAL_LIST_INIT(gang_colors_pool, list("red","orange","yellow","green","blue","purple", "white"))
|
||||
GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/obj/item/clothing/suit/jacket/leather/overcoat,/obj/item/clothing/suit/jacket/puffer,/obj/item/clothing/suit/jacket/miljacket,/obj/item/clothing/suit/jacket/puffer,/obj/item/clothing/suit/pirate,/obj/item/clothing/suit/poncho,/obj/item/clothing/suit/apron/overalls,/obj/item/clothing/suit/jacket/letterman))
|
||||
|
||||
/datum/game_mode
|
||||
var/list/datum/gang/gangs = list()
|
||||
@@ -164,6 +165,8 @@ GLOBAL_LIST_INIT(gang_colors_pool, list("red","orange","yellow","green","blue","
|
||||
///////////////////////////////////////////
|
||||
/datum/game_mode/proc/add_gangster(datum/mind/gangster_mind, datum/gang/G, check = 1)
|
||||
if(!G || (gangster_mind in get_all_gangsters()) || (gangster_mind.enslaved_to && !is_gangster(gangster_mind.enslaved_to)))
|
||||
if(is_in_gang(gangster_mind.current, G.name) && !(gangster_mind in get_gang_bosses()))
|
||||
return 3
|
||||
return 0
|
||||
if(check && gangster_mind.current.isloyal()) //Check to see if the potential gangster is implanted
|
||||
return 1
|
||||
@@ -193,6 +196,10 @@ GLOBAL_LIST_INIT(gang_colors_pool, list("red","orange","yellow","green","blue","
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/datum/game_mode/proc/remove_gangster(datum/mind/gangster_mind, beingborged, silent, remove_bosses=0)
|
||||
var/datum/gang/gang = gangster_mind.gang_datum
|
||||
for(var/obj/O in gangster_mind.current.contents)
|
||||
if(istype(O, /obj/item/device/gangtool/soldier))
|
||||
qdel(O)
|
||||
|
||||
if(!gang)
|
||||
return 0
|
||||
|
||||
@@ -325,3 +332,4 @@ GLOBAL_LIST_INIT(gang_colors_pool, list("red","orange","yellow","green","blue","
|
||||
SSticker.station_explosion_cinematic(1,"gang war", null)
|
||||
SSticker.mode.explosion_in_progress = 0
|
||||
SSticker.force_ending = TRUE
|
||||
|
||||
|
||||
@@ -15,33 +15,91 @@
|
||||
var/list/territory_lost = list()
|
||||
var/recalls = 1
|
||||
var/dom_attempts = 2
|
||||
var/points = 15
|
||||
var/inner_outfit
|
||||
var/outer_outfit
|
||||
var/datum/atom_hud/antag/gang/ganghud
|
||||
var/is_deconvertible = TRUE //Can you deconvert normal gangsters from the gang
|
||||
|
||||
var/domination_timer
|
||||
var/is_dominating
|
||||
|
||||
var/item_list
|
||||
var/item_category_list
|
||||
var/buyable_items = list(
|
||||
var/boss_item_list
|
||||
var/boss_category_list
|
||||
var/static/list/boss_items = list(
|
||||
/datum/gang_item/function/gang_ping,
|
||||
/datum/gang_item/function/recall,
|
||||
/datum/gang_item/function/outfit,
|
||||
|
||||
/datum/gang_item/clothing/under,
|
||||
/datum/gang_item/clothing/suit,
|
||||
/datum/gang_item/clothing/hat,
|
||||
/datum/gang_item/clothing/neck,
|
||||
/datum/gang_item/clothing/shoes,
|
||||
/datum/gang_item/clothing/mask,
|
||||
/datum/gang_item/clothing/hands,
|
||||
/datum/gang_item/clothing/belt,
|
||||
|
||||
/datum/gang_item/weapon/shuriken,
|
||||
/datum/gang_item/weapon/switchblade,
|
||||
/datum/gang_item/weapon/improvised,
|
||||
/datum/gang_item/weapon/ammo/improvised_ammo,
|
||||
/datum/gang_item/weapon/surplus,
|
||||
/datum/gang_item/weapon/ammo/surplus_ammo,
|
||||
/datum/gang_item/weapon/pistol,
|
||||
/datum/gang_item/weapon/ammo/pistol_ammo,
|
||||
/datum/gang_item/weapon/sniper,
|
||||
/datum/gang_item/weapon/ammo/sniper_ammo,
|
||||
/datum/gang_item/weapon/machinegun,
|
||||
/datum/gang_item/weapon/uzi,
|
||||
/datum/gang_item/weapon/ammo/uzi_ammo,
|
||||
/datum/gang_item/equipment/sharpener,
|
||||
/datum/gang_item/equipment/spraycan,
|
||||
/datum/gang_item/equipment/sharpener,
|
||||
/datum/gang_item/equipment/emp,
|
||||
/datum/gang_item/equipment/c4,
|
||||
/datum/gang_item/equipment/frag,
|
||||
/datum/gang_item/equipment/stimpack,
|
||||
/datum/gang_item/equipment/implant_breaker,
|
||||
/datum/gang_item/equipment/wetwork_boots,
|
||||
/datum/gang_item/equipment/pen,
|
||||
/datum/gang_item/equipment/gangtool,
|
||||
/datum/gang_item/equipment/necklace,
|
||||
/datum/gang_item/equipment/dominator
|
||||
)
|
||||
|
||||
var/reg_item_list
|
||||
var/reg_category_list
|
||||
var/static/list/soldier_items = list(
|
||||
/datum/gang_item/clothing/under,
|
||||
/datum/gang_item/clothing/suit,
|
||||
/datum/gang_item/clothing/hat,
|
||||
/datum/gang_item/clothing/neck,
|
||||
/datum/gang_item/clothing/shoes,
|
||||
/datum/gang_item/clothing/mask,
|
||||
/datum/gang_item/clothing/hands,
|
||||
/datum/gang_item/clothing/belt,
|
||||
|
||||
/datum/gang_item/weapon/shuriken,
|
||||
/datum/gang_item/weapon/switchblade,
|
||||
/datum/gang_item/weapon/improvised,
|
||||
/datum/gang_item/weapon/ammo/improvised_ammo,
|
||||
/datum/gang_item/weapon/surplus,
|
||||
/datum/gang_item/weapon/ammo/surplus_ammo,
|
||||
/datum/gang_item/weapon/pistol,
|
||||
/datum/gang_item/weapon/ammo/pistol_ammo,
|
||||
/datum/gang_item/weapon/sniper,
|
||||
/datum/gang_item/weapon/ammo/sniper_ammo,
|
||||
/datum/gang_item/weapon/machinegun,
|
||||
/datum/gang_item/weapon/uzi,
|
||||
/datum/gang_item/weapon/ammo/uzi_ammo,
|
||||
/datum/gang_item/equipment/sharpener,
|
||||
/datum/gang_item/equipment/spraycan,
|
||||
/datum/gang_item/equipment/sharpener,
|
||||
/datum/gang_item/equipment/emp,
|
||||
/datum/gang_item/equipment/c4,
|
||||
/datum/gang_item/equipment/frag,
|
||||
/datum/gang_item/equipment/stimpack,
|
||||
/datum/gang_item/equipment/implant_breaker,
|
||||
/datum/gang_item/equipment/wetwork_boots,
|
||||
)
|
||||
|
||||
/datum/gang/New(loc,gangname)
|
||||
if(!GLOB.gang_colors_pool.len)
|
||||
message_admins("WARNING: Maximum number of gangs have been exceeded!")
|
||||
@@ -53,36 +111,56 @@
|
||||
switch(color)
|
||||
if("red")
|
||||
color_hex = "#DA0000"
|
||||
inner_outfit = pick(/obj/item/clothing/under/color/red, /obj/item/clothing/under/lawyer/red)
|
||||
if("orange")
|
||||
color_hex = "#FF9300"
|
||||
inner_outfit = pick(/obj/item/clothing/under/color/orange, /obj/item/clothing/under/geisha)
|
||||
if("yellow")
|
||||
color_hex = "#FFF200"
|
||||
inner_outfit = pick(/obj/item/clothing/under/color/yellow, /obj/item/clothing/under/burial, /obj/item/clothing/under/suit_jacket/tan)
|
||||
if("green")
|
||||
color_hex = "#A8E61D"
|
||||
inner_outfit = pick(/obj/item/clothing/under/color/green, /obj/item/clothing/under/syndicate/camo, /obj/item/clothing/under/suit_jacket/green)
|
||||
if("blue")
|
||||
color_hex = "#00B7EF"
|
||||
inner_outfit = pick(/obj/item/clothing/under/color/blue, /obj/item/clothing/under/suit_jacket/navy)
|
||||
if("purple")
|
||||
color_hex = "#DA00FF"
|
||||
inner_outfit = pick(/obj/item/clothing/under/color/lightpurple, /obj/item/clothing/under/lawyer/purpsuit)
|
||||
if("white")
|
||||
color_hex = "#FFFFFF"
|
||||
inner_outfit = pick(/obj/item/clothing/under/color/white, /obj/item/clothing/under/suit_jacket/white)
|
||||
|
||||
name = (gangname ? gangname : pick(GLOB.gang_name_pool))
|
||||
GLOB.gang_name_pool -= name
|
||||
|
||||
outer_outfit = pick(GLOB.gang_outfit_pool)
|
||||
ganghud = new()
|
||||
ganghud.color = color_hex
|
||||
log_game("The [name] Gang has been created. Their gang color is [color].")
|
||||
build_item_list()
|
||||
|
||||
/datum/gang/proc/build_item_list()
|
||||
item_list = list()
|
||||
item_category_list = list()
|
||||
for(var/V in buyable_items)
|
||||
var/datum/gang_item/G = new V()
|
||||
item_list[G.id] = G
|
||||
var/list/Cat = item_category_list[G.category]
|
||||
boss_item_list = list()
|
||||
boss_category_list = list()
|
||||
for(var/B in boss_items)
|
||||
var/datum/gang_item/G = new B()
|
||||
boss_item_list[G.id] = G
|
||||
var/list/Cat = boss_category_list[G.category]
|
||||
if(Cat)
|
||||
Cat += G
|
||||
else
|
||||
item_category_list[G.category] = list(G)
|
||||
boss_category_list[G.category] = list(G)
|
||||
|
||||
reg_item_list = list()
|
||||
reg_category_list = list()
|
||||
for(var/S in soldier_items)
|
||||
var/datum/gang_item/G = new S()
|
||||
reg_item_list[G.id] = G
|
||||
var/list/Cat = reg_category_list[G.category]
|
||||
if(Cat)
|
||||
Cat += G
|
||||
else
|
||||
reg_category_list[G.category] = list(G)
|
||||
|
||||
/datum/gang/proc/add_gang_hud(datum/mind/recruit_mind)
|
||||
ganghud.join_hud(recruit_mind.current)
|
||||
@@ -103,52 +181,6 @@
|
||||
/datum/gang/proc/domination_time_remaining()
|
||||
var/diff = domination_timer - world.time
|
||||
return diff / 10
|
||||
//////////////////////////////////////////// OUTFITS
|
||||
|
||||
|
||||
//Used by recallers when purchasing a gang outfit. First time a gang outfit is purchased the buyer decides a gang style which is stored so gang outfits are uniform
|
||||
/datum/gang/proc/gang_outfit(mob/living/carbon/user,obj/item/device/gangtool/gangtool)
|
||||
if(!user || !gangtool)
|
||||
return 0
|
||||
if(!gangtool.can_use(user))
|
||||
return 0
|
||||
|
||||
var/gang_style_list = list("Gang Colors","Black Suits","White Suits","Leather Jackets","Leather Overcoats","Puffer Jackets","Military Jackets","Tactical Turtlenecks","Soviet Uniforms")
|
||||
if(!style && (user.mind in SSticker.mode.get_gang_bosses())) //Only the boss gets to pick a style
|
||||
style = input("Pick an outfit style.", "Pick Style") as null|anything in gang_style_list
|
||||
|
||||
if(gangtool.can_use(user) && (gangtool.outfits >= 1))
|
||||
var/outfit_path
|
||||
switch(style)
|
||||
if(null || "Gang Colors")
|
||||
outfit_path = text2path("/obj/item/clothing/under/color/[color]")
|
||||
if("Black Suits")
|
||||
outfit_path = /obj/item/clothing/under/suit_jacket/charcoal
|
||||
if("White Suits")
|
||||
outfit_path = /obj/item/clothing/under/suit_jacket/white
|
||||
if("Puffer Jackets")
|
||||
outfit_path = /obj/item/clothing/suit/jacket/puffer
|
||||
if("Leather Jackets")
|
||||
outfit_path = /obj/item/clothing/suit/jacket/leather
|
||||
if("Leather Overcoats")
|
||||
outfit_path = /obj/item/clothing/suit/jacket/leather/overcoat
|
||||
if("Military Jackets")
|
||||
outfit_path = /obj/item/clothing/suit/jacket/miljacket
|
||||
if("Soviet Uniforms")
|
||||
outfit_path = /obj/item/clothing/under/soviet
|
||||
if("Tactical Turtlenecks")
|
||||
outfit_path = /obj/item/clothing/under/syndicate
|
||||
|
||||
if(outfit_path)
|
||||
var/obj/item/clothing/outfit = new outfit_path(user.loc)
|
||||
outfit.armor = list(melee = 20, bullet = 30, laser = 10, energy = 10, bomb = 20, bio = 0, rad = 0, fire = 30, acid = 30)
|
||||
outfit.desc += " Tailored for the [name] Gang to offer the wearer moderate protection against ballistics and physical trauma."
|
||||
outfit.gang = src
|
||||
user.put_in_hands(outfit)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
//////////////////////////////////////////// MESSAGING
|
||||
|
||||
@@ -186,45 +218,7 @@
|
||||
lost_names += "[territory_lost[area]]"
|
||||
territory -= area
|
||||
|
||||
//Count uniformed gangsters
|
||||
var/uniformed = 0
|
||||
for(var/datum/mind/gangmind in (gangsters|bosses))
|
||||
if(ishuman(gangmind.current))
|
||||
var/mob/living/carbon/human/gangster = gangmind.current
|
||||
//Gangster must be alive and on station
|
||||
if((gangster.stat == DEAD) || (gangster.z > ZLEVEL_STATION))
|
||||
continue
|
||||
|
||||
var/obj/item/clothing/outfit
|
||||
var/obj/item/clothing/gang_outfit
|
||||
if(gangster.w_uniform)
|
||||
outfit = gangster.w_uniform
|
||||
if(outfit.gang == src)
|
||||
gang_outfit = outfit
|
||||
if(gangster.wear_suit)
|
||||
outfit = gangster.wear_suit
|
||||
if(outfit.gang == src)
|
||||
gang_outfit = outfit
|
||||
|
||||
if(gang_outfit)
|
||||
to_chat(gangster, "<span class='notice'>The [src] Gang's influence grows as you wear [gang_outfit].</span>")
|
||||
uniformed ++
|
||||
|
||||
//Calculate and report influence growth
|
||||
var/message = "<b>[src] Gang Status Report:</b><BR>*---------*<br>"
|
||||
if(is_dominating)
|
||||
var/seconds_remaining = domination_time_remaining()
|
||||
var/new_time = max(180, seconds_remaining - (uniformed * 4) - (territory.len * 2))
|
||||
if(new_time < seconds_remaining)
|
||||
message += "Takeover shortened by [seconds_remaining - new_time] seconds for defending [territory.len] territories and [uniformed] uniformed gangsters.<BR>"
|
||||
set_domination_time(new_time)
|
||||
message += "<b>[seconds_remaining] seconds remain</b> in hostile takeover.<BR>"
|
||||
else
|
||||
var/points_new = min(999,points + 15 + (uniformed * 2) + territory.len)
|
||||
if(points_new != points)
|
||||
message += "Gang influence has increased by [points_new - points] for defending [territory.len] territories and [uniformed] uniformed gangsters.<BR>"
|
||||
points = points_new
|
||||
message += "Your gang now has <b>[points] influence</b>.<BR>"
|
||||
|
||||
//Process new territories
|
||||
for(var/area in territory_new)
|
||||
@@ -234,27 +228,69 @@
|
||||
territory += area
|
||||
|
||||
//Report territory changes
|
||||
var/message = "<b>[src] Gang Status Report:</b>.<BR>*---------*<BR>"
|
||||
message += "<b>[territory_new.len] new territories:</b><br><i>[added_names]</i><br>"
|
||||
message += "<b>[territory_lost.len] territories lost:</b><br><i>[lost_names]</i><br>"
|
||||
|
||||
//Clear the lists
|
||||
territory_new = list()
|
||||
territory_lost = list()
|
||||
|
||||
var/control = round((territory.len/GLOB.start_state.num_territories)*100, 1)
|
||||
message += "Your gang now has <b>[control]% control</b> of the station.<BR>*---------*"
|
||||
message_gangtools(message)
|
||||
|
||||
//Increase outfit stock
|
||||
for(var/obj/item/device/gangtool/tool in gangtools)
|
||||
tool.outfits = min(tool.outfits+1,5)
|
||||
var/sbonus = sqrt(LAZYLEN(territory)) // Bonus given to soldier's for the gang's total territory
|
||||
message += "Your gang now has <b>[control]% control</b> of the station.<BR>*---------*<BR>"
|
||||
if(is_dominating)
|
||||
var/seconds_remaining = domination_time_remaining()
|
||||
var/new_time = max(180, seconds_remaining - (territory.len * 2))
|
||||
if(new_time < seconds_remaining)
|
||||
message += "Takeover shortened by [seconds_remaining - new_time] seconds for defending [territory.len] territories.<BR>"
|
||||
set_domination_time(new_time)
|
||||
message += "<b>[seconds_remaining] seconds remain</b> in hostile takeover.<BR>"
|
||||
else
|
||||
for(var/obj/item/device/gangtool/G in gangtools)
|
||||
var/pmessage = message
|
||||
var/points_new = 0
|
||||
if(istype(G, /obj/item/device/gangtool/soldier))
|
||||
points_new = max(0,round(3 - G.points/10)) + (sbonus) + (LAZYLEN(G.tags)/2) // Soldier points
|
||||
pmessage += "Your influence has increased by [round(sbonus)] from your gang holding [LAZYLEN(territory)] territories, and a bonus of [round(LAZYLEN(G.tags)/2)] for territories you have personally marked and kept intact.<BR>"
|
||||
else
|
||||
points_new = max(0,round(5 - G.points/10)) + LAZYLEN(territory) // Boss points, more focused on big picture
|
||||
pmessage += "Your influence has increased by [round(points_new)] from your gang holding [territory.len] territories<BR>"
|
||||
G.points += points_new
|
||||
var/mob/living/carbon/human/ganger = get(G.loc, /mob/living)
|
||||
var/points_newer = 0
|
||||
var/static/inner = inner_outfit
|
||||
var/static/outer = outer_outfit
|
||||
if(ishuman(ganger) && ganger.mind in (gangsters|bosses))
|
||||
for(var/obj/C in ganger.contents)
|
||||
if(C.type == inner_outfit)
|
||||
points_newer += 2
|
||||
continue
|
||||
if(C.type == outer_outfit)
|
||||
points_newer += 2
|
||||
continue
|
||||
switch(C.type)
|
||||
if(/obj/item/clothing/neck/necklace/dope)
|
||||
points_newer += 2
|
||||
if(/obj/item/clothing/head/collectable/petehat/gang)
|
||||
points_newer += 4
|
||||
if(/obj/item/clothing/shoes/gang)
|
||||
points_newer += 6
|
||||
if(/obj/item/clothing/mask/gskull)
|
||||
points_newer += 5
|
||||
if(/obj/item/clothing/gloves/gang)
|
||||
points_newer += 3
|
||||
if(/obj/item/weapon/storage/belt/military/gang)
|
||||
points_newer += 4
|
||||
if(points_newer)
|
||||
G.points += points_newer
|
||||
pmessage += "Your influential choice of clothing has further increased your influence by [points_newer] points.<BR>"
|
||||
pmessage += "You now have <b>[G.points] influence</b>.<BR>"
|
||||
to_chat(ganger, "<span class='notice'>\icon[G] [pmessage]</span>")
|
||||
|
||||
|
||||
//Multiverse
|
||||
|
||||
/datum/gang/multiverse
|
||||
dom_attempts = 0
|
||||
points = 0
|
||||
fighting_style = "multiverse"
|
||||
is_deconvertible = FALSE
|
||||
|
||||
@@ -263,4 +299,4 @@
|
||||
ganghud = new()
|
||||
|
||||
/datum/gang/multiverse/income()
|
||||
return
|
||||
return
|
||||
|
||||
@@ -6,14 +6,12 @@
|
||||
var/category
|
||||
var/id
|
||||
|
||||
|
||||
/datum/gang_item/proc/purchase(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool, check_canbuy = TRUE)
|
||||
if(check_canbuy && !can_buy(user, gang, gangtool))
|
||||
return FALSE
|
||||
var/real_cost = get_cost(user, gang, gangtool)
|
||||
if(gang && real_cost)
|
||||
gang.message_gangtools("A [get_name_display(user, gang, gangtool)] was purchased by [user.real_name] for [real_cost] Influence.")
|
||||
log_game("A [id] was purchased by [key_name(user)] ([gang.name] Gang) for [real_cost] Influence.")
|
||||
gang.points -= real_cost
|
||||
gangtool.points -= real_cost
|
||||
spawn_item(user, gang, gangtool)
|
||||
return TRUE
|
||||
|
||||
@@ -25,7 +23,7 @@
|
||||
to_chat(user, spawn_msg)
|
||||
|
||||
/datum/gang_item/proc/can_buy(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
|
||||
return gang && (gang.points >= get_cost(user, gang, gangtool)) && can_see(user, gang, gangtool)
|
||||
return gang && (gangtool.points >= get_cost(user, gang, gangtool)) && can_see(user, gang, gangtool)
|
||||
|
||||
/datum/gang_item/proc/can_see(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
|
||||
return TRUE
|
||||
@@ -78,23 +76,104 @@
|
||||
gangtool.recall(user)
|
||||
|
||||
|
||||
/datum/gang_item/function/outfit
|
||||
name = "Create Armored Gang Outfit"
|
||||
id = "outfit"
|
||||
///////////////////
|
||||
//CLOTHING
|
||||
///////////////////
|
||||
|
||||
/datum/gang_item/function/outfit/can_buy(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
|
||||
return gangtool && (gangtool.outfits > 0) && ..()
|
||||
/datum/gang_item/clothing
|
||||
category = "Purchase Influence-Enhancing Clothes:"
|
||||
|
||||
/datum/gang_item/clothing/under
|
||||
name = "Gang Uniform"
|
||||
id = "under"
|
||||
cost = 1
|
||||
|
||||
/datum/gang_item/clothing/under/spawn_item(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
|
||||
if(gang.inner_outfit)
|
||||
var/obj/item/O = new gang.inner_outfit(user.loc)
|
||||
user.put_in_hands(O)
|
||||
to_chat(user, "<span class='notice'> This is your gang's official uniform, wearing it will increase your influence")
|
||||
|
||||
/datum/gang_item/clothing/suit
|
||||
name = "Gang Armored Outerwear"
|
||||
id = "suit"
|
||||
cost = 1
|
||||
|
||||
/datum/gang_item/clothing/suit/spawn_item(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
|
||||
if(gang.outer_outfit)
|
||||
var/obj/item/O = new gang.outer_outfit(user.loc)
|
||||
O.armor = list(melee = 20, bullet = 35, laser = 10, energy = 10, bomb = 30, bio = 0, rad = 0, fire = 30, acid = 30)
|
||||
O.desc += " Tailored for the [gang.name] Gang to offer the wearer moderate protection against ballistics and physical trauma."
|
||||
user.put_in_hands(O)
|
||||
to_chat(user, "<span class='notice'> This is your gang's official outerwear, wearing it will increase your influence")
|
||||
|
||||
|
||||
/datum/gang_item/clothing/hat
|
||||
name = "Pimp Hat"
|
||||
id = "hat"
|
||||
cost = 18
|
||||
item_path = /obj/item/clothing/head/collectable/petehat/gang
|
||||
|
||||
/obj/item/clothing/head/collectable/petehat/gang
|
||||
name = "pimpin' hat"
|
||||
desc = "The undisputed king of style."
|
||||
|
||||
/datum/gang_item/clothing/mask
|
||||
name = "Golden Death Mask"
|
||||
id = "mask"
|
||||
cost = 20
|
||||
item_path = /obj/item/clothing/mask/gskull
|
||||
|
||||
/obj/item/clothing/mask/gskull
|
||||
name = "golden death mask"
|
||||
icon_state = "gskull"
|
||||
desc = "Strike terror, and envy, into the hearts of your enemies."
|
||||
|
||||
|
||||
/datum/gang_item/clothing/shoes
|
||||
name = "Bling Boots"
|
||||
id = "boots"
|
||||
cost = 25
|
||||
item_path = /obj/item/clothing/shoes/gang
|
||||
|
||||
/obj/item/clothing/shoes/gang
|
||||
name = "blinged-out boots"
|
||||
desc = "Stand aside peasants."
|
||||
icon_state = "bling"
|
||||
|
||||
/datum/gang_item/clothing/neck
|
||||
name = "Gold Necklace"
|
||||
id = "necklace"
|
||||
cost = 10
|
||||
item_path = /obj/item/clothing/neck/necklace/dope
|
||||
|
||||
|
||||
/datum/gang_item/clothing/hands
|
||||
name = "Decorative Brass Knuckles"
|
||||
id = "hand"
|
||||
cost = 12
|
||||
item_path = /obj/item/clothing/gloves/gang
|
||||
|
||||
/obj/item/clothing/gloves/gang
|
||||
name = "braggadocio's brass knuckles"
|
||||
desc = "Purely decorative, don't find out the hard way."
|
||||
icon_state = "knuckles"
|
||||
w_class = 3
|
||||
|
||||
/datum/gang_item/clothing/belt
|
||||
name = "Badass Belt"
|
||||
id = "belt"
|
||||
cost = 15
|
||||
item_path = /obj/item/weapon/storage/belt/military/gang
|
||||
|
||||
/obj/item/weapon/storage/belt/military/gang
|
||||
name = "badass belt"
|
||||
icon_state = "gangbelt"
|
||||
item_state = "gang"
|
||||
desc = "The belt buckle simply reads 'BAMF'."
|
||||
storage_slots = 1
|
||||
|
||||
/datum/gang_item/function/outfit/get_cost_display(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
|
||||
if(gangtool && !gangtool.outfits)
|
||||
return "(Restocking)"
|
||||
return ..()
|
||||
|
||||
/datum/gang_item/function/outfit/spawn_item(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
|
||||
if(gang && gang.gang_outfit(user, gangtool))
|
||||
to_chat(user, "<span class='notice'><b>Gang Outfits</b> can act as armor with moderate protection against ballistic and melee attacks. Every gangster wearing one will also help grow your gang's influence.</span>")
|
||||
if(gangtool)
|
||||
gangtool.outfits -= 1
|
||||
|
||||
///////////////////
|
||||
//WEAPONS
|
||||
@@ -120,10 +199,34 @@
|
||||
cost = 5
|
||||
item_path = /obj/item/weapon/switchblade
|
||||
|
||||
/datum/gang_item/weapon/surplus
|
||||
name = "Surplus Rifle"
|
||||
id = "surplus"
|
||||
cost = 8
|
||||
item_path = /obj/item/weapon/gun/ballistic/automatic/surplus
|
||||
|
||||
/datum/gang_item/weapon/ammo/surplus_ammo
|
||||
name = "Surplus Rifle Ammo"
|
||||
id = "surplus_ammo"
|
||||
cost = 5
|
||||
item_path = /obj/item/ammo_box/magazine/m10mm/rifle
|
||||
|
||||
/datum/gang_item/weapon/improvised
|
||||
name = "Sawn-Off Improvised Shotgun"
|
||||
id = "sawn"
|
||||
cost = 6
|
||||
item_path = /obj/item/weapon/gun/ballistic/revolver/doublebarrel/improvised/sawn
|
||||
|
||||
/datum/gang_item/weapon/ammo/improvised_ammo
|
||||
name = "Box of Buckshot"
|
||||
id = "buckshot"
|
||||
cost = 5
|
||||
item_path = /obj/item/weapon/storage/box/lethalshot
|
||||
|
||||
/datum/gang_item/weapon/pistol
|
||||
name = "10mm Pistol"
|
||||
id = "pistol"
|
||||
cost = 25
|
||||
cost = 30
|
||||
item_path = /obj/item/weapon/gun/ballistic/automatic/pistol
|
||||
|
||||
/datum/gang_item/weapon/ammo/pistol_ammo
|
||||
@@ -144,12 +247,19 @@
|
||||
cost = 15
|
||||
item_path = /obj/item/ammo_box/magazine/sniper_rounds
|
||||
|
||||
/datum/gang_item/weapon/machinegun
|
||||
name = "Mounted Machine Gun"
|
||||
id = "MG"
|
||||
cost = 50
|
||||
item_path = /obj/machinery/manned_turret
|
||||
spawn_msg = "<span class='notice'>The mounted machine gun features enhanced responsiveness. Hold down on the trigger while firing to control where you're shooting.</span>"
|
||||
|
||||
/datum/gang_item/weapon/uzi
|
||||
name = "Uzi SMG"
|
||||
id = "uzi"
|
||||
cost = 60
|
||||
item_path = /obj/item/weapon/gun/ballistic/automatic/mini_uzi
|
||||
id = "uzi"
|
||||
|
||||
|
||||
/datum/gang_item/weapon/ammo/uzi_ammo
|
||||
name = "Uzi Ammo"
|
||||
@@ -157,7 +267,6 @@
|
||||
cost = 40
|
||||
item_path = /obj/item/ammo_box/magazine/uzim9mm
|
||||
|
||||
|
||||
///////////////////
|
||||
//EQUIPMENT
|
||||
///////////////////
|
||||
@@ -178,12 +287,6 @@
|
||||
cost = 3
|
||||
item_path = /obj/item/weapon/sharpener
|
||||
|
||||
/datum/gang_item/equipment/necklace
|
||||
name = "Gold Necklace"
|
||||
id = "necklace"
|
||||
cost = 1
|
||||
item_path = /obj/item/clothing/neck/necklace/dope
|
||||
|
||||
|
||||
/datum/gang_item/equipment/emp
|
||||
name = "EMP Grenade"
|
||||
@@ -200,13 +303,13 @@
|
||||
/datum/gang_item/equipment/frag
|
||||
name = "Fragmentation Grenade"
|
||||
id = "frag nade"
|
||||
cost = 10
|
||||
cost = 18
|
||||
item_path = /obj/item/weapon/grenade/syndieminibomb/concussion/frag
|
||||
|
||||
/datum/gang_item/equipment/stimpack
|
||||
name = "Black Market Stimulants"
|
||||
id = "stimpack"
|
||||
cost = 15
|
||||
cost = 12
|
||||
item_path = /obj/item/weapon/reagent_containers/syringe/stimulants
|
||||
|
||||
/datum/gang_item/equipment/implant_breaker
|
||||
@@ -223,6 +326,18 @@
|
||||
if(spawn_msg)
|
||||
to_chat(user, spawn_msg)
|
||||
|
||||
/datum/gang_item/equipment/wetwork_boots
|
||||
name = "Wetwork boots"
|
||||
id = "wetwork"
|
||||
cost = 20
|
||||
item_path = /obj/item/clothing/shoes/combat/gang
|
||||
|
||||
/obj/item/clothing/shoes/combat/gang
|
||||
name = "Wetwork boots"
|
||||
desc = "A gang's best hitmen are prepared for anything."
|
||||
permeability_coefficient = 0.01
|
||||
flags = NOSLIP
|
||||
|
||||
/datum/gang_item/equipment/pen
|
||||
name = "Recruitment Pen"
|
||||
id = "pen"
|
||||
@@ -316,4 +431,4 @@
|
||||
return ..()
|
||||
|
||||
/datum/gang_item/equipment/dominator/spawn_item(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
|
||||
new item_path(user.loc)
|
||||
new item_path(user.loc)
|
||||
|
||||
@@ -25,7 +25,16 @@
|
||||
var/datum/gang/G = user.mind.gang_datum
|
||||
var/recruitable = SSticker.mode.add_gangster(M.mind,G)
|
||||
switch(recruitable)
|
||||
if(3)
|
||||
for(var/obj/O in M.contents)
|
||||
if(istype(O, /obj/item/device/gangtool/soldier))
|
||||
to_chat(user, "<span class='warning'>This gangster already has an uplink!</span>")
|
||||
return
|
||||
new /obj/item/device/gangtool/soldier(M)
|
||||
to_chat(user, "<span class='warning'>You inject [M] with a new gangtool!</span>")
|
||||
cooldown(G)
|
||||
if(2)
|
||||
new /obj/item/device/gangtool/soldier(M)
|
||||
M.Paralyse(5)
|
||||
cooldown(G)
|
||||
if(1)
|
||||
@@ -57,4 +66,4 @@
|
||||
cooldown = 0
|
||||
icon_state = "pen"
|
||||
var/mob/M = get(src, /mob)
|
||||
to_chat(M, "<span class='notice'>\icon[src] [src][(src.loc == M)?(""):(" in your [src.loc]")] vibrates softly. It is ready to be used again.</span>")
|
||||
to_chat(M, "<span class='notice'>\icon[src] [src][(src.loc == M)?(""):(" in your [src.loc]")] vibrates softly. It is ready to be used again.</span>")
|
||||
|
||||
@@ -12,9 +12,11 @@
|
||||
origin_tech = "programming=5;bluespace=2;syndicate=5"
|
||||
var/datum/gang/gang //Which gang uses this?
|
||||
var/recalling = 0
|
||||
var/outfits = 3
|
||||
var/outfits = 2
|
||||
var/free_pen = 0
|
||||
var/promotable = 0
|
||||
var/points = 15
|
||||
var/list/tags = list()
|
||||
|
||||
/obj/item/device/gangtool/Initialize() //Initialize supply point income if it hasn't already been started
|
||||
..()
|
||||
@@ -48,14 +50,14 @@
|
||||
var/isboss = (user.mind == gang.bosses[1])
|
||||
dat += "Registration: <B>[gang.name] Gang [isboss ? "Boss" : "Lieutenant"]</B><br>"
|
||||
dat += "Organization Size: <B>[gang.gangsters.len + gang.bosses.len]</B> | Station Control: <B>[round((gang.territory.len/GLOB.start_state.num_territories)*100, 1)]%</B><br>"
|
||||
dat += "Gang Influence: <B>[gang.points]</B><br>"
|
||||
dat += "Time until Influence grows: <B>[(gang.points >= 999) ? ("--:--") : (time2text(SSticker.mode.gang_points.next_point_time - world.time, "mm:ss"))]</B><br>"
|
||||
dat += "Your Influence: <B>[points]</B><br>"
|
||||
dat += "Time until Influence grows: <B>[time2text(SSticker.mode.gang_points.next_point_time - world.time, "mm:ss")]</B><br>"
|
||||
dat += "<hr>"
|
||||
|
||||
|
||||
for(var/cat in gang.item_category_list)
|
||||
for(var/cat in gang.boss_category_list)
|
||||
dat += "<b>[cat]</b><br>"
|
||||
for(var/V in gang.item_category_list[cat])
|
||||
for(var/V in gang.boss_category_list[cat])
|
||||
var/datum/gang_item/G = V
|
||||
if(!G.can_see(user, gang, src))
|
||||
continue
|
||||
@@ -76,7 +78,7 @@
|
||||
|
||||
dat += "<a href='?src=\ref[src];choice=refresh'>Refresh</a><br>"
|
||||
|
||||
var/datum/browser/popup = new(user, "gangtool", "Welcome to GangTool v3.4", 340, 625)
|
||||
var/datum/browser/popup = new(user, "gangtool", "Welcome to GangTool v3.5", 340, 625)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
@@ -95,7 +97,7 @@
|
||||
return
|
||||
|
||||
if(href_list["purchase"])
|
||||
var/datum/gang_item/G = gang.item_list[href_list["purchase"]]
|
||||
var/datum/gang_item/G = gang.boss_item_list[href_list["purchase"]]
|
||||
if(G && G.can_buy(usr, gang, src))
|
||||
G.purchase(usr, gang, src, FALSE)
|
||||
|
||||
@@ -168,7 +170,7 @@
|
||||
if(recalling)
|
||||
to_chat(usr, "<span class='warning'>Error: Recall already in progress.</span>")
|
||||
return 0
|
||||
|
||||
|
||||
if(!gang.recalls)
|
||||
to_chat(usr, "<span class='warning'>Error: Unable to access communication arrays. Firewall has logged our signature and is blocking all further attempts.</span>")
|
||||
|
||||
@@ -212,7 +214,7 @@
|
||||
userturf = get_turf(user)
|
||||
if(userturf.z == 1) //Check one more time that they are on station.
|
||||
if(SSshuttle.cancelEvac(user))
|
||||
gang.recalls -= 1
|
||||
gang.recalls -= 1
|
||||
return 1
|
||||
|
||||
to_chat(loc, "<span class='info'>\icon[src]No response recieved. Emergency shuttle cannot be recalled at this time.</span>")
|
||||
@@ -227,18 +229,103 @@
|
||||
return 0
|
||||
if(!user.mind)
|
||||
return 0
|
||||
|
||||
if(gang) //If it's already registered, only let the gang's bosses use this
|
||||
if(user.mind in gang.bosses)
|
||||
return 1
|
||||
else //If it's not registered, any gangster can use this to register
|
||||
if(user.mind in SSticker.mode.get_all_gangsters())
|
||||
return 1
|
||||
|
||||
if(gang && (user.mind in gang.bosses)) //If it's already registered, only let the gang's bosses use this
|
||||
return 1
|
||||
else if(user.mind in SSticker.mode.get_all_gangsters()) // For soldiers and potential LT's
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/device/gangtool/spare
|
||||
outfits = 1
|
||||
|
||||
/obj/item/device/gangtool/spare/lt
|
||||
promotable = 1
|
||||
promotable = 1
|
||||
|
||||
///////////// Internal tool used by gang regulars ///////////
|
||||
|
||||
/obj/item/device/gangtool/soldier
|
||||
points = 5
|
||||
|
||||
/obj/item/device/gangtool/soldier/New(mob/user)
|
||||
. = ..()
|
||||
gang = user.mind.gang_datum
|
||||
gang.gangtools += src
|
||||
var/datum/action/innate/gang/tool/GT = new
|
||||
GT.Grant(user, src, gang)
|
||||
|
||||
/obj/item/device/gangtool/soldier/attack_self(mob/user)
|
||||
if (!can_use(user))
|
||||
return
|
||||
var/dat
|
||||
if(gang.is_dominating)
|
||||
dat += "<center><font color='red'>Takeover In Progress:<br><B>[gang.domination_time_remaining()] seconds remain</B></font></center>"
|
||||
dat += "Registration: <B>[gang.name] - Foot Soldier</B><br>"
|
||||
dat += "Organization Size: <B>[gang.gangsters.len + gang.bosses.len]</B> | Station Control: <B>[round((gang.territory.len/GLOB.start_state.num_territories)*100, 1)]%</B><br>"
|
||||
dat += "Your Influence: <B>[points]</B><br>"
|
||||
if(LAZYLEN(tags))
|
||||
dat += "Your tags generate bonus influence for you.<br> You have tagged the following territories:"
|
||||
for(var/obj/effect/decal/cleanable/crayon/gang/T in tags)
|
||||
dat += " [T.territory] -"
|
||||
else
|
||||
dat += "You have not personally tagged any territory for your gang. Use a spray can to mark your territory and receive bonus influence."
|
||||
dat += "<br>Time until Influence grows: <B>[time2text(SSticker.mode.gang_points.next_point_time - world.time, "mm:ss")]</B><br>"
|
||||
dat += "<hr>"
|
||||
for(var/cat in gang.reg_category_list)
|
||||
dat += "<b>[cat]</b><br>"
|
||||
for(var/V in gang.reg_category_list[cat])
|
||||
var/datum/gang_item/G = V
|
||||
if(!G.can_see(user, gang, src))
|
||||
continue
|
||||
|
||||
var/cost = G.get_cost_display(user, gang, src)
|
||||
if(cost)
|
||||
dat += cost + " "
|
||||
|
||||
var/toAdd = G.get_name_display(user, gang, src)
|
||||
if(G.can_buy(user, gang, src))
|
||||
toAdd = "<a href='?src=\ref[src];purchase=[G.id]'>[toAdd]</a>"
|
||||
dat += toAdd
|
||||
var/extra = G.get_extra_info(user, gang, src)
|
||||
if(extra)
|
||||
dat += "<br><i>[extra]</i>"
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
|
||||
dat += "<a href='?src=\ref[src];choice=refresh'>Refresh</a><br>"
|
||||
|
||||
var/datum/browser/popup = new(user, "gangtool", "Welcome to GangTool v3.5", 340, 625)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
|
||||
/obj/item/device/gangtool/soldier/Topic(href, href_list)
|
||||
if(!can_use(usr))
|
||||
return
|
||||
if(href_list["purchase"])
|
||||
var/datum/gang_item/G = gang.reg_item_list[href_list["purchase"]]
|
||||
if(G && G.can_buy(usr, gang, src))
|
||||
G.purchase(usr, gang, src, FALSE)
|
||||
|
||||
attack_self(usr)
|
||||
|
||||
/datum/action/innate/gang
|
||||
background_icon_state = "bg_spell"
|
||||
|
||||
/datum/action/innate/gang/IsAvailable()
|
||||
if(!owner.mind || !owner.mind in SSticker.mode.get_all_gangsters())
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/gang/tool
|
||||
name = "Personal Gang Tool"
|
||||
desc = "An implanted gang tool that lets you purchase gear"
|
||||
background_icon_state = "bg_mime"
|
||||
button_icon_state = "bolt_action"
|
||||
var/obj/item/device/gangtool/soldier/GT
|
||||
|
||||
/datum/action/innate/gang/tool/Grant(mob/user, obj/reg, datum/gang/G)
|
||||
. = ..()
|
||||
GT = reg
|
||||
button.color = G.color
|
||||
|
||||
/datum/action/innate/gang/tool/Activate()
|
||||
GT.attack_self(owner)
|
||||
|
||||
@@ -328,7 +328,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event
|
||||
/obj/effect/meteor/tunguska/Move()
|
||||
. = ..()
|
||||
if(.)
|
||||
new /obj/effect/overlay/temp/revenant(get_turf(src))
|
||||
new /obj/effect/temp_visual/revenant(get_turf(src))
|
||||
|
||||
/obj/effect/meteor/tunguska/meteor_effect()
|
||||
..()
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
stealth_active = 1
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/M = loc
|
||||
new /obj/effect/overlay/temp/dir_setting/ninja/cloak(get_turf(M), M.dir)
|
||||
new /obj/effect/temp_visual/dir_setting/ninja/cloak(get_turf(M), M.dir)
|
||||
M.name_override = disguise.name
|
||||
M.icon = disguise.icon
|
||||
M.icon_state = disguise.icon_state
|
||||
@@ -78,7 +78,7 @@
|
||||
stealth_active = 0
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/M = loc
|
||||
new /obj/effect/overlay/temp/dir_setting/ninja(get_turf(M), M.dir)
|
||||
new /obj/effect/temp_visual/dir_setting/ninja(get_turf(M), M.dir)
|
||||
M.name_override = null
|
||||
M.cut_overlays()
|
||||
M.regenerate_icons()
|
||||
|
||||
@@ -16,38 +16,38 @@
|
||||
flick("alien-pad", src)
|
||||
for(var/mob/living/target in loc)
|
||||
target.forceMove(teleport_target)
|
||||
new /obj/effect/overlay/temp/dir_setting/ninja(get_turf(target), target.dir)
|
||||
new /obj/effect/temp_visual/dir_setting/ninja(get_turf(target), target.dir)
|
||||
to_chat(target, "<span class='warning'>The instability of the warp leaves you disoriented!</span>")
|
||||
target.Stun(3)
|
||||
|
||||
/obj/machinery/abductor/pad/proc/Retrieve(mob/living/target)
|
||||
flick("alien-pad", src)
|
||||
new /obj/effect/overlay/temp/dir_setting/ninja(get_turf(target), target.dir)
|
||||
new /obj/effect/temp_visual/dir_setting/ninja(get_turf(target), target.dir)
|
||||
Warp(target)
|
||||
|
||||
/obj/machinery/abductor/pad/proc/MobToLoc(place,mob/living/target)
|
||||
new /obj/effect/overlay/temp/teleport_abductor(place)
|
||||
new /obj/effect/temp_visual/teleport_abductor(place)
|
||||
sleep(80)
|
||||
flick("alien-pad", src)
|
||||
target.forceMove(place)
|
||||
new /obj/effect/overlay/temp/dir_setting/ninja(get_turf(target), target.dir)
|
||||
new /obj/effect/temp_visual/dir_setting/ninja(get_turf(target), target.dir)
|
||||
|
||||
/obj/machinery/abductor/pad/proc/PadToLoc(place)
|
||||
new /obj/effect/overlay/temp/teleport_abductor(place)
|
||||
new /obj/effect/temp_visual/teleport_abductor(place)
|
||||
sleep(80)
|
||||
flick("alien-pad", src)
|
||||
for(var/mob/living/target in get_turf(src))
|
||||
target.forceMove(place)
|
||||
new /obj/effect/overlay/temp/dir_setting/ninja(get_turf(target), target.dir)
|
||||
new /obj/effect/temp_visual/dir_setting/ninja(get_turf(target), target.dir)
|
||||
|
||||
|
||||
/obj/effect/overlay/temp/teleport_abductor
|
||||
/obj/effect/temp_visual/teleport_abductor
|
||||
name = "Huh"
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "teleport"
|
||||
duration = 80
|
||||
|
||||
/obj/effect/overlay/temp/teleport_abductor/Initialize()
|
||||
/obj/effect/temp_visual/teleport_abductor/Initialize()
|
||||
. = ..()
|
||||
var/datum/effect_system/spark_spread/S = new
|
||||
S.set_up(10,0,loc)
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD)
|
||||
obj_damage = 0
|
||||
environment_smash = 0
|
||||
environment_smash = ENVIRONMENT_SMASH_NONE
|
||||
attacktext = "shocks"
|
||||
attack_sound = 'sound/effects/EMPulse.ogg'
|
||||
friendly = "pinches"
|
||||
@@ -435,7 +435,7 @@
|
||||
resources += resource_gain
|
||||
do_attack_animation(target)
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
var/obj/effect/overlay/temp/swarmer/integrate/I = new /obj/effect/overlay/temp/swarmer/integrate(get_turf(target))
|
||||
var/obj/effect/temp_visual/swarmer/integrate/I = new /obj/effect/temp_visual/swarmer/integrate(get_turf(target))
|
||||
I.pixel_x = target.pixel_x
|
||||
I.pixel_y = target.pixel_y
|
||||
I.pixel_z = target.pixel_z
|
||||
@@ -452,7 +452,7 @@
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/swarmer/proc/DisIntegrate(atom/movable/target)
|
||||
new /obj/effect/overlay/temp/swarmer/disintegration(get_turf(target))
|
||||
new /obj/effect/temp_visual/swarmer/disintegration(get_turf(target))
|
||||
do_attack_animation(target)
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
target.ex_act(3)
|
||||
@@ -497,7 +497,7 @@
|
||||
/mob/living/simple_animal/hostile/swarmer/proc/DismantleMachine(obj/machinery/target)
|
||||
do_attack_animation(target)
|
||||
to_chat(src, "<span class='info'>We begin to dismantle this machine. We will need to be uninterrupted.</span>")
|
||||
var/obj/effect/overlay/temp/swarmer/dismantle/D = new /obj/effect/overlay/temp/swarmer/dismantle(get_turf(target))
|
||||
var/obj/effect/temp_visual/swarmer/dismantle/D = new /obj/effect/temp_visual/swarmer/dismantle(get_turf(target))
|
||||
D.pixel_x = target.pixel_x
|
||||
D.pixel_y = target.pixel_y
|
||||
D.pixel_z = target.pixel_z
|
||||
@@ -507,7 +507,7 @@
|
||||
M.amount = 5
|
||||
for(var/obj/item/I in target.component_parts)
|
||||
I.loc = M.loc
|
||||
var/obj/effect/overlay/temp/swarmer/disintegration/N = new /obj/effect/overlay/temp/swarmer/disintegration(get_turf(target))
|
||||
var/obj/effect/temp_visual/swarmer/disintegration/N = new /obj/effect/temp_visual/swarmer/disintegration(get_turf(target))
|
||||
N.pixel_x = target.pixel_x
|
||||
N.pixel_y = target.pixel_y
|
||||
N.pixel_z = target.pixel_z
|
||||
@@ -519,23 +519,23 @@
|
||||
qdel(target)
|
||||
|
||||
|
||||
/obj/effect/overlay/temp/swarmer //temporary swarmer visual feedback objects
|
||||
/obj/effect/temp_visual/swarmer //temporary swarmer visual feedback objects
|
||||
icon = 'icons/mob/swarmer.dmi'
|
||||
layer = BELOW_MOB_LAYER
|
||||
|
||||
/obj/effect/overlay/temp/swarmer/disintegration
|
||||
/obj/effect/temp_visual/swarmer/disintegration
|
||||
icon_state = "disintegrate"
|
||||
duration = 10
|
||||
|
||||
/obj/effect/overlay/temp/swarmer/disintegration/Initialize()
|
||||
/obj/effect/temp_visual/swarmer/disintegration/Initialize()
|
||||
. = ..()
|
||||
playsound(loc, "sparks", 100, 1)
|
||||
|
||||
/obj/effect/overlay/temp/swarmer/dismantle
|
||||
/obj/effect/temp_visual/swarmer/dismantle
|
||||
icon_state = "dismantle"
|
||||
duration = 25
|
||||
|
||||
/obj/effect/overlay/temp/swarmer/integrate
|
||||
/obj/effect/temp_visual/swarmer/integrate
|
||||
icon_state = "integrate"
|
||||
duration = 5
|
||||
|
||||
|
||||
@@ -35,7 +35,12 @@
|
||||
var/morphed = 0
|
||||
var/atom/movable/form = null
|
||||
var/morph_time = 0
|
||||
|
||||
var/static/list/blacklist_typecache = typecacheof(list(
|
||||
/obj/screen,
|
||||
/obj/singularity,
|
||||
/mob/living/simple_animal/hostile/morph,
|
||||
/obj/effect))
|
||||
|
||||
var/playstyle_string = "<b><font size=3 color='red'>You are a morph,</font> an abomination of science created primarily with changeling cells. \
|
||||
You may take the form of anything nearby by shift-clicking it. This process will alert any nearby \
|
||||
observers, and can only be performed once every five seconds. While morphed, you move faster, but do \
|
||||
@@ -67,13 +72,7 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/morph/proc/allowed(atom/movable/A) // make it into property/proc ? not sure if worth it
|
||||
if(istype(A,/obj/screen))
|
||||
return 0
|
||||
if(istype(A,/obj/singularity))
|
||||
return 0
|
||||
if(istype(A,/mob/living/simple_animal/hostile/morph))
|
||||
return 0
|
||||
return 1
|
||||
return !is_type_in_typecache(A, blacklist_typecache)
|
||||
|
||||
/mob/living/simple_animal/hostile/morph/proc/eat(atom/movable/A)
|
||||
if(A && A.loc != src)
|
||||
@@ -100,6 +99,7 @@
|
||||
visible_message("<span class='warning'>[src] suddenly twists and changes shape, becoming a copy of [target]!</span>", \
|
||||
"<span class='notice'>You twist your body and assume the form of [target].</span>")
|
||||
appearance = target.appearance
|
||||
copy_overlays(target)
|
||||
alpha = max(alpha, 150) //fucking chameleons
|
||||
transform = initial(transform)
|
||||
pixel_y = initial(pixel_y)
|
||||
|
||||
@@ -202,7 +202,7 @@
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(4, 0, L)
|
||||
s.start()
|
||||
new /obj/effect/overlay/temp/revenant(L.loc)
|
||||
new /obj/effect/temp_visual/revenant(L.loc)
|
||||
sleep(20)
|
||||
if(!L.on) //wait, wait, don't shock me
|
||||
return
|
||||
@@ -237,7 +237,7 @@
|
||||
/obj/effect/proc_holder/spell/aoe_turf/revenant/defile/proc/defile(turf/T)
|
||||
if(T.flags & NOJAUNT)
|
||||
T.flags -= NOJAUNT
|
||||
new /obj/effect/overlay/temp/revenant(T)
|
||||
new /obj/effect/temp_visual/revenant(T)
|
||||
if(!istype(T, /turf/open/floor/plating) && !istype(T, /turf/open/floor/engine/cult) && isfloorturf(T) && prob(15))
|
||||
var/turf/open/floor/floor = T
|
||||
if(floor.intact && floor.floor_tile)
|
||||
@@ -246,10 +246,10 @@
|
||||
floor.burnt = 0
|
||||
floor.make_plating(1)
|
||||
if(T.type == /turf/closed/wall && prob(15))
|
||||
new /obj/effect/overlay/temp/revenant(T)
|
||||
new /obj/effect/temp_visual/revenant(T)
|
||||
T.ChangeTurf(/turf/closed/wall/rust)
|
||||
if(T.type == /turf/closed/wall/r_wall && prob(10))
|
||||
new /obj/effect/overlay/temp/revenant(T)
|
||||
new /obj/effect/temp_visual/revenant(T)
|
||||
T.ChangeTurf(/turf/closed/wall/r_wall/rust)
|
||||
for(var/obj/structure/closet/closet in T.contents)
|
||||
closet.open()
|
||||
@@ -261,7 +261,7 @@
|
||||
for(var/obj/structure/window/window in T)
|
||||
window.take_damage(rand(30,80))
|
||||
if(window && window.fulltile)
|
||||
new /obj/effect/overlay/temp/revenant/cracks(window.loc)
|
||||
new /obj/effect/temp_visual/revenant/cracks(window.loc)
|
||||
for(var/obj/machinery/light/light in T)
|
||||
light.flicker(20) //spooky
|
||||
|
||||
@@ -284,7 +284,7 @@
|
||||
/obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction/proc/malfunction(turf/T, mob/user)
|
||||
for(var/mob/living/simple_animal/bot/bot in T)
|
||||
if(!bot.emagged)
|
||||
new /obj/effect/overlay/temp/revenant(bot.loc)
|
||||
new /obj/effect/temp_visual/revenant(bot.loc)
|
||||
bot.locked = 0
|
||||
bot.open = 1
|
||||
bot.emag_act()
|
||||
@@ -292,21 +292,21 @@
|
||||
if(human == user)
|
||||
continue
|
||||
to_chat(human, "<span class='revenwarning'>You feel [pick("your sense of direction flicker out", "a stabbing pain in your head", "your mind fill with static")].</span>")
|
||||
new /obj/effect/overlay/temp/revenant(human.loc)
|
||||
new /obj/effect/temp_visual/revenant(human.loc)
|
||||
human.emp_act(1)
|
||||
for(var/obj/thing in T)
|
||||
if(istype(thing, /obj/machinery/dominator) || istype(thing, /obj/machinery/power/apc) || istype(thing, /obj/machinery/power/smes)) //Doesn't work on dominators, SMES and APCs, to prevent kekkery
|
||||
continue
|
||||
if(prob(20))
|
||||
if(prob(50))
|
||||
new /obj/effect/overlay/temp/revenant(thing.loc)
|
||||
new /obj/effect/temp_visual/revenant(thing.loc)
|
||||
thing.emag_act(null)
|
||||
else
|
||||
if(!istype(thing, /obj/machinery/clonepod)) //I hate everything but mostly the fact there's no better way to do this without just not affecting it at all
|
||||
thing.emp_act(1)
|
||||
for(var/mob/living/silicon/robot/S in T) //Only works on cyborgs, not AI
|
||||
playsound(S, 'sound/machines/warning-buzzer.ogg', 50, 1)
|
||||
new /obj/effect/overlay/temp/revenant(S.loc)
|
||||
new /obj/effect/temp_visual/revenant(S.loc)
|
||||
S.spark_system.start()
|
||||
S.emp_act(1)
|
||||
|
||||
@@ -329,7 +329,7 @@
|
||||
for(var/mob/living/mob in T)
|
||||
if(mob == user)
|
||||
continue
|
||||
new /obj/effect/overlay/temp/revenant(mob.loc)
|
||||
new /obj/effect/temp_visual/revenant(mob.loc)
|
||||
if(iscarbon(mob))
|
||||
if(ishuman(mob))
|
||||
var/mob/living/carbon/human/H = mob
|
||||
@@ -350,14 +350,14 @@
|
||||
mob.adjustToxLoss(5)
|
||||
for(var/obj/structure/spacevine/vine in T) //Fucking with botanists, the ability.
|
||||
vine.add_atom_colour("#823abb", TEMPORARY_COLOUR_PRIORITY)
|
||||
new /obj/effect/overlay/temp/revenant(vine.loc)
|
||||
new /obj/effect/temp_visual/revenant(vine.loc)
|
||||
QDEL_IN(vine, 10)
|
||||
for(var/obj/structure/glowshroom/shroom in T)
|
||||
shroom.add_atom_colour("#823abb", TEMPORARY_COLOUR_PRIORITY)
|
||||
new /obj/effect/overlay/temp/revenant(shroom.loc)
|
||||
new /obj/effect/temp_visual/revenant(shroom.loc)
|
||||
QDEL_IN(shroom, 10)
|
||||
for(var/obj/machinery/hydroponics/tray in T)
|
||||
new /obj/effect/overlay/temp/revenant(tray.loc)
|
||||
new /obj/effect/temp_visual/revenant(tray.loc)
|
||||
tray.pestlevel = rand(8, 10)
|
||||
tray.weedlevel = rand(8, 10)
|
||||
tray.toxic = rand(45, 55)
|
||||
|
||||
@@ -33,11 +33,11 @@
|
||||
to_chat(affected_mob, "<span class='revennotice'>You suddenly feel [pick("sick and tired", "disoriented", "tired and confused", "nauseated", "faint", "dizzy")]...</span>")
|
||||
affected_mob.confused += 8
|
||||
affected_mob.adjustStaminaLoss(8)
|
||||
new /obj/effect/overlay/temp/revenant(affected_mob.loc)
|
||||
new /obj/effect/temp_visual/revenant(affected_mob.loc)
|
||||
if(stagedamage < stage)
|
||||
stagedamage++
|
||||
affected_mob.adjustToxLoss(stage*2) //should, normally, do about 30 toxin damage.
|
||||
new /obj/effect/overlay/temp/revenant(affected_mob.loc)
|
||||
new /obj/effect/temp_visual/revenant(affected_mob.loc)
|
||||
if(prob(45))
|
||||
affected_mob.adjustStaminaLoss(stage)
|
||||
..() //So we don't increase a stage before applying the stage damage.
|
||||
@@ -56,7 +56,7 @@
|
||||
finalstage = TRUE
|
||||
to_chat(affected_mob, "<span class='revenbignotice'>You feel like [pick("nothing's worth it anymore", "nobody ever needed your help", "nothing you did mattered", "everything you tried to do was worthless")].</span>")
|
||||
affected_mob.adjustStaminaLoss(45)
|
||||
new /obj/effect/overlay/temp/revenant(affected_mob.loc)
|
||||
new /obj/effect/temp_visual/revenant(affected_mob.loc)
|
||||
if(affected_mob.dna && affected_mob.dna.species)
|
||||
affected_mob.dna.species.handle_mutant_bodyparts(affected_mob,"#1d2953")
|
||||
affected_mob.dna.species.handle_hair(affected_mob,"#1d2953")
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
maxHealth = 200
|
||||
health = 200
|
||||
healable = 0
|
||||
environment_smash = 1
|
||||
environment_smash = ENVIRONMENT_SMASH_STRUCTURES
|
||||
obj_damage = 50
|
||||
melee_damage_lower = 30
|
||||
melee_damage_upper = 30
|
||||
|
||||
@@ -459,8 +459,7 @@
|
||||
var/datum/game_mode/nuclear/NM = SSticker.mode
|
||||
NM.nukes_left --
|
||||
if(!SSticker.mode.check_finished())//If the mode does not deal with the nuke going off so just reboot because everyone is stuck as is
|
||||
spawn()
|
||||
world.Reboot("Station destroyed by Nuclear Device.", "end_error", "nuke - unhandled ending")
|
||||
SSticker.Reboot("Station destroyed by Nuclear Device.", "end_error", "nuke - unhandled ending")
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -175,6 +175,7 @@
|
||||
continue
|
||||
var/mob/living/carbon/human/H = X
|
||||
if(H.stat == DEAD)
|
||||
H.dust(TRUE)
|
||||
spooky_scaries.Remove(X)
|
||||
continue
|
||||
listclearnulls(spooky_scaries)
|
||||
@@ -584,7 +585,7 @@
|
||||
var/turf/T = get_turf(user)
|
||||
playsound(T,'sound/magic/WarpWhistle.ogg', 200, 1)
|
||||
user.canmove = 0
|
||||
new /obj/effect/overlay/temp/tornado(T)
|
||||
new /obj/effect/temp_visual/tornado(T)
|
||||
sleep(20)
|
||||
if(interrupted(user))
|
||||
return
|
||||
@@ -602,7 +603,7 @@
|
||||
T = potential_T
|
||||
break
|
||||
breakout += 1
|
||||
new /obj/effect/overlay/temp/tornado(T)
|
||||
new /obj/effect/temp_visual/tornado(T)
|
||||
sleep(20)
|
||||
if(interrupted(user))
|
||||
return
|
||||
@@ -620,7 +621,7 @@
|
||||
last_user.canmove = 1
|
||||
return ..()
|
||||
|
||||
/obj/effect/overlay/temp/tornado
|
||||
/obj/effect/temp_visual/tornado
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "tornado"
|
||||
name = "tornado"
|
||||
@@ -630,6 +631,6 @@
|
||||
duration = 40
|
||||
pixel_x = 500
|
||||
|
||||
/obj/effect/overlay/temp/tornado/Initialize()
|
||||
/obj/effect/temp_visual/tornado/Initialize()
|
||||
. = ..()
|
||||
animate(src, pixel_x = -500, time = 40)
|
||||
|
||||
@@ -236,7 +236,7 @@
|
||||
|
||||
/obj/machinery/disco/proc/hierofunk()
|
||||
for(var/i in 1 to 10)
|
||||
spawn_atom_to_turf(/obj/effect/overlay/temp/hierophant/telegraph/edge, src, 1, FALSE)
|
||||
spawn_atom_to_turf(/obj/effect/temp_visual/hierophant/telegraph/edge, src, 1, FALSE)
|
||||
sleep(5)
|
||||
|
||||
/obj/machinery/disco/proc/lights_spin()
|
||||
|
||||
@@ -363,7 +363,7 @@
|
||||
assemblytype = /obj/structure/door_assembly/door_assembly_cult
|
||||
hackProof = 1
|
||||
aiControlDisabled = 1
|
||||
var/openingoverlaytype = /obj/effect/overlay/temp/cult/door
|
||||
var/openingoverlaytype = /obj/effect/temp_visual/cult/door
|
||||
var/friendly = FALSE
|
||||
|
||||
/obj/machinery/door/airlock/cult/New()
|
||||
@@ -380,7 +380,7 @@
|
||||
new openingoverlaytype(loc)
|
||||
return 1
|
||||
else
|
||||
new /obj/effect/overlay/temp/cult/sac(loc)
|
||||
new /obj/effect/temp_visual/cult/sac(loc)
|
||||
var/atom/throwtarget
|
||||
throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(M, src)))
|
||||
M << pick(sound('sound/hallucinations/turn_around1.ogg',0,1,50), sound('sound/hallucinations/turn_around2.ogg',0,1,50))
|
||||
@@ -407,7 +407,7 @@
|
||||
icon = 'icons/obj/doors/airlocks/cult/unruned/cult.dmi'
|
||||
overlays_file = 'icons/obj/doors/airlocks/cult/unruned/overlays.dmi'
|
||||
assemblytype = /obj/structure/door_assembly/door_assembly_cult/unruned
|
||||
openingoverlaytype = /obj/effect/overlay/temp/cult/door/unruned
|
||||
openingoverlaytype = /obj/effect/temp_visual/cult/door/unruned
|
||||
|
||||
/obj/machinery/door/airlock/cult/unruned/friendly
|
||||
friendly = TRUE
|
||||
@@ -438,8 +438,8 @@
|
||||
/obj/machinery/door/airlock/clockwork/New()
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
new /obj/effect/overlay/temp/ratvar/door(T)
|
||||
new /obj/effect/overlay/temp/ratvar/beam/door(T)
|
||||
new /obj/effect/temp_visual/ratvar/door(T)
|
||||
new /obj/effect/temp_visual/ratvar/beam/door(T)
|
||||
change_construction_value(5)
|
||||
|
||||
/obj/machinery/door/airlock/clockwork/Destroy()
|
||||
|
||||
@@ -328,7 +328,7 @@
|
||||
|
||||
/obj/machinery/door/window/clockwork/setDir(direct)
|
||||
if(!made_glow)
|
||||
var/obj/effect/E = new /obj/effect/overlay/temp/ratvar/door/window(get_turf(src))
|
||||
var/obj/effect/E = new /obj/effect/temp_visual/ratvar/door/window(get_turf(src))
|
||||
E.setDir(direct)
|
||||
made_glow = TRUE
|
||||
..()
|
||||
|
||||
@@ -159,7 +159,7 @@ Class Procs:
|
||||
/obj/machinery/emp_act(severity)
|
||||
if(use_power && !stat)
|
||||
use_power(7500/severity)
|
||||
new /obj/effect/overlay/temp/emp(loc)
|
||||
new /obj/effect/temp_visual/emp(loc)
|
||||
..()
|
||||
|
||||
/obj/machinery/proc/open_machine(drop = 1)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#define TURRET_STUN 0
|
||||
#define TURRET_LETHAL 1
|
||||
|
||||
#define POPUP_ANIM_TIME 5
|
||||
#define POPDOWN_ANIM_TIME 5 //Be sure to change the icon animation at the same time or it'll look bad
|
||||
|
||||
#define POPUP_ANIM_TIME 5
|
||||
#define POPDOWN_ANIM_TIME 5 //Be sure to change the icon animation at the same time or it'll look bad
|
||||
|
||||
/obj/machinery/porta_turret
|
||||
name = "turret"
|
||||
icon = 'icons/obj/turrets.dmi'
|
||||
@@ -87,9 +87,9 @@
|
||||
if(has_cover)
|
||||
cover = new /obj/machinery/porta_turret_cover(loc)
|
||||
cover.parent_turret = src
|
||||
underlays += image('icons/obj/turrets.dmi',icon_state = "basedark")
|
||||
underlays += image('icons/obj/turrets.dmi',icon_state = "basedark")
|
||||
if(!has_cover)
|
||||
INVOKE_ASYNC(src, .proc/popUp)
|
||||
INVOKE_ASYNC(src, .proc/popUp)
|
||||
|
||||
/obj/machinery/porta_turret/update_icon()
|
||||
cut_overlays()
|
||||
@@ -368,10 +368,10 @@
|
||||
var/list/targets = list()
|
||||
var/turretview = view(scan_range, base)
|
||||
for(var/A in turretview)
|
||||
var/atom/AA = A
|
||||
if(AA.invisibility>SEE_INVISIBLE_LIVING)
|
||||
continue
|
||||
|
||||
var/atom/AA = A
|
||||
if(AA.invisibility>SEE_INVISIBLE_LIVING)
|
||||
continue
|
||||
|
||||
if(check_anomalies)//if it's set to check for simple animals
|
||||
if(istype(A, /mob/living/simple_animal))
|
||||
var/mob/living/simple_animal/SA = A
|
||||
@@ -426,7 +426,7 @@
|
||||
raising = 1
|
||||
if(cover)
|
||||
flick("popup", cover)
|
||||
sleep(POPUP_ANIM_TIME)
|
||||
sleep(POPUP_ANIM_TIME)
|
||||
raising = 0
|
||||
if(cover)
|
||||
cover.icon_state = "openTurretCover"
|
||||
@@ -442,7 +442,7 @@
|
||||
raising = 1
|
||||
if(cover)
|
||||
flick("popdown", cover)
|
||||
sleep(POPDOWN_ANIM_TIME)
|
||||
sleep(POPDOWN_ANIM_TIME)
|
||||
raising = 0
|
||||
if(cover)
|
||||
cover.icon_state = "turretCover"
|
||||
@@ -553,6 +553,7 @@
|
||||
use_power = 0
|
||||
has_cover = 0
|
||||
scan_range = 9
|
||||
req_access = list(GLOB.access_syndicate)
|
||||
stun_projectile = /obj/item/projectile/bullet
|
||||
lethal_projectile = /obj/item/projectile/bullet
|
||||
lethal_projectile_sound = 'sound/weapons/Gunshot.ogg'
|
||||
@@ -569,6 +570,8 @@
|
||||
return 10 //Syndicate turrets shoot everything not in their faction
|
||||
|
||||
/obj/machinery/porta_turret/syndicate/pod
|
||||
max_integrity = 40
|
||||
integrity_failure = 20
|
||||
obj_integrity = 40
|
||||
stun_projectile = /obj/item/projectile/bullet/weakbullet3
|
||||
lethal_projectile = /obj/item/projectile/bullet/weakbullet3
|
||||
@@ -792,7 +795,7 @@
|
||||
/obj/item/wallframe/turret_control
|
||||
name = "turret control frame"
|
||||
desc = "Used for building turret control panels"
|
||||
icon_state = "apc"
|
||||
icon_state = "apc"
|
||||
result_path = /obj/machinery/turretid
|
||||
materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT)
|
||||
|
||||
@@ -921,3 +924,170 @@
|
||||
on = 0
|
||||
spawn(100)
|
||||
on = 1
|
||||
|
||||
/////// MANNED TURRET ////////
|
||||
|
||||
/obj/machinery/manned_turret
|
||||
name = "machine gun turret"
|
||||
desc = "While the trigger is held down, this gun will redistribute recoil to allow its user to easily shift targets."
|
||||
icon = 'icons/obj/turrets.dmi'
|
||||
icon_state = "machinegun"
|
||||
can_buckle = TRUE
|
||||
density = TRUE
|
||||
max_integrity = 100
|
||||
obj_integrity = 100
|
||||
buckle_lying = 0
|
||||
layer = ABOVE_MOB_LAYER
|
||||
var/view_range = 10
|
||||
var/cooldown = 0
|
||||
var/projectile_type = /obj/item/projectile/bullet/weakbullet3
|
||||
var/rate_of_fire = 1
|
||||
var/number_of_shots = 40
|
||||
var/cooldown_duration = 90
|
||||
var/atom/target
|
||||
var/turf/target_turf
|
||||
var/warned = FALSE
|
||||
|
||||
//BUCKLE HOOKS
|
||||
|
||||
/obj/machinery/manned_turret/unbuckle_mob(mob/living/buckled_mob,force = 0)
|
||||
playsound(src,'sound/mecha/mechmove01.ogg', 50, 1)
|
||||
for(var/obj/item/I in buckled_mob.held_items)
|
||||
if(istype(I, /obj/item/gun_control))
|
||||
qdel(I)
|
||||
if(istype(buckled_mob))
|
||||
buckled_mob.pixel_x = 0
|
||||
buckled_mob.pixel_y = 0
|
||||
if(buckled_mob.client)
|
||||
buckled_mob.client.change_view(world.view)
|
||||
anchored = FALSE
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/manned_turret/user_buckle_mob(mob/living/M, mob/living/carbon/user)
|
||||
if(user.incapacitated() || !istype(user))
|
||||
return
|
||||
M.forceMove(get_turf(src))
|
||||
..()
|
||||
for(var/V in M.held_items)
|
||||
var/obj/item/I = V
|
||||
if(istype(I))
|
||||
if(M.dropItemToGround(I))
|
||||
var/obj/item/gun_control/TC = new /obj/item/gun_control(src)
|
||||
M.put_in_hands(TC)
|
||||
else //Entries in the list should only ever be items or null, so if it's not an item, we can assume it's an empty hand
|
||||
var/obj/item/gun_control/TC = new /obj/item/gun_control(src)
|
||||
M.put_in_hands(TC)
|
||||
M.pixel_y = 14
|
||||
layer = ABOVE_MOB_LAYER
|
||||
setDir(SOUTH)
|
||||
playsound(src,'sound/mecha/mechmove01.ogg', 50, 1)
|
||||
anchored = TRUE
|
||||
if(user.client)
|
||||
user.client.change_view(view_range)
|
||||
|
||||
/obj/item/gun_control
|
||||
name = "turret controls"
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "offhand"
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
flags = ABSTRACT | NODROP
|
||||
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF | NOBLUDGEON
|
||||
var/obj/machinery/manned_turret/turret
|
||||
|
||||
/obj/item/gun_control/New(obj/machinery/manned_turret/MT)
|
||||
if(MT)
|
||||
turret = MT
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/obj/item/gun_control/CanItemAutoclick()
|
||||
return 1
|
||||
|
||||
/obj/item/gun_control/afterattack(atom/targeted_atom, mob/user)
|
||||
..()
|
||||
var/obj/machinery/manned_turret/E = user.buckled
|
||||
E.setDir(get_dir(E,targeted_atom))
|
||||
user.setDir(E.dir)
|
||||
switch(E.dir)
|
||||
if(NORTH)
|
||||
E.layer = BELOW_MOB_LAYER
|
||||
user.pixel_x = 0
|
||||
user.pixel_y = -14
|
||||
if(NORTHEAST)
|
||||
E.layer = BELOW_MOB_LAYER
|
||||
user.pixel_x = -8
|
||||
user.pixel_y = -4
|
||||
if(EAST)
|
||||
E.layer = ABOVE_MOB_LAYER
|
||||
user.pixel_x = -14
|
||||
user.pixel_y = 0
|
||||
if(SOUTHEAST)
|
||||
E.layer = BELOW_MOB_LAYER
|
||||
user.pixel_x = -8
|
||||
user.pixel_y = 4
|
||||
if(SOUTH)
|
||||
E.layer = ABOVE_MOB_LAYER
|
||||
user.pixel_x = 0
|
||||
user.pixel_y = 14
|
||||
if(SOUTHWEST)
|
||||
E.layer = BELOW_MOB_LAYER
|
||||
user.pixel_x = 8
|
||||
user.pixel_y = 4
|
||||
if(WEST)
|
||||
E.layer = ABOVE_MOB_LAYER
|
||||
user.pixel_x = 14
|
||||
user.pixel_y = 0
|
||||
if(NORTHWEST)
|
||||
E.layer = BELOW_MOB_LAYER
|
||||
user.pixel_x = 8
|
||||
user.pixel_y = -4
|
||||
E.checkfire(targeted_atom, user)
|
||||
|
||||
/obj/machinery/manned_turret/proc/checkfire(atom/targeted_atom, mob/user)
|
||||
target = targeted_atom
|
||||
if(target == user || target == get_turf(src))
|
||||
return
|
||||
if(world.time < cooldown)
|
||||
if(!warned && world.time > (cooldown - cooldown_duration + rate_of_fire*number_of_shots)) // To capture the window where one is done firing
|
||||
warned = TRUE
|
||||
playsound(src, 'sound/weapons/sear.ogg', 100, 1)
|
||||
return
|
||||
else
|
||||
cooldown = world.time + cooldown_duration
|
||||
warned = FALSE
|
||||
INVOKE_ASYNC(src, /obj/machinery/manned_turret/.proc/volley)
|
||||
|
||||
/obj/machinery/manned_turret/proc/volley()
|
||||
target_turf = get_turf(target)
|
||||
for(var/i in 1 to number_of_shots)
|
||||
addtimer(CALLBACK(src, /obj/machinery/manned_turret/.proc/fire_helper), i*rate_of_fire)
|
||||
|
||||
|
||||
/obj/machinery/manned_turret/proc/fire_helper()
|
||||
if(!src)
|
||||
return
|
||||
var/turf/targets_from = get_turf(src)
|
||||
if(QDELETED(target))
|
||||
target = target_turf
|
||||
var/obj/item/projectile/P = new projectile_type(targets_from)
|
||||
P.current = targets_from
|
||||
P.starting = targets_from
|
||||
P.firer = src
|
||||
P.original = target
|
||||
playsound(src, 'sound/weapons/Gunshot_smg.ogg', 75, 1)
|
||||
P.yo = target.y - targets_from.y + rand(-1,1)
|
||||
P.xo = target.x - targets_from.x + rand(-1,1)
|
||||
P.fire()
|
||||
|
||||
/obj/machinery/manned_turret/ultimate // Admin-only proof of concept for autoclicker automatics
|
||||
name = "Infinity Gun"
|
||||
view_range = 12
|
||||
projectile_type = /obj/item/projectile/bullet/weakbullet3
|
||||
|
||||
|
||||
/obj/machinery/manned_turret/ultimate/checkfire(atom/targeted_atom, mob/user)
|
||||
target = targeted_atom
|
||||
if(target == user || target == get_turf(src))
|
||||
return
|
||||
target_turf = get_turf(target)
|
||||
fire_helper(target_turf)
|
||||
|
||||
@@ -1152,6 +1152,32 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
|
||||
premium = list(/obj/item/clothing/under/suit_jacket/checkered=1,/obj/item/clothing/head/mailman=1,/obj/item/clothing/under/rank/mailman=1,/obj/item/clothing/suit/jacket/leather=1,/obj/item/clothing/suit/jacket/leather/overcoat=1,/obj/item/clothing/under/pants/mustangjeans=1,/obj/item/clothing/neck/necklace/dope=3,/obj/item/clothing/suit/jacket/letterman_nanotrasen=1)
|
||||
refill_canister = /obj/item/weapon/vending_refill/clothing
|
||||
|
||||
/obj/machinery/vending/toyliberationstation
|
||||
name = "\improper Syndicate Donksoft Toy Vendor"
|
||||
desc = "A ages 8 and up approved vendor that dispenses toys. If you were to find the right wires, you can unlock the adult mode setting!"
|
||||
icon_state = "syndi"
|
||||
req_access_txt = "1"
|
||||
product_slogans = "Get your cool toys today!;Trigger a valid hunter today!;Quality toy weapons for cheap prices!;Give them to HoPs for all access!;Give them to HoS to get perma briged!"
|
||||
product_ads = "Feel robust with your toys!;Express your inner child today!;Toy weapons don't kill people, but valid hunters do!;Who needs responsibilities when you have toy weapons?;Make your next murder FUN!"
|
||||
vend_reply = "Come back for more!"
|
||||
products = list(/obj/item/weapon/gun/ballistic/automatic/toy/unrestricted = 10,
|
||||
/obj/item/weapon/gun/ballistic/automatic/toy/pistol/unrestricted = 10,
|
||||
/obj/item/weapon/gun/ballistic/shotgun/toy/unrestricted = 10,
|
||||
/obj/item/toy/sword = 10, /obj/item/ammo_box/foambox = 20,
|
||||
/obj/item/toy/foamblade = 10,
|
||||
/obj/item/toy/syndicateballoon = 10,
|
||||
/obj/item/clothing/suit/syndicatefake = 5,
|
||||
/obj/item/clothing/head/syndicatefake = 5) //OPS IN DORMS oh wait it's just a assistant
|
||||
contraband = list(/obj/item/weapon/gun/ballistic/shotgun/toy/crossbow = 10, //Congrats, you unlocked the +18 setting!
|
||||
/obj/item/weapon/gun/ballistic/automatic/c20r/toy/unrestricted = 10,
|
||||
/obj/item/weapon/gun/ballistic/automatic/l6_saw/toy/unrestricted = 10,
|
||||
/obj/item/ammo_box/foambox/riot = 20,
|
||||
/obj/item/toy/katana = 10,
|
||||
/obj/item/weapon/twohanded/dualsaber/toy = 5,
|
||||
/obj/item/toy/cards/deck/syndicate = 10) //Gambling and it hurts, making it a +18 item
|
||||
armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50)
|
||||
resistance_flags = FIRE_PROOF
|
||||
|
||||
#undef STANDARD_CHARGE
|
||||
#undef CONTRABAND_CHARGE
|
||||
#undef COIN_CHARGE
|
||||
|
||||
@@ -64,12 +64,9 @@
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/proc/move_ores()
|
||||
if(locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in chassis.equipment)
|
||||
var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo
|
||||
if(ore_box)
|
||||
for(var/obj/item/weapon/ore/ore in range(1, chassis))
|
||||
if(get_dir(chassis,ore)&chassis.dir)
|
||||
ore.Move(ore_box)
|
||||
if(locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in chassis.equipment && istype(chassis, /obj/mecha/working/ripley))
|
||||
var/obj/mecha/working/ripley/R = chassis //we could assume that it's a ripley because it has a clamp, but that's ~unsafe~ and ~bad practice~
|
||||
R.collect_ore()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/can_attach(obj/mecha/M as obj)
|
||||
if(..())
|
||||
@@ -109,36 +106,19 @@
|
||||
icon_state = "mecha_analyzer"
|
||||
selectable = 0
|
||||
equip_cooldown = 30
|
||||
var/scanning = 0
|
||||
var/scanning_time = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/mining_scanner/New()
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/mining_scanner/attach(obj/mecha/M)
|
||||
..()
|
||||
M.occupant_sight_flags |= SEE_TURFS
|
||||
if(M.occupant)
|
||||
M.occupant.update_sight()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/mining_scanner/detach()
|
||||
chassis.occupant_sight_flags &= ~SEE_TURFS
|
||||
if(chassis.occupant)
|
||||
chassis.occupant.update_sight()
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/mining_scanner/process()
|
||||
if(!loc)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
qdel(src)
|
||||
if(scanning)
|
||||
return
|
||||
if(istype(loc,/obj/mecha/working))
|
||||
if(istype(loc,/obj/mecha/working) && scanning_time <= world.time)
|
||||
var/obj/mecha/working/mecha = loc
|
||||
if(!mecha.occupant)
|
||||
return
|
||||
var/list/L = list(mecha.occupant)
|
||||
scanning = 1
|
||||
mineral_scan_pulse(L,get_turf(loc))
|
||||
spawn(equip_cooldown)
|
||||
scanning = 0
|
||||
scanning_time = world.time + equip_cooldown
|
||||
mineral_scan_pulse(get_turf(src))
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
var/variance = 0
|
||||
var/randomspread = 0 //use random spread for machineguns, instead of shotgun scatter
|
||||
var/projectile_delay = 0
|
||||
var/firing_effect_type = /obj/effect/overlay/temp/dir_setting/firing_effect //the visual effect appearing when the weapon is fired.
|
||||
var/firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect //the visual effect appearing when the weapon is fired.
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/can_attach(obj/mecha/combat/M)
|
||||
if(..())
|
||||
@@ -60,7 +60,7 @@
|
||||
//Base energy weapon type
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy
|
||||
name = "general energy weapon"
|
||||
firing_effect_type = /obj/effect/overlay/temp/dir_setting/firing_effect/energy
|
||||
firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/energy
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/get_shot_amount()
|
||||
return min(round(chassis.cell.charge / energy_drain), projectiles_per_shot)
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
var/list/facing_modifiers = list(FRONT_ARMOUR = 1.5, SIDE_ARMOUR = 1, BACK_ARMOUR = 0.5)
|
||||
var/obj/item/weapon/stock_parts/cell/cell
|
||||
var/state = 0
|
||||
var/cell_power_remaining = 1 // 0 - no power, 1 - 100% power in cell. Starts as 1 so putting any cell into empty mech doesn't deplete charge from it
|
||||
var/list/log = new
|
||||
var/last_message = 0
|
||||
var/add_req_access = 1
|
||||
|
||||
@@ -213,7 +213,6 @@
|
||||
clearInternalDamage(MECHA_INT_TEMP_CONTROL)
|
||||
to_chat(user, "<span class='notice'>You repair the damaged temperature controller.</span>")
|
||||
else if(state==3 && cell)
|
||||
cell_power_remaining = max(0.1, cell.charge/cell.maxcharge) //10% charge or whatever is remaining in the current cell
|
||||
cell.forceMove(loc)
|
||||
cell = null
|
||||
state = 4
|
||||
@@ -232,7 +231,6 @@
|
||||
var/obj/item/weapon/stock_parts/cell/C = W
|
||||
to_chat(user, "<span class='notice'>You install the powercell.</span>")
|
||||
C.forceMove(src)
|
||||
C.use(max(0, C.charge - C.maxcharge*cell_power_remaining)) //Set inserted cell's power to saved percentage if that's higher
|
||||
cell = C
|
||||
log_message("Powercell installed")
|
||||
else
|
||||
|
||||
@@ -19,12 +19,17 @@
|
||||
|
||||
/obj/mecha/working/ripley/Move()
|
||||
. = ..()
|
||||
if(. && (locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in equipment))
|
||||
if(.)
|
||||
collect_ore()
|
||||
update_pressure()
|
||||
|
||||
/obj/mecha/working/ripley/proc/collect_ore()
|
||||
if(locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in equipment)
|
||||
var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in cargo
|
||||
if(ore_box)
|
||||
for(var/obj/item/weapon/ore/ore in get_turf(src))
|
||||
ore.Move(ore_box)
|
||||
update_pressure()
|
||||
for(var/obj/item/weapon/ore/ore in range(1, src))
|
||||
if(ore.Adjacent(src) && ((get_dir(src, ore) & dir) || ore.loc == loc)) //we can reach it and it's in front of us? grab it!
|
||||
ore.forceMove(ore_box)
|
||||
|
||||
/obj/mecha/working/ripley/Destroy()
|
||||
for(var/i=1, i <= hides, i++)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
/obj/effect/decal/cleanable/crayon/Initialize(mapload, main = "#FFFFFF", var/type = "rune1", var/e_name = "rune", var/rotation = 0, var/alt_icon = null)
|
||||
..()
|
||||
|
||||
|
||||
name = e_name
|
||||
desc = "A [name] vandalizing the station."
|
||||
if(type == "poseur tag")
|
||||
@@ -30,22 +30,25 @@
|
||||
layer = HIGH_OBJ_LAYER //Harder to hide
|
||||
do_icon_rotate = FALSE //These are designed to always face south, so no rotation please.
|
||||
var/datum/gang/gang
|
||||
var/obj/item/device/gangtool/linked_tool
|
||||
var/area/territory
|
||||
|
||||
/obj/effect/decal/cleanable/crayon/gang/Initialize(mapload, var/datum/gang/G, var/e_name = "gang tag", var/rotation = 0)
|
||||
/obj/effect/decal/cleanable/crayon/gang/Initialize(mapload, var/datum/gang/G, var/e_name = "gang tag", var/rotation = 0, var/mob/user)
|
||||
if(!type || !G)
|
||||
qdel(src)
|
||||
|
||||
var/area/territory = get_area(src)
|
||||
territory = get_area(src)
|
||||
gang = G
|
||||
var/newcolor = G.color_hex
|
||||
icon_state = G.name
|
||||
G.territory_new |= list(territory.type = territory.name)
|
||||
|
||||
linked_tool = locate(/obj/item/device/gangtool) in user.contents
|
||||
if(linked_tool)
|
||||
linked_tool.tags += src
|
||||
..(mapload, newcolor, icon_state, e_name, rotation)
|
||||
|
||||
/obj/effect/decal/cleanable/crayon/gang/Destroy()
|
||||
var/area/territory = get_area(src)
|
||||
|
||||
if(linked_tool)
|
||||
linked_tool.tags -= src
|
||||
if(gang)
|
||||
gang.territory -= territory.type
|
||||
gang.territory_new -= territory.type
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/obj/effect/overlay/temp/point
|
||||
/obj/effect/temp_visual/point
|
||||
name = "pointer"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "arrow"
|
||||
layer = POINT_LAYER
|
||||
duration = 25
|
||||
|
||||
/obj/effect/overlay/temp/point/Initialize(mapload, set_invis = 0)
|
||||
/obj/effect/temp_visual/point/Initialize(mapload, set_invis = 0)
|
||||
..()
|
||||
var/atom/old_loc = loc
|
||||
loc = get_turf(src)
|
||||
|
||||
@@ -93,6 +93,4 @@
|
||||
|
||||
/obj/effect/abstract/proximity_checker/Crossed(atom/movable/AM)
|
||||
set waitfor = FALSE
|
||||
var/atom/H = monitor.host
|
||||
testing("HasProx: [H] -> [AM]")
|
||||
H.HasProximity(AM)
|
||||
monitor.host.HasProximity(AM)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
var/area/A = get_area(T)
|
||||
|
||||
new /obj/structure/alien/egg(T)
|
||||
new /obj/effect/overlay/temp/gravpush(T)
|
||||
new /obj/effect/temp_visual/gravpush(T)
|
||||
playsound(T, 'sound/items/party_horn.ogg', 50, 1, -1)
|
||||
|
||||
message_admins("An alien egg has been delivered to [A] at [ADMIN_COORDJMP(T)].")
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
//temporary visual effects(/obj/effect/overlay/temp) used by clockcult stuff
|
||||
/obj/effect/overlay/temp/ratvar
|
||||
//temporary visual effects(/obj/effect/temp_visual) used by clockcult stuff
|
||||
/obj/effect/temp_visual/ratvar
|
||||
name = "ratvar's light"
|
||||
icon = 'icons/effects/clockwork_effects.dmi'
|
||||
duration = 8
|
||||
randomdir = 0
|
||||
layer = ABOVE_NORMAL_TURF_LAYER
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/door
|
||||
/obj/effect/temp_visual/ratvar/door
|
||||
icon_state = "ratvardoorglow"
|
||||
layer = CLOSED_DOOR_LAYER //above closed doors
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/door/window
|
||||
/obj/effect/temp_visual/ratvar/door/window
|
||||
icon_state = "ratvarwindoorglow"
|
||||
layer = ABOVE_WINDOW_LAYER
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/beam
|
||||
/obj/effect/temp_visual/ratvar/beam
|
||||
icon_state = "ratvarbeamglow"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/beam/door
|
||||
/obj/effect/temp_visual/ratvar/beam/door
|
||||
layer = CLOSED_DOOR_LAYER
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/beam/grille
|
||||
/obj/effect/temp_visual/ratvar/beam/grille
|
||||
layer = BELOW_OBJ_LAYER
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/beam/itemconsume
|
||||
/obj/effect/temp_visual/ratvar/beam/itemconsume
|
||||
layer = HIGH_OBJ_LAYER
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/beam/falsewall
|
||||
/obj/effect/temp_visual/ratvar/beam/falsewall
|
||||
layer = OBJ_LAYER
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/beam/catwalk
|
||||
/obj/effect/temp_visual/ratvar/beam/catwalk
|
||||
layer = LATTICE_LAYER
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/wall
|
||||
/obj/effect/temp_visual/ratvar/wall
|
||||
icon_state = "ratvarwallglow"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/wall/false
|
||||
/obj/effect/temp_visual/ratvar/wall/false
|
||||
layer = OBJ_LAYER
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/floor
|
||||
/obj/effect/temp_visual/ratvar/floor
|
||||
icon_state = "ratvarfloorglow"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/floor/catwalk
|
||||
/obj/effect/temp_visual/ratvar/floor/catwalk
|
||||
layer = LATTICE_LAYER
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/window
|
||||
/obj/effect/temp_visual/ratvar/window
|
||||
icon_state = "ratvarwindowglow"
|
||||
layer = ABOVE_OBJ_LAYER
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/window/single
|
||||
/obj/effect/temp_visual/ratvar/window/single
|
||||
icon_state = "ratvarwindowglow_s"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/gear
|
||||
/obj/effect/temp_visual/ratvar/gear
|
||||
icon_state = "ratvargearglow"
|
||||
layer = BELOW_OBJ_LAYER
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/grille
|
||||
/obj/effect/temp_visual/ratvar/grille
|
||||
icon_state = "ratvargrilleglow"
|
||||
layer = BELOW_OBJ_LAYER
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/grille/broken
|
||||
/obj/effect/temp_visual/ratvar/grille/broken
|
||||
icon_state = "ratvarbrokengrilleglow"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/mending_mantra
|
||||
/obj/effect/temp_visual/ratvar/mending_mantra
|
||||
layer = ABOVE_MOB_LAYER
|
||||
duration = 20
|
||||
alpha = 200
|
||||
@@ -70,7 +70,7 @@
|
||||
light_range = 1.5
|
||||
light_color = "#1E8CE1"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/mending_mantra/Initialize(mapload)
|
||||
/obj/effect/temp_visual/ratvar/mending_mantra/Initialize(mapload)
|
||||
. = ..()
|
||||
transform = matrix()*2
|
||||
var/matrix/M = transform
|
||||
@@ -78,7 +78,7 @@
|
||||
animate(src, alpha = 20, time = duration, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL)
|
||||
animate(src, transform = M, time = duration, flags = ANIMATION_PARALLEL)
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/volt_hit
|
||||
/obj/effect/temp_visual/ratvar/volt_hit
|
||||
name = "volt blast"
|
||||
layer = ABOVE_MOB_LAYER
|
||||
duration = 5
|
||||
@@ -89,13 +89,13 @@
|
||||
var/mob/user
|
||||
var/damage = 20
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/volt_hit/Initialize(mapload, caster, multiplier)
|
||||
/obj/effect/temp_visual/ratvar/volt_hit/Initialize(mapload, caster, multiplier)
|
||||
if(multiplier)
|
||||
damage *= multiplier
|
||||
duration = max(round(damage * 0.2), 1)
|
||||
. = ..()
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/volt_hit/true/Initialize(mapload, caster, multiplier)
|
||||
/obj/effect/temp_visual/ratvar/volt_hit/true/Initialize(mapload, caster, multiplier)
|
||||
. = ..()
|
||||
user = caster
|
||||
if(user)
|
||||
@@ -104,7 +104,7 @@
|
||||
transform = M
|
||||
INVOKE_ASYNC(src, .proc/volthit)
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/volt_hit/proc/volthit()
|
||||
/obj/effect/temp_visual/ratvar/volt_hit/proc/volthit()
|
||||
if(user)
|
||||
Beam(get_turf(user), "volt_ray", time=duration, maxdistance=8, beam_type=/obj/effect/ebeam/volt_ray)
|
||||
var/hit_amount = 0
|
||||
@@ -134,61 +134,61 @@
|
||||
else
|
||||
playsound(src, "sparks", 50, 1)
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/ocular_warden
|
||||
/obj/effect/temp_visual/ratvar/ocular_warden
|
||||
name = "warden's gaze"
|
||||
layer = ABOVE_MOB_LAYER
|
||||
icon_state = "warden_gaze"
|
||||
duration = 3
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/ocular_warden/Initialize()
|
||||
/obj/effect/temp_visual/ratvar/ocular_warden/Initialize()
|
||||
. = ..()
|
||||
pixel_x = rand(-8, 8)
|
||||
pixel_y = rand(-10, 10)
|
||||
animate(src, alpha = 0, time = 3, easing = EASE_OUT)
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/spearbreak
|
||||
/obj/effect/temp_visual/ratvar/spearbreak
|
||||
icon = 'icons/effects/64x64.dmi'
|
||||
icon_state = "ratvarspearbreak"
|
||||
layer = BELOW_MOB_LAYER
|
||||
pixel_y = -16
|
||||
pixel_x = -16
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/geis_binding
|
||||
/obj/effect/temp_visual/ratvar/geis_binding
|
||||
icon_state = "geisbinding"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/geis_binding/top
|
||||
/obj/effect/temp_visual/ratvar/geis_binding/top
|
||||
icon_state = "geisbinding_top"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/component
|
||||
/obj/effect/temp_visual/ratvar/component
|
||||
icon = 'icons/obj/clockwork_objects.dmi'
|
||||
icon_state = "belligerent_eye"
|
||||
layer = ABOVE_MOB_LAYER
|
||||
duration = 10
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/component/Initialize()
|
||||
/obj/effect/temp_visual/ratvar/component/Initialize()
|
||||
. = ..()
|
||||
transform = matrix()*0.75
|
||||
pixel_x = rand(-10, 10)
|
||||
pixel_y = rand(-10, -2)
|
||||
animate(src, pixel_y = pixel_y + 10, alpha = 50, time = 10, easing = EASE_OUT)
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/component/cogwheel
|
||||
/obj/effect/temp_visual/ratvar/component/cogwheel
|
||||
icon_state = "vanguard_cogwheel"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/component/capacitor
|
||||
/obj/effect/temp_visual/ratvar/component/capacitor
|
||||
icon_state = "geis_capacitor"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/component/alloy
|
||||
/obj/effect/temp_visual/ratvar/component/alloy
|
||||
icon_state = "replicant_alloy"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/component/ansible
|
||||
/obj/effect/temp_visual/ratvar/component/ansible
|
||||
icon_state = "hierophant_ansible"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/sigil
|
||||
/obj/effect/temp_visual/ratvar/sigil
|
||||
name = "glowing circle"
|
||||
icon_state = "sigildull"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/sigil/transgression
|
||||
/obj/effect/temp_visual/ratvar/sigil/transgression
|
||||
color = "#FAE48C"
|
||||
layer = ABOVE_MOB_LAYER
|
||||
duration = 70
|
||||
@@ -196,13 +196,13 @@
|
||||
light_power = 2
|
||||
light_color = "#FAE48C"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/sigil/transgression/Initialize()
|
||||
/obj/effect/temp_visual/ratvar/sigil/transgression/Initialize()
|
||||
. = ..()
|
||||
var/oldtransform = transform
|
||||
animate(src, transform = matrix()*2, time = 5)
|
||||
animate(transform = oldtransform, alpha = 0, time = 65)
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/sigil/vitality
|
||||
/obj/effect/temp_visual/ratvar/sigil/vitality
|
||||
color = "#1E8CE1"
|
||||
icon_state = "sigilactivepulse"
|
||||
layer = ABOVE_MOB_LAYER
|
||||
@@ -210,7 +210,7 @@
|
||||
light_power = 0.5
|
||||
light_color = "#1E8CE1"
|
||||
|
||||
/obj/effect/overlay/temp/ratvar/sigil/accession
|
||||
/obj/effect/temp_visual/ratvar/sigil/accession
|
||||
color = "#AF0AAF"
|
||||
layer = ABOVE_MOB_LAYER
|
||||
duration = 70
|
||||
|
||||
@@ -1,58 +1,58 @@
|
||||
//temporary visual effects(/obj/effect/overlay/temp) used by cult stuff
|
||||
/obj/effect/overlay/temp/cult
|
||||
//temporary visual effects(/obj/effect/temp_visual) used by cult stuff
|
||||
/obj/effect/temp_visual/cult
|
||||
icon = 'icons/effects/cult_effects.dmi'
|
||||
randomdir = 0
|
||||
duration = 10
|
||||
|
||||
/obj/effect/overlay/temp/cult/sparks
|
||||
/obj/effect/temp_visual/cult/sparks
|
||||
randomdir = 1
|
||||
name = "blood sparks"
|
||||
icon_state = "bloodsparkles"
|
||||
|
||||
/obj/effect/overlay/temp/cult/blood // The traditional teleport
|
||||
/obj/effect/temp_visual/cult/blood // The traditional teleport
|
||||
name = "blood jaunt"
|
||||
duration = 12
|
||||
icon_state = "bloodin"
|
||||
|
||||
/obj/effect/overlay/temp/cult/blood/out
|
||||
/obj/effect/temp_visual/cult/blood/out
|
||||
icon_state = "bloodout"
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/cult/phase // The veil shifter teleport
|
||||
/obj/effect/temp_visual/dir_setting/cult/phase // The veil shifter teleport
|
||||
name = "phase glow"
|
||||
duration = 7
|
||||
icon_state = "cultin"
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/cult/phase/out
|
||||
/obj/effect/temp_visual/dir_setting/cult/phase/out
|
||||
icon_state = "cultout"
|
||||
|
||||
/obj/effect/overlay/temp/cult/sac
|
||||
/obj/effect/temp_visual/cult/sac
|
||||
name = "maw of Nar-Sie"
|
||||
icon_state = "sacconsume"
|
||||
|
||||
/obj/effect/overlay/temp/cult/door
|
||||
/obj/effect/temp_visual/cult/door
|
||||
name = "unholy glow"
|
||||
icon_state = "doorglow"
|
||||
layer = CLOSED_FIREDOOR_LAYER //above closed doors
|
||||
|
||||
/obj/effect/overlay/temp/cult/door/unruned
|
||||
/obj/effect/temp_visual/cult/door/unruned
|
||||
icon_state = "unruneddoorglow"
|
||||
|
||||
/obj/effect/overlay/temp/cult/turf
|
||||
/obj/effect/temp_visual/cult/turf
|
||||
name = "unholy glow"
|
||||
icon_state = "wallglow"
|
||||
layer = ABOVE_NORMAL_TURF_LAYER
|
||||
|
||||
/obj/effect/overlay/temp/cult/turf/floor
|
||||
/obj/effect/temp_visual/cult/turf/floor
|
||||
icon_state = "floorglow"
|
||||
duration = 5
|
||||
|
||||
//visuals for runes being magically created
|
||||
/obj/effect/overlay/temp/cult/rune_spawn
|
||||
/obj/effect/temp_visual/cult/rune_spawn
|
||||
icon_state = "runeouter"
|
||||
alpha = 0
|
||||
var/turnedness = 179 //179 turns counterclockwise, 181 turns clockwise
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/Initialize(mapload, set_duration, set_color)
|
||||
/obj/effect/temp_visual/cult/rune_spawn/Initialize(mapload, set_duration, set_color)
|
||||
if(isnum(set_duration))
|
||||
duration = set_duration
|
||||
if(set_color)
|
||||
@@ -66,79 +66,79 @@
|
||||
animate(src, alpha = 255, time = duration, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL)
|
||||
animate(src, transform = oldtransform, time = duration, flags = ANIMATION_PARALLEL)
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune1
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune1
|
||||
icon_state = "rune1words"
|
||||
turnedness = 181
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune1/inner
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune1/inner
|
||||
icon_state = "rune1inner"
|
||||
turnedness = 179
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune1/center
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune1/center
|
||||
icon_state = "rune1center"
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune2
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune2
|
||||
icon_state = "rune2words"
|
||||
turnedness = 181
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune2/inner
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune2/inner
|
||||
icon_state = "rune2inner"
|
||||
turnedness = 179
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune2/center
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune2/center
|
||||
icon_state = "rune2center"
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune3
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune3
|
||||
icon_state = "rune3words"
|
||||
turnedness = 181
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune3/inner
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune3/inner
|
||||
icon_state = "rune3inner"
|
||||
turnedness = 179
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune3/center
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune3/center
|
||||
icon_state = "rune3center"
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune4
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune4
|
||||
icon_state = "rune4words"
|
||||
turnedness = 181
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune4/inner
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune4/inner
|
||||
icon_state = "rune4inner"
|
||||
turnedness = 179
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune4/center
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune4/center
|
||||
icon_state = "rune4center"
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune5
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune5
|
||||
icon_state = "rune5words"
|
||||
turnedness = 181
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune5/inner
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune5/inner
|
||||
icon_state = "rune5inner"
|
||||
turnedness = 179
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune5/center
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune5/center
|
||||
icon_state = "rune5center"
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune6
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune6
|
||||
icon_state = "rune6words"
|
||||
turnedness = 181
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune6/inner
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune6/inner
|
||||
icon_state = "rune6inner"
|
||||
turnedness = 179
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune6/center
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune6/center
|
||||
icon_state = "rune6center"
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune7
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune7
|
||||
icon_state = "rune7words"
|
||||
turnedness = 181
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune7/inner
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune7/inner
|
||||
icon_state = "rune7inner"
|
||||
turnedness = 179
|
||||
|
||||
/obj/effect/overlay/temp/cult/rune_spawn/rune7/center
|
||||
/obj/effect/temp_visual/cult/rune_spawn/rune7/center
|
||||
icon_state = "rune7center"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
//unsorted miscellaneous temporary visuals
|
||||
/obj/effect/overlay/temp/dir_setting/bloodsplatter
|
||||
/obj/effect/temp_visual/dir_setting/bloodsplatter
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
duration = 5
|
||||
randomdir = FALSE
|
||||
layer = BELOW_MOB_LAYER
|
||||
var/splatter_type = "splatter"
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/bloodsplatter/Initialize(mapload, set_dir)
|
||||
/obj/effect/temp_visual/dir_setting/bloodsplatter/Initialize(mapload, set_dir)
|
||||
if(set_dir in GLOB.diagonals)
|
||||
icon_state = "[splatter_type][pick(1, 2, 6)]"
|
||||
else
|
||||
@@ -40,22 +40,22 @@
|
||||
layer = ABOVE_MOB_LAYER
|
||||
animate(src, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = duration)
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/bloodsplatter/xenosplatter
|
||||
/obj/effect/temp_visual/dir_setting/bloodsplatter/xenosplatter
|
||||
splatter_type = "xsplatter"
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/speedbike_trail
|
||||
/obj/effect/temp_visual/dir_setting/speedbike_trail
|
||||
name = "speedbike trails"
|
||||
icon_state = "ion_fade"
|
||||
layer = BELOW_MOB_LAYER
|
||||
duration = 10
|
||||
randomdir = 0
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/firing_effect
|
||||
/obj/effect/temp_visual/dir_setting/firing_effect
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "firing_effect"
|
||||
duration = 2
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/firing_effect/setDir(newdir)
|
||||
/obj/effect/temp_visual/dir_setting/firing_effect/setDir(newdir)
|
||||
switch(newdir)
|
||||
if(NORTH)
|
||||
layer = BELOW_MOB_LAYER
|
||||
@@ -69,84 +69,84 @@
|
||||
pixel_y = rand(-1,1)
|
||||
..()
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/firing_effect/energy
|
||||
/obj/effect/temp_visual/dir_setting/firing_effect/energy
|
||||
icon_state = "firing_effect_energy"
|
||||
duration = 3
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/firing_effect/magic
|
||||
/obj/effect/temp_visual/dir_setting/firing_effect/magic
|
||||
icon_state = "shieldsparkles"
|
||||
duration = 3
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/ninja
|
||||
/obj/effect/temp_visual/dir_setting/ninja
|
||||
name = "ninja shadow"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "uncloak"
|
||||
duration = 9
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/ninja/cloak
|
||||
/obj/effect/temp_visual/dir_setting/ninja/cloak
|
||||
icon_state = "cloak"
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/ninja/shadow
|
||||
/obj/effect/temp_visual/dir_setting/ninja/shadow
|
||||
icon_state = "shadow"
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/ninja/phase
|
||||
/obj/effect/temp_visual/dir_setting/ninja/phase
|
||||
name = "ninja energy"
|
||||
icon_state = "phasein"
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/ninja/phase/out
|
||||
/obj/effect/temp_visual/dir_setting/ninja/phase/out
|
||||
icon_state = "phaseout"
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/wraith
|
||||
/obj/effect/temp_visual/dir_setting/wraith
|
||||
name = "blood"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "phase_shift2"
|
||||
duration = 12
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/wraith/out
|
||||
/obj/effect/temp_visual/dir_setting/wraith/out
|
||||
icon_state = "phase_shift"
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/tailsweep
|
||||
/obj/effect/temp_visual/dir_setting/tailsweep
|
||||
icon_state = "tailsweep"
|
||||
duration = 4
|
||||
|
||||
/obj/effect/overlay/temp/wizard
|
||||
/obj/effect/temp_visual/wizard
|
||||
name = "water"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "reappear"
|
||||
duration = 5
|
||||
|
||||
/obj/effect/overlay/temp/wizard/out
|
||||
/obj/effect/temp_visual/wizard/out
|
||||
icon_state = "liquify"
|
||||
duration = 12
|
||||
|
||||
/obj/effect/overlay/temp/monkeyify
|
||||
/obj/effect/temp_visual/monkeyify
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "h2monkey"
|
||||
duration = 22
|
||||
|
||||
/obj/effect/overlay/temp/monkeyify/humanify
|
||||
/obj/effect/temp_visual/monkeyify/humanify
|
||||
icon_state = "monkey2h"
|
||||
|
||||
/obj/effect/overlay/temp/borgflash
|
||||
/obj/effect/temp_visual/borgflash
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "blspell"
|
||||
duration = 5
|
||||
|
||||
/obj/effect/overlay/temp/guardian
|
||||
/obj/effect/temp_visual/guardian
|
||||
randomdir = 0
|
||||
|
||||
/obj/effect/overlay/temp/guardian/phase
|
||||
/obj/effect/temp_visual/guardian/phase
|
||||
duration = 5
|
||||
icon_state = "phasein"
|
||||
|
||||
/obj/effect/overlay/temp/guardian/phase/out
|
||||
/obj/effect/temp_visual/guardian/phase/out
|
||||
icon_state = "phaseout"
|
||||
|
||||
/obj/effect/overlay/temp/decoy
|
||||
/obj/effect/temp_visual/decoy
|
||||
desc = "It's a decoy!"
|
||||
duration = 15
|
||||
|
||||
/obj/effect/overlay/temp/decoy/Initialize(mapload, atom/mimiced_atom)
|
||||
/obj/effect/temp_visual/decoy/Initialize(mapload, atom/mimiced_atom)
|
||||
. = ..()
|
||||
alpha = initial(alpha)
|
||||
if(mimiced_atom)
|
||||
@@ -155,95 +155,95 @@
|
||||
setDir(mimiced_atom.dir)
|
||||
mouse_opacity = 0
|
||||
|
||||
/obj/effect/overlay/temp/decoy/fading/Initialize(mapload, atom/mimiced_atom)
|
||||
/obj/effect/temp_visual/decoy/fading/Initialize(mapload, atom/mimiced_atom)
|
||||
. = ..()
|
||||
animate(src, alpha = 0, time = duration)
|
||||
|
||||
/obj/effect/overlay/temp/decoy/fading/fivesecond
|
||||
/obj/effect/temp_visual/decoy/fading/fivesecond
|
||||
duration = 50
|
||||
|
||||
/obj/effect/overlay/temp/small_smoke
|
||||
/obj/effect/temp_visual/small_smoke
|
||||
icon_state = "smoke"
|
||||
duration = 50
|
||||
|
||||
/obj/effect/overlay/temp/fire
|
||||
/obj/effect/temp_visual/fire
|
||||
icon = 'icons/effects/fire.dmi'
|
||||
icon_state = "3"
|
||||
duration = 20
|
||||
|
||||
/obj/effect/overlay/temp/revenant
|
||||
/obj/effect/temp_visual/revenant
|
||||
name = "spooky lights"
|
||||
icon_state = "purplesparkles"
|
||||
|
||||
/obj/effect/overlay/temp/revenant/cracks
|
||||
/obj/effect/temp_visual/revenant/cracks
|
||||
name = "glowing cracks"
|
||||
icon_state = "purplecrack"
|
||||
duration = 6
|
||||
|
||||
/obj/effect/overlay/temp/gravpush
|
||||
/obj/effect/temp_visual/gravpush
|
||||
name = "gravity wave"
|
||||
icon_state = "shieldsparkles"
|
||||
duration = 5
|
||||
|
||||
/obj/effect/overlay/temp/telekinesis
|
||||
/obj/effect/temp_visual/telekinesis
|
||||
name = "telekinetic force"
|
||||
icon_state = "empdisable"
|
||||
duration = 5
|
||||
|
||||
/obj/effect/overlay/temp/emp
|
||||
/obj/effect/temp_visual/emp
|
||||
name = "emp sparks"
|
||||
icon_state = "empdisable"
|
||||
|
||||
/obj/effect/overlay/temp/emp/pulse
|
||||
/obj/effect/temp_visual/emp/pulse
|
||||
name = "emp pulse"
|
||||
icon_state = "emppulse"
|
||||
duration = 8
|
||||
randomdir = 0
|
||||
|
||||
/obj/effect/overlay/temp/gib_animation
|
||||
/obj/effect/temp_visual/gib_animation
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
duration = 15
|
||||
|
||||
/obj/effect/overlay/temp/gib_animation/Initialize(mapload, gib_icon)
|
||||
/obj/effect/temp_visual/gib_animation/Initialize(mapload, gib_icon)
|
||||
icon_state = gib_icon // Needs to be before ..() so icon is correct
|
||||
. = ..()
|
||||
|
||||
/obj/effect/overlay/temp/gib_animation/animal
|
||||
/obj/effect/temp_visual/gib_animation/animal
|
||||
icon = 'icons/mob/animal.dmi'
|
||||
|
||||
/obj/effect/overlay/temp/dust_animation
|
||||
/obj/effect/temp_visual/dust_animation
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
duration = 15
|
||||
|
||||
/obj/effect/overlay/temp/dust_animation/Initialize(mapload, dust_icon)
|
||||
/obj/effect/temp_visual/dust_animation/Initialize(mapload, dust_icon)
|
||||
icon_state = dust_icon // Before ..() so the correct icon is flick()'d
|
||||
. = ..()
|
||||
|
||||
/obj/effect/overlay/temp/mummy_animation
|
||||
/obj/effect/temp_visual/mummy_animation
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "mummy_revive"
|
||||
duration = 20
|
||||
|
||||
/obj/effect/overlay/temp/heal //color is white by default, set to whatever is needed
|
||||
/obj/effect/temp_visual/heal //color is white by default, set to whatever is needed
|
||||
name = "healing glow"
|
||||
icon_state = "heal"
|
||||
duration = 15
|
||||
|
||||
/obj/effect/overlay/temp/heal/Initialize(mapload, set_color)
|
||||
/obj/effect/temp_visual/heal/Initialize(mapload, set_color)
|
||||
if(set_color)
|
||||
add_atom_colour(set_color, FIXED_COLOUR_PRIORITY)
|
||||
. = ..()
|
||||
pixel_x = rand(-12, 12)
|
||||
pixel_y = rand(-9, 0)
|
||||
|
||||
/obj/effect/overlay/temp/kinetic_blast
|
||||
/obj/effect/temp_visual/kinetic_blast
|
||||
name = "kinetic explosion"
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
icon_state = "kinetic_blast"
|
||||
layer = ABOVE_ALL_MOB_LAYER
|
||||
duration = 4
|
||||
|
||||
/obj/effect/overlay/temp/explosion
|
||||
/obj/effect/temp_visual/explosion
|
||||
name = "explosion"
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "explosion"
|
||||
@@ -251,22 +251,22 @@
|
||||
pixel_y = -32
|
||||
duration = 8
|
||||
|
||||
/obj/effect/overlay/temp/explosion/fast
|
||||
/obj/effect/temp_visual/explosion/fast
|
||||
icon_state = "explosionfast"
|
||||
duration = 4
|
||||
|
||||
/obj/effect/overlay/temp/blob
|
||||
/obj/effect/temp_visual/blob
|
||||
name = "blob"
|
||||
icon_state = "blob_attack"
|
||||
alpha = 140
|
||||
randomdir = 0
|
||||
duration = 6
|
||||
|
||||
/obj/effect/overlay/temp/impact_effect
|
||||
/obj/effect/temp_visual/impact_effect
|
||||
icon_state = "impact_bullet"
|
||||
duration = 5
|
||||
|
||||
/obj/effect/overlay/temp/impact_effect/Initialize(mapload, atom/target, obj/item/projectile/P)
|
||||
/obj/effect/temp_visual/impact_effect/Initialize(mapload, atom/target, obj/item/projectile/P)
|
||||
if(target == P.original) //the projectile hit the target originally clicked
|
||||
pixel_x = P.p_x + target.pixel_x - 16 + rand(-4,4)
|
||||
pixel_y = P.p_y + target.pixel_y - 16 + rand(-4,4)
|
||||
@@ -275,37 +275,37 @@
|
||||
pixel_y = target.pixel_y + rand(-4,4)
|
||||
. = ..()
|
||||
|
||||
/obj/effect/overlay/temp/impact_effect/red_laser
|
||||
/obj/effect/temp_visual/impact_effect/red_laser
|
||||
icon_state = "impact_laser"
|
||||
duration = 4
|
||||
|
||||
/obj/effect/overlay/temp/impact_effect/red_laser/wall
|
||||
/obj/effect/temp_visual/impact_effect/red_laser/wall
|
||||
icon_state = "impact_laser_wall"
|
||||
duration = 10
|
||||
|
||||
/obj/effect/overlay/temp/impact_effect/blue_laser
|
||||
/obj/effect/temp_visual/impact_effect/blue_laser
|
||||
icon_state = "impact_laser_blue"
|
||||
duration = 4
|
||||
|
||||
/obj/effect/overlay/temp/impact_effect/green_laser
|
||||
/obj/effect/temp_visual/impact_effect/green_laser
|
||||
icon_state = "impact_laser_green"
|
||||
duration = 4
|
||||
|
||||
/obj/effect/overlay/temp/impact_effect/purple_laser
|
||||
/obj/effect/temp_visual/impact_effect/purple_laser
|
||||
icon_state = "impact_laser_purple"
|
||||
duration = 4
|
||||
|
||||
/obj/effect/overlay/temp/impact_effect/ion
|
||||
/obj/effect/temp_visual/impact_effect/ion
|
||||
icon_state = "shieldsparkles"
|
||||
duration = 6
|
||||
|
||||
/obj/effect/overlay/temp/heart
|
||||
/obj/effect/temp_visual/heart
|
||||
name = "heart"
|
||||
icon = 'icons/mob/animal.dmi'
|
||||
icon_state = "heart"
|
||||
duration = 25
|
||||
|
||||
/obj/effect/overlay/temp/heart/Initialize(mapload)
|
||||
/obj/effect/temp_visual/heart/Initialize(mapload)
|
||||
. = ..()
|
||||
pixel_x = rand(-4,4)
|
||||
pixel_y = rand(-4,4)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//temporary visual effects
|
||||
/obj/effect/overlay/temp
|
||||
/obj/effect/temp_visual
|
||||
icon_state = "nothing"
|
||||
anchored = 1
|
||||
layer = ABOVE_MOB_LAYER
|
||||
@@ -8,30 +8,30 @@
|
||||
var/randomdir = TRUE
|
||||
var/timerid
|
||||
|
||||
/obj/effect/overlay/temp/Initialize()
|
||||
/obj/effect/temp_visual/Initialize()
|
||||
. = ..()
|
||||
if(randomdir)
|
||||
setDir(pick(GLOB.cardinal))
|
||||
|
||||
timerid = QDEL_IN(src, duration)
|
||||
|
||||
/obj/effect/overlay/temp/Destroy()
|
||||
/obj/effect/temp_visual/Destroy()
|
||||
. = ..()
|
||||
deltimer(timerid)
|
||||
|
||||
/obj/effect/overlay/temp/singularity_act()
|
||||
/obj/effect/temp_visual/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/overlay/temp/singularity_pull()
|
||||
/obj/effect/temp_visual/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/overlay/temp/ex_act()
|
||||
/obj/effect/temp_visual/ex_act()
|
||||
return
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting
|
||||
/obj/effect/temp_visual/dir_setting
|
||||
randomdir = FALSE
|
||||
|
||||
/obj/effect/overlay/temp/dir_setting/Initialize(mapload, set_dir)
|
||||
/obj/effect/temp_visual/dir_setting/Initialize(mapload, set_dir)
|
||||
if(set_dir)
|
||||
setDir(set_dir)
|
||||
. = ..()
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ")
|
||||
|
||||
if(heavy_range > 1)
|
||||
new /obj/effect/overlay/temp/emp/pulse(epicenter)
|
||||
new /obj/effect/temp_visual/emp/pulse(epicenter)
|
||||
|
||||
if(heavy_range > light_range)
|
||||
light_range = heavy_range
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
var/pre_noise = FALSE
|
||||
var/post_noise = FALSE
|
||||
|
||||
|
||||
/obj/item/toy/crayon/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is jamming [src] up [user.p_their()] nose and into [user.p_their()] brain. It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return (BRUTELOSS|OXYLOSS)
|
||||
@@ -422,7 +423,7 @@
|
||||
var/gangID = user.mind.gang_datum
|
||||
var/area/territory = get_area(target)
|
||||
|
||||
new /obj/effect/decal/cleanable/crayon/gang(target,gangID,"graffiti",0)
|
||||
new /obj/effect/decal/cleanable/crayon/gang(target,gangID,"graffiti",0,user)
|
||||
to_chat(user, "<span class='notice'>You tagged [territory] for your gang!</span>")
|
||||
|
||||
/obj/item/toy/crayon/red
|
||||
|
||||
@@ -56,13 +56,13 @@
|
||||
qdel(active_dummy)
|
||||
active_dummy = null
|
||||
to_chat(usr, "<span class='notice'>You deactivate \the [src].</span>")
|
||||
new /obj/effect/overlay/temp/emp/pulse(get_turf(src))
|
||||
new /obj/effect/temp_visual/emp/pulse(get_turf(src))
|
||||
else
|
||||
playsound(get_turf(src), 'sound/effects/pop.ogg', 100, 1, -6)
|
||||
var/obj/effect/dummy/chameleon/C = new/obj/effect/dummy/chameleon(usr.loc)
|
||||
C.activate(usr, saved_appearance, src)
|
||||
to_chat(usr, "<span class='notice'>You activate \the [src].</span>")
|
||||
new /obj/effect/overlay/temp/emp/pulse(get_turf(src))
|
||||
new /obj/effect/temp_visual/emp/pulse(get_turf(src))
|
||||
|
||||
/obj/item/device/chameleon/proc/disrupt(delete_dummy = 1)
|
||||
if(active_dummy)
|
||||
|
||||
@@ -162,18 +162,18 @@
|
||||
return
|
||||
var/T = get_turf(target)
|
||||
if(locate(/mob/living) in T)
|
||||
new /obj/effect/overlay/temp/medical_holosign(T,user) //produce a holographic glow
|
||||
new /obj/effect/temp_visual/medical_holosign(T,user) //produce a holographic glow
|
||||
holo_cooldown = world.time + 100
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/effect/overlay/temp/medical_holosign
|
||||
/obj/effect/temp_visual/medical_holosign
|
||||
name = "medical holosign"
|
||||
desc = "A small holographic glow that indicates a medic is coming to treat a patient."
|
||||
icon_state = "medi_holo"
|
||||
duration = 30
|
||||
|
||||
/obj/effect/overlay/temp/medical_holosign/Initialize(mapload, creator)
|
||||
/obj/effect/temp_visual/medical_holosign/Initialize(mapload, creator)
|
||||
. = ..()
|
||||
playsound(loc, 'sound/machines/ping.ogg', 50, 0) //make some noise!
|
||||
if(creator)
|
||||
|
||||
@@ -196,13 +196,6 @@ GLOBAL_LIST_INIT(sinew_recipes, list ( \
|
||||
user.visible_message("[user] starts cutting hair off \the [src].", "<span class='notice'>You start cutting the hair off \the [src]...</span>", "<span class='italics'>You hear the sound of a knife rubbing against flesh.</span>")
|
||||
if(do_after(user,50, target = src))
|
||||
to_chat(user, "<span class='notice'>You cut the hair from this [src.singular_name].</span>")
|
||||
//Try locating an exisitng stack on the tile and add to there if possible
|
||||
for(var/obj/item/stack/sheet/hairlesshide/HS in user.loc)
|
||||
if(HS.amount < 50)
|
||||
HS.amount++
|
||||
use(1)
|
||||
break
|
||||
//If it gets to here it means it did not find a suitable stack on the tile.
|
||||
var/obj/item/stack/sheet/hairlesshide/HS = new(user.loc)
|
||||
HS.amount = 1
|
||||
use(1)
|
||||
@@ -230,3 +223,9 @@ GLOBAL_LIST_INIT(sinew_recipes, list ( \
|
||||
HS.amount = 1
|
||||
wetness = initial(wetness)
|
||||
src.use(1)
|
||||
|
||||
/obj/item/stack/sheet/wetleather/microwave_act(obj/machinery/microwave/MW)
|
||||
..()
|
||||
var/obj/item/stack/sheet/leather/L = new(loc)
|
||||
L.amount = amount
|
||||
qdel(src)
|
||||
|
||||
@@ -50,7 +50,8 @@
|
||||
M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
|
||||
M.updateappearance(mutations_overlay_update=1)
|
||||
log_attack(log_msg)
|
||||
return TRUE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/weapon/dnainjector/attack(mob/target, mob/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
@@ -77,9 +78,9 @@
|
||||
|
||||
add_logs(user, target, "injected", src)
|
||||
|
||||
if(!inject(target, user)) //Now we actually do the heavy lifting.
|
||||
to_chat(user, "<span class='notice'>It appears that [target] does not have compatible DNA.</span>")
|
||||
|
||||
if(!inject(target, user)) //Now we actually do the heavy lifting.
|
||||
to_chat(user, "<span class='notice'>It appears that [target] does not have compatible DNA.</span>")
|
||||
|
||||
used = 1
|
||||
icon_state = "dnainjector0"
|
||||
desc += " This one is used up."
|
||||
@@ -307,11 +308,11 @@
|
||||
|
||||
/obj/item/weapon/dnainjector/timed/inject(mob/living/carbon/M, mob/user)
|
||||
prepare()
|
||||
if(M.stat == DEAD) //prevents dead people from having their DNA changed
|
||||
to_chat(user, "<span class='notice'>You can't modify [M]'s DNA while [M.p_theyre()] dead.</span>")
|
||||
return FALSE
|
||||
|
||||
if(M.has_dna() && !(M.disabilities & NOCLONE))
|
||||
if(M.stat == DEAD) //prevents dead people from having their DNA changed
|
||||
to_chat(user, "<span class='notice'>You can't modify [M]'s DNA while [M.p_theyre()] dead.</span>")
|
||||
return
|
||||
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
|
||||
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
|
||||
var/endtime = world.time+duration
|
||||
@@ -352,9 +353,9 @@
|
||||
M.updateappearance(mutations_overlay_update=1)
|
||||
M.dna.temporary_mutations[UI_CHANGED] = endtime
|
||||
log_attack(log_msg)
|
||||
return TRUE
|
||||
else
|
||||
to_chat(user, "<span class='notice'>It appears that [M] does not have compatible DNA.</span>")
|
||||
return
|
||||
return FALSE
|
||||
|
||||
/obj/item/weapon/dnainjector/timed/hulk
|
||||
name = "\improper DNA injector (Hulk)"
|
||||
|
||||
@@ -48,27 +48,27 @@
|
||||
/obj/item/weapon/grenade/attack_self(mob/user)
|
||||
if(!active)
|
||||
if(clown_check(user))
|
||||
preprime(user)
|
||||
preprime(user)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.throw_mode_on()
|
||||
|
||||
/obj/item/weapon/grenade/proc/preprime(mob/user)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>You prime the [name]! [det_time/10] seconds!</span>")
|
||||
playsound(loc, 'sound/weapons/armbomb.ogg', 60, 1)
|
||||
active = TRUE
|
||||
icon_state = initial(icon_state) + "_active"
|
||||
add_fingerprint(user)
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
if(user)
|
||||
var/message = "[ADMIN_LOOKUPFLW(user)]) has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)]"
|
||||
GLOB.bombers += message
|
||||
message_admins(message)
|
||||
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].")
|
||||
|
||||
addtimer(CALLBACK(src, .proc/prime), det_time)
|
||||
/obj/item/weapon/grenade/proc/preprime(mob/user)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>You prime the [name]! [det_time/10] seconds!</span>")
|
||||
playsound(loc, 'sound/weapons/armbomb.ogg', 60, 1)
|
||||
active = TRUE
|
||||
icon_state = initial(icon_state) + "_active"
|
||||
add_fingerprint(user)
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
if(user)
|
||||
var/message = "[ADMIN_LOOKUPFLW(user)]) has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)]"
|
||||
GLOB.bombers += message
|
||||
message_admins(message)
|
||||
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].")
|
||||
|
||||
addtimer(CALLBACK(src, .proc/prime), det_time)
|
||||
|
||||
/obj/item/weapon/grenade/proc/prime()
|
||||
|
||||
@@ -108,4 +108,4 @@
|
||||
if(damage && attack_type == PROJECTILE_ATTACK && prob(15))
|
||||
owner.visible_message("<span class='danger'>[attack_text] hits [owner]'s [src], setting it off! What a shot!</span>")
|
||||
prime()
|
||||
return 1 //It hit the grenade, not them
|
||||
return 1 //It hit the grenade, not them
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
var/mob/living/carbon/human/H = imp_in
|
||||
if(!ishuman(H))
|
||||
return
|
||||
if(istype(H.martial_art, /datum/martial_art/krav_maga))
|
||||
if(!H.mind)
|
||||
return
|
||||
if(istype(H.mind.martial_art, /datum/martial_art/krav_maga))
|
||||
style.remove(H)
|
||||
else
|
||||
style.teach(H,1)
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
target.apply_damage(force * fisto_setting, BRUTE)
|
||||
target.visible_message("<span class='danger'>[user]'s powerfist lets out a loud hiss as they punch [target.name]!</span>", \
|
||||
"<span class='userdanger'>You cry out in pain as [user]'s punch flings you backwards!</span>")
|
||||
new /obj/effect/overlay/temp/kinetic_blast(target.loc)
|
||||
new /obj/effect/temp_visual/kinetic_blast(target.loc)
|
||||
playsound(loc, 'sound/weapons/resonator_blast.ogg', 50, 1)
|
||||
playsound(loc, 'sound/weapons/genhit2.ogg', 50, 1)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user